Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check 3.11 support #247

Merged
merged 8 commits into from
Jul 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 6 additions & 5 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ concurrency:
jobs:
test:
name: test with CPython ${{ matrix.py }}
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
py:
- "3.11.0-beta.4"
- "3.10"
- "3.9"
- "3.8"
Expand Down Expand Up @@ -66,7 +67,7 @@ jobs:

coverage:
name: Combine coverage
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
needs: test
steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -98,7 +99,7 @@ jobs:

check:
name: tox env ${{ matrix.tox_env }}
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
Expand All @@ -124,7 +125,7 @@ jobs:
publish:
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
needs: [check, coverage]
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Setup python to build package
uses: actions/setup-python@v4
Expand All @@ -138,7 +139,7 @@ jobs:
- name: Build sdist and wheel
run: python -m build -s -w . -o dist
- name: Publish to PyPi
uses: pypa/gh-action-pypi-publish@master
uses: pypa/gh-action-pypi-publish@v1.5.1
with:
skip_existing: true
user: __token__
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 1.19.0

- Support for CPython 3.11, no longer adds `Optional` when the argument is default per
[recommendation from PEP-484](https://github.com/tox-dev/sphinx-autodoc-typehints/pull/247).

## 1.18.3

- Support and require `nptyping>=2.1.2`
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ The following configuration options are accepted:
directive, if present, otherwise fall back to using `:rtype:`. Use in conjunction with
[napoleon_use_rtype](https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html#confval-napoleon_use_rtype)
to avoid generation of duplicate or redundant return type information.
- `typehints_defaults` (default: `None`): If `None`, defaults are not added. Otherwise adds a default annotation:
- `typehints_defaults` (default: `None`): If `None`, defaults are not added. Otherwise, adds a default annotation:

- `'comma'` adds it after the type, changing Sphinx’ default look to “**param** (_int_, default: `1`) -- text”.
- `'braces'` adds `(default: ...)` after the type (useful for numpydoc like styles).
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ other =
*\sphinx-autodoc-typehints

[coverage:report]
fail_under = 82
fail_under = 81

[coverage:html]
show_contexts = true
Expand Down
7 changes: 5 additions & 2 deletions src/sphinx_autodoc_typehints/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ def get_annotation_args(annotation: Any, module: str, class_name: str) -> tuple[
return annotation.__values__ # type: ignore # deduced Any
elif class_name == "Generic":
return annotation.__parameters__ # type: ignore # deduced Any
return getattr(annotation, "__args__", ())
result = getattr(annotation, "__args__", ())
# 3.10 and earlier Tuple[()] returns ((), ) instead of () the tuple does
result = () if len(result) == 1 and result[0] == () else result # type: ignore
return result


def format_internal_tuple(t: tuple[Any, ...], config: Config) -> str:
Expand Down Expand Up @@ -161,7 +164,7 @@ def format_annotation(annotation: Any, config: Config) -> str: # noqa: C901 # t
formatted_args = None if args else args_format
elif full_name == "typing.Optional":
args = tuple(x for x in args if x is not type(None)) # noqa: E721
elif full_name == "typing.Union" and type(None) in args:
elif full_name in ("typing.Union", "types.UnionType") and type(None) in args:
if len(args) == 2:
full_name = "typing.Optional"
args = tuple(x for x in args if x is not type(None)) # noqa: E721
Expand Down
8 changes: 4 additions & 4 deletions tests/roots/test-dummy/dummy_module.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import typing
from dataclasses import dataclass
from mailbox import Mailbox
from typing import Callable, Union
from typing import Callable, Optional, Union


def get_local_function():
Expand Down Expand Up @@ -191,7 +191,7 @@ def method_without_typehint(self, x): # noqa: U100


def function_with_typehint_comment_not_inline(x=None, *y, z, **kwargs): # noqa: U100
# type: (Union[str, bytes], *str, bytes, **int) -> None
# type: (Union[str, bytes, None], *str, bytes, **int) -> None
"""
Function docstring.

Expand All @@ -210,7 +210,7 @@ class ClassWithTypehintsNotInline:
"""

def __init__(self, x=None): # noqa: U100
# type: (Callable[[int, bytes], int]) -> None
# type: (Optional[Callable[[int, bytes], int]]) -> None
pass

def foo(self, x=1):
Expand All @@ -224,7 +224,7 @@ def foo(self, x=1):

@classmethod
def mk(cls, x=None):
# type: (Callable[[int, bytes], int]) -> ClassWithTypehintsNotInline
# type: (Optional[Callable[[int, bytes], int]]) -> ClassWithTypehintsNotInline
"""
Method docstring.

Expand Down
7 changes: 4 additions & 3 deletions tests/test_sphinx_autodoc_typehints.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ def test_parse_annotation(annotation: Any, module: str, class_name: str, args: t
(S, ":py:class:`~typing.TypeVar`\\(``S``, bound= miss)"),
# ## These test for correct internal tuple rendering, even if not all are valid Tuple types
# Zero-length tuple remains
(Tuple[()], ":py:data:`~typing.Tuple`\\[()]"),
(Tuple[()], ":py:data:`~typing.Tuple`"),
# Internal single tuple with simple types is flattened in the output
(Tuple[(int,)], ":py:data:`~typing.Tuple`\\[:py:class:`int`]"),
(Tuple[(int, int)], ":py:data:`~typing.Tuple`\\[:py:class:`int`, :py:class:`int`]"),
Expand Down Expand Up @@ -374,7 +374,7 @@ def set_python_path() -> None:
def maybe_fix_py310(expected_contents: str) -> str:
if PY310_PLUS:
for old, new in [
("*bool** | **None*", '"bool" | "None"'),
("*bool** | **None*", '"Optional"["bool"]'),
("*int** | **str** | **float*", '"int" | "str" | "float"'),
("*str** | **None*", '"Optional"["str"]'),
("(*bool*)", '("bool")'),
Expand Down Expand Up @@ -719,7 +719,8 @@ def test_sphinx_output_future_annotations(app: SphinxTestApp, status: StringIO)
Return type:
str
"""
assert text_contents == maybe_fix_py310(dedent(expected_contents))
expected_contents = maybe_fix_py310(dedent(expected_contents))
assert text_contents == expected_contents


@pytest.mark.parametrize(
Expand Down
4 changes: 3 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[tox]
envlist =
fix
py311
py310
py39
py38
Expand Down Expand Up @@ -45,7 +46,7 @@ description = run type check on code base
setenv =
{tty:MYPY_FORCE_COLOR = 1}
deps =
mypy==0.961
mypy==0.971
types-docutils
commands =
mypy --python-version 3.10 src
Expand All @@ -71,6 +72,7 @@ commands =
coverage html -d {toxworkdir}/htmlcov
diff-cover --compare-branch {env:DIFF_AGAINST:origin/main} {toxworkdir}/coverage.xml
depends =
py311
py310
py39
py38
Expand Down