diff --git a/.github/workflows/black-fmt.yml b/.github/workflows/black-fmt.yml deleted file mode 100644 index 1ea06e7..0000000 --- a/.github/workflows/black-fmt.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: black-action - -on: [push, pull_request, workflow_dispatch] - -jobs: - linter_name: - name: black formatter - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Check files using the black formatter - uses: rickstaa/action-black@v1 - id: action_black - with: - black_args: ". --line-length 120 --check --diff" diff --git a/.github/workflows/lint-and-fmt.yml b/.github/workflows/lint-and-fmt.yml new file mode 100644 index 0000000..2dc3660 --- /dev/null +++ b/.github/workflows/lint-and-fmt.yml @@ -0,0 +1,52 @@ +name: Lint and Format + +on: + push: + branches: [main] + pull_request: + merge_group: + workflow_dispatch: + +jobs: + lint-and-fmt: + runs-on: ubuntu-latest + strategy: + matrix: + # Only run linter and formatter on minimum supported Python version + python-version: ["3.8"] + architecture: ["x64"] + name: lint and fmt - Python ${{ matrix.python-version }} on ${{ matrix.architecture }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install prettier + run: | + npm install -g prettier + + - name: Install poetry + run: pipx install poetry + + - name: Install python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + architecture: ${{ matrix.architecture }} + cache: "poetry" + + - name: Install just + uses: extractions/setup-just@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install dependencies + run: | + just ci-install + + - name: lint + run: | + just ci-lint + + - name: format check + run: | + just ci-fmt-check diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index e266018..a8c5a71 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -1,15 +1,20 @@ name: Unit Test -on: [push, pull_request, workflow_dispatch] +on: + push: + branches: [main] + pull_request: + merge_group: + workflow_dispatch: jobs: unit-test: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12-dev"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] architecture: ["x64"] - name: Python ${{ matrix.python-version }} on ${{ matrix.architecture }} test + name: unittest - Python ${{ matrix.python-version }} on ${{ matrix.architecture }} steps: - name: Checkout uses: actions/checkout@v4 @@ -24,11 +29,15 @@ jobs: architecture: ${{ matrix.architecture }} cache: "poetry" + - name: Install just + uses: extractions/setup-just@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Install dependencies - if: steps.poetry-cache.outputs.cache-hit != 'true' run: | - poetry install -E rst-parser + just ci-install - name: unit test run: | - poetry run pytest + just ci-test diff --git a/.vscode/settings.json b/.vscode/settings.json index 9f541b9..594c544 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,9 @@ { "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python", - "python.formatting.provider": "black", - "python.formatting.blackArgs": ["--line-length", "120"], "python.analysis.typeCheckingMode": "strict", "python.analysis.inlayHints.functionReturnTypes": true, - "python.analysis.inlayHints.variableTypes": true + "python.analysis.inlayHints.variableTypes": true, + "[python]": { + "editor.defaultFormatter": "charliermarsh.ruff" + } } diff --git a/dochooks/_compat.py b/dochooks/_compat.py index d530af4..f2a9f5c 100644 --- a/dochooks/_compat.py +++ b/dochooks/_compat.py @@ -1,35 +1,12 @@ from __future__ import annotations -try: - from typing import Literal # type: ignore -except ImportError: - from typing_extensions import Literal # type: ignore +import sys -try: - from typing import Final # type: ignore -except ImportError: - from typing_extensions import Final # type: ignore - -try: - from typing import TypeAlias # type: ignore -except ImportError: - from typing_extensions import TypeAlias # type: ignore - -try: - from typing import TypedDict # type: ignore -except ImportError: - from typing_extensions import TypedDict # type: ignore - -try: - from typing import assert_type # type: ignore -except ImportError: - from typing_extensions import assert_type # type: ignore - -try: +if sys.version_info >= (3, 9): from functools import cache # type: ignore -except ImportError: +else: from functools import lru_cache # type: ignore cache = lru_cache(maxsize=None) -__all__ = ["Literal", "Final", "TypeAlias", "TypedDict", "assert_type", "cache"] +__all__ = ["cache"] diff --git a/dochooks/api_doc_checker/check.py b/dochooks/api_doc_checker/check.py index 7005a15..ca7285a 100644 --- a/dochooks/api_doc_checker/check.py +++ b/dochooks/api_doc_checker/check.py @@ -1,7 +1,7 @@ from __future__ import annotations import argparse -from typing import Optional, Sequence +from typing import Sequence from dochooks import __version__ @@ -34,7 +34,7 @@ def check(text: str, file_path: str = "") -> bool: def _check_file(file_path: str) -> ReturnCode: return_code = PASS - with open(file_path, "r", encoding="utf8", newline="\n") as f: + with open(file_path, encoding="utf8", newline="\n") as f: content = f.read() if not check(content, file_path): # print(f"No spaces between EN and CN chars detected at: {file_path}:{lineno}:\t{line}") @@ -42,7 +42,7 @@ def _check_file(file_path: str) -> ReturnCode: return return_code -def main(argv: Optional[Sequence[str]] = None) -> ReturnCode: +def main(argv: Sequence[str] | None = None) -> ReturnCode: parser = argparse.ArgumentParser(prog="dochooks", description="pre-commit hooks for documentation") parser.add_argument("-v", "--version", action="version", version=__version__) parser.add_argument("filenames", nargs="*", help="Filenames to check") diff --git a/dochooks/api_doc_checker/checkers/dead_link_checker.py b/dochooks/api_doc_checker/checkers/dead_link_checker.py index 140f294..42238bc 100644 --- a/dochooks/api_doc_checker/checkers/dead_link_checker.py +++ b/dochooks/api_doc_checker/checkers/dead_link_checker.py @@ -2,7 +2,6 @@ import re from pathlib import Path -from typing import Optional import docutils.nodes import httpx @@ -15,7 +14,7 @@ class DeadLinkChecker(Checker): - _links: list[tuple[Optional[int], str]] = [] + _links: list[tuple[int | None, str]] = [] def visit_reference(self, node: docutils.nodes.Element): uri = node.get("refuri") diff --git a/dochooks/api_doc_checker/checkers/parameters_checker.py b/dochooks/api_doc_checker/checkers/parameters_checker.py index c05ecdc..9851e6e 100644 --- a/dochooks/api_doc_checker/checkers/parameters_checker.py +++ b/dochooks/api_doc_checker/checkers/parameters_checker.py @@ -1,11 +1,10 @@ from __future__ import annotations import re -from typing import Optional +from typing import Literal, TypedDict import docutils.nodes -from ..._compat import Literal, TypedDict from ..utils import PATTERN_IDENTIFIER, is_valid_identifier from .checker import Checker, assert_is_element @@ -14,11 +13,11 @@ class APIParameter(TypedDict): name: str - type: Optional[str] + type: str | None is_rest: bool is_keyword: bool optional: bool - default: Optional[str] + default: str | None class ParametersChecker(Checker): @@ -34,8 +33,8 @@ class ParametersChecker(Checker): _check_result = True _section_name_stack: list[str] = [] - _api_type: Optional[APIType] = None - _api_name: Optional[str] = None + _api_type: APIType | None = None + _api_name: str | None = None _api_parameters: list[APIParameter] # TODO: 直接抽取函数声明来检查 @@ -82,7 +81,7 @@ def visit_section(self, node: docutils.nodes.Element): def depart_section(self, node: docutils.nodes.Element): self._section_name_stack.pop() - def _extract_parameter_info_from_list_item(self, node: docutils.nodes.Element) -> Optional[APIParameter]: + def _extract_parameter_info_from_list_item(self, node: docutils.nodes.Element) -> APIParameter | None: """对单行信息进行提取并检查""" doc_parameter: APIParameter = APIParameter( @@ -203,10 +202,10 @@ def result(self) -> bool: return self._check_result -def parse_api_name_and_parameters(api_declaration: str) -> tuple[Optional[str], list[APIParameter]]: +def parse_api_name_and_parameters(api_declaration: str) -> tuple[str | None, list[APIParameter]]: """解析 API 声明的名称和参数""" - api_name: Optional[str] = None + api_name: str | None = None api_parameters: list[APIParameter] = [] api_declaration = api_declaration.strip() diff --git a/dochooks/api_doc_checker/core/roles.py b/dochooks/api_doc_checker/core/roles.py index e72ab57..97b0452 100644 --- a/dochooks/api_doc_checker/core/roles.py +++ b/dochooks/api_doc_checker/core/roles.py @@ -9,10 +9,9 @@ - [The Docutils Document Tree](https://docutils.sourceforge.io/docs/ref/doctree.html) """ - from __future__ import annotations -from typing import Any, Callable, Optional +from typing import TYPE_CHECKING, Any, Callable, Optional import docutils import docutils.nodes @@ -112,18 +111,19 @@ # https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html SPHINX_EXT_AUTODOC_ROLES: list[str] = [] -RoleFn = Callable[ - [ - str, - str, - str, - int, - docutils.parsers.rst.states.Inliner, - Optional[dict[str, Any]], - Optional[list[str]], - ], - tuple[list[Any], list[Any]], -] +if TYPE_CHECKING: + RoleFn = Callable[ + [ + str, + str, + str, + int, + docutils.parsers.rst.states.Inliner, + Optional[dict[str, Any]], # type: ignore + Optional[list[str]], # type: ignore + ], + tuple[list[Any], list[Any]], # type: ignore + ] def _ignore_role( @@ -132,8 +132,8 @@ def _ignore_role( text: str, lineno: int, inliner: docutils.parsers.rst.states.Inliner, - options: Optional[dict[str, Any]] = None, - content: Optional[list[str]] = None, + options: dict[str, Any] | None = None, + content: list[str] | None = None, ) -> tuple[list[Any], list[Any]]: """Stub for unknown roles.""" print("name:", name) @@ -159,8 +159,8 @@ def _custom_role( text: str, lineno: int, inliner: docutils.parsers.rst.states.Inliner, - options: Optional[dict[str, Any]] = None, - content: Optional[list[str]] = None, + options: dict[str, Any] | None = None, + content: list[str] | None = None, ) -> tuple[list[Any], list[Any]]: node = docutils.nodes.literal( rawsource=rawtext, diff --git a/dochooks/insert_whitespace_between_cn_and_en_char/check.py b/dochooks/insert_whitespace_between_cn_and_en_char/check.py index 8e51f4a..056e5a4 100644 --- a/dochooks/insert_whitespace_between_cn_and_en_char/check.py +++ b/dochooks/insert_whitespace_between_cn_and_en_char/check.py @@ -1,7 +1,7 @@ from __future__ import annotations import argparse -from typing import Optional, Sequence +from typing import Sequence from dochooks import __version__ @@ -17,7 +17,7 @@ def check(string: str) -> bool: def _check_file(file_path: str) -> ReturnCode: return_code = PASS - with open(file_path, "r", encoding="utf8", newline="\n") as f: + with open(file_path, encoding="utf8", newline="\n") as f: for lineno, line in enumerate(f, 1): if not check(line): print(f"No spaces between EN and CN chars detected at: {file_path}:{lineno}:\t{line}") @@ -25,7 +25,7 @@ def _check_file(file_path: str) -> ReturnCode: return return_code -def main(argv: Optional[Sequence[str]] = None) -> ReturnCode: +def main(argv: Sequence[str] | None = None) -> ReturnCode: parser = argparse.ArgumentParser(prog="dochooks", description="pre-commit hooks for documentation") parser.add_argument("-v", "--version", action="version", version=__version__) parser.add_argument("filenames", nargs="*", help="Filenames to check") diff --git a/dochooks/insert_whitespace_between_cn_and_en_char/format.py b/dochooks/insert_whitespace_between_cn_and_en_char/format.py index ea9fa32..c12735f 100644 --- a/dochooks/insert_whitespace_between_cn_and_en_char/format.py +++ b/dochooks/insert_whitespace_between_cn_and_en_char/format.py @@ -1,7 +1,7 @@ from __future__ import annotations import argparse -from typing import Optional, Sequence +from typing import Sequence from dochooks import __version__ @@ -19,7 +19,7 @@ def format(text: str) -> str: def _format_file(file_path: str) -> ReturnCode: return_code = PASS formatted_text = "" - with open(file_path, "r", encoding="utf8", newline="\n") as f: + with open(file_path, encoding="utf8", newline="\n") as f: for lineno, line in enumerate(f, 1): if not check(line): line = format(line) @@ -32,7 +32,7 @@ def _format_file(file_path: str) -> ReturnCode: return return_code -def main(argv: Optional[Sequence[str]] = None) -> ReturnCode: +def main(argv: Sequence[str] | None = None) -> ReturnCode: parser = argparse.ArgumentParser(prog="dochooks", description="pre-commit hooks for documentation") parser.add_argument("-v", "--version", action="version", version=__version__) parser.add_argument("filenames", nargs="*", help="Filenames to check") diff --git a/dochooks/insert_whitespace_between_cn_and_en_char/regex.py b/dochooks/insert_whitespace_between_cn_and_en_char/regex.py index c272d0e..23bf08c 100644 --- a/dochooks/insert_whitespace_between_cn_and_en_char/regex.py +++ b/dochooks/insert_whitespace_between_cn_and_en_char/regex.py @@ -1,9 +1,7 @@ from __future__ import annotations import re -from typing import Pattern - -from .._compat import Final +from typing import Final, Pattern REGEX_CN_CHAR_STR: Final[str] = r"[\u4e00-\u9fa5]" REGEX_EN_CHAR_STR: Final[str] = r"[a-zA-Z0-9]" diff --git a/justfile b/justfile index 9917faa..ac43716 100644 --- a/justfile +++ b/justfile @@ -1,18 +1,21 @@ VERSION := `poetry run python -c "import sys; from dochooks import __version__ as version; sys.stdout.write(version)"` +install: + poetry install -E rst-parser + test: poetry run pytest just clean fmt: - poetry run isort . - poetry run black . - -fmt-docs: - prettier --write '**/*.md' + poetry run ruff format . lint: poetry run pyright dochooks tests + poetry run ruff check . + +fmt-docs: + prettier --write '**/*.md' build: poetry build @@ -37,3 +40,17 @@ clean-builds: hooks-update: poetry run pre-commit autoupdate + +ci-install: + poetry install --no-interaction --no-root -E rst-parser + +ci-fmt-check: + poetry run ruff format --check --diff . + prettier --check '**/*.md' + +ci-lint: + just lint + +ci-test: + poetry run pytest --reruns 3 --reruns-delay 1 + just clean diff --git a/poetry.lock b/poetry.lock index 7508db3..cb2f514 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,108 +1,49 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "anyio" -version = "3.7.1" +version = "4.3.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, - {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, + {file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"}, + {file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"}, ] [package.dependencies] -exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" +typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} [package.extras] -doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"] -test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (<0.22)"] - -[[package]] -name = "black" -version = "24.2.0" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.8" -files = [ - {file = "black-24.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6981eae48b3b33399c8757036c7f5d48a535b962a7c2310d19361edeef64ce29"}, - {file = "black-24.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d533d5e3259720fdbc1b37444491b024003e012c5173f7d06825a77508085430"}, - {file = "black-24.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61a0391772490ddfb8a693c067df1ef5227257e72b0e4108482b8d41b5aee13f"}, - {file = "black-24.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:992e451b04667116680cb88f63449267c13e1ad134f30087dec8527242e9862a"}, - {file = "black-24.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:163baf4ef40e6897a2a9b83890e59141cc8c2a98f2dda5080dc15c00ee1e62cd"}, - {file = "black-24.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e37c99f89929af50ffaf912454b3e3b47fd64109659026b678c091a4cd450fb2"}, - {file = "black-24.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9de21bafcba9683853f6c96c2d515e364aee631b178eaa5145fc1c61a3cc92"}, - {file = "black-24.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:9db528bccb9e8e20c08e716b3b09c6bdd64da0dd129b11e160bf082d4642ac23"}, - {file = "black-24.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d84f29eb3ee44859052073b7636533ec995bd0f64e2fb43aeceefc70090e752b"}, - {file = "black-24.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e08fb9a15c914b81dd734ddd7fb10513016e5ce7e6704bdd5e1251ceee51ac9"}, - {file = "black-24.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:810d445ae6069ce64030c78ff6127cd9cd178a9ac3361435708b907d8a04c693"}, - {file = "black-24.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ba15742a13de85e9b8f3239c8f807723991fbfae24bad92d34a2b12e81904982"}, - {file = "black-24.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e53a8c630f71db01b28cd9602a1ada68c937cbf2c333e6ed041390d6968faf4"}, - {file = "black-24.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:93601c2deb321b4bad8f95df408e3fb3943d85012dddb6121336b8e24a0d1218"}, - {file = "black-24.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0057f800de6acc4407fe75bb147b0c2b5cbb7c3ed110d3e5999cd01184d53b0"}, - {file = "black-24.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:faf2ee02e6612577ba0181f4347bcbcf591eb122f7841ae5ba233d12c39dcb4d"}, - {file = "black-24.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:057c3dc602eaa6fdc451069bd027a1b2635028b575a6c3acfd63193ced20d9c8"}, - {file = "black-24.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:08654d0797e65f2423f850fc8e16a0ce50925f9337fb4a4a176a7aa4026e63f8"}, - {file = "black-24.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca610d29415ee1a30a3f30fab7a8f4144e9d34c89a235d81292a1edb2b55f540"}, - {file = "black-24.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:4dd76e9468d5536abd40ffbc7a247f83b2324f0c050556d9c371c2b9a9a95e31"}, - {file = "black-24.2.0-py3-none-any.whl", hash = "sha256:e8a6ae970537e67830776488bca52000eaa37fa63b9988e8c487458d9cd5ace6"}, - {file = "black-24.2.0.tar.gz", hash = "sha256:bce4f25c27c3435e4dace4815bcb2008b87e167e3bf4ee47ccdc5ce906eb4894"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (>=0.23)"] [[package]] name = "certifi" -version = "2023.7.22" +version = "2024.2.2" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, - {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, ] [[package]] name = "cfgv" -version = "3.3.1" +version = "3.4.0" description = "Validate configuration and produce human readable error messages." optional = false -python-versions = ">=3.6.1" -files = [ - {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, - {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, -] - -[[package]] -name = "click" -version = "8.1.6" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "click-8.1.6-py3-none-any.whl", hash = "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5"}, - {file = "click-8.1.6.tar.gz", hash = "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd"}, + {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, + {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, ] -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - [[package]] name = "colorama" version = "0.4.6" @@ -116,13 +57,13 @@ files = [ [[package]] name = "distlib" -version = "0.3.7" +version = "0.3.8" description = "Distribution utilities" optional = false python-versions = "*" files = [ - {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"}, - {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"}, + {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, + {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, ] [[package]] @@ -138,13 +79,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.1.2" +version = "1.2.0" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.1.2-py3-none-any.whl", hash = "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f"}, - {file = "exceptiongroup-1.1.2.tar.gz", hash = "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5"}, + {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, + {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, ] [package.extras] @@ -152,18 +93,19 @@ test = ["pytest (>=6)"] [[package]] name = "filelock" -version = "3.12.2" +version = "3.13.1" description = "A platform independent file lock." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"}, - {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"}, + {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, + {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, ] [package.extras] -docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +typing = ["typing-extensions (>=4.8)"] [[package]] name = "h11" @@ -178,13 +120,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.2" +version = "1.0.4" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7"}, - {file = "httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535"}, + {file = "httpcore-1.0.4-py3-none-any.whl", hash = "sha256:ac418c1db41bade2ad53ae2f3834a3a0f5ae76b56cf5aa497d2d033384fc7d73"}, + {file = "httpcore-1.0.4.tar.gz", hash = "sha256:cb2839ccfcba0d2d3c1131d3c3e26dfc327326fbe7a5dc0dbfe9f6c9151bb022"}, ] [package.dependencies] @@ -195,7 +137,7 @@ h11 = ">=0.13,<0.15" asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<0.23.0)"] +trio = ["trio (>=0.22.0,<0.25.0)"] [[package]] name = "httpx" @@ -224,13 +166,13 @@ socks = ["socksio (==1.*)"] [[package]] name = "identify" -version = "2.5.26" +version = "2.5.35" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.26-py2.py3-none-any.whl", hash = "sha256:c22a8ead0d4ca11f1edd6c9418c3220669b3b7533ada0a0ffa6cc0ef85cf9b54"}, - {file = "identify-2.5.26.tar.gz", hash = "sha256:7243800bce2f58404ed41b7c002e53d4d22bcf3ae1b7900c2d7aefd95394bf7f"}, + {file = "identify-2.5.35-py2.py3-none-any.whl", hash = "sha256:c4de0081837b211594f8e877a6b4fad7ca32bbfc1a9307fdd61c28bfe923f13e"}, + {file = "identify-2.5.35.tar.gz", hash = "sha256:10a7ca245cfcd756a554a7288159f72ff105ad233c7c4b9c6f0f4d108f5f6791"}, ] [package.extras] @@ -238,13 +180,13 @@ license = ["ukkonen"] [[package]] name = "idna" -version = "3.4" +version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, + {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, ] [[package]] @@ -258,31 +200,6 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] -[[package]] -name = "isort" -version = "5.13.2" -description = "A Python utility / library to sort Python imports." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, - {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, -] - -[package.extras] -colors = ["colorama (>=0.4.6)"] - -[[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 = "nodeenv" version = "1.8.0" @@ -299,40 +216,29 @@ setuptools = "*" [[package]] name = "packaging" -version = "23.1" +version = "24.0" 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.2" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, - {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] [[package]] name = "platformdirs" -version = "3.10.0" +version = "4.2.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, - {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, + {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, + {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, ] [package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] [[package]] name = "pluggy" @@ -369,13 +275,13 @@ virtualenv = ">=20.10.0" [[package]] name = "pyright" -version = "1.1.353" +version = "1.1.354" description = "Command line wrapper for pyright" optional = false python-versions = ">=3.7" files = [ - {file = "pyright-1.1.353-py3-none-any.whl", hash = "sha256:8d7e6719d0be4fd9f4a37f010237c6a74d91ec1e7c81de634c2f3f9965f8ab43"}, - {file = "pyright-1.1.353.tar.gz", hash = "sha256:24343bbc2a4f997563f966b6244a2e863473f1d85af6d24abcb366fcbb4abca9"}, + {file = "pyright-1.1.354-py3-none-any.whl", hash = "sha256:f28d61ae8ae035fc52ded1070e8d9e786051a26a4127bbd7a4ba0399b81b37b5"}, + {file = "pyright-1.1.354.tar.gz", hash = "sha256:b1070dc774ff2e79eb0523fe87f4ba9a90550de7e4b030a2bc9e031864029a1f"}, ] [package.dependencies] @@ -407,6 +313,21 @@ tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "pytest-rerunfailures" +version = "14.0" +description = "pytest plugin to re-run tests to eliminate flaky failures" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-rerunfailures-14.0.tar.gz", hash = "sha256:4a400bcbcd3c7a4ad151ab8afac123d90eca3abe27f98725dc4d9702887d2e92"}, + {file = "pytest_rerunfailures-14.0-py3-none-any.whl", hash = "sha256:4197bdd2eaeffdbf50b5ea6e7236f47ff0e44d1def8dae08e409f536d84e7b32"}, +] + +[package.dependencies] +packaging = ">=17.1" +pytest = ">=7.2" + [[package]] name = "pyyaml" version = "6.0.1" @@ -467,31 +388,57 @@ files = [ {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] +[[package]] +name = "ruff" +version = "0.3.3" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.3.3-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:973a0e388b7bc2e9148c7f9be8b8c6ae7471b9be37e1cc732f8f44a6f6d7720d"}, + {file = "ruff-0.3.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfa60d23269d6e2031129b053fdb4e5a7b0637fc6c9c0586737b962b2f834493"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1eca7ff7a47043cf6ce5c7f45f603b09121a7cc047447744b029d1b719278eb5"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7d3f6762217c1da954de24b4a1a70515630d29f71e268ec5000afe81377642d"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b24c19e8598916d9c6f5a5437671f55ee93c212a2c4c569605dc3842b6820386"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5a6cbf216b69c7090f0fe4669501a27326c34e119068c1494f35aaf4cc683778"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352e95ead6964974b234e16ba8a66dad102ec7bf8ac064a23f95371d8b198aab"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d6ab88c81c4040a817aa432484e838aaddf8bfd7ca70e4e615482757acb64f8"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79bca3a03a759cc773fca69e0bdeac8abd1c13c31b798d5bb3c9da4a03144a9f"}, + {file = "ruff-0.3.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:2700a804d5336bcffe063fd789ca2c7b02b552d2e323a336700abb8ae9e6a3f8"}, + {file = "ruff-0.3.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fd66469f1a18fdb9d32e22b79f486223052ddf057dc56dea0caaf1a47bdfaf4e"}, + {file = "ruff-0.3.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:45817af234605525cdf6317005923bf532514e1ea3d9270acf61ca2440691376"}, + {file = "ruff-0.3.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0da458989ce0159555ef224d5b7c24d3d2e4bf4c300b85467b08c3261c6bc6a8"}, + {file = "ruff-0.3.3-py3-none-win32.whl", hash = "sha256:f2831ec6a580a97f1ea82ea1eda0401c3cdf512cf2045fa3c85e8ef109e87de0"}, + {file = "ruff-0.3.3-py3-none-win_amd64.whl", hash = "sha256:be90bcae57c24d9f9d023b12d627e958eb55f595428bafcb7fec0791ad25ddfc"}, + {file = "ruff-0.3.3-py3-none-win_arm64.whl", hash = "sha256:0171aab5fecdc54383993389710a3d1227f2da124d76a2784a7098e818f92d61"}, + {file = "ruff-0.3.3.tar.gz", hash = "sha256:38671be06f57a2f8aba957d9f701ea889aa5736be806f18c0cd03d6ff0cbca8d"}, +] + [[package]] name = "setuptools" -version = "68.0.0" +version = "69.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"}, - {file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"}, + {file = "setuptools-69.2.0-py3-none-any.whl", hash = "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c"}, + {file = "setuptools-69.2.0.tar.gz", hash = "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "sniffio" -version = "1.3.0" +version = "1.3.1" description = "Sniff out which async library your code is running under" optional = false python-versions = ">=3.7" files = [ - {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, - {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, ] [[package]] @@ -540,22 +487,22 @@ files = [ [[package]] name = "virtualenv" -version = "20.24.2" +version = "20.25.1" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.24.2-py3-none-any.whl", hash = "sha256:43a3052be36080548bdee0b42919c88072037d50d56c28bd3f853cbe92b953ff"}, - {file = "virtualenv-20.24.2.tar.gz", hash = "sha256:fd8a78f46f6b99a67b7ec5cf73f92357891a7b3a40fd97637c27f854aae3b9e0"}, + {file = "virtualenv-20.25.1-py3-none-any.whl", hash = "sha256:961c026ac520bac5f69acb8ea063e8a4f071bcc9457b9c1f28f6b085c511583a"}, + {file = "virtualenv-20.25.1.tar.gz", hash = "sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197"}, ] [package.dependencies] distlib = ">=0.3.7,<1" filelock = ">=3.12.2,<4" -platformdirs = ">=3.9.1,<4" +platformdirs = ">=3.9.1,<5" [package.extras] -docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] [extras] @@ -564,4 +511,4 @@ rst-parser = ["docutils"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "be3a0742c0cb92ac9a4cf809114c1ed2bf435f6e3dc8a6e6f761bc67f0c308ba" +content-hash = "b03d342a4bb42f69e8e00f615f937f1a24303e7ef1f1a5d7dfdad0c11dce08ba" diff --git a/pyproject.toml b/pyproject.toml index 7210dfe..f5e5ec1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,13 +12,13 @@ httpx = "^0.27.0" [tool.poetry.group.dev.dependencies] pytest = "^8.0.0" -black = "^24.0.0" -isort = "^5.12.0" tomli = { version = "^2.0.1", python = "<3.11" } pre-commit = "^3.0.0" types-docutils = "^0.19.0" httpx = { extras = ["socks"], version = "^0.27.0" } -pyright = "^1.1.262" +pyright = "^1.1.354" +ruff = "^0.3.3" +pytest-rerunfailures = "^14.0" [tool.poetry.extras] rst-parser = ["docutils"] @@ -28,13 +28,43 @@ check-whitespace-between-cn-and-en-char = "dochooks.insert_whitespace_between_cn insert-whitespace-between-cn-and-en-char = "dochooks.insert_whitespace_between_cn_and_en_char.format:main" api-doc-checker = "dochooks.api_doc_checker.check:main" -[tool.black] +[tool.pyright] +include = ["dochooks", "tests"] +pythonVersion = "3.8" +typeCheckingMode = "strict" + +[tool.ruff] line-length = 120 +target-version = "py38" + +[tool.ruff.lint] +select = [ + # Pyflakes + "F", + # Pycodestyle + "E", + "W", + # Isort + "I", + # Pyupgrade + "UP", + # Flake8-pyi + "PYI", + # Yesqa + "RUF100", +] +ignore = [ + "E501", # line too long, duplicate with ruff fmt + "F401", # imported but unused, duplicate with pyright + "F841", # local variable is assigned to but never used, duplicate with pyright +] + +[tool.ruff.lint.isort] +required-imports = ["from __future__ import annotations"] +known-first-party = ["moelib"] -[tool.isort] -profile = "black" -add_imports = ["from __future__ import annotations"] -skip = ["setup.py", ".venv"] +[tool.ruff.lint.per-file-ignores] +"setup.py" = ["I"] [build-system] requires = ["poetry-core>=1.1.0"] diff --git a/tests/test_api_doc_checker/test_checkers/test_parameters_checker.py b/tests/test_api_doc_checker/test_checkers/test_parameters_checker.py index e2398dc..d0be5ee 100644 --- a/tests/test_api_doc_checker/test_checkers/test_parameters_checker.py +++ b/tests/test_api_doc_checker/test_checkers/test_parameters_checker.py @@ -1,7 +1,6 @@ from __future__ import annotations import re -from typing import Optional import pytest @@ -107,9 +106,7 @@ def test_pattern_doc_parameter_type(): ), ], ) -def test_parse_api_name_and_parameters( - api_declaration: str, api_name: Optional[str], api_parameters: list[APIParameter] -): +def test_parse_api_name_and_parameters(api_declaration: str, api_name: str | None, api_parameters: list[APIParameter]): api_name_actual, api_parameters_actual = parse_api_name_and_parameters(api_declaration) assert api_name == api_name_actual assert api_parameters == api_parameters_actual diff --git a/tests/test_dochooks.py b/tests/test_dochooks.py deleted file mode 100644 index 73688f1..0000000 --- a/tests/test_dochooks.py +++ /dev/null @@ -1,18 +0,0 @@ -from __future__ import annotations - -import sys - -from dochooks import __version__ - -if sys.version_info >= (3, 11): # pragma: >=3.11 cover - import tomllib -else: # pragma: <3.11 cover - import tomli as tomllib - - -with open("pyproject.toml", "rb") as f: - project_info = tomllib.load(f) - - -def test_version(): - assert __version__ == project_info["tool"]["poetry"]["version"]