From 3c1773a8c19576afaaba10b4548f4ee274066419 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 21:56:05 -0700 Subject: [PATCH 1/5] Bump pypa/gh-action-pypi-publish from 1.9.0 to 1.10.1 (#477) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0b36a5c..ceebf6e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,4 +24,4 @@ jobs: - name: Build package run: pyproject-build -s -w . -o dist - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@v1.9.0 + uses: pypa/gh-action-pypi-publish@v1.10.1 From d0fa2bb3b084d1f1579db338810a828c25b5c61f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 22:05:05 -0700 Subject: [PATCH 2/5] [pre-commit.ci] pre-commit autoupdate (#472) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 6 +-- .../dummy_module_future_annotations.py | 8 ++-- tests/roots/test-dummy/dummy_module_simple.py | 2 +- .../dummy_module_simple_default_role.py | 2 +- .../dummy_module_simple_no_use_rtype.py | 8 ++-- ...dummy_module_without_complete_typehints.py | 8 ++-- tests/test_integration.py | 42 +++++++++---------- .../test_integration_autodoc_type_aliases.py | 2 +- tests/test_integration_issue_384.py | 2 +- tests/test_sphinx_autodoc_typehints.py | 6 +-- 10 files changed, 43 insertions(+), 43 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ed62eca..703693d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.29.0 + rev: 0.29.2 hooks: - id: check-github-workflows args: [ "--verbose" ] @@ -20,12 +20,12 @@ repos: - id: tox-ini-fmt args: ["-p", "fix"] - repo: https://github.com/tox-dev/pyproject-fmt - rev: "2.1.4" + rev: "2.2.1" hooks: - id: pyproject-fmt additional_dependencies: ["tox>=4.14.2"] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.5.4" + rev: "v0.6.3" hooks: - id: ruff-format - id: ruff diff --git a/tests/roots/test-dummy/dummy_module_future_annotations.py b/tests/roots/test-dummy/dummy_module_future_annotations.py index 389cc98..325cc91 100644 --- a/tests/roots/test-dummy/dummy_module_future_annotations.py +++ b/tests/roots/test-dummy/dummy_module_future_annotations.py @@ -2,10 +2,10 @@ def function_with_py310_annotations( - self, # noqa: ANN001, ARG001 - x: bool | None, # noqa: ARG001 - y: int | str | float, # noqa: ARG001,PYI041 - z: str | None = None, # noqa: ARG001 + self, # noqa: ANN001 + x: bool | None, + y: int | str | float, # noqa: PYI041 + z: str | None = None, ) -> str: """ Method docstring. diff --git a/tests/roots/test-dummy/dummy_module_simple.py b/tests/roots/test-dummy/dummy_module_simple.py index fed8cdf..b1b03ed 100644 --- a/tests/roots/test-dummy/dummy_module_simple.py +++ b/tests/roots/test-dummy/dummy_module_simple.py @@ -1,7 +1,7 @@ from __future__ import annotations -def function(x: bool, y: int = 1) -> str: # noqa: ARG001 +def function(x: bool, y: int = 1) -> str: """ Function docstring. diff --git a/tests/roots/test-dummy/dummy_module_simple_default_role.py b/tests/roots/test-dummy/dummy_module_simple_default_role.py index 758196f..3f575de 100644 --- a/tests/roots/test-dummy/dummy_module_simple_default_role.py +++ b/tests/roots/test-dummy/dummy_module_simple_default_role.py @@ -1,7 +1,7 @@ from __future__ import annotations -def function(x: bool, y: int) -> str: # noqa: ARG001 +def function(x: bool, y: int) -> str: """ Function docstring. diff --git a/tests/roots/test-dummy/dummy_module_simple_no_use_rtype.py b/tests/roots/test-dummy/dummy_module_simple_no_use_rtype.py index 8dc80e7..b7c8277 100644 --- a/tests/roots/test-dummy/dummy_module_simple_no_use_rtype.py +++ b/tests/roots/test-dummy/dummy_module_simple_no_use_rtype.py @@ -1,7 +1,7 @@ from __future__ import annotations -def function_no_returns(x: bool, y: int = 1) -> str: # noqa: ARG001 +def function_no_returns(x: bool, y: int = 1) -> str: """ Function docstring. @@ -10,7 +10,7 @@ def function_no_returns(x: bool, y: int = 1) -> str: # noqa: ARG001 """ -def function_returns_with_type(x: bool, y: int = 1) -> str: # noqa: ARG001 +def function_returns_with_type(x: bool, y: int = 1) -> str: """ Function docstring. @@ -20,7 +20,7 @@ def function_returns_with_type(x: bool, y: int = 1) -> str: # noqa: ARG001 """ -def function_returns_with_compound_type(x: bool, y: int = 1) -> str: # noqa: ARG001 +def function_returns_with_compound_type(x: bool, y: int = 1) -> str: """ Function docstring. @@ -30,7 +30,7 @@ def function_returns_with_compound_type(x: bool, y: int = 1) -> str: # noqa: AR """ -def function_returns_without_type(x: bool, y: int = 1) -> str: # noqa: ARG001 +def function_returns_without_type(x: bool, y: int = 1) -> str: """ Function docstring. diff --git a/tests/roots/test-dummy/dummy_module_without_complete_typehints.py b/tests/roots/test-dummy/dummy_module_without_complete_typehints.py index 44ca046..ce40ff3 100644 --- a/tests/roots/test-dummy/dummy_module_without_complete_typehints.py +++ b/tests/roots/test-dummy/dummy_module_without_complete_typehints.py @@ -1,7 +1,7 @@ from __future__ import annotations -def function_with_some_defaults_and_without_typehints(x, y=None): # noqa: ANN001, ANN201, ARG001 +def function_with_some_defaults_and_without_typehints(x, y=None): # noqa: ANN001, ANN201 """ Function docstring. @@ -10,7 +10,7 @@ def function_with_some_defaults_and_without_typehints(x, y=None): # noqa: ANN00 """ -def function_with_some_defaults_and_some_typehints(x: int, y=None): # noqa: ANN001, ANN201, ARG001 +def function_with_some_defaults_and_some_typehints(x: int, y=None): # noqa: ANN001, ANN201 """ Function docstring. @@ -19,7 +19,7 @@ def function_with_some_defaults_and_some_typehints(x: int, y=None): # noqa: ANN """ -def function_with_some_defaults_and_more_typehints(x: int, y=None) -> str: # noqa: ANN001, ARG001 +def function_with_some_defaults_and_more_typehints(x: int, y=None) -> str: # noqa: ANN001 """ Function docstring. @@ -28,7 +28,7 @@ def function_with_some_defaults_and_more_typehints(x: int, y=None) -> str: # no """ -def function_with_defaults_and_some_typehints(x: int = 0, y=None) -> str: # noqa: ANN001, ARG001 +def function_with_defaults_and_some_typehints(x: int = 0, y=None) -> str: # noqa: ANN001 """ Function docstring. diff --git a/tests/test_integration.py b/tests/test_integration.py index a9aec4c..c0f7ff5 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -50,7 +50,7 @@ def dec(val: T) -> T: @expected("mod.get_local_function()") def get_local_function(): # noqa: ANN201 - def wrapper(self) -> str: # noqa: ANN001, ARG001 + def wrapper(self) -> str: # noqa: ANN001 """ Wrapper """ @@ -271,7 +271,7 @@ def __init__(self, message: str) -> None: bytes """, ) -def function(x: bool, y: int, z_: Optional[str] = None) -> str: # noqa: ARG001, UP007 +def function(x: bool, y: int, z_: Optional[str] = None) -> str: # noqa: UP007 """ Function docstring. @@ -299,7 +299,7 @@ def function(x: bool, y: int, z_: Optional[str] = None) -> str: # noqa: ARG001, * ****kwargs** ("str") -- bar """, ) -def function_with_starred_documentation_param_names(*args: int, **kwargs: str): # noqa: ANN201, ARG001 +def function_with_starred_documentation_param_names(*args: int, **kwargs: str): # noqa: ANN201 r""" Function docstring. @@ -322,7 +322,7 @@ def function_with_starred_documentation_param_names(*args: int, **kwargs: str): **x** ("str") -- foo """, ) -def function_with_escaped_default(x: str = "\b"): # noqa: ANN201, ARG001 +def function_with_escaped_default(x: str = "\b"): # noqa: ANN201 """ Function docstring. @@ -341,7 +341,7 @@ def function_with_escaped_default(x: str = "\b"): # noqa: ANN201, ARG001 **x** (a.b.c) -- foo """, ) -def function_with_unresolvable_annotation(x: a.b.c): # noqa: ANN201, ARG001, F821 +def function_with_unresolvable_annotation(x: a.b.c): # noqa: ANN201, F821 """ Function docstring. @@ -365,8 +365,8 @@ def function_with_unresolvable_annotation(x: a.b.c): # noqa: ANN201, ARG001, F8 """, ) def function_with_typehint_comment( # noqa: ANN201 - x, # type: int # noqa: ANN001, ARG001 - y, # type: str # noqa: ANN001, ARG001 + x, # type: int # noqa: ANN001 + y, # type: str # noqa: ANN001 ): # type: (...) -> None """ @@ -457,7 +457,7 @@ def method_without_typehint(self, x): # noqa: ANN001, ANN201, ARG002, PLR6301 "None" """, ) -def function_with_typehint_comment_not_inline(x=None, *y, z, **kwargs): # noqa: ANN001, ANN002, ANN003, ANN201, ARG001 +def function_with_typehint_comment_not_inline(x=None, *y, z, **kwargs): # noqa: ANN001, ANN002, ANN003, ANN201 # type: (Union[str, bytes, None], *str, bytes, **int) -> None """ Function docstring. @@ -592,7 +592,7 @@ def __init__(self, func: Callable[[int, str], str]) -> None: **x** ("Mailbox") -- function """, ) -def mocked_import(x: Mailbox): # noqa: ANN201, ARG001 +def mocked_import(x: Mailbox): # noqa: ANN201 """ A docstring. @@ -648,7 +648,7 @@ def func_with_overload(a: str, b: str) -> None: ... "None" """, ) -def func_with_overload(a: Union[int, str], b: Union[int, str]) -> None: # noqa: ARG001, UP007 +def func_with_overload(a: Union[int, str], b: Union[int, str]) -> None: # noqa: UP007 """ f does the thing. The arguments can either be ints or strings but they must both have the same type. @@ -727,7 +727,7 @@ def func_with_examples_and_returns_after() -> int: More info about the function here. """, ) -def func_with_parameters_and_stuff_after(a: int, b: int) -> int: # noqa: ARG001 +def func_with_parameters_and_stuff_after(a: int, b: int) -> int: """A func :param a: a tells us something @@ -761,7 +761,7 @@ def func_with_parameters_and_stuff_after(a: int, b: int) -> int: # noqa: ARG001 int """, ) -def func_with_rtype_in_weird_spot(a: int, b: int) -> int: # noqa: ARG001 +def func_with_rtype_in_weird_spot(a: int, b: int) -> int: """A func :param a: a tells us something @@ -809,7 +809,7 @@ def func_with_rtype_in_weird_spot(a: int, b: int) -> int: # noqa: ARG001 More stuff here. """, ) -def empty_line_between_parameters(a: int, b: int) -> int: # noqa: ARG001 +def empty_line_between_parameters(a: int, b: int) -> int: """A func :param a: One of the following possibilities: @@ -1002,7 +1002,7 @@ def napoleon_returns() -> CodeType: """, ) -def google_docstrings(arg1: CodeType, arg2: ModuleType) -> CodeType: # noqa: ARG001 +def google_docstrings(arg1: CodeType, arg2: ModuleType) -> CodeType: """Summary line. Extended description of function. @@ -1034,7 +1034,7 @@ def google_docstrings(arg1: CodeType, arg2: ModuleType) -> CodeType: # noqa: AR """, ) -def docstring_with_multiline_note_after_params(param: int) -> None: # noqa: ARG001 +def docstring_with_multiline_note_after_params(param: int) -> None: """Do something. Args: @@ -1065,7 +1065,7 @@ def docstring_with_multiline_note_after_params(param: int) -> None: # noqa: ARG """, ) -def docstring_with_bullet_list_after_params(param: int) -> None: # noqa: ARG001 +def docstring_with_bullet_list_after_params(param: int) -> None: """Do something. Args: @@ -1098,7 +1098,7 @@ def docstring_with_bullet_list_after_params(param: int) -> None: # noqa: ARG001 """, ) -def docstring_with_definition_list_after_params(param: int) -> None: # noqa: ARG001 +def docstring_with_definition_list_after_params(param: int) -> None: """Do something. Args: @@ -1132,7 +1132,7 @@ def docstring_with_definition_list_after_params(param: int) -> None: # noqa: AR """, ) -def docstring_with_enum_list_after_params(param: int) -> None: # noqa: ARG001 +def docstring_with_enum_list_after_params(param: int) -> None: """Do something. Args: @@ -1167,7 +1167,7 @@ def docstring_with_enum_list_after_params(param: int) -> None: # noqa: ARG001 -[ Example ]- """, ) -def docstring_with_definition_list_after_params_no_blank_line(param: int) -> None: # noqa: ARG001 +def docstring_with_definition_list_after_params_no_blank_line(param: int) -> None: """Do something. Args: @@ -1292,7 +1292,7 @@ def typehints_use_signature(a: AsyncGenerator) -> AsyncGenerator: """, rst_prolog=prolog, ) -def docstring_with_multiline_note_after_params_prolog_replace(param: int) -> None: # noqa: ARG001 +def docstring_with_multiline_note_after_params_prolog_replace(param: int) -> None: """Do something. Args: @@ -1329,7 +1329,7 @@ def docstring_with_multiline_note_after_params_prolog_replace(param: int) -> Non """, rst_epilog=epilog, ) -def docstring_with_multiline_note_after_params_epilog_replace(param: int) -> None: # noqa: ARG001 +def docstring_with_multiline_note_after_params_epilog_replace(param: int) -> None: """Do something. Args: diff --git a/tests/test_integration_autodoc_type_aliases.py b/tests/test_integration_autodoc_type_aliases.py index 7d21971..de3e832 100644 --- a/tests/test_integration_autodoc_type_aliases.py +++ b/tests/test_integration_autodoc_type_aliases.py @@ -114,7 +114,7 @@ def g(s: AliasedClass) -> AliasedClass: """, ) -def function(x: ArrayLike, y: Schema) -> str: # noqa: ARG001 +def function(x: ArrayLike, y: Schema) -> str: """ Function docstring. diff --git a/tests/test_integration_issue_384.py b/tests/test_integration_issue_384.py index 66815e6..31b977b 100644 --- a/tests/test_integration_issue_384.py +++ b/tests/test_integration_issue_384.py @@ -59,7 +59,7 @@ def dec(val: T) -> T: """, ) -def function(x: int = 5, y: int = 10, z: int = 15) -> str: # noqa: ARG001 +def function(x: int = 5, y: int = 10, z: int = 15) -> str: """ Function docstring. diff --git a/tests/test_sphinx_autodoc_typehints.py b/tests/test_sphinx_autodoc_typehints.py index 94c1c86..77f1536 100644 --- a/tests/test_sphinx_autodoc_typehints.py +++ b/tests/test_sphinx_autodoc_typehints.py @@ -355,15 +355,15 @@ def test_parse_annotation(annotation: Any, module: str, class_name: str, args: t # Zero-length tuple remains pytest.param(Tuple[()], ":py:data:`~typing.Tuple`", id="Tuple-p"), # noqa: UP006 # Internal single tuple with simple types is flattened in the output - pytest.param(Tuple[(int,)], r":py:data:`~typing.Tuple`\ \[:py:class:`int`]", id="Tuple-p-int"), # noqa: UP006 + pytest.param(Tuple[int,], r":py:data:`~typing.Tuple`\ \[:py:class:`int`]", id="Tuple-p-int"), # noqa: UP006 pytest.param( - Tuple[(int, int)], # noqa: UP006 + Tuple[int, int], # noqa: UP006 r":py:data:`~typing.Tuple`\ \[:py:class:`int`, :py:class:`int`]", id="Tuple-p-int-int", # noqa: RUF100, UP006 ), # Ellipsis in single tuple also gets flattened pytest.param( - Tuple[(int, ...)], # noqa: UP006 + Tuple[int, ...], # noqa: UP006 r":py:data:`~typing.Tuple`\ \[:py:class:`int`, :py:data:`...`]", id="Tuple-p-Ellipsis", ), From 852239613cd976874723c41a1b74ba4ec6b542c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Sat, 7 Sep 2024 07:55:03 -0700 Subject: [PATCH 3/5] Fix CI and add 3.13 as target with dep/tool upgrades MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bernát Gábor --- .github/workflows/check.yml | 22 +++------- .pre-commit-config.yaml | 14 ++++-- README.md | 4 +- pyproject.toml | 30 +++++++------ src/sphinx_autodoc_typehints/__init__.py | 2 +- .../{parser.py => _parser.py} | 0 .../attributes_patch.py | 2 +- .../demo_typing_guard.py | 2 +- tox.ini | 43 +++++++++---------- 9 files changed, 58 insertions(+), 61 deletions(-) rename src/sphinx_autodoc_typehints/{parser.py => _parser.py} (100%) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 4fc0e6a..2fdef1c 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -20,6 +20,7 @@ jobs: fail-fast: false matrix: py: + - "3.13" - "3.12" - "3.11" - "3.10" @@ -38,20 +39,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: ${{ matrix.py }} - - name: Pick environment to run - run: | - import os - import sys - from pathlib import Path - env = "TOXENV=py{}{}\n".format(*sys.version_info[0:2]) - print("Picked:\n{}for{}".format(env, sys.version)) - with Path(os.environ["GITHUB_ENV"]).open("a") as file_handler: - file_handler.write(env) - shell: python - - name: Setup test suite - run: tox -vv --notest - - name: Run test suite - run: tox --skip-pkg-install + allow-prereleases: true + - name: setup test suite + run: tox run -vv --notest --skip-missing-interpreters false -e ${{ matrix.py }} + - name: run test suite + run: tox run --skip-pkg-install -e ${{ matrix.py }} env: PYTEST_ADDOPTS: "-vv --durations=20" CI_RUN: "yes" @@ -118,7 +110,7 @@ jobs: with: python-version: "3.12" - name: Install tox - run: python -m pip install tox + run: python -m pip install tox-uv - name: Setup test suite run: tox -vv --notest -e ${{ matrix.tox_env }} - name: Run test suite diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 703693d..4b981c1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,14 +8,14 @@ repos: rev: 0.29.2 hooks: - id: check-github-workflows - args: [ "--verbose" ] + args: ["--verbose"] - repo: https://github.com/codespell-project/codespell rev: v2.3.0 hooks: - id: codespell additional_dependencies: ["tomli>=2.0.1"] - repo: https://github.com/tox-dev/tox-ini-fmt - rev: "1.3.1" + rev: "1.3.2" hooks: - id: tox-ini-fmt args: ["-p", "fix"] @@ -23,13 +23,19 @@ repos: rev: "2.2.1" hooks: - id: pyproject-fmt - additional_dependencies: ["tox>=4.14.2"] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.6.3" + rev: "v0.6.4" hooks: - id: ruff-format - id: ruff args: ["--fix", "--unsafe-fixes", "--exit-non-zero-on-fix"] + - repo: https://github.com/rbubley/mirrors-prettier + rev: "v3.3.3" # Use the sha / tag you want to point at + hooks: + - id: prettier + additional_dependencies: + - prettier@3.3.3 + - "@prettier/plugin-xml@3.4.1" - repo: meta hooks: - id: check-hooks-apply diff --git a/README.md b/README.md index ff2ff49..745ece3 100644 --- a/README.md +++ b/README.md @@ -63,8 +63,8 @@ The following configuration options are accepted: - `always_document_param_types` (default: `False`): If `False`, do not add type info for undocumented parameters. If `True`, add stub documentation for undocumented parameters to be able to add type info. - `always_use_bars_union ` (default: `False`): If `True`, display Union's using the | operator described in PEP 604. - (e.g `X` | `Y` or `int` | `None`). If `False`, Unions will display with the typing in brackets. (e.g. `Union[X, Y]` - or `Optional[int]`) + (e.g `X` | `Y` or `int` | `None`). If `False`, Unions will display with the typing in brackets. (e.g. `Union[X, Y]` + or `Optional[int]`) - `typehints_document_rtype` (default: `True`): If `False`, never add an `:rtype:` directive. If `True`, add the `:rtype:` directive if no existing `:rtype:` is found. - `typehints_use_rtype` (default: `True`): Controls behavior when `typehints_document_rtype` is set to `True`. If diff --git a/pyproject.toml b/pyproject.toml index 945866c..24120a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ build-backend = "hatchling.build" requires = [ "hatch-vcs>=0.4", - "hatchling>=1.24", + "hatchling>=1.25", ] [project] @@ -35,29 +35,30 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Documentation :: Sphinx", ] dynamic = [ "version", ] dependencies = [ - "sphinx>=7.3.5", + "sphinx>=8.0.2", ] optional-dependencies.docs = [ - "furo>=2024.1.29", + "furo>=2024.8.6", ] optional-dependencies.numpy = [ "nptyping>=2.5", ] optional-dependencies.testing = [ "covdefaults>=2.3", - "coverage>=7.4.4", - "defusedxml>=0.7.1", # required by sphinx.testing - "diff-cover>=9", - "pytest>=8.1.1", + "coverage>=7.6.1", + "defusedxml>=0.7.1", # required by sphinx.testing + "diff-cover>=9.1.1", + "pytest>=8.3.2", "pytest-cov>=5", - "sphobjinv>=2.3.1", - "typing-extensions>=4.11", + "sphobjinv>=2.3.1.1", + "typing-extensions>=4.12.2", ] urls.Changelog = "https://github.com/tox-dev/sphinx-autodoc-typehints/blob/main/CHANGELOG.md" urls.Homepage = "https://github.com/tox-dev/sphinx-autodoc-typehints" @@ -68,9 +69,6 @@ urls.Tracker = "https://github.com/tox-dev/sphinx-autodoc-typehints/issues" build.hooks.vcs.version-file = "src/sphinx_autodoc_typehints/version.py" version.source = "vcs" -[tool.black] -line-length = 120 - [tool.ruff] target-version = "py39" line-length = 120 @@ -87,18 +85,19 @@ lint.ignore = [ "CPY", # No copyright statements "D203", # `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible "D212", # `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible + "DOC", # no sphinx support "ISC001", # Conflict with formatter "S104", # Possible binding to all interface ] lint.per-file-ignores."tests/**/*.py" = [ "D", # don't care about documentation in tests - "FBT", # don"t care about booleans as positional arguments in tests + "FBT", # don't care about booleans as positional arguments in tests "INP001", # no implicit namespace "PLC2701", # private imports "PLR0913", # any number of arguments in tests "PLR0917", # any number of arguments in tests "PLR2004", # Magic value used in comparison, consider replacing with a constant variable - "S101", # asserts allowed in tests... + "S101", # asserts allowed in tests "S603", # `subprocess` call: check for execution of untrusted input ] lint.isort = { known-first-party = [ @@ -115,6 +114,9 @@ ignore-words = "ignore-words.txt" write-changes = true count = true +[tool.pyproject-fmt] +max_supported_python = "3.13" + [tool.pytest.ini_options] testpaths = [ "tests", diff --git a/src/sphinx_autodoc_typehints/__init__.py b/src/sphinx_autodoc_typehints/__init__.py index fbd57ce..3aaf5fe 100644 --- a/src/sphinx_autodoc_typehints/__init__.py +++ b/src/sphinx_autodoc_typehints/__init__.py @@ -20,7 +20,7 @@ from sphinx.util.inspect import TypeAliasForwardRef, TypeAliasNamespace, stringify_signature from sphinx.util.inspect import signature as sphinx_signature -from .parser import parse +from ._parser import parse from .patches import install_patches from .version import __version__ diff --git a/src/sphinx_autodoc_typehints/parser.py b/src/sphinx_autodoc_typehints/_parser.py similarity index 100% rename from src/sphinx_autodoc_typehints/parser.py rename to src/sphinx_autodoc_typehints/_parser.py diff --git a/src/sphinx_autodoc_typehints/attributes_patch.py b/src/sphinx_autodoc_typehints/attributes_patch.py index 6e4575d..d038eae 100644 --- a/src/sphinx_autodoc_typehints/attributes_patch.py +++ b/src/sphinx_autodoc_typehints/attributes_patch.py @@ -11,7 +11,7 @@ from sphinx.domains.python import PyAttribute from sphinx.ext.autodoc import AttributeDocumenter -from .parser import parse +from ._parser import parse if TYPE_CHECKING: from docutils.frontend import Values diff --git a/tests/roots/test-resolve-typing-guard/demo_typing_guard.py b/tests/roots/test-resolve-typing-guard/demo_typing_guard.py index 5c36943..0c42d6e 100644 --- a/tests/roots/test-resolve-typing-guard/demo_typing_guard.py +++ b/tests/roots/test-resolve-typing-guard/demo_typing_guard.py @@ -3,7 +3,7 @@ from __future__ import annotations import typing -from builtins import ValueError # handle does not have __module__ +from builtins import ValueError # handle does not have __module__ # noqa: A004 from functools import cmp_to_key # has __module__ but cannot get module as is builtin from typing import TYPE_CHECKING diff --git a/tox.ini b/tox.ini index 0a98e19..e2460ba 100644 --- a/tox.ini +++ b/tox.ini @@ -3,13 +3,13 @@ requires = tox>=4.2 env_list = fix - py312 - py311 - py310 - py39 type coverage readme + 3.12 + 3.11 + 3.10 + 3.9 skip_missing_interpreters = true [testenv] @@ -37,22 +37,15 @@ commands = description = format the code base to adhere to our styles, and complain about what we cannot do automatically skip_install = true deps = - pre-commit>=3.6.2 + pre-commit-uv>=4.1 commands = pre-commit run --all-files --show-diff-on-failure -[testenv:py312] -extras = - testing - type-comment - [testenv:type] description = run type check on code base deps = - mypy==1.8 - types-docutils>=0.20.0.20240304 -set_env = - {tty:MYPY_FORCE_COLOR = 1} + mypy==1.11.2 + types-docutils>=0.21.0.20240907 commands = mypy src mypy tests @@ -62,8 +55,8 @@ description = combine coverage files and generate diff (against DIFF_AGAINST def skip_install = true deps = covdefaults>=2.3 - coverage>=7.4.3 - diff-cover>=8.0.3 + coverage>=7.6.1 + diff-cover>=9.1.1 extras = parallel_show_output = true pass_env = @@ -77,23 +70,27 @@ commands = coverage html -d {toxworkdir}/htmlcov diff-cover --compare-branch {env:DIFF_AGAINST:origin/main} {toxworkdir}/coverage.xml depends = - py312 - py311 - py310 - py39 - py38 + 3.12 + 3.11 + 3.10 + 3.9 [testenv:readme] description = check that the long description is valid (need for PyPI) skip_install = true deps = - build[virtualenv]>=1.1.1 - twine>=5 + build[virtualenv]>=1.2.2 + twine>=5.1.1 extras = commands = pyproject-build -o {envtmpdir} --wheel --sdist . twine check {envtmpdir}/* +[testenv:3.13] +extras = + testing + type-comment + [testenv:dev] description = generate a DEV environment package = editable From f15864efb7b2b8e56665c792a7d69bb8706d7950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Sat, 7 Sep 2024 08:00:45 -0700 Subject: [PATCH 4/5] Drop 3.9 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bernát Gábor --- .github/workflows/check.yml | 6 ---- pyproject.toml | 5 ++- src/sphinx_autodoc_typehints/__init__.py | 7 ++-- tests/test_integration.py | 3 +- .../test_integration_autodoc_type_aliases.py | 5 ++- tests/test_integration_issue_384.py | 5 ++- tests/test_sphinx_autodoc_typehints.py | 32 +++++++++++++------ tox.ini | 4 +-- 8 files changed, 34 insertions(+), 33 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 2fdef1c..a912b77 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -24,7 +24,6 @@ jobs: - "3.12" - "3.11" - "3.10" - - "3.9" steps: - name: Setup python for tox uses: actions/setup-python@v5 @@ -48,11 +47,6 @@ jobs: PYTEST_ADDOPTS: "-vv --durations=20" CI_RUN: "yes" DIFF_AGAINST: HEAD - - name: Rename coverage report file - run: - import os; import sys; os.rename(f".tox/.coverage.{os.environ['TOXENV']}", - f".tox/.coverage.{os.environ['TOXENV']}-{sys.platform}") - shell: python - name: Upload coverage data uses: actions/upload-artifact@v3 with: diff --git a/pyproject.toml b/pyproject.toml index 24120a9..5c8cbfe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ maintainers = [ authors = [ { name = "Bernát Gábor", email = "gaborjbernat@gmail.com" }, ] -requires-python = ">=3.9" +requires-python = ">=3.10" classifiers = [ "Development Status :: 5 - Production/Stable", "Framework :: Sphinx :: Extension", @@ -31,7 +31,6 @@ classifiers = [ "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -70,7 +69,7 @@ build.hooks.vcs.version-file = "src/sphinx_autodoc_typehints/version.py" version.source = "vcs" [tool.ruff] -target-version = "py39" +target-version = "py310" line-length = 120 format.preview = true format.docstring-code-line-length = 100 diff --git a/src/sphinx_autodoc_typehints/__init__.py b/src/sphinx_autodoc_typehints/__init__.py index 3aaf5fe..d2b1b06 100644 --- a/src/sphinx_autodoc_typehints/__init__.py +++ b/src/sphinx_autodoc_typehints/__init__.py @@ -10,7 +10,7 @@ import textwrap import types from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, AnyStr, Callable, ForwardRef, NewType, TypeVar, get_type_hints +from typing import TYPE_CHECKING, Any, AnyStr, ForwardRef, NewType, TypeVar, get_type_hints from docutils import nodes from docutils.frontend import OptionParser @@ -26,6 +26,7 @@ if TYPE_CHECKING: from ast import FunctionDef, Module, stmt + from collections.abc import Callable from docutils.nodes import Node from docutils.parsers.rst import states @@ -79,8 +80,6 @@ def get_annotation_module(annotation: Any) -> str: def _is_newtype(annotation: Any) -> bool: - if sys.version_info < (3, 10): - return inspect.isfunction(annotation) and hasattr(annotation, "__supertype__") return isinstance(annotation, NewType) @@ -379,7 +378,7 @@ def process_signature( # noqa: C901, PLR0913, PLR0917 # when method starts with double underscore Python applies mangling -> prepend the class name method_name = f"_{obj.__qualname__.split('.')[-2]}{method_name}" method_object = outer.__dict__[method_name] if outer else obj - if not isinstance(method_object, (classmethod, staticmethod)): + if not isinstance(method_object, classmethod | staticmethod): start = 1 sph_signature = sph_signature.replace(parameters=parameters[start:]) diff --git a/tests/test_integration.py b/tests/test_integration.py index c0f7ff5..cbd218e 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -9,7 +9,6 @@ from typing import ( # no type comments TYPE_CHECKING, Any, - Callable, NewType, Optional, TypeVar, @@ -20,7 +19,7 @@ import pytest if TYPE_CHECKING: - from collections.abc import AsyncGenerator + from collections.abc import AsyncGenerator, Callable from io import StringIO from mailbox import Mailbox from types import CodeType, ModuleType diff --git a/tests/test_integration_autodoc_type_aliases.py b/tests/test_integration_autodoc_type_aliases.py index de3e832..b3063fe 100644 --- a/tests/test_integration_autodoc_type_aliases.py +++ b/tests/test_integration_autodoc_type_aliases.py @@ -4,11 +4,12 @@ import sys from pathlib import Path from textwrap import dedent, indent -from typing import TYPE_CHECKING, Any, Callable, Literal, NewType, TypeVar # no type comments +from typing import TYPE_CHECKING, Any, Literal, NewType, TypeVar import pytest if TYPE_CHECKING: + from collections.abc import Callable from io import StringIO from sphinx.testing.util import SphinxTestApp @@ -156,8 +157,6 @@ def test_integration( result = (Path(app.srcdir) / "_build/text/index.txt").read_text() expected = val.EXPECTED - if sys.version_info < (3, 10): - expected = expected.replace("NewType", "NewType()") try: assert result.strip() == dedent(expected).strip() except Exception: diff --git a/tests/test_integration_issue_384.py b/tests/test_integration_issue_384.py index 31b977b..dec84d3 100644 --- a/tests/test_integration_issue_384.py +++ b/tests/test_integration_issue_384.py @@ -4,11 +4,12 @@ import sys from pathlib import Path from textwrap import dedent, indent -from typing import TYPE_CHECKING, Any, Callable, NewType, TypeVar # no type comments +from typing import TYPE_CHECKING, Any, NewType, TypeVar import pytest if TYPE_CHECKING: + from collections.abc import Callable from io import StringIO from sphinx.testing.util import SphinxTestApp @@ -109,8 +110,6 @@ def test_integration( result = (Path(app.srcdir) / "_build/text/index.txt").read_text() expected = val.EXPECTED - if sys.version_info < (3, 10): - expected = expected.replace("NewType", "NewType()") try: assert result.strip() == dedent(expected).strip() except Exception: diff --git a/tests/test_sphinx_autodoc_typehints.py b/tests/test_sphinx_autodoc_typehints.py index 77f1536..4e8041f 100644 --- a/tests/test_sphinx_autodoc_typehints.py +++ b/tests/test_sphinx_autodoc_typehints.py @@ -72,9 +72,9 @@ # Mypy does not support recursive type aliases, but # other type checkers do. -RecList = Union[int, List["RecList"]] # noqa: UP006 -MutualRecA = Union[bool, List["MutualRecB"]] # noqa: UP006 -MutualRecB = Union[str, List["MutualRecA"]] # noqa: UP006 +RecList = Union[int, List["RecList"]] # noqa: UP006, UP007 +MutualRecA = Union[bool, List["MutualRecB"]] # noqa: UP006, UP007 +MutualRecB = Union[str, List["MutualRecA"]] # noqa: UP006, UP007 class A: @@ -150,7 +150,7 @@ def __getitem__(self, params): # noqa: ANN001, ANN204 pytest.param(Dict[T, int], "typing", "Dict", (T, int), id="Dict_typevar"), # type: ignore[valid-type] # noqa: UP006 pytest.param(Tuple, "typing", "Tuple", (), id="Tuple"), # noqa: UP006 pytest.param(Tuple[str, int], "typing", "Tuple", (str, int), id="Tuple_parametrized"), # noqa: UP006 - pytest.param(Union[str, int], "typing", "Union", (str, int), id="Union"), + pytest.param(Union[str, int], "typing", "Union", (str, int), id="Union"), # noqa: UP007 pytest.param(Callable, "typing", "Callable", (), id="Callable"), pytest.param(Callable[..., str], "typing", "Callable", (..., str), id="Callable_returntype"), pytest.param(Callable[[int, str], str], "typing", "Callable", (int, str, str), id="Callable_all_types"), @@ -266,20 +266,32 @@ def test_parse_annotation(annotation: Any, module: str, class_name: str, args: t ), pytest.param(Union, ":py:data:`~typing.Union`", id="Union"), pytest.param( - Union[str, bool], r":py:data:`~typing.Union`\ \[:py:class:`str`, :py:class:`bool`]", id="Union-str-bool" + Union[str, bool], # noqa: UP007 + r":py:data:`~typing.Union`\ \[:py:class:`str`, :py:class:`bool`]", + id="Union-str-bool", ), pytest.param( - Union[str, bool, None], + Union[str, bool, None], # noqa: UP007 r":py:data:`~typing.Union`\ \[:py:class:`str`, :py:class:`bool`, :py:obj:`None`]", id="Union-str-bool-None", ), pytest.param( - Union[str, Any], r":py:data:`~typing.Union`\ \[:py:class:`str`, :py:data:`~typing.Any`]", id="Union-str-Any" + Union[str, Any], # noqa: UP007 + r":py:data:`~typing.Union`\ \[:py:class:`str`, :py:data:`~typing.Any`]", + id="Union-str-Any", ), - pytest.param(Optional[str], r":py:data:`~typing.Optional`\ \[:py:class:`str`]", id="Optional-str"), - pytest.param(Union[str, None], r":py:data:`~typing.Optional`\ \[:py:class:`str`]", id="Optional-str-None"), pytest.param( - Optional[Union[str, bool]], + Optional[str], # noqa: UP007 + r":py:data:`~typing.Optional`\ \[:py:class:`str`]", + id="Optional-str", + ), + pytest.param( + Union[str, None], # noqa: UP007 + r":py:data:`~typing.Optional`\ \[:py:class:`str`]", + id="Optional-str-None", + ), + pytest.param( + Optional[str | bool], # noqa: UP007 r":py:data:`~typing.Union`\ \[:py:class:`str`, :py:class:`bool`, :py:obj:`None`]", id="Optional-Union-str-bool", ), diff --git a/tox.ini b/tox.ini index e2460ba..39d8ba5 100644 --- a/tox.ini +++ b/tox.ini @@ -6,10 +6,10 @@ env_list = type coverage readme + 3.13 3.12 3.11 3.10 - 3.9 skip_missing_interpreters = true [testenv] @@ -70,10 +70,10 @@ commands = coverage html -d {toxworkdir}/htmlcov diff-cover --compare-branch {env:DIFF_AGAINST:origin/main} {toxworkdir}/coverage.xml depends = + 3.13 3.12 3.11 3.10 - 3.9 [testenv:readme] description = check that the long description is valid (need for PyPI) From 475c49e447f57a74787c413a0e4e46a893a75e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Sat, 7 Sep 2024 08:05:36 -0700 Subject: [PATCH 5/5] Fix upload-artifact@v4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bernát Gábor --- .github/workflows/check.yml | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index a912b77..fd93e1c 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -48,10 +48,12 @@ jobs: CI_RUN: "yes" DIFF_AGAINST: HEAD - name: Upload coverage data - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: coverage-data + include-hidden-files: true + name: .coverage.${{ matrix.py }} path: ".tox/.coverage.*" + retention-days: 3 coverage: name: Combine coverage @@ -69,18 +71,19 @@ jobs: - name: Setup coverage tool run: tox -e coverage --notest - name: Install package builder - run: python -m pip install build + run: python -m pip install build[uv] - name: Build package - run: pyproject-build --wheel . + run: pyproject-build --wheel --installer uv . - name: Download coverage data - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - name: coverage-data path: .tox + pattern: .coverage.* + merge-multiple: true - name: Combine and report coverage run: tox -e coverage - name: Upload HTML report - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: html-report path: .tox/htmlcov @@ -106,6 +109,6 @@ jobs: - name: Install tox run: python -m pip install tox-uv - name: Setup test suite - run: tox -vv --notest -e ${{ matrix.tox_env }} + run: tox -vv --notest --skip-missing-interpreters false -e ${{ matrix.tox_env }} - name: Run test suite run: tox --skip-pkg-install -e ${{ matrix.tox_env }}