diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 52ef3bd..a94bade 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,29 +2,33 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-added-large-files - id: check-merge-conflict + - id: check-executables-have-shebangs + - id: check-shebang-scripts-are-executable + - id: end-of-file-fixer - repo: https://github.com/asottile/pyupgrade - rev: v3.3.1 + rev: v3.15.0 hooks: - id: pyupgrade args: - "--py39-plus" - - repo: https://github.com/psf/black - rev: 23.1.0 + - repo: https://github.com/psf/black-pre-commit-mirror + rev: 23.12.1 hooks: - id: black - repo: https://github.com/PyCQA/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 6.1.0 hooks: - id: flake8 additional_dependencies: + - flake8-absolute-import - flake8-annotations - flake8-builtins - flake8-comprehensions @@ -37,7 +41,7 @@ repos: - flake8-use-fstring - flake8-use-pathlib - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.0-alpha.4 + rev: v3.1.0 hooks: - id: prettier args: diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..ed0d2d9 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + "recommendations": [ + "esbenp.prettier-vscode", + "ms-python.black-formatter", + "ms-python.flake8", + "ms-python.isort", + "ms-python.python", + "ms-python.vscode-pylance" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 92897f2..3ecdf52 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,10 +1,16 @@ { - "python.linting.pylintEnabled": false, - "python.linting.flake8Enabled": true, - "python.linting.enabled": true, "editor.formatOnSave": true, - "python.formatting.provider": "black", "python.testing.pytestArgs": ["tests"], "python.testing.pytestEnabled": true, - "git.rebaseWhenSync": true + "git.rebaseWhenSync": true, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[python]": { + "editor.defaultFormatter": "ms-python.black-formatter", + "editor.codeActionsOnSave": { + "source.organizeImports": "explicit" + } + }, + "window.title": "${dirty}${rootName}${separator}${activeEditorShort}" } diff --git a/mtgproxies/cli.py b/mtgproxies/cli.py index cadd2eb..a57c074 100644 --- a/mtgproxies/cli.py +++ b/mtgproxies/cli.py @@ -4,7 +4,7 @@ from mtgproxies.decklists.decklist import Decklist -def parse_decklist_spec(decklist_spec: str, warn_levels=["ERROR", "WARNING", "COSMETIC"]) -> Decklist: +def parse_decklist_spec(decklist_spec: str, warn_levels=("ERROR", "WARNING", "COSMETIC")) -> Decklist: """Attempt to parse a decklist from different locations. Args: diff --git a/mtgproxies/decklists/decklist.py b/mtgproxies/decklists/decklist.py index 8e144e2..69d8e3f 100644 --- a/mtgproxies/decklists/decklist.py +++ b/mtgproxies/decklists/decklist.py @@ -21,10 +21,10 @@ class Card: count: int card: dict[str | Any] - def __getitem__(self, key: str): + def __getitem__(self, key: str) -> Any: return self.card[key] - def __contains__(self, key: str): + def __contains__(self, key: str) -> bool: return key in self.card @property @@ -63,7 +63,7 @@ class Decklist: entries: list[Card | Comment] = field(default_factory=list) name: str = None - def append_card(self, count, card) -> None: + def append_card(self, count: int, card) -> None: """Append a card line to this decklist.""" self.entries.append(Card(count, card)) diff --git a/mtgproxies/decklists/sanitizing.py b/mtgproxies/decklists/sanitizing.py index 1b30c8b..56737b5 100644 --- a/mtgproxies/decklists/sanitizing.py +++ b/mtgproxies/decklists/sanitizing.py @@ -56,7 +56,7 @@ def validate_card_name(card_name: str): return validated_name, warnings -def get_print_warnings(card): +def get_print_warnings(card) -> list[str]: """Returns warnings for low-resolution scans.""" warnings = [] if not card["highres_image"] or card["digital"]: diff --git a/mtgproxies/plotting/splitpages.py b/mtgproxies/plotting/splitpages.py index f2f8cb0..a8d3a1a 100644 --- a/mtgproxies/plotting/splitpages.py +++ b/mtgproxies/plotting/splitpages.py @@ -1,3 +1,7 @@ +from __future__ import annotations + +from types import TracebackType + import matplotlib.pyplot as plt @@ -7,15 +11,21 @@ class SplitPages: This mirrors the functionality of the `PdfPages` wrapper from matplotlib. """ - def __init__(self, filename): + def __init__(self, filename: str) -> None: + """Create a new SplitPages object.""" self.file_basename = filename[: filename.rindex(".")] self.file_extension = filename[filename.rindex(".") :] self.pagecount = 0 - def __enter__(self): + def __enter__(self) -> SplitPages: return self - def __exit__(self, exc_type, exc_val, exc_tb): + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ): pass def savefig(self, figure=None, **kwargs): diff --git a/mtgproxies/print_cards.py b/mtgproxies/print_cards.py index ddec26d..93ae6e4 100644 --- a/mtgproxies/print_cards.py +++ b/mtgproxies/print_cards.py @@ -104,7 +104,7 @@ def print_cards_fpdf( border_crop: int = 14, background_color: tuple[int, int, int] = None, cropmarks: bool = True, -): +) -> None: """Print a list of cards to a pdf file. Args: diff --git a/pyproject.toml b/pyproject.toml index 0788a5e..f40db30 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,2 +1,3 @@ [tool.black] line-length = 120 +target-version = ['py39', 'py310', 'py311', 'py312'] diff --git a/scryfall/rate_limit.py b/scryfall/rate_limit.py index 932904d..4d38aae 100644 --- a/scryfall/rate_limit.py +++ b/scryfall/rate_limit.py @@ -1,5 +1,8 @@ +from __future__ import annotations + import threading import time +from types import TracebackType class RateLimiter: @@ -23,5 +26,10 @@ def __enter__(self) -> None: self.last_call = time.time() return self - def __exit__(self, type, value, traceback) -> None: + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: pass # Nothing to do here diff --git a/setup.cfg b/setup.cfg index 11105a0..b74c731 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,10 +1,10 @@ [flake8] -ignore = E203,E741,W503,D100,D104,D105,PL123,ANN101 +ignore = E203,E741,W503,D100,D104,D105,PL123,ANN101,ANN102 per-file-ignores = - tests/*:D103,ANN201 + tests/*:D103,ANN201,ABS101 max-line-length = 120 docstring-convention = google -known-modules = mtg-proxies:[mtgproxies,scryfall] +known-modules = mtg-proxies:[mtgproxies,scryfall],fpdf2:[fpdf] [isort] line_length = 120 diff --git a/setup.py b/setup.py index bf8eb90..8339a6e 100644 --- a/setup.py +++ b/setup.py @@ -6,14 +6,15 @@ Modified by Madoshakalaka@Github (dependency links added) """ -from os import path +from pathlib import Path from setuptools import find_packages, setup -here = path.abspath(path.dirname(__file__)) +here = Path(__file__).parent + # Get the long description from the README file -with open(path.join(here, "README.md"), encoding="utf-8") as f: +with open(here / "README.md", encoding="utf-8") as f: long_description = f.read() # Arguments marked as "Required" below must be included for upload to PyPI. diff --git a/test_token.py b/test_token.py index 2401c89..207486b 100644 --- a/test_token.py +++ b/test_token.py @@ -24,7 +24,7 @@ def find_token(type_line, power, toughness, colors, oracle_text): return scryfall.recommend_print(oracle_id=cards[0]["oracle_id"]) -def parse_colors(s): +def parse_colors(s: str): colors = set() reverse_color_names = {value: key for key, value in color_names.items()} diff --git a/tests/scryfall_test.py b/tests/scryfall_test.py index 4e34832..f0f695b 100644 --- a/tests/scryfall_test.py +++ b/tests/scryfall_test.py @@ -16,7 +16,7 @@ def test_get_faces(id: str, n_faces: int): card = scryfall.card_by_id()[id] faces = scryfall.get_faces(card) - assert type(faces) == list + assert type(faces) is list assert len(faces) == n_faces for face in faces: assert "illustration_id" in face