diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5400a73..d3161c0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.7', '3.8', '3.9'] + python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 diff --git a/scanpydoc/elegant_typehints/formatting.py b/scanpydoc/elegant_typehints/formatting.py index 2e3f169..a7d239d 100644 --- a/scanpydoc/elegant_typehints/formatting.py +++ b/scanpydoc/elegant_typehints/formatting.py @@ -34,7 +34,10 @@ def _format_full(annotation: Type[Any], config: Config) -> Optional[str]: # Only if this is a real class we override sphinx_autodoc_typehints if inspect.isclass(annotation) or inspect.isclass(origin): - full_name = f"{annotation.__module__}.{annotation.__qualname__}" + try: + full_name = f"{annotation.__module__}.{annotation.__qualname__}" + except AttributeError: + full_name = f"{origin.__module__}.{origin.__qualname__}" override = elegant_typehints.qualname_overrides.get(full_name) role = "exc" if issubclass(annotation_cls, BaseException) else "class" if override is not None: diff --git a/tests/test_elegant_typehints.py b/tests/test_elegant_typehints.py index ae388f6..ab8cbb6 100644 --- a/tests/test_elegant_typehints.py +++ b/tests/test_elegant_typehints.py @@ -150,6 +150,13 @@ def test_literal(app): assert _format_full(Literal["str", 1, None], app.config) is None +@pytest.mark.skipif(sys.version_info < (3, 10), reason="Syntax only available on 3.10+") +def test_syntax_vs_typing(app): + u = eval("int | str") + assert _format_terse(u, app.config) == ":py:class:`int` | :py:class:`str`" + assert _format_full(u, app.config) is None # this used to crash + + def test_qualname_overrides_class(app, _testmod): assert _testmod.Class.__module__ == "_testmod" assert _format_terse(_testmod.Class, app.config) == ":py:class:`~test.Class`"