From 9bee9ba11b1a388fe36dfe32990322c7f14499e3 Mon Sep 17 00:00:00 2001 From: Jovial Joe Jayarson Date: Tue, 13 Jun 2023 19:17:26 +0530 Subject: [PATCH 1/3] maint: migrate to black formatting --- .gitignore | 1 + main.py | 290 +++++++++++++++++++++------------------------ tests/test_main.py | 130 ++++++++++---------- 3 files changed, 201 insertions(+), 220 deletions(-) diff --git a/.gitignore b/.gitignore index 5dbaef6..03bcb22 100644 --- a/.gitignore +++ b/.gitignore @@ -113,6 +113,7 @@ celerybeat.pid # Environments *.env +env.sh .venv env/ venv/ diff --git a/main.py b/main.py index 0963da2..7a2706d 100644 --- a/main.py +++ b/main.py @@ -45,42 +45,36 @@ import re import os # external -# # requests from requests.exceptions import RequestException from requests import get as rq_get -# # github from github import GithubException, Github -# # faker from faker import Faker -# pylint: disable = logging-fstring-interpolation - - ################### setup ################### print() # hush existing loggers -# pylint: disable = no-member # see: https://stackoverflow.com/q/20965287 for lgr_name in logger.root.manager.loggerDict: # to disable log propagation completely set '.propagate = False' logger.getLogger(lgr_name).setLevel(logger.WARNING) -# pylint: enable = no-member # somehow github.Requester gets missed out from loggerDict -logger.getLogger('github.Requester').setLevel(logger.WARNING) +logger.getLogger("github.Requester").setLevel(logger.WARNING) # configure logger logger.basicConfig( - datefmt='%Y-%m-%d %H:%M:%S', - format='[%(asctime)s] ln. %(lineno)-3d %(levelname)-8s %(message)s', - level=logger.DEBUG + datefmt="%Y-%m-%d %H:%M:%S", + format="[%(asctime)s] ln. %(lineno)-3d %(levelname)-8s %(message)s", + level=logger.DEBUG, ) try: - if len(sys.argv) == 2 and sys.argv[1] == '--dev': + if len(sys.argv) == 2 and sys.argv[1] == "--dev": # get env-vars from .env file for development from dotenv import load_dotenv + # comment this out to disable colored logging from loguru import logger + # load from .env before class def gets parsed load_dotenv() except ImportError as im_err: @@ -109,13 +103,13 @@ def strtobool(val: str | bool): val = val.lower() - if val in {'y', 'yes', 't', 'true', 'on', '1'}: + if val in {"y", "yes", "t", "true", "on", "1"}: return True - if val in {'n', 'no', 'f', 'false', 'off', '0'}: + if val in {"n", "no", "f", "false", "off", "0"}: return False - raise ValueError(f'invalid truth value for {val}') + raise ValueError(f"invalid truth value for {val}") ################### data ################### @@ -127,52 +121,49 @@ class WakaInput: WakaReadme Input Env Variables ------------------------------ """ + # constants prefix_length: int = 16 graph_length: int = 25 # mapped environment variables # # required - gh_token: str | None = os.getenv('INPUT_GH_TOKEN') - waka_key: str | None = os.getenv('INPUT_WAKATIME_API_KEY') - api_base_url: str | None = os.getenv( - 'INPUT_API_BASE_URL', 'https://wakatime.com/api' - ) - repository: str | None = os.getenv('INPUT_REPOSITORY') + gh_token: str | None = os.getenv("INPUT_GH_TOKEN") + waka_key: str | None = os.getenv("INPUT_WAKATIME_API_KEY") + api_base_url: str | None = os.getenv("INPUT_API_BASE_URL", "https://wakatime.com/api") + repository: str | None = os.getenv("INPUT_REPOSITORY") # # depends commit_message: str = os.getenv( - 'INPUT_COMMIT_MESSAGE', 'Updated WakaReadme graph with new metrics' + "INPUT_COMMIT_MESSAGE", "Updated WakaReadme graph with new metrics" ) - code_lang: str = os.getenv('INPUT_CODE_LANG', 'txt') - _section_name: str = os.getenv('INPUT_SECTION_NAME', 'waka') - start_comment: str = f'' - end_comment: str = f'' - waka_block_pattern: str = f'{start_comment}[\\s\\S]+{end_comment}' + code_lang: str = os.getenv("INPUT_CODE_LANG", "txt") + _section_name: str = os.getenv("INPUT_SECTION_NAME", "waka") + start_comment: str = f"" + end_comment: str = f"" + waka_block_pattern: str = f"{start_comment}[\\s\\S]+{end_comment}" # # optional - show_title: str | bool = os.getenv('INPUT_SHOW_TITLE') or False - block_style: str = os.getenv('INPUT_BLOCKS', '░▒▓█') - time_range: str = os.getenv('INPUT_TIME_RANGE', 'last_7_days') - show_time: str | bool = os.getenv('INPUT_SHOW_TIME') or False - show_total_time: str | bool = os.getenv('INPUT_SHOW_TOTAL') or False - show_masked_time: str | bool = os.getenv('INPUT_SHOW_MASKED_TIME') or False - language_count: str | int = os.getenv('INPUT_LANG_COUNT') or 5 - stop_at_other: str | bool = os.getenv('INPUT_STOP_AT_OTHER') or False + show_title: str | bool = os.getenv("INPUT_SHOW_TITLE") or False + block_style: str = os.getenv("INPUT_BLOCKS", "░▒▓█") + time_range: str = os.getenv("INPUT_TIME_RANGE", "last_7_days") + show_time: str | bool = os.getenv("INPUT_SHOW_TIME") or False + show_total_time: str | bool = os.getenv("INPUT_SHOW_TOTAL") or False + show_masked_time: str | bool = os.getenv("INPUT_SHOW_MASKED_TIME") or False + language_count: str | int = os.getenv("INPUT_LANG_COUNT") or 5 + stop_at_other: str | bool = os.getenv("INPUT_STOP_AT_OTHER") or False def validate_input(self): """ Validate Input Env Variables ---------------------------- """ - logger.debug('Validating input variables') + logger.debug("Validating input variables") if not self.gh_token or not self.waka_key or not self.api_base_url or not self.repository: - logger.error('Invalid inputs') - logger.info('Refer https://github.com/athul/waka-readme') + logger.error("Invalid inputs") + logger.info("Refer https://github.com/athul/waka-readme") return False if len(self.commit_message) < 1: - logger.error( - 'Commit message length must be greater than 1 character long' - ) + logger.error("Commit message length must be greater than 1 character long") return False try: @@ -186,35 +177,39 @@ class WakaInput: return False if not self._section_name.isalnum(): - logger.warning('Section name must be in any of [[a-z][A-Z][0-9]]') - logger.debug('Using default section name: waka') - self._section_name = 'waka' - self.start_comment = f'' - self.end_comment = f'' - self.waka_block_pattern = f'{self.start_comment}[\\s\\S]+{self.end_comment}' + logger.warning("Section name must be in any of [[a-z][A-Z][0-9]]") + logger.debug("Using default section name: waka") + self._section_name = "waka" + self.start_comment = f"" + self.end_comment = f"" + self.waka_block_pattern = f"{self.start_comment}[\\s\\S]+{self.end_comment}" if len(self.block_style) < 2: - logger.warning('Graph block must be longer than 2 characters') - logger.debug('Using default blocks: ░▒▓█') - self.block_style = '░▒▓█' + logger.warning("Graph block must be longer than 2 characters") + logger.debug("Using default blocks: ░▒▓█") + self.block_style = "░▒▓█" if self.time_range not in { - 'last_7_days', 'last_30_days', 'last_6_months', 'last_year', 'all_time' - }: # 'all_time' is un-documented, should it be used? - logger.warning('Invalid time range') - logger.debug('Using default time range: last_7_days') - self.time_range = 'last_7_days' + "last_7_days", + "last_30_days", + "last_6_months", + "last_year", + "all_time", + }: # "all_time" is un-documented, should it be used? + logger.warning("Invalid time range") + logger.debug("Using default time range: last_7_days") + self.time_range = "last_7_days" try: self.language_count = int(self.language_count) if self.language_count < -1: raise ValueError except ValueError: - logger.warning('Invalid language count') - logger.debug('Using default language count: 5') + logger.warning("Invalid language count") + logger.debug("Using default language count: 5") self.language_count = 5 - logger.debug('Input validation complete\n') + logger.debug("Input validation complete\n") return True @@ -228,40 +223,38 @@ def make_title(dawn: str | None, dusk: str | None, /): Makes title for WakaReadme. """ - logger.debug('Making title') + logger.debug("Making title") if not dawn or not dusk: - logger.error('Cannot find start/end date\n') + logger.error("Cannot find start/end date\n") sys.exit(1) - api_dfm, msg_dfm = '%Y-%m-%dT%H:%M:%SZ', '%d %B %Y' + api_dfm, msg_dfm = "%Y-%m-%dT%H:%M:%SZ", "%d %B %Y" try: start_date = datetime.strptime(dawn, api_dfm).strftime(msg_dfm) end_date = datetime.strptime(dusk, api_dfm).strftime(msg_dfm) except ValueError as err: - logger.error(f'{err}\n') + logger.error(f"{err}\n") sys.exit(1) - logger.debug('Title was made\n') - return f'From: {start_date} - To: {end_date}' + logger.debug("Title was made\n") + return f"From: {start_date} - To: {end_date}" -def make_graph(block_style: str, percent: float, gr_len: int, lg_nm: str = '', /): +def make_graph(block_style: str, percent: float, gr_len: int, lg_nm: str = "", /): """ WakaReadme Graph ---------------- Makes time graph from the API's data. """ - logger.debug(f'Generating graph for "{lg_nm or "..."}"') + logger.debug(f"Generating graph for '{lg_nm or '...'}'") markers = len(block_style) - 1 proportion = percent / 100 * gr_len graph_bar = block_style[-1] * int(proportion + 0.5 / markers) - remainder_block = int( - (proportion - len(graph_bar)) * markers + 0.5 - ) - graph_bar += block_style[remainder_block] if remainder_block > 0 else '' + remainder_block = int((proportion - len(graph_bar)) * markers + 0.5) + graph_bar += block_style[remainder_block] if remainder_block > 0 else "" graph_bar += block_style[0] * (gr_len - len(graph_bar)) - logger.debug(f'"{lg_nm or "..."}" graph generated') + logger.debug(f"'{lg_nm or '...'}' graph generated") return graph_bar @@ -273,68 +266,65 @@ def prep_content(stats: dict[str, Any], language_count: int = 5, stop_at_other: Prepared markdown content from the fetched statistics. ``` """ - logger.debug('Making contents') - contents = '' + logger.debug("Making contents") + contents = "" # make title if wk_i.show_title: - contents += make_title(stats.get('start'), stats.get('end')) + '\n\n' + contents += make_title(stats.get("start"), stats.get("end")) + "\n\n" # make byline if wk_i.show_masked_time and ( - total_time := stats.get('human_readable_total_including_other_language') + total_time := stats.get("human_readable_total_including_other_language") ): - # overrides 'human_readable_total' - contents += f'Total Time: {total_time}\n\n' - elif wk_i.show_total_time and ( - total_time := stats.get('human_readable_total') - ): - contents += f'Total Time: {total_time}\n\n' + # overrides "human_readable_total" + contents += f"Total Time: {total_time}\n\n" + elif wk_i.show_total_time and (total_time := stats.get("human_readable_total")): + contents += f"Total Time: {total_time}\n\n" lang_info: list[dict[str, int | float | str]] | None = [] # Check if any language data exists - if not (lang_info := stats.get('languages')): - logger.debug('The API data seems to be empty, please wait for a day') - contents += 'No activity tracked' - return contents.rstrip('\n') + if not (lang_info := stats.get("languages")): + logger.debug("The API data seems to be empty, please wait for a day") + contents += "No activity tracked" + return contents.rstrip("\n") # make lang content pad_len = len( # comment if it feels way computationally expensive - max((str(lng['name']) for lng in lang_info), key=len) + max((str(lng["name"]) for lng in lang_info), key=len) # and then don't for get to set pad_len to say 13 :) ) if language_count == 0 and not stop_at_other: logger.debug( - 'Set INPUT_LANG_COUNT to -1 to retrieve all language' - + ' or specify a positive number (ie. above 0)' + "Set INPUT_LANG_COUNT to -1 to retrieve all language" + + " or specify a positive number (ie. above 0)" ) - return contents.rstrip('\n') + return contents.rstrip("\n") for idx, lang in enumerate(lang_info): - lang_name = str(lang['name']) + lang_name = str(lang["name"]) # >>> add languages to filter here <<< # if lang_name in {...}: continue - lang_time = str(lang['text']) if wk_i.show_time else '' - lang_ratio = float(lang['percent']) - lang_bar = make_graph( - wk_i.block_style, lang_ratio, wk_i.graph_length, lang_name - ) + lang_time = str(lang["text"]) if wk_i.show_time else "" + lang_ratio = float(lang["percent"]) + lang_bar = make_graph(wk_i.block_style, lang_ratio, wk_i.graph_length, lang_name) contents += ( - f'{lang_name.ljust(pad_len)} ' + - f'{lang_time: <16}{lang_bar} ' + - f'{lang_ratio:.2f}'.zfill(5) + ' %\n' + f"{lang_name.ljust(pad_len)} " + + f"{lang_time: <16}{lang_bar} " + + f"{lang_ratio:.2f}".zfill(5) + + " %\n" ) if language_count == -1: continue - if stop_at_other and (lang_name == 'Other'): + if stop_at_other and (lang_name == "Other"): break - if idx+1 >= language_count > 0: # idx starts at 0 + if idx + 1 >= language_count > 0: # idx starts at 0 break - logger.debug('Contents were made\n') - return contents.rstrip('\n') + logger.debug("Contents were made\n") + return contents.rstrip("\n") def fetch_stats(): @@ -346,44 +336,38 @@ def fetch_stats(): """ attempts = 4 statistic: dict[str, dict[str, Any]] = {} - encoded_key = str( - b64encode(bytes(str(wk_i.waka_key), 'utf-8')), 'utf-8' - ) - logger.debug( - f'Pulling WakaTime stats from {" ".join(wk_i.time_range.split("_"))}' - ) + encoded_key = str(b64encode(bytes(str(wk_i.waka_key), "utf-8")), "utf-8") + logger.debug(f"Pulling WakaTime stats from {' '.join(wk_i.time_range.split('_'))}") while attempts > 0: - resp_message, fake_ua = '', cryptogenic.choice( - [str(fake.user_agent()) for _ in range(5)] - ) + resp_message, fake_ua = "", cryptogenic.choice([str(fake.user_agent()) for _ in range(5)]) # making a request - if (resp := rq_get( - url=f'{str(wk_i.api_base_url).rstrip("/")}/v1/users/current/stats/{wk_i.time_range}', - headers={ - 'Authorization': f'Basic {encoded_key}', - 'User-Agent': fake_ua, - }, - timeout=30 * (5 - attempts) - )).status_code != 200: - resp_message += f' • {conn_info}' if ( - conn_info := resp.json().get('message') - ) else '' + if ( + resp := rq_get( + url=f"{str(wk_i.api_base_url).rstrip('/')}/v1/users/current/stats/{wk_i.time_range}", + headers={ + "Authorization": f"Basic {encoded_key}", + "User-Agent": fake_ua, + }, + timeout=(30.0 * (5 - attempts)), + ) + ).status_code != 200: + resp_message += f" • {conn_info}" if (conn_info := resp.json().get("message")) else "" logger.debug( - f'API response #{5 - attempts}: {resp.status_code} • {resp.reason}{resp_message}' + f"API response #{5 - attempts}: {resp.status_code} •" + f" {resp.reason}{resp_message}" ) if resp.status_code == 200 and (statistic := resp.json()): - logger.debug('Fetched WakaTime statistics') + logger.debug("Fetched WakaTime statistics") break - logger.debug(f'Retrying in {30 * (5 - attempts )}s ...') + logger.debug(f"Retrying in {30 * (5 - attempts )}s ...") sleep(30 * (5 - attempts)) attempts -= 1 - if err := (statistic.get('error') or statistic.get('errors')): - logger.error(f'{err}\n') + if err := (statistic.get("error") or statistic.get("errors")): + logger.error(f"{err}\n") sys.exit(1) print() - return statistic.get('data') + return statistic.get("data") def churn(old_readme: str, /): @@ -395,31 +379,29 @@ def churn(old_readme: str, /): """ # check if placeholder pattern exists in readme if not re.findall(wk_i.waka_block_pattern, old_readme): - logger.warning( - f'Can\'t find `{wk_i.waka_block_pattern}` pattern in readme' - ) + logger.warning(f"Can't find `{wk_i.waka_block_pattern}` pattern in readme") return None # getting contents if not (waka_stats := fetch_stats()): - logger.error('Unable to fetch data, please rerun workflow\n') + logger.error("Unable to fetch data, please rerun workflow\n") sys.exit(1) # preparing contents try: - generated_content = prep_content(waka_stats, int( - wk_i.language_count), bool(wk_i.stop_at_other) + generated_content = prep_content( + waka_stats, int(wk_i.language_count), bool(wk_i.stop_at_other) ) except (AttributeError, KeyError, ValueError) as err: - logger.error(f'Unable to read API data | {err}\n') + logger.error(f"Unable to read API data | {err}\n") sys.exit(1) - print(generated_content, '\n', sep='') + print(generated_content, "\n", sep="") # substituting old contents new_readme = re.sub( pattern=wk_i.waka_block_pattern, - repl=f'{wk_i.start_comment}\n\n```{wk_i.code_lang}\n{generated_content}\n```\n\n{wk_i.end_comment}', - string=old_readme + repl=f"{wk_i.start_comment}\n\n```{wk_i.code_lang}\n{generated_content}\n```\n\n{wk_i.end_comment}", + string=old_readme, ) - if len(sys.argv) == 2 and sys.argv[1] == '--dev': - logger.debug('Detected run in `dev` mode.') + if len(sys.argv) == 2 and sys.argv[1] == "--dev": + logger.debug("Detected run in `dev` mode.") # to avoid accidentally writing back to Github # when developing and testing WakaReadme return None @@ -432,41 +414,41 @@ def genesis(): Run Program ----------- """ - logger.debug('Connecting to GitHub') + logger.debug("Connecting to GitHub") gh_connect = Github(wk_i.gh_token) # since a validator is being used casting to string here is okay gh_repo = gh_connect.get_repo(str(wk_i.repository)) readme_file = gh_repo.get_readme() - logger.debug('Decoding readme contents\n') - readme_contents = str(readme_file.decoded_content, encoding='utf-8') + logger.debug("Decoding readme contents\n") + readme_contents = str(readme_file.decoded_content, encoding="utf-8") if new_content := churn(readme_contents): - logger.debug('WakaReadme stats has changed') + logger.debug("WakaReadme stats has changed") gh_repo.update_file( path=readme_file.path, message=wk_i.commit_message, content=new_content, - sha=readme_file.sha + sha=readme_file.sha, ) - logger.info('Stats updated successfully') + logger.info("Stats updated successfully") return - logger.info('WakaReadme was not updated') + logger.info("WakaReadme was not updated") ################### driver ################### -if __name__ == '__main__': +if __name__ == "__main__": # faker data preparation fake = Faker() Faker.seed(0) cryptogenic = SystemRandom() # initial waka-readme setup - logger.debug('Initialize WakaReadme') + logger.debug("Initialize WakaReadme") wk_i = WakaInput() if not wk_i.validate_input(): - logger.error('Environment variables are misconfigured\n') + logger.error("Environment variables are misconfigured\n") sys.exit(1) # run @@ -474,9 +456,9 @@ if __name__ == '__main__': genesis() except KeyboardInterrupt: print() - logger.error('Interrupt signal received\n') + logger.error("Interrupt signal received\n") sys.exit(1) except (GithubException, RequestException) as rq_exp: - logger.critical(f'{rq_exp}\n') + logger.critical(f"{rq_exp}\n") sys.exit(1) - print('\nThanks for using WakaReadme!\n') + print("\nThanks for using WakaReadme!\n") diff --git a/tests/test_main.py b/tests/test_main.py index 9e261ad..1793cfc 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -6,16 +6,17 @@ Tests for the main.py from importlib import import_module from dataclasses import dataclass # , field from itertools import product -# from pathlib import Path -# from inspect import cleandoc -# from typing import Any -# from json import load import unittest import sys import os +# from pathlib import Path +# from inspect import cleandoc +# from typing import Any +# from json import load + try: - prime = import_module('main') + prime = import_module("main") # works when running as # python -m unittest discover except ImportError as err: @@ -26,6 +27,7 @@ except ImportError as err: @dataclass class TestData: """Test Data""" + # for future tests # waka_json: dict[str, dict[str, Any]] = field( # default_factory=lambda: {} @@ -33,66 +35,66 @@ class TestData: bar_percent: tuple[int | float, ...] | None = None graph_blocks: tuple[str, ...] | None = None waka_graphs: tuple[list[str], ...] | None = None - dummy_readme: str = '' + dummy_readme: str = "" def populate(self) -> None: """Populate Test Data""" # for future tests # with open( - # file=Path(__file__).parent / 'sample_data.json', - # encoding='utf-8', - # mode='rt', + # file=Path(__file__).parent / "sample_data.json", + # encoding="utf-8", + # mode="rt", # ) as wkf: # self.waka_json = load(wkf) - self.bar_percent = ( - 0, 100, 49.999, 50, 25, 75, 3.14, 9.901, 87.334, 87.333, 4.666, 4.667 - ) + self.bar_percent = (0, 100, 49.999, 50, 25, 75, 3.14, 9.901, 87.334, 87.333, 4.666, 4.667) self.graph_blocks = ("░▒▓█", "⚪⚫", "⓪①②③④⑤⑥⑦⑧⑨⑩") - self.waka_graphs = ([ - "░░░░░░░░░░░░░░░░░░░░░░░░░", - "█████████████████████████", - "████████████▒░░░░░░░░░░░░", - "████████████▓░░░░░░░░░░░░", - "██████▒░░░░░░░░░░░░░░░░░░", - "██████████████████▓░░░░░░", - "▓░░░░░░░░░░░░░░░░░░░░░░░░", - "██▒░░░░░░░░░░░░░░░░░░░░░░", - "██████████████████████░░░", - "█████████████████████▓░░░", - "█░░░░░░░░░░░░░░░░░░░░░░░░", - "█▒░░░░░░░░░░░░░░░░░░░░░░░" - ], + self.waka_graphs = ( [ - "⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪", - "⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫", - "⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪", - "⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪", - "⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪", - "⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪", - "⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪", - "⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪", - "⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪", - "⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪", - "⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪", - "⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪" - ], + "░░░░░░░░░░░░░░░░░░░░░░░░░", + "█████████████████████████", + "████████████▒░░░░░░░░░░░░", + "████████████▓░░░░░░░░░░░░", + "██████▒░░░░░░░░░░░░░░░░░░", + "██████████████████▓░░░░░░", + "▓░░░░░░░░░░░░░░░░░░░░░░░░", + "██▒░░░░░░░░░░░░░░░░░░░░░░", + "██████████████████████░░░", + "█████████████████████▓░░░", + "█░░░░░░░░░░░░░░░░░░░░░░░░", + "█▒░░░░░░░░░░░░░░░░░░░░░░░", + ], [ - "⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪", - "⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩", - "⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑤⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪", - "⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑤⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪", - "⑩⑩⑩⑩⑩⑩③⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪", - "⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑧⓪⓪⓪⓪⓪⓪", - "⑧⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪", - "⑩⑩⑤⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪", - "⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑧⓪⓪⓪", - "⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑧⓪⓪⓪", - "⑩②⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪", - "⑩②⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪" - ]) + "⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪", + "⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫", + "⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪", + "⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪", + "⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪", + "⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪⚪⚪⚪", + "⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪", + "⚫⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪", + "⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪", + "⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚫⚪⚪⚪", + "⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪", + "⚫⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪", + ], + [ + "⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪", + "⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩", + "⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑤⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪", + "⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑤⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪", + "⑩⑩⑩⑩⑩⑩③⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪", + "⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑧⓪⓪⓪⓪⓪⓪", + "⑧⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪", + "⑩⑩⑤⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪", + "⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑧⓪⓪⓪", + "⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑩⑧⓪⓪⓪", + "⑩②⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪", + "⑩②⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪⓪", + ], + ) # self.dummy_readme = cleandoc(""" # My Test Readme Start @@ -108,42 +110,38 @@ class TestMain(unittest.TestCase): def test_make_graph(self) -> None: """Test graph maker""" if not tds.graph_blocks or not tds.waka_graphs or not tds.bar_percent: - raise AssertionError('Data population failed') + raise AssertionError("Data population failed") for (idx, grb), (jdy, bpc) in product( enumerate(tds.graph_blocks), enumerate(tds.bar_percent) ): - self.assertEqual( - prime.make_graph(grb, bpc, 25), - tds.waka_graphs[idx][jdy] - ) + self.assertEqual(prime.make_graph(grb, bpc, 25), tds.waka_graphs[idx][jdy]) def test_make_title(self) -> None: """Test title maker""" self.assertRegex( - prime.make_title('2022-01-11T23:18:19Z', '2021-12-09T10:22:06Z'), - r'From: \d{2} \w{3,9} \d{4} - To: \d{2} \w{3,9} \d{4}' + prime.make_title("2022-01-11T23:18:19Z", "2021-12-09T10:22:06Z"), + r"From: \d{2} \w{3,9} \d{4} - To: \d{2} \w{3,9} \d{4}", ) def test_strtobool(self) -> None: """Test string to bool""" - self.assertTrue(prime.strtobool('Yes')) - self.assertFalse(prime.strtobool('nO')) + self.assertTrue(prime.strtobool("Yes")) + self.assertFalse(prime.strtobool("nO")) self.assertTrue(prime.strtobool(True)) self.assertRaises(AttributeError, prime.strtobool, None) - self.assertRaises(ValueError, prime.strtobool, 'yo!') + self.assertRaises(ValueError, prime.strtobool, "yo!") self.assertRaises(AttributeError, prime.strtobool, 20.5) tds = TestData() tds.populate() -if __name__ == '__main__': +if __name__ == "__main__": try: - sys.path.insert(0, os.path.abspath( - os.path.join(os.path.dirname(__file__), '..') - )) + sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) import main as prime + # works when running as # python tests/test_main.py except ImportError as im_er: From 82c9408d6d18f495ac3c53e28cc4d4d7790cc000 Mon Sep 17 00:00:00 2001 From: Jovial Joe Jayarson Date: Tue, 13 Jun 2023 19:40:52 +0530 Subject: [PATCH 2/3] maint: follows google pydocstyle --- main.py | 69 +++++++++++++++++----------------------------- tests/test_main.py | 16 +++++------ 2 files changed, 33 insertions(+), 52 deletions(-) diff --git a/main.py b/main.py index 7a2706d..5f02ab0 100644 --- a/main.py +++ b/main.py @@ -1,25 +1,20 @@ -""" -WakaReadme : WakaTime progress visualizer -========================================= +"""WakaReadme : WakaTime progress visualizer. Wakatime Metrics on your Profile Readme. Title: ------- ```txt From: 15 February, 2022 - To: 22 February, 2022 ```` Byline: -------- ```txt Total: 34 hrs 43 mins ``` Body: ------ ```txt Python 27 hrs 29 mins ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣀⣀⣀⣀⣀ 77.83 % @@ -29,7 +24,7 @@ TOML 1 hr 48 mins ⣿⣤⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀ Other 35 mins ⣦⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀ 01.68 % ``` -#### Contents = Title + Byline + Body +Contents := Title + Byline + Body """ # standard @@ -85,18 +80,25 @@ except ImportError as im_err: def strtobool(val: str | bool): - """ - strtobool - --------- + """Strtobool. - PEP 632 https://www.python.org/dev/peps/pep-0632/ is depreciating distutils. - This is from the official source code with slight modifications. + PEP 632 https://www.python.org/dev/peps/pep-0632/ is depreciating distutils. + This is from the official source code with slight modifications. - Converts a string representation of truth to True or False. + Converts a string representation of truth to `True` or `False`. - - True values are `'y', 'yes', 't', 'true', 'on', and '1'`. - - False values are `'n', 'no', 'f', 'false', 'off', and '0'`. - - Raises `ValueError` if `val` is anything else. + Args: + val: + Value to be converted to bool. + + Returns: + (Literal[True]): + If `val` is any of 'y', 'yes', 't', 'true', 'on', or '1'. + (Literal[False]): + If `val` is any of 'n', 'no', 'f', 'false', 'off', and '0'. + + Raises: + ValueError: If `val` is anything else. """ if isinstance(val, bool): return val @@ -117,10 +119,7 @@ def strtobool(val: str | bool): @dataclass(slots=True) class WakaInput: - """ - WakaReadme Input Env Variables - ------------------------------ - """ + """WakaReadme Input Env Variables.""" # constants prefix_length: int = 16 @@ -152,10 +151,7 @@ class WakaInput: stop_at_other: str | bool = os.getenv("INPUT_STOP_AT_OTHER") or False def validate_input(self): - """ - Validate Input Env Variables - ---------------------------- - """ + """Validate Input Env Variables.""" logger.debug("Validating input variables") if not self.gh_token or not self.waka_key or not self.api_base_url or not self.repository: logger.error("Invalid inputs") @@ -217,9 +213,7 @@ class WakaInput: def make_title(dawn: str | None, dusk: str | None, /): - """ - WakaReadme Title - ---------------- + """WakaReadme Title. Makes title for WakaReadme. """ @@ -240,9 +234,7 @@ def make_title(dawn: str | None, dusk: str | None, /): def make_graph(block_style: str, percent: float, gr_len: int, lg_nm: str = "", /): - """ - WakaReadme Graph - ---------------- + """WakaReadme Graph. Makes time graph from the API's data. """ @@ -259,9 +251,7 @@ def make_graph(block_style: str, percent: float, gr_len: int, lg_nm: str = "", / def prep_content(stats: dict[str, Any], language_count: int = 5, stop_at_other: bool = False, /): - """ - WakaReadme Prepare Markdown - --------------------------- + """WakaReadme Prepare Markdown. Prepared markdown content from the fetched statistics. ``` @@ -328,9 +318,7 @@ def prep_content(stats: dict[str, Any], language_count: int = 5, stop_at_other: def fetch_stats(): - """ - WakaReadme Fetch Stats - ---------------------- + """WakaReadme Fetch Stats. Returns statistics as JSON string. """ @@ -371,9 +359,7 @@ def fetch_stats(): def churn(old_readme: str, /): - """ - WakaReadme Churn - ---------------- + """WakaReadme Churn. Composes WakaTime stats within markdown code snippet. """ @@ -410,10 +396,7 @@ def churn(old_readme: str, /): def genesis(): - """ - Run Program - ----------- - """ + """Run Program.""" logger.debug("Connecting to GitHub") gh_connect = Github(wk_i.gh_token) # since a validator is being used casting to string here is okay diff --git a/tests/test_main.py b/tests/test_main.py index 1793cfc..8bc3fc4 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1,6 +1,4 @@ -""" -Tests for the main.py -""" +"""Unit Tests.""" # standard from importlib import import_module @@ -26,7 +24,7 @@ except ImportError as err: @dataclass class TestData: - """Test Data""" + """Test Data.""" # for future tests # waka_json: dict[str, dict[str, Any]] = field( @@ -38,7 +36,7 @@ class TestData: dummy_readme: str = "" def populate(self) -> None: - """Populate Test Data""" + """Populate Test Data.""" # for future tests # with open( # file=Path(__file__).parent / "sample_data.json", @@ -105,10 +103,10 @@ class TestData: class TestMain(unittest.TestCase): - """Testing Main Module""" + """Testing Main Module.""" def test_make_graph(self) -> None: - """Test graph maker""" + """Test graph maker.""" if not tds.graph_blocks or not tds.waka_graphs or not tds.bar_percent: raise AssertionError("Data population failed") @@ -118,14 +116,14 @@ class TestMain(unittest.TestCase): self.assertEqual(prime.make_graph(grb, bpc, 25), tds.waka_graphs[idx][jdy]) def test_make_title(self) -> None: - """Test title maker""" + """Test title maker.""" self.assertRegex( prime.make_title("2022-01-11T23:18:19Z", "2021-12-09T10:22:06Z"), r"From: \d{2} \w{3,9} \d{4} - To: \d{2} \w{3,9} \d{4}", ) def test_strtobool(self) -> None: - """Test string to bool""" + """Test string to bool.""" self.assertTrue(prime.strtobool("Yes")) self.assertFalse(prime.strtobool("nO")) self.assertTrue(prime.strtobool(True)) From 1fc26a41215ad9af81415e6792283e0f655a00ef Mon Sep 17 00:00:00 2001 From: Jovial Joe Jayarson Date: Tue, 13 Jun 2023 20:03:28 +0530 Subject: [PATCH 3/3] feat: update dependencies; bump version --- .gitignore | 3 + poetry.lock | 450 ++++++++++++++++++++----------------------------- poetry.toml | 2 + pyproject.toml | 53 +++++- 4 files changed, 236 insertions(+), 272 deletions(-) diff --git a/.gitignore b/.gitignore index 03bcb22..ddf70ba 100644 --- a/.gitignore +++ b/.gitignore @@ -157,3 +157,6 @@ cython_debug/ # asdf .tool-versions + +# ruff +.ruff_cache diff --git a/poetry.lock b/poetry.lock index 26203d6..101b0d3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,41 +1,9 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. - -[[package]] -name = "astroid" -version = "2.15.4" -description = "An abstract syntax tree for Python with inference support." -category = "dev" -optional = false -python-versions = ">=3.7.2" -files = [ - {file = "astroid-2.15.4-py3-none-any.whl", hash = "sha256:a1b8543ef9d36ea777194bc9b17f5f8678d2c56ee6a45b2c2f17eec96f242347"}, - {file = "astroid-2.15.4.tar.gz", hash = "sha256:c81e1c7fbac615037744d067a9bb5f9aeb655edf59b63ee8b59585475d6f80d8"}, -] - -[package.dependencies] -lazy-object-proxy = ">=1.4.0" -wrapt = {version = ">=1.14,<2", markers = "python_version >= \"3.11\""} - -[[package]] -name = "autopep8" -version = "2.0.2" -description = "A tool that automatically formats Python code to conform to the PEP 8 style guide" -category = "dev" -optional = false -python-versions = ">=3.6" -files = [ - {file = "autopep8-2.0.2-py2.py3-none-any.whl", hash = "sha256:86e9303b5e5c8160872b2f5ef611161b2893e9bfe8ccc7e2f76385947d57a2f1"}, - {file = "autopep8-2.0.2.tar.gz", hash = "sha256:f9849cdd62108cb739dbcdbfb7fdcc9a30d1b63c4cc3e1c1f893b5360941b61c"}, -] - -[package.dependencies] -pycodestyle = ">=2.10.0" +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "bandit" version = "1.7.5" description = "Security oriented static analyser for python code." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -55,23 +23,68 @@ test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", toml = ["tomli (>=1.1.0)"] yaml = ["PyYAML"] +[[package]] +name = "black" +version = "23.3.0" +description = "The uncompromising code formatter." +optional = false +python-versions = ">=3.7" +files = [ + {file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"}, + {file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"}, + {file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"}, + {file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"}, + {file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"}, + {file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"}, + {file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"}, + {file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"}, + {file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"}, + {file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"}, + {file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"}, + {file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"}, + {file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"}, + {file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"}, + {file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"}, + {file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"}, +] + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + [[package]] name = "certifi" -version = "2022.12.7" +version = "2023.5.7" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, - {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, + {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, + {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, ] [[package]] name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." -category = "main" optional = false python-versions = "*" files = [ @@ -148,7 +161,6 @@ pycparser = "*" name = "charset-normalizer" version = "3.1.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -229,11 +241,24 @@ files = [ {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, ] +[[package]] +name = "click" +version = "8.1.3" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + [[package]] name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -243,31 +268,30 @@ files = [ [[package]] name = "cryptography" -version = "41.0.0" +version = "41.0.1" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-41.0.0-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:3c5ef25d060c80d6d9f7f9892e1d41bb1c79b78ce74805b8cb4aa373cb7d5ec8"}, - {file = "cryptography-41.0.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:8362565b3835ceacf4dc8f3b56471a2289cf51ac80946f9087e66dc283a810e0"}, - {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3680248309d340fda9611498a5319b0193a8dbdb73586a1acf8109d06f25b92d"}, - {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84a165379cb9d411d58ed739e4af3396e544eac190805a54ba2e0322feb55c46"}, - {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:4ab14d567f7bbe7f1cdff1c53d5324ed4d3fc8bd17c481b395db224fb405c237"}, - {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9f65e842cb02550fac96536edb1d17f24c0a338fd84eaf582be25926e993dde4"}, - {file = "cryptography-41.0.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:b7f2f5c525a642cecad24ee8670443ba27ac1fab81bba4cc24c7b6b41f2d0c75"}, - {file = "cryptography-41.0.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7d92f0248d38faa411d17f4107fc0bce0c42cae0b0ba5415505df72d751bf62d"}, - {file = "cryptography-41.0.0-cp37-abi3-win32.whl", hash = "sha256:34d405ea69a8b34566ba3dfb0521379b210ea5d560fafedf9f800a9a94a41928"}, - {file = "cryptography-41.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:344c6de9f8bda3c425b3a41b319522ba3208551b70c2ae00099c205f0d9fd3be"}, - {file = "cryptography-41.0.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:88ff107f211ea696455ea8d911389f6d2b276aabf3231bf72c8853d22db755c5"}, - {file = "cryptography-41.0.0-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:b846d59a8d5a9ba87e2c3d757ca019fa576793e8758174d3868aecb88d6fc8eb"}, - {file = "cryptography-41.0.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f5d0bf9b252f30a31664b6f64432b4730bb7038339bd18b1fafe129cfc2be9be"}, - {file = "cryptography-41.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5c1f7293c31ebc72163a9a0df246f890d65f66b4a40d9ec80081969ba8c78cc9"}, - {file = "cryptography-41.0.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bf8fc66012ca857d62f6a347007e166ed59c0bc150cefa49f28376ebe7d992a2"}, - {file = "cryptography-41.0.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a4fc68d1c5b951cfb72dfd54702afdbbf0fb7acdc9b7dc4301bbf2225a27714d"}, - {file = "cryptography-41.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:14754bcdae909d66ff24b7b5f166d69340ccc6cb15731670435efd5719294895"}, - {file = "cryptography-41.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0ddaee209d1cf1f180f1efa338a68c4621154de0afaef92b89486f5f96047c55"}, - {file = "cryptography-41.0.0.tar.gz", hash = "sha256:6b71f64beeea341c9b4f963b48ee3b62d62d57ba93eb120e1196b31dc1025e78"}, + {file = "cryptography-41.0.1-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:f73bff05db2a3e5974a6fd248af2566134d8981fd7ab012e5dd4ddb1d9a70699"}, + {file = "cryptography-41.0.1-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:1a5472d40c8f8e91ff7a3d8ac6dfa363d8e3138b961529c996f3e2df0c7a411a"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fa01527046ca5facdf973eef2535a27fec4cb651e4daec4d043ef63f6ecd4ca"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b46e37db3cc267b4dea1f56da7346c9727e1209aa98487179ee8ebed09d21e43"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d198820aba55660b4d74f7b5fd1f17db3aa5eb3e6893b0a41b75e84e4f9e0e4b"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:948224d76c4b6457349d47c0c98657557f429b4e93057cf5a2f71d603e2fc3a3"}, + {file = "cryptography-41.0.1-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:059e348f9a3c1950937e1b5d7ba1f8e968508ab181e75fc32b879452f08356db"}, + {file = "cryptography-41.0.1-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:b4ceb5324b998ce2003bc17d519080b4ec8d5b7b70794cbd2836101406a9be31"}, + {file = "cryptography-41.0.1-cp37-abi3-win32.whl", hash = "sha256:8f4ab7021127a9b4323537300a2acfb450124b2def3756f64dc3a3d2160ee4b5"}, + {file = "cryptography-41.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:1fee5aacc7367487b4e22484d3c7e547992ed726d14864ee33c0176ae43b0d7c"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:9a6c7a3c87d595608a39980ebaa04d5a37f94024c9f24eb7d10262b92f739ddb"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5d092fdfedaec4cbbffbf98cddc915ba145313a6fdaab83c6e67f4e6c218e6f3"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a8e6c2de6fbbcc5e14fd27fb24414507cb3333198ea9ab1258d916f00bc3039"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb33ccf15e89f7ed89b235cff9d49e2e62c6c981a6061c9c8bb47ed7951190bc"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5f0ff6e18d13a3de56f609dd1fd11470918f770c6bd5d00d632076c727d35485"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7bfc55a5eae8b86a287747053140ba221afc65eb06207bedf6e019b8934b477c"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:eb8163f5e549a22888c18b0d53d6bb62a20510060a22fd5a995ec8a05268df8a"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:8dde71c4169ec5ccc1087bb7521d54251c016f126f922ab2dfe6649170a3b8c5"}, + {file = "cryptography-41.0.1.tar.gz", hash = "sha256:d34579085401d3f49762d2f7d6634d6b6c2ae1242202e860f4d26b046e3a1006"}, ] [package.dependencies] @@ -285,47 +309,30 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.13" +version = "1.2.14" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ - {file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"}, - {file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"}, + {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, + {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest (<5)", "PyTest-Cov", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] - -[[package]] -name = "dill" -version = "0.3.6" -description = "serialize all of python" -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"}, - {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"}, -] - -[package.extras] -graph = ["objgraph (>=1.7.2)"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] [[package]] name = "faker" -version = "18.6.2" +version = "18.10.1" description = "Faker is a Python package that generates fake data for you." -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "Faker-18.6.2-py3-none-any.whl", hash = "sha256:6385386ba8d5aa255bec72f5392c2b795fcec8bebf975a9953488948d54bce35"}, - {file = "Faker-18.6.2.tar.gz", hash = "sha256:ef61bbf266d30819e83bab4a6c74a0f5979ce4d19d4c9305719dd26cb7d8d51c"}, + {file = "Faker-18.10.1-py3-none-any.whl", hash = "sha256:633b278caa3ec239463f9139c74da2607c8da5710e56d5d7d30fc8a7440104c4"}, + {file = "Faker-18.10.1.tar.gz", hash = "sha256:d9f363720c4a6cf9884c6c3e26e2ce26266ffe5d741a9bc7cb9256779bc62190"}, ] [package.dependencies] @@ -335,7 +342,6 @@ python-dateutil = ">=2.4" name = "gitdb" version = "4.0.10" description = "Git Object Database" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -350,7 +356,6 @@ smmap = ">=3.0.1,<6" name = "gitpython" version = "3.1.31" description = "GitPython is a Python library used to interact with Git repositories" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -365,7 +370,6 @@ gitdb = ">=4.0.1,<5" name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -373,75 +377,10 @@ files = [ {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, ] -[[package]] -name = "isort" -version = "5.12.0" -description = "A Python utility / library to sort Python imports." -category = "dev" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, - {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, -] - -[package.extras] -colors = ["colorama (>=0.4.3)"] -pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] -plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] - -[[package]] -name = "lazy-object-proxy" -version = "1.9.0" -description = "A fast and thorough lazy object proxy." -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, -] - [[package]] name = "loguru" version = "0.7.0" description = "Python logging made (stupidly) simple" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -458,14 +397,13 @@ dev = ["Sphinx (==5.3.0)", "colorama (==0.4.5)", "colorama (==0.4.6)", "freezegu [[package]] name = "markdown-it-py" -version = "2.2.0" +version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" -category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"}, - {file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"}, + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, ] [package.dependencies] @@ -478,26 +416,13 @@ compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0 linkify = ["linkify-it-py (>=1,<3)"] plugins = ["mdit-py-plugins"] profiling = ["gprof2dot"] -rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] -[[package]] -name = "mccabe" -version = "0.7.0" -description = "McCabe checker, plugin for flake8" -category = "dev" -optional = false -python-versions = ">=3.6" -files = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] - [[package]] name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -505,11 +430,43 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "packaging" +version = "23.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, + {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, +] + +[[package]] +name = "pathspec" +version = "0.11.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, + {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, +] + [[package]] name = "pbr" version = "5.11.1" description = "Python Build Reasonableness" -category = "dev" optional = false python-versions = ">=2.6" files = [ @@ -519,37 +476,23 @@ files = [ [[package]] name = "platformdirs" -version = "3.5.0" +version = "3.5.3" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.5.0-py3-none-any.whl", hash = "sha256:47692bc24c1958e8b0f13dd727307cff1db103fca36399f457da8e05f222fdc4"}, - {file = "platformdirs-3.5.0.tar.gz", hash = "sha256:7954a68d0ba23558d753f73437c55f89027cf8f5108c19844d4b82e5af396335"}, + {file = "platformdirs-3.5.3-py3-none-any.whl", hash = "sha256:0ade98a4895e87dc51d47151f7d2ec290365a585151d97b4d8d6312ed6132fed"}, + {file = "platformdirs-3.5.3.tar.gz", hash = "sha256:e48fabd87db8f3a7df7150a4a5ea22c546ee8bc39bc2473244730d4b56d2cc4e"}, ] [package.extras] -docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] - -[[package]] -name = "pycodestyle" -version = "2.10.0" -description = "Python style guide checker" -category = "dev" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pycodestyle-2.10.0-py2.py3-none-any.whl", hash = "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"}, - {file = "pycodestyle-2.10.0.tar.gz", hash = "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053"}, -] +docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"] [[package]] name = "pycparser" version = "2.21" description = "C parser in Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -559,14 +502,13 @@ files = [ [[package]] name = "pygithub" -version = "1.58.1" +version = "1.58.2" description = "Use the full Github API v3" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "PyGithub-1.58.1-py3-none-any.whl", hash = "sha256:4e7fe9c3ec30d5fde5b4fbb97f18821c9dbf372bf6df337fe66f6689a65e0a83"}, - {file = "PyGithub-1.58.1.tar.gz", hash = "sha256:7d528b4ad92bc13122129fafd444ce3d04c47d2d801f6446b6e6ee2d410235b3"}, + {file = "PyGithub-1.58.2-py3-none-any.whl", hash = "sha256:f435884af617c6debaa76cbc355372d1027445a56fbc39972a3b9ed4968badc8"}, + {file = "PyGithub-1.58.2.tar.gz", hash = "sha256:1e6b1b7afe31f75151fb81f7ab6b984a7188a852bdb123dbb9ae90023c3ce60f"}, ] [package.dependencies] @@ -579,7 +521,6 @@ requests = ">=2.14.0" name = "pygments" version = "2.15.1" description = "Pygments is a syntax highlighting package written in Python." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -592,14 +533,13 @@ plugins = ["importlib-metadata"] [[package]] name = "pyjwt" -version = "2.6.0" +version = "2.7.0" description = "JSON Web Token implementation in Python" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "PyJWT-2.6.0-py3-none-any.whl", hash = "sha256:d83c3d892a77bbb74d3e1a2cfa90afaadb60945205d1095d9221f04466f64c14"}, - {file = "PyJWT-2.6.0.tar.gz", hash = "sha256:69285c7e31fc44f68a1feb309e948e0df53259d579295e6cfe2b1792329f05fd"}, + {file = "PyJWT-2.7.0-py3-none-any.whl", hash = "sha256:ba2b425b15ad5ef12f200dc67dd56af4e26de2331f965c5439994dad075876e1"}, + {file = "PyJWT-2.7.0.tar.gz", hash = "sha256:bd6ca4a3c4285c1a2d4349e5a035fdf8fb94e04ccd0fcbe6ba289dae9cc3e074"}, ] [package.dependencies] @@ -611,36 +551,10 @@ dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pyte docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] -[[package]] -name = "pylint" -version = "2.17.3" -description = "python code static checker" -category = "dev" -optional = false -python-versions = ">=3.7.2" -files = [ - {file = "pylint-2.17.3-py3-none-any.whl", hash = "sha256:a6cbb4c6e96eab4a3c7de7c6383c512478f58f88d95764507d84c899d656a89a"}, - {file = "pylint-2.17.3.tar.gz", hash = "sha256:761907349e699f8afdcd56c4fe02f3021ab5b3a0fc26d19a9bfdc66c7d0d5cd5"}, -] - -[package.dependencies] -astroid = ">=2.15.4,<=2.17.0-dev0" -colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -dill = {version = ">=0.3.6", markers = "python_version >= \"3.11\""} -isort = ">=4.2.5,<6" -mccabe = ">=0.6,<0.8" -platformdirs = ">=2.2.0" -tomlkit = ">=0.10.1" - -[package.extras] -spelling = ["pyenchant (>=3.2,<4.0)"] -testutils = ["gitpython (>3)"] - [[package]] name = "pynacl" version = "1.5.0" description = "Python binding to the Networking and Cryptography (NaCl) library" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -667,7 +581,6 @@ tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -682,7 +595,6 @@ six = ">=1.5" name = "python-dotenv" version = "1.0.0" description = "Read key-value pairs from a .env file and set them as environment variables" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -697,7 +609,6 @@ cli = ["click (>=5.0)"] name = "pyyaml" version = "6.0" description = "YAML parser and emitter for Python" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -747,7 +658,6 @@ files = [ name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -767,28 +677,52 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.3.5" +version = "13.4.2" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -category = "dev" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.3.5-py3-none-any.whl", hash = "sha256:69cdf53799e63f38b95b9bf9c875f8c90e78dd62b2f00c13a911c7a3b9fa4704"}, - {file = "rich-13.3.5.tar.gz", hash = "sha256:2d11b9b8dd03868f09b4fffadc84a6a8cda574e40dc90821bd845720ebb8e89c"}, + {file = "rich-13.4.2-py3-none-any.whl", hash = "sha256:8f87bc7ee54675732fa66a05ebfe489e27264caeeff3728c945d25971b6485ec"}, + {file = "rich-13.4.2.tar.gz", hash = "sha256:d653d6bccede5844304c605d5aac802c7cf9621efd700b46c7ec2b51ea914898"}, ] [package.dependencies] -markdown-it-py = ">=2.2.0,<3.0.0" +markdown-it-py = ">=2.2.0" pygments = ">=2.13.0,<3.0.0" [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] +[[package]] +name = "ruff" +version = "0.0.272" +description = "An extremely fast Python linter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.0.272-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:ae9b57546e118660175d45d264b87e9b4c19405c75b587b6e4d21e6a17bf4fdf"}, + {file = "ruff-0.0.272-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:1609b864a8d7ee75a8c07578bdea0a7db75a144404e75ef3162e0042bfdc100d"}, + {file = "ruff-0.0.272-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee76b4f05fcfff37bd6ac209d1370520d509ea70b5a637bdf0a04d0c99e13dff"}, + {file = "ruff-0.0.272-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:48eccf225615e106341a641f826b15224b8a4240b84269ead62f0afd6d7e2d95"}, + {file = "ruff-0.0.272-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:677284430ac539bb23421a2b431b4ebc588097ef3ef918d0e0a8d8ed31fea216"}, + {file = "ruff-0.0.272-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9c4bfb75456a8e1efe14c52fcefb89cfb8f2a0d31ed8d804b82c6cf2dc29c42c"}, + {file = "ruff-0.0.272-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86bc788245361a8148ff98667da938a01e1606b28a45e50ac977b09d3ad2c538"}, + {file = "ruff-0.0.272-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:27b2ea68d2aa69fff1b20b67636b1e3e22a6a39e476c880da1282c3e4bf6ee5a"}, + {file = "ruff-0.0.272-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd2bbe337a3f84958f796c77820d55ac2db1e6753f39d1d1baed44e07f13f96d"}, + {file = "ruff-0.0.272-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d5a208f8ef0e51d4746930589f54f9f92f84bb69a7d15b1de34ce80a7681bc00"}, + {file = "ruff-0.0.272-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:905ff8f3d6206ad56fcd70674453527b9011c8b0dc73ead27618426feff6908e"}, + {file = "ruff-0.0.272-py3-none-musllinux_1_2_i686.whl", hash = "sha256:19643d448f76b1eb8a764719072e9c885968971bfba872e14e7257e08bc2f2b7"}, + {file = "ruff-0.0.272-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:691d72a00a99707a4e0b2846690961157aef7b17b6b884f6b4420a9f25cd39b5"}, + {file = "ruff-0.0.272-py3-none-win32.whl", hash = "sha256:dc406e5d756d932da95f3af082814d2467943631a587339ee65e5a4f4fbe83eb"}, + {file = "ruff-0.0.272-py3-none-win_amd64.whl", hash = "sha256:a37ec80e238ead2969b746d7d1b6b0d31aa799498e9ba4281ab505b93e1f4b28"}, + {file = "ruff-0.0.272-py3-none-win_arm64.whl", hash = "sha256:06b8ee4eb8711ab119db51028dd9f5384b44728c23586424fd6e241a5b9c4a3b"}, + {file = "ruff-0.0.272.tar.gz", hash = "sha256:273a01dc8c3c4fd4c2af7ea7a67c8d39bb09bce466e640dd170034da75d14cab"}, +] + [[package]] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -800,7 +734,6 @@ files = [ name = "smmap" version = "5.0.0" description = "A pure Python implementation of a sliding window memory map manager" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -810,53 +743,39 @@ files = [ [[package]] name = "stevedore" -version = "5.0.0" +version = "5.1.0" description = "Manage dynamic plugins for Python applications" -category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "stevedore-5.0.0-py3-none-any.whl", hash = "sha256:bd5a71ff5e5e5f5ea983880e4a1dd1bb47f8feebbb3d95b592398e2f02194771"}, - {file = "stevedore-5.0.0.tar.gz", hash = "sha256:2c428d2338976279e8eb2196f7a94910960d9f7ba2f41f3988511e95ca447021"}, + {file = "stevedore-5.1.0-py3-none-any.whl", hash = "sha256:8cc040628f3cea5d7128f2e76cf486b2251a4e543c7b938f58d9a377f6694a2d"}, + {file = "stevedore-5.1.0.tar.gz", hash = "sha256:a54534acf9b89bc7ed264807013b505bf07f74dbe4bcfa37d32bd063870b087c"}, ] [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" [[package]] -name = "tomlkit" -version = "0.11.8" -description = "Style preserving TOML library" -category = "dev" +name = "urllib3" +version = "2.0.3" +description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.7" files = [ - {file = "tomlkit-0.11.8-py3-none-any.whl", hash = "sha256:8c726c4c202bdb148667835f68d68780b9a003a9ec34167b6c673b38eff2a171"}, - {file = "tomlkit-0.11.8.tar.gz", hash = "sha256:9330fc7faa1db67b541b28e62018c17d20be733177d290a13b24c62d1614e0c3"}, -] - -[[package]] -name = "urllib3" -version = "1.26.15" -description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, - {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, + {file = "urllib3-2.0.3-py3-none-any.whl", hash = "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1"}, + {file = "urllib3-2.0.3.tar.gz", hash = "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] -secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] [[package]] name = "win32-setctime" version = "1.1.0" description = "A small Python utility to set file creation time on Windows" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -871,7 +790,6 @@ dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"] name = "wrapt" version = "1.15.0" description = "Module for decorators, wrappers and monkey patching." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -955,4 +873,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "e368c1f2f1987f42fd91766848463443b0c6e768d2698e7c031077a45a878866" +content-hash = "ea47c80c21aad63ad15cbc17a15da81646cd7ec873b9148774c943c26e2c0e28" diff --git a/poetry.toml b/poetry.toml index d11b90b..56f0a25 100644 --- a/poetry.toml +++ b/poetry.toml @@ -1,2 +1,4 @@ [virtualenvs] prefer-active-python = true +in-project = true +path = ".venv" diff --git a/pyproject.toml b/pyproject.toml index 4503b6b..aa62f91 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,27 +1,68 @@ +#################### +# Metadata # +#################### + [tool.poetry] name = "waka-readme" -version = "0.2.0" +version = "0.2.1" description = "Wakatime Weekly Metrics on your Profile Readme." authors = ["Athul Cyriac Ajay "] license = "MIT" readme = "README.md" + +#################### +# Dependencies # +#################### + [tool.poetry.dependencies] python = "^3.11" -faker = "^18.6.2" -pygithub = "^1.58.1" +faker = "^18.10.1" +pygithub = "^1.58.2" requests = "^2.31.0" [tool.poetry.group.dev] optional = true [tool.poetry.group.dev.dependencies] -autopep8 = "^2.0.2" -bandit = "^1.7.5" loguru = "^0.7.0" -pylint = "^2.17.3" python-dotenv = "^1.0.0" +[tool.poetry.group.tooling] +optional = true + +[tool.poetry.group.tooling.dependencies] +bandit = "^1.7.5" +black = "^23.3.0" +ruff = "^0.0.272" + + +#################### +# Build System # +#################### + [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" + + +#################### +# Configurations # +#################### + +[tool.black] +line-length = 100 +target-version = ["py311"] + +[tool.bandit] +exclude_dirs = [".github", ".pytest_cache", ".tox", ".vscode", "site", "tests"] + +[tool.ruff] +line-length = 100 + +[tool.ruff.pydocstyle] +convention = "google" + +[tool.ruff.isort] +force-sort-within-sections = true +relative-imports-order = "closest-to-furthest"