Skip to content

Commit cd2bf0a

Browse files
j-carsonj-carsonpicnixz
authored
sphinx-doc#11917 - Fix rendering of inherited members for Python 3.9 (sphinx-doc#11919)
Co-authored-by: j-carson <[email protected]> Co-authored-by: Bénédikt Tran <[email protected]>
1 parent 11d522a commit cd2bf0a

File tree

4 files changed

+72
-1
lines changed

4 files changed

+72
-1
lines changed

CHANGES.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ Bugs fixed
7272
Patch by Colin Marquardt.
7373
* #11598: Do not use query components in URLs for assets in EPUB rendering.
7474
Patch by David Runge.
75+
* #11917: Fix rendering of annotated inherited members for Python 3.9.
76+
Patch by Janet Carson.
7577
* #11925: Blacklist the ``sphinxprettysearchresults`` extension; the functionality
7678
it provides was merged into Sphinx v2.0.0.
7779
Patch by James Addison.

sphinx/util/inspect.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,13 @@ def getall(obj: Any) -> Sequence[str] | None:
8787

8888
def getannotations(obj: Any) -> Mapping[str, Any]:
8989
"""Get __annotations__ from given *obj* safely."""
90-
__annotations__ = safe_getattr(obj, '__annotations__', None)
90+
if sys.version_info >= (3, 10, 0) or not isinstance(obj, type):
91+
__annotations__ = safe_getattr(obj, '__annotations__', None)
92+
else:
93+
# Workaround for bugfix not available until python 3.10 as recommended by docs
94+
# https://docs.python.org/3.10/howto/annotations.html#accessing-the-annotations-dict-of-an-object-in-python-3-9-and-older
95+
__dict__ = safe_getattr(obj, '__dict__', {})
96+
__annotations__ = __dict__.get('__annotations__', None)
9197
if isinstance(__annotations__, Mapping):
9298
return __annotations__
9399
else:
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""
2+
Test case for #11387 corner case involving inherited
3+
members with type annotations on python 3.9 and earlier
4+
"""
5+
6+
class HasTypeAnnotatedMember:
7+
inherit_me: int
8+
"""Inherited"""
9+
10+
class NoTypeAnnotation(HasTypeAnnotatedMember):
11+
a = 1
12+
"""Local"""
13+
14+
class NoTypeAnnotation2(HasTypeAnnotatedMember):
15+
a = 1
16+
"""Local"""
17+

tests/test_extensions/test_ext_autodoc_autoclass.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,3 +515,49 @@ def test_autoattribute_TypeVar_module_level(app):
515515
" alias of TypeVar('T1')",
516516
'',
517517
]
518+
519+
520+
@pytest.mark.sphinx('html', testroot='ext-autodoc')
521+
def test_inherited_instance_variable_with_annotations(app):
522+
options = {'members': None,
523+
'inherited-members': None}
524+
actual = do_autodoc(app, 'class', 'target.inherited_annotations.NoTypeAnnotation', options)
525+
assert list(actual) == [
526+
'',
527+
'.. py:class:: NoTypeAnnotation()',
528+
' :module: target.inherited_annotations',
529+
'',
530+
'',
531+
' .. py:attribute:: NoTypeAnnotation.a',
532+
' :module: target.inherited_annotations',
533+
' :value: 1',
534+
'',
535+
' Local',
536+
'',
537+
'',
538+
' .. py:attribute:: NoTypeAnnotation.inherit_me',
539+
' :module: target.inherited_annotations',
540+
' :type: int',
541+
'',
542+
' Inherited',
543+
'',
544+
]
545+
546+
547+
@pytest.mark.sphinx('html', testroot='ext-autodoc')
548+
def test_no_inherited_instance_variable_with_annotations(app):
549+
options = {'members': None}
550+
actual = do_autodoc(app, 'class', 'target.inherited_annotations.NoTypeAnnotation2', options)
551+
assert list(actual) == [
552+
'',
553+
'.. py:class:: NoTypeAnnotation2()',
554+
' :module: target.inherited_annotations',
555+
'',
556+
'',
557+
' .. py:attribute:: NoTypeAnnotation2.a',
558+
' :module: target.inherited_annotations',
559+
' :value: 1',
560+
'',
561+
' Local',
562+
'',
563+
]

0 commit comments

Comments
 (0)