From e62a37cfe9718442263e45723e14058871c2d4e6 Mon Sep 17 00:00:00 2001 From: satr Date: Tue, 22 Aug 2023 16:39:23 +0100 Subject: [PATCH 01/33] Add links for inherited methods and attributes --- sphinx/ext/autosummary/generate.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index 06814f9ba96..54df4f9ffb0 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -320,10 +320,34 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, ns['members'] = dir(obj) ns['inherited_members'] = \ set(dir(obj)) - set(obj.__dict__.keys()) + ns['methods'], ns['all_methods'] = \ _get_members(doc, app, obj, {'method'}, include_public={'__init__'}) ns['attributes'], ns['all_attributes'] = \ _get_members(doc, app, obj, {'attribute', 'property'}) + + method_string = [m.split(".")[-1] for m in ns['methods']] + attr_string = [m.split(".")[-1] for m in ns['attributes']] + + # Find the first link for this attribute in higher classes + ns['inherited_paths'] = [] + ns['inherited_methods'] = [] + ns['inherited_attributes'] = [] + + for i in (set(dir(obj)) - set(obj.__dict__.keys())): + for cl in obj.__mro__: + local = set(cl.__dict__.keys()) + if i in local: + cl_str = cl.__module__ + "." + cl.__name__ + "." + i + if i[0] != "_": + ns['inherited_paths'].append(cl_str) + + if i in method_string: + ns['inherited_methods'].append(cl_str) + elif i in attr_string: + ns['inherited_attributes'].append(cl_str) + break + if modname is None or qualname is None: modname, qualname = _split_full_qualified_name(name) From 4e71d5b3366fb9c64f6c735d1bd5cc3a2e240bbf Mon Sep 17 00:00:00 2001 From: satr-cowi <54358974+satr-cowi@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:31:27 +0100 Subject: [PATCH 02/33] Docs update for additional autosummary inherited options Explanations of inherited_paths, inherited_methods and inherited_attributes --- doc/usage/extensions/autosummary.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/doc/usage/extensions/autosummary.rst b/doc/usage/extensions/autosummary.rst index a18460b52bd..65af38abaa2 100644 --- a/doc/usage/extensions/autosummary.rst +++ b/doc/usage/extensions/autosummary.rst @@ -303,6 +303,27 @@ The following variables are available in the templates: .. versionadded:: 1.8.0 +.. data:: inherited_methods + + List containing names of only inherited methods. Only available for + classes. + + .. versionadded:: 7.2.7 + +.. data:: inherited_attributes + + List containing names of only inherited attributes. Only available for + classes. + + .. versionadded:: 7.2.7 + +.. data:: inherited_paths + + List containing the full path inherited members. Will only return the closest + parent from which this class was inherited. Only available for classes. + + .. versionadded:: 7.2.7 + .. data:: functions List containing names of "public" functions in the module. Here, "public" From 2f4d125c61dfd8557cb68f9b73e148c9c3e6c543 Mon Sep 17 00:00:00 2001 From: satr Date: Fri, 6 Oct 2023 16:51:49 +0100 Subject: [PATCH 03/33] Formatting update for linter --- sphinx/ext/autosummary/generate.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index 54df4f9ffb0..ae802752491 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -320,20 +320,20 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, ns['members'] = dir(obj) ns['inherited_members'] = \ set(dir(obj)) - set(obj.__dict__.keys()) - + ns['methods'], ns['all_methods'] = \ _get_members(doc, app, obj, {'method'}, include_public={'__init__'}) ns['attributes'], ns['all_attributes'] = \ _get_members(doc, app, obj, {'attribute', 'property'}) - + method_string = [m.split(".")[-1] for m in ns['methods']] attr_string = [m.split(".")[-1] for m in ns['attributes']] - + # Find the first link for this attribute in higher classes ns['inherited_paths'] = [] ns['inherited_methods'] = [] ns['inherited_attributes'] = [] - + for i in (set(dir(obj)) - set(obj.__dict__.keys())): for cl in obj.__mro__: local = set(cl.__dict__.keys()) @@ -341,13 +341,12 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, cl_str = cl.__module__ + "." + cl.__name__ + "." + i if i[0] != "_": ns['inherited_paths'].append(cl_str) - + if i in method_string: ns['inherited_methods'].append(cl_str) elif i in attr_string: ns['inherited_attributes'].append(cl_str) - break - + break if modname is None or qualname is None: modname, qualname = _split_full_qualified_name(name) From bee1d6b7255ea5b2a5be84334c9cef30e94777be Mon Sep 17 00:00:00 2001 From: satr Date: Mon, 9 Oct 2023 12:44:47 +0100 Subject: [PATCH 04/33] Review comment changes Change name to qualnames Re-use previously defined inherited members Include private in qualnames, but still not in methods/attributes --- sphinx/ext/autosummary/generate.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index ae802752491..55d4c73f448 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -330,22 +330,20 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, attr_string = [m.split(".")[-1] for m in ns['attributes']] # Find the first link for this attribute in higher classes - ns['inherited_paths'] = [] + ns['inherited_qualnames'] = [] ns['inherited_methods'] = [] ns['inherited_attributes'] = [] - for i in (set(dir(obj)) - set(obj.__dict__.keys())): + for i in ns['inherited_members']: for cl in obj.__mro__: local = set(cl.__dict__.keys()) if i in local: - cl_str = cl.__module__ + "." + cl.__name__ + "." + i - if i[0] != "_": - ns['inherited_paths'].append(cl_str) - - if i in method_string: - ns['inherited_methods'].append(cl_str) - elif i in attr_string: - ns['inherited_attributes'].append(cl_str) + cl_str = f"{cl.__module__}.{cl.__name__}.{i}" + ns['inherited_qualnames'].append(cl_str) + if i in method_string: + ns['inherited_methods'].append(cl_str) + elif i in attr_string: + ns['inherited_attributes'].append(cl_str) break if modname is None or qualname is None: From 4302a9740b5f0d16f4a800d88db7916f2a41018a Mon Sep 17 00:00:00 2001 From: satr Date: Mon, 9 Oct 2023 12:45:02 +0100 Subject: [PATCH 05/33] Autosummary documentation improvements --- doc/usage/extensions/autosummary.rst | 72 ++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/doc/usage/extensions/autosummary.rst b/doc/usage/extensions/autosummary.rst index 65af38abaa2..b9efec3a229 100644 --- a/doc/usage/extensions/autosummary.rst +++ b/doc/usage/extensions/autosummary.rst @@ -293,36 +293,78 @@ The following variables are available in the templates: .. data:: members - List containing names of all members of the module or class. Only available + List containing names of all members of the module or class. Only available for modules and classes. .. data:: inherited_members - List containing names of all inherited members of class. Only available for + List containing names of all inherited members of class. Only available for classes. .. versionadded:: 1.8.0 +.. data:: inherited_qualnames + + List containing the fully qualified names of each inherited member. Will return + just the closest parent from which this class was inherited. Only available + for classes. + + The following example assumes that this code block has been written as + part of a module ``mypackage.test`` + + .. code-block:: python + + class foo(): + foo_attr = "I'm an attribute" + def __init__(self): + print("object initialised") + + def do_something(self): + print("Foo something") + + def _i_am_private(self): + print("I'm a private method") + + class bar(foo): + def do_something_else(self): + print("Bar something") + + Available parameters for the autosummary of class ``bar`` in the above + example are: + + * ``name`` returns ``'bar'`` + * ``objname`` returns ``'bar'`` + * ``fullname`` returns ``'mypackage.test.bar'`` + * ``methods`` returns ``['__init__', 'do_something', 'do_something_else']`` + * ``attributes`` returns ``['foo_attr']`` + * ``members`` returns a list with many built in methods/attributes and + ``['__init__', '_i_am_private', 'do_something', 'do_something_else', + 'foo_attr']`` + * ``inherited_members`` returns a set with many built in methods/attributes + and ``{'__init__', '_i_am_private','do_something', 'foo_attr'}`` + * ``inherited_qualnames`` returns a list with many built in methods/ + attributes and ``['mypackage.test.foo.__init__', + 'mypackage.test.foo._i_am_private', 'mypackage.test.foo.do_something', + 'mypackage.test.foo.foo_attr']`` + * ``inherited_methods`` returns ``['mypackage.test.foo.do_something', + 'mypackage.test.foo.__init__']`` + * ``inherited_attributes`` returns ``['mypackage.test.foo.foo_attr']`` + + .. versionadded:: 7.3.0 + .. data:: inherited_methods - List containing names of only inherited methods. Only available for - classes. + List containing fully qualified names of "public" inherited methods only. + ``__init__`` is still included. Only available for classes. - .. versionadded:: 7.2.7 + .. versionadded:: 7.3.0 .. data:: inherited_attributes - List containing names of only inherited attributes. Only available for - classes. - - .. versionadded:: 7.2.7 - -.. data:: inherited_paths - - List containing the full path inherited members. Will only return the closest - parent from which this class was inherited. Only available for classes. + List containing qualified names of "public" inherited attributes only. + Only available for classes. - .. versionadded:: 7.2.7 + .. versionadded:: 7.3.0 .. data:: functions From 092f70612fa9e3e3d7102d28ac67cb89dff76f79 Mon Sep 17 00:00:00 2001 From: satr Date: Mon, 9 Oct 2023 12:52:59 +0100 Subject: [PATCH 06/33] Docs linter updates --- doc/usage/extensions/autosummary.rst | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/usage/extensions/autosummary.rst b/doc/usage/extensions/autosummary.rst index b9efec3a229..8339bb70714 100644 --- a/doc/usage/extensions/autosummary.rst +++ b/doc/usage/extensions/autosummary.rst @@ -306,12 +306,12 @@ The following variables are available in the templates: .. data:: inherited_qualnames List containing the fully qualified names of each inherited member. Will return - just the closest parent from which this class was inherited. Only available + just the closest parent from which this class was inherited. Only available for classes. - - The following example assumes that this code block has been written as + + The following example assumes that this code block has been written as part of a module ``mypackage.test`` - + .. code-block:: python class foo(): @@ -328,22 +328,22 @@ The following variables are available in the templates: class bar(foo): def do_something_else(self): print("Bar something") - - Available parameters for the autosummary of class ``bar`` in the above + + Available parameters for the autosummary of class ``bar`` in the above example are: - + * ``name`` returns ``'bar'`` * ``objname`` returns ``'bar'`` * ``fullname`` returns ``'mypackage.test.bar'`` * ``methods`` returns ``['__init__', 'do_something', 'do_something_else']`` * ``attributes`` returns ``['foo_attr']`` * ``members`` returns a list with many built in methods/attributes and - ``['__init__', '_i_am_private', 'do_something', 'do_something_else', + ``['__init__', '_i_am_private', 'do_something', 'do_something_else', 'foo_attr']`` * ``inherited_members`` returns a set with many built in methods/attributes and ``{'__init__', '_i_am_private','do_something', 'foo_attr'}`` * ``inherited_qualnames`` returns a list with many built in methods/ - attributes and ``['mypackage.test.foo.__init__', + attributes and ``['mypackage.test.foo.__init__', 'mypackage.test.foo._i_am_private', 'mypackage.test.foo.do_something', 'mypackage.test.foo.foo_attr']`` * ``inherited_methods`` returns ``['mypackage.test.foo.do_something', @@ -354,14 +354,14 @@ The following variables are available in the templates: .. data:: inherited_methods - List containing fully qualified names of "public" inherited methods only. + List containing fully qualified names of "public" inherited methods only. ``__init__`` is still included. Only available for classes. .. versionadded:: 7.3.0 .. data:: inherited_attributes - List containing qualified names of "public" inherited attributes only. + List containing qualified names of "public" inherited attributes only. Only available for classes. .. versionadded:: 7.3.0 From 063d33fadf2b946664dffab0984581e943708ec7 Mon Sep 17 00:00:00 2001 From: satr-cowi <54358974+satr-cowi@users.noreply.github.com> Date: Mon, 9 Oct 2023 13:42:44 +0100 Subject: [PATCH 07/33] Update autosummary.rst --- doc/usage/extensions/autosummary.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/usage/extensions/autosummary.rst b/doc/usage/extensions/autosummary.rst index 8339bb70714..44545630c6f 100644 --- a/doc/usage/extensions/autosummary.rst +++ b/doc/usage/extensions/autosummary.rst @@ -329,7 +329,7 @@ The following variables are available in the templates: def do_something_else(self): print("Bar something") - Available parameters for the autosummary of class ``bar`` in the above + Some available parameters for the autosummary of class ``bar`` in the above example are: * ``name`` returns ``'bar'`` From b8dff3fec9169e49fc00b4f911f6a99820dafad4 Mon Sep 17 00:00:00 2001 From: satr Date: Mon, 9 Oct 2023 15:39:32 +0100 Subject: [PATCH 08/33] Change inherited_members into ordered list --- sphinx/ext/autosummary/generate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index 55d4c73f448..8732e283da8 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -319,7 +319,7 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, elif doc.objtype == 'class': ns['members'] = dir(obj) ns['inherited_members'] = \ - set(dir(obj)) - set(obj.__dict__.keys()) + [x for x in dict.fromkeys(dir(obj)).keys() if x not in obj.__dict__.keys()] ns['methods'], ns['all_methods'] = \ _get_members(doc, app, obj, {'method'}, include_public={'__init__'}) From 697be3354e428c0e24e4644dacd0c1da87c96d95 Mon Sep 17 00:00:00 2001 From: satr Date: Mon, 9 Oct 2023 15:40:22 +0100 Subject: [PATCH 09/33] Added unittest to existing tests for inherited methods and attributes --- tests/test_ext_autosummary.py | 74 +++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/tests/test_ext_autosummary.py b/tests/test_ext_autosummary.py index 43f3ae00c80..61c684bc83a 100644 --- a/tests/test_ext_autosummary.py +++ b/tests/test_ext_autosummary.py @@ -355,6 +355,80 @@ def test_autosummary_generate_content_for_module_imported_members_inherited_modu assert context['name'] == '' assert context['objtype'] == 'module' +@pytest.mark.sphinx(testroot='ext-autosummary') +def test_autosummary_generate_content_for_module_imported_members_inherited_class(app): + import autosummary_dummy_inherited_module + template = Mock() + + generate_autosummary_content('autosummary_dummy_inherited_module.InheritedAttrClass', + autosummary_dummy_inherited_module.InheritedAttrClass, + None, template, None, True, app, False, {}) + assert template.render.call_args[0][0] == 'class' + + context = template.render.call_args[0][1] + assert context['members'] == ['Bar', 'CONSTANT3', 'CONSTANT4', '__annotations__', + '__class__', '__delattr__', '__dict__', '__dir__', + '__doc__', '__eq__', '__format__', '__ge__', + '__getattribute__', '__gt__', '__hash__', '__init__', + '__init_subclass__', '__le__', '__lt__', '__module__', + '__ne__', '__new__', '__reduce__', '__reduce_ex__', + '__repr__', '__setattr__', '__sizeof__', '__str__', + '__subclasshook__', '__weakref__', 'bar', 'baz'] + assert context['inherited_members'] == ['Bar', 'CONSTANT3', 'CONSTANT4', '__class__', + '__delattr__', '__dict__', '__dir__', '__eq__', + '__format__', '__ge__', '__getattribute__', '__gt__', + '__hash__', '__init_subclass__', '__le__', '__lt__', + '__ne__', '__new__', '__reduce__', '__reduce_ex__', + '__repr__', '__setattr__', '__sizeof__', '__str__', + '__subclasshook__', '__weakref__', 'bar', 'baz'] + assert context['methods'] == ['__init__', 'bar'] + assert context['all_methods'] == ['__delattr__', '__dir__', '__eq__', '__format__', '__ge__', + '__getattribute__', '__gt__', '__hash__', '__init__', + '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', + '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', + '__sizeof__', '__str__', '__subclasshook__', 'bar'] + assert context['attributes'] == ['CONSTANT3', 'CONSTANT4', 'baz', 'subclassattr', 'value'] + assert context['all_attributes'] == ['CONSTANT3', 'CONSTANT4', '__annotations__', '__dict__', + '__doc__', '__module__', '__weakref__', 'baz', + 'subclassattr', 'value'] + assert context['inherited_qualnames'] == [ + "autosummary_dummy_module.Foo.Bar", + "autosummary_dummy_module.Foo.CONSTANT3", + "autosummary_dummy_module.Foo.CONSTANT4", + "builtins.object.__class__", + "builtins.object.__delattr__", + "autosummary_dummy_module.Foo.__dict__", + "builtins.object.__dir__", + "builtins.object.__eq__", + "builtins.object.__format__", + "builtins.object.__ge__", + "builtins.object.__getattribute__", + "builtins.object.__gt__", + "builtins.object.__hash__", + "builtins.object.__init_subclass__", + "builtins.object.__le__", + "builtins.object.__lt__", + "builtins.object.__ne__", + "builtins.object.__new__", + "builtins.object.__reduce__", + "builtins.object.__reduce_ex__", + "builtins.object.__repr__", + "builtins.object.__setattr__", + "builtins.object.__sizeof__", + "builtins.object.__str__", + "builtins.object.__subclasshook__", + "autosummary_dummy_module.Foo.__weakref__", + "autosummary_dummy_module.Foo.bar", + "autosummary_dummy_module.Foo.baz"] + assert context['inherited_methods'] == ['autosummary_dummy_module.Foo.bar'] + assert context['inherited_attributes'] == ['autosummary_dummy_module.Foo.CONSTANT3', + 'autosummary_dummy_module.Foo.CONSTANT4', + 'autosummary_dummy_module.Foo.baz'] + assert context['fullname'] == 'autosummary_dummy_inherited_module.InheritedAttrClass' + assert context['module'] == 'autosummary_dummy_inherited_module' + assert context['objname'] == 'InheritedAttrClass' + assert context['name'] == 'InheritedAttrClass' + assert context['objtype'] == 'class' @pytest.mark.sphinx('dummy', testroot='ext-autosummary') def test_autosummary_generate(app, status, warning): From 192ad95f3ed4353a176b021f56d00cd2b785b5d4 Mon Sep 17 00:00:00 2001 From: satr Date: Mon, 9 Oct 2023 15:47:36 +0100 Subject: [PATCH 10/33] lint formatting --- sphinx/ext/autosummary/generate.py | 2 +- tests/test_ext_autosummary.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index 8732e283da8..24243690fdf 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -319,7 +319,7 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, elif doc.objtype == 'class': ns['members'] = dir(obj) ns['inherited_members'] = \ - [x for x in dict.fromkeys(dir(obj)).keys() if x not in obj.__dict__.keys()] + [x for x in dict.fromkeys(dir(obj)) if x not in obj.__dict__] ns['methods'], ns['all_methods'] = \ _get_members(doc, app, obj, {'method'}, include_public={'__init__'}) diff --git a/tests/test_ext_autosummary.py b/tests/test_ext_autosummary.py index 61c684bc83a..ea516496e5a 100644 --- a/tests/test_ext_autosummary.py +++ b/tests/test_ext_autosummary.py @@ -355,13 +355,14 @@ def test_autosummary_generate_content_for_module_imported_members_inherited_modu assert context['name'] == '' assert context['objtype'] == 'module' + @pytest.mark.sphinx(testroot='ext-autosummary') def test_autosummary_generate_content_for_module_imported_members_inherited_class(app): import autosummary_dummy_inherited_module template = Mock() generate_autosummary_content('autosummary_dummy_inherited_module.InheritedAttrClass', - autosummary_dummy_inherited_module.InheritedAttrClass, + autosummary_dummy_inherited_module.InheritedAttrClass, None, template, None, True, app, False, {}) assert template.render.call_args[0][0] == 'class' @@ -430,6 +431,7 @@ def test_autosummary_generate_content_for_module_imported_members_inherited_clas assert context['name'] == 'InheritedAttrClass' assert context['objtype'] == 'class' + @pytest.mark.sphinx('dummy', testroot='ext-autosummary') def test_autosummary_generate(app, status, warning): app.builder.build_all() From e9edee715eb256de684d2f5e9a18402ed851de47 Mon Sep 17 00:00:00 2001 From: satr Date: Mon, 9 Oct 2023 17:54:16 +0100 Subject: [PATCH 11/33] Removed use of __dict__ Attributes now also include attributes defined in _init_ like in test --- sphinx/ext/autosummary/generate.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index 24243690fdf..281fe8969ef 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -317,9 +317,12 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, ns['modules'] = imported_modules + modules ns["all_modules"] = all_imported_modules + all_modules elif doc.objtype == 'class': - ns['members'] = dir(obj) + ns['members'] = list(_get_class_members(obj)) + obj_classinfo = _get_class_members(obj,False) + obj_local = [j for j,k in obj_classinfo.items() if k == obj] + ns['inherited_members'] = \ - [x for x in dict.fromkeys(dir(obj)) if x not in obj.__dict__] + [x for x in dict.fromkeys(ns['members']) if x not in obj_local] ns['methods'], ns['all_methods'] = \ _get_members(doc, app, obj, {'method'}, include_public={'__init__'}) @@ -336,7 +339,9 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, for i in ns['inherited_members']: for cl in obj.__mro__: - local = set(cl.__dict__.keys()) + classinfo = _get_class_members(cl,False) + local = [j for j,k in classinfo.items() if k == cl] + if i in local: cl_str = f"{cl.__module__}.{cl.__name__}.{i}" ns['inherited_qualnames'].append(cl_str) @@ -381,10 +386,12 @@ def _skip_member(app: Sphinx, obj: Any, name: str, objtype: str) -> bool: name, exc, type='autosummary') return False - -def _get_class_members(obj: Any) -> dict[str, Any]: +def _get_class_members(obj: Any, return_object=True) -> dict[str, Any]: members = sphinx.ext.autodoc.get_class_members(obj, None, safe_getattr) - return {name: member.object for name, member in members.items()} + if return_object: + return {name: member.object for name, member in members.items()} + else: + return {name: member.class_ for name, member in members.items()} def _get_module_members(app: Sphinx, obj: Any) -> dict[str, Any]: From b7a0049593977379a86f7c0aa3815a9eff5d4ba5 Mon Sep 17 00:00:00 2001 From: satr Date: Mon, 9 Oct 2023 17:54:55 +0100 Subject: [PATCH 12/33] Test shouldn't depend on Python version or os. Includes attributes in __init__ --- tests/test_ext_autosummary.py | 73 ++++++++++------------------------- 1 file changed, 20 insertions(+), 53 deletions(-) diff --git a/tests/test_ext_autosummary.py b/tests/test_ext_autosummary.py index ea516496e5a..71a48f61d06 100644 --- a/tests/test_ext_autosummary.py +++ b/tests/test_ext_autosummary.py @@ -367,64 +367,31 @@ def test_autosummary_generate_content_for_module_imported_members_inherited_clas assert template.render.call_args[0][0] == 'class' context = template.render.call_args[0][1] - assert context['members'] == ['Bar', 'CONSTANT3', 'CONSTANT4', '__annotations__', - '__class__', '__delattr__', '__dict__', '__dir__', - '__doc__', '__eq__', '__format__', '__ge__', - '__getattribute__', '__gt__', '__hash__', '__init__', - '__init_subclass__', '__le__', '__lt__', '__module__', - '__ne__', '__new__', '__reduce__', '__reduce_ex__', - '__repr__', '__setattr__', '__sizeof__', '__str__', - '__subclasshook__', '__weakref__', 'bar', 'baz'] - assert context['inherited_members'] == ['Bar', 'CONSTANT3', 'CONSTANT4', '__class__', - '__delattr__', '__dict__', '__dir__', '__eq__', - '__format__', '__ge__', '__getattribute__', '__gt__', - '__hash__', '__init_subclass__', '__le__', '__lt__', - '__ne__', '__new__', '__reduce__', '__reduce_ex__', - '__repr__', '__setattr__', '__sizeof__', '__str__', - '__subclasshook__', '__weakref__', 'bar', 'baz'] + + def assert_all_a_in_b(a,b): + assert all(x in b for x in a) + + assert_all_a_in_b(['Bar', 'CONSTANT3', 'CONSTANT4', '__init__', 'bar', 'baz', + 'subclassattr', 'value'],context['members']) + assert_all_a_in_b(['Bar', 'CONSTANT3', 'CONSTANT4', 'bar', 'baz','value'], + context['inherited_members']) + assert '__init__' not in context['inherited_members'] + assert 'subclassattr' not in context['inherited_members'] + assert context['methods'] == ['__init__', 'bar'] - assert context['all_methods'] == ['__delattr__', '__dir__', '__eq__', '__format__', '__ge__', - '__getattribute__', '__gt__', '__hash__', '__init__', - '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', - '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', - '__sizeof__', '__str__', '__subclasshook__', 'bar'] assert context['attributes'] == ['CONSTANT3', 'CONSTANT4', 'baz', 'subclassattr', 'value'] - assert context['all_attributes'] == ['CONSTANT3', 'CONSTANT4', '__annotations__', '__dict__', - '__doc__', '__module__', '__weakref__', 'baz', - 'subclassattr', 'value'] - assert context['inherited_qualnames'] == [ - "autosummary_dummy_module.Foo.Bar", - "autosummary_dummy_module.Foo.CONSTANT3", - "autosummary_dummy_module.Foo.CONSTANT4", - "builtins.object.__class__", - "builtins.object.__delattr__", - "autosummary_dummy_module.Foo.__dict__", - "builtins.object.__dir__", - "builtins.object.__eq__", - "builtins.object.__format__", - "builtins.object.__ge__", - "builtins.object.__getattribute__", - "builtins.object.__gt__", - "builtins.object.__hash__", - "builtins.object.__init_subclass__", - "builtins.object.__le__", - "builtins.object.__lt__", - "builtins.object.__ne__", - "builtins.object.__new__", - "builtins.object.__reduce__", - "builtins.object.__reduce_ex__", - "builtins.object.__repr__", - "builtins.object.__setattr__", - "builtins.object.__sizeof__", - "builtins.object.__str__", - "builtins.object.__subclasshook__", - "autosummary_dummy_module.Foo.__weakref__", - "autosummary_dummy_module.Foo.bar", - "autosummary_dummy_module.Foo.baz"] + assert_all_a_in_b(["autosummary_dummy_module.Foo.Bar", + "autosummary_dummy_module.Foo.CONSTANT3", + "autosummary_dummy_module.Foo.CONSTANT4", + "autosummary_dummy_module.Foo.bar", + "autosummary_dummy_module.Foo.baz", + "autosummary_dummy_module.Foo.value"], + context['inherited_qualnames']) assert context['inherited_methods'] == ['autosummary_dummy_module.Foo.bar'] assert context['inherited_attributes'] == ['autosummary_dummy_module.Foo.CONSTANT3', 'autosummary_dummy_module.Foo.CONSTANT4', - 'autosummary_dummy_module.Foo.baz'] + 'autosummary_dummy_module.Foo.baz', + 'autosummary_dummy_module.Foo.value'] assert context['fullname'] == 'autosummary_dummy_inherited_module.InheritedAttrClass' assert context['module'] == 'autosummary_dummy_inherited_module' assert context['objname'] == 'InheritedAttrClass' From 0901005321a16ef016a22003359205c5c34e3880 Mon Sep 17 00:00:00 2001 From: satr Date: Mon, 9 Oct 2023 17:55:09 +0100 Subject: [PATCH 13/33] docs updated --- doc/usage/extensions/autosummary.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/usage/extensions/autosummary.rst b/doc/usage/extensions/autosummary.rst index 44545630c6f..755863a1027 100644 --- a/doc/usage/extensions/autosummary.rst +++ b/doc/usage/extensions/autosummary.rst @@ -340,14 +340,14 @@ The following variables are available in the templates: * ``members`` returns a list with many built in methods/attributes and ``['__init__', '_i_am_private', 'do_something', 'do_something_else', 'foo_attr']`` - * ``inherited_members`` returns a set with many built in methods/attributes - and ``{'__init__', '_i_am_private','do_something', 'foo_attr'}`` + * ``inherited_members`` returns a list with many built in methods/attributes + and ``['__init__', '_i_am_private','do_something', 'foo_attr']`` * ``inherited_qualnames`` returns a list with many built in methods/ attributes and ``['mypackage.test.foo.__init__', 'mypackage.test.foo._i_am_private', 'mypackage.test.foo.do_something', 'mypackage.test.foo.foo_attr']`` - * ``inherited_methods`` returns ``['mypackage.test.foo.do_something', - 'mypackage.test.foo.__init__']`` + * ``inherited_methods`` returns ``['mypackage.test.foo.__init__', + 'mypackage.test.foo.do_something']`` * ``inherited_attributes`` returns ``['mypackage.test.foo.foo_attr']`` .. versionadded:: 7.3.0 From de412e0521215f1047759adcc77990bf850c1b8f Mon Sep 17 00:00:00 2001 From: satr Date: Mon, 9 Oct 2023 18:00:14 +0100 Subject: [PATCH 14/33] Linting corrections --- sphinx/ext/autosummary/generate.py | 15 ++++++++------- tests/test_ext_autosummary.py | 10 +++++----- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index 281fe8969ef..cc59b04b28b 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -318,9 +318,9 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, ns["all_modules"] = all_imported_modules + all_modules elif doc.objtype == 'class': ns['members'] = list(_get_class_members(obj)) - obj_classinfo = _get_class_members(obj,False) - obj_local = [j for j,k in obj_classinfo.items() if k == obj] - + obj_classinfo = _get_class_members(obj, False) + obj_local = [j for j, k in obj_classinfo.items() if k == obj] + ns['inherited_members'] = \ [x for x in dict.fromkeys(ns['members']) if x not in obj_local] @@ -339,9 +339,9 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, for i in ns['inherited_members']: for cl in obj.__mro__: - classinfo = _get_class_members(cl,False) - local = [j for j,k in classinfo.items() if k == cl] - + classinfo = _get_class_members(cl, False) + local = [j for j, k in classinfo.items() if k == cl] + if i in local: cl_str = f"{cl.__module__}.{cl.__name__}.{i}" ns['inherited_qualnames'].append(cl_str) @@ -386,7 +386,8 @@ def _skip_member(app: Sphinx, obj: Any, name: str, objtype: str) -> bool: name, exc, type='autosummary') return False -def _get_class_members(obj: Any, return_object=True) -> dict[str, Any]: + +def _get_class_members(obj: Any, return_object=True: bool) -> dict[str, Any]: members = sphinx.ext.autodoc.get_class_members(obj, None, safe_getattr) if return_object: return {name: member.object for name, member in members.items()} diff --git a/tests/test_ext_autosummary.py b/tests/test_ext_autosummary.py index 71a48f61d06..688e48426e4 100644 --- a/tests/test_ext_autosummary.py +++ b/tests/test_ext_autosummary.py @@ -367,17 +367,17 @@ def test_autosummary_generate_content_for_module_imported_members_inherited_clas assert template.render.call_args[0][0] == 'class' context = template.render.call_args[0][1] - - def assert_all_a_in_b(a,b): + + def assert_all_a_in_b(a, b): assert all(x in b for x in a) assert_all_a_in_b(['Bar', 'CONSTANT3', 'CONSTANT4', '__init__', 'bar', 'baz', - 'subclassattr', 'value'],context['members']) - assert_all_a_in_b(['Bar', 'CONSTANT3', 'CONSTANT4', 'bar', 'baz','value'], + 'subclassattr', 'value'], context['members']) + assert_all_a_in_b(['Bar', 'CONSTANT3', 'CONSTANT4', 'bar', 'baz', 'value'], context['inherited_members']) assert '__init__' not in context['inherited_members'] assert 'subclassattr' not in context['inherited_members'] - + assert context['methods'] == ['__init__', 'bar'] assert context['attributes'] == ['CONSTANT3', 'CONSTANT4', 'baz', 'subclassattr', 'value'] assert_all_a_in_b(["autosummary_dummy_module.Foo.Bar", From 4f3aa013f08e6a6e8ee267d86283f8a5d5818a4c Mon Sep 17 00:00:00 2001 From: satr Date: Mon, 9 Oct 2023 18:01:47 +0100 Subject: [PATCH 15/33] correction --- sphinx/ext/autosummary/generate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index cc59b04b28b..9eb9163567a 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -387,7 +387,7 @@ def _skip_member(app: Sphinx, obj: Any, name: str, objtype: str) -> bool: return False -def _get_class_members(obj: Any, return_object=True: bool) -> dict[str, Any]: +def _get_class_members(obj: Any, return_object: bool = True) -> dict[str, Any]: members = sphinx.ext.autodoc.get_class_members(obj, None, safe_getattr) if return_object: return {name: member.object for name, member in members.items()} From 8e62aedf75edaa018ba8545520df7b6348b0a3d0 Mon Sep 17 00:00:00 2001 From: satr Date: Mon, 9 Oct 2023 18:03:43 +0100 Subject: [PATCH 16/33] another linting correction --- tests/test_ext_autosummary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_ext_autosummary.py b/tests/test_ext_autosummary.py index 688e48426e4..2e2883b74ed 100644 --- a/tests/test_ext_autosummary.py +++ b/tests/test_ext_autosummary.py @@ -371,7 +371,7 @@ def test_autosummary_generate_content_for_module_imported_members_inherited_clas def assert_all_a_in_b(a, b): assert all(x in b for x in a) - assert_all_a_in_b(['Bar', 'CONSTANT3', 'CONSTANT4', '__init__', 'bar', 'baz', + assert_all_a_in_b(['Bar', 'CONSTANT3', 'CONSTANT4', '__init__', 'bar', 'baz', 'subclassattr', 'value'], context['members']) assert_all_a_in_b(['Bar', 'CONSTANT3', 'CONSTANT4', 'bar', 'baz', 'value'], context['inherited_members']) From 71c1729e67fca139cba431f57b8cf797258030af Mon Sep 17 00:00:00 2001 From: satr Date: Fri, 13 Oct 2023 12:24:17 +0100 Subject: [PATCH 17/33] Refactor to minimise _get_class_members calls --- sphinx/ext/autosummary/generate.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index 9eb9163567a..9d6f56d2ea1 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -337,19 +337,19 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, ns['inherited_methods'] = [] ns['inherited_attributes'] = [] - for i in ns['inherited_members']: - for cl in obj.__mro__: - classinfo = _get_class_members(cl, False) - local = [j for j, k in classinfo.items() if k == cl] + inherited_set = set(ns['inherited_members']) + for cl in obj.__mro__: + classinfo = _get_class_members(cl, False) + local = [j for j, k in classinfo.items() if k == cl] - if i in local: + for i in local: + if i in inherited_set: cl_str = f"{cl.__module__}.{cl.__name__}.{i}" ns['inherited_qualnames'].append(cl_str) if i in method_string: ns['inherited_methods'].append(cl_str) elif i in attr_string: ns['inherited_attributes'].append(cl_str) - break if modname is None or qualname is None: modname, qualname = _split_full_qualified_name(name) From 3199fe0e5c7d80dde4cd70805b95360f4c597fba Mon Sep 17 00:00:00 2001 From: satr Date: Wed, 25 Sep 2024 12:13:55 +0100 Subject: [PATCH 18/33] ruff format --- sphinx/ext/autosummary/generate.py | 11 +-- tests/test_extensions/test_ext_autosummary.py | 76 ++++++++++++++----- 2 files changed, 62 insertions(+), 25 deletions(-) diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index fad4ba541b9..55f28033086 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -350,8 +350,9 @@ def generate_autosummary_content( obj_classinfo = _get_class_members(obj, False) obj_local = [j for j, k in obj_classinfo.items() if k == obj] - ns['inherited_members'] = \ - [x for x in dict.fromkeys(ns['members']) if x not in obj_local] + ns['inherited_members'] = [ + x for x in dict.fromkeys(ns['members']) if x not in obj_local + ] ns['methods'], ns['all_methods'] = _get_members( doc, app, obj, {'method'}, include_public={'__init__'} @@ -360,8 +361,8 @@ def generate_autosummary_content( doc, app, obj, {'attribute', 'property'} ) - method_string = [m.split(".")[-1] for m in ns['methods']] - attr_string = [m.split(".")[-1] for m in ns['attributes']] + method_string = [m.split('.')[-1] for m in ns['methods']] + attr_string = [m.split('.')[-1] for m in ns['attributes']] # Find the first link for this attribute in higher classes ns['inherited_qualnames'] = [] @@ -375,7 +376,7 @@ def generate_autosummary_content( for i in local: if i in inherited_set: - cl_str = f"{cl.__module__}.{cl.__name__}.{i}" + cl_str = f'{cl.__module__}.{cl.__name__}.{i}' ns['inherited_qualnames'].append(cl_str) if i in method_string: ns['inherited_methods'].append(cl_str) diff --git a/tests/test_extensions/test_ext_autosummary.py b/tests/test_extensions/test_ext_autosummary.py index 2a743494fb7..fef9a129857 100644 --- a/tests/test_extensions/test_ext_autosummary.py +++ b/tests/test_extensions/test_ext_autosummary.py @@ -490,11 +490,20 @@ def test_autosummary_generate_content_for_module_imported_members_inherited_modu @pytest.mark.sphinx(testroot='ext-autosummary') def test_autosummary_generate_content_for_module_imported_members_inherited_class(app): import autosummary_dummy_inherited_module + template = Mock() - generate_autosummary_content('autosummary_dummy_inherited_module.InheritedAttrClass', - autosummary_dummy_inherited_module.InheritedAttrClass, - None, template, None, True, app, False, {}) + generate_autosummary_content( + 'autosummary_dummy_inherited_module.InheritedAttrClass', + autosummary_dummy_inherited_module.InheritedAttrClass, + None, + template, + None, + True, + app, + False, + {}, + ) assert template.render.call_args[0][0] == 'class' context = template.render.call_args[0][1] @@ -502,28 +511,55 @@ def test_autosummary_generate_content_for_module_imported_members_inherited_clas def assert_all_a_in_b(a, b): assert all(x in b for x in a) - assert_all_a_in_b(['Bar', 'CONSTANT3', 'CONSTANT4', '__init__', 'bar', 'baz', - 'subclassattr', 'value'], context['members']) - assert_all_a_in_b(['Bar', 'CONSTANT3', 'CONSTANT4', 'bar', 'baz', 'value'], - context['inherited_members']) + assert_all_a_in_b( + [ + 'Bar', + 'CONSTANT3', + 'CONSTANT4', + '__init__', + 'bar', + 'baz', + 'subclassattr', + 'value', + ], + context['members'], + ) + assert_all_a_in_b( + ['Bar', 'CONSTANT3', 'CONSTANT4', 'bar', 'baz', 'value'], + context['inherited_members'], + ) assert '__init__' not in context['inherited_members'] assert 'subclassattr' not in context['inherited_members'] assert context['methods'] == ['__init__', 'bar'] - assert context['attributes'] == ['CONSTANT3', 'CONSTANT4', 'baz', 'subclassattr', 'value'] - assert_all_a_in_b(["autosummary_dummy_module.Foo.Bar", - "autosummary_dummy_module.Foo.CONSTANT3", - "autosummary_dummy_module.Foo.CONSTANT4", - "autosummary_dummy_module.Foo.bar", - "autosummary_dummy_module.Foo.baz", - "autosummary_dummy_module.Foo.value"], - context['inherited_qualnames']) + assert context['attributes'] == [ + 'CONSTANT3', + 'CONSTANT4', + 'baz', + 'subclassattr', + 'value', + ] + assert_all_a_in_b( + [ + 'autosummary_dummy_module.Foo.Bar', + 'autosummary_dummy_module.Foo.CONSTANT3', + 'autosummary_dummy_module.Foo.CONSTANT4', + 'autosummary_dummy_module.Foo.bar', + 'autosummary_dummy_module.Foo.baz', + 'autosummary_dummy_module.Foo.value', + ], + context['inherited_qualnames'], + ) assert context['inherited_methods'] == ['autosummary_dummy_module.Foo.bar'] - assert context['inherited_attributes'] == ['autosummary_dummy_module.Foo.CONSTANT3', - 'autosummary_dummy_module.Foo.CONSTANT4', - 'autosummary_dummy_module.Foo.baz', - 'autosummary_dummy_module.Foo.value'] - assert context['fullname'] == 'autosummary_dummy_inherited_module.InheritedAttrClass' + assert context['inherited_attributes'] == [ + 'autosummary_dummy_module.Foo.CONSTANT3', + 'autosummary_dummy_module.Foo.CONSTANT4', + 'autosummary_dummy_module.Foo.baz', + 'autosummary_dummy_module.Foo.value', + ] + assert ( + context['fullname'] == 'autosummary_dummy_inherited_module.InheritedAttrClass' + ) assert context['module'] == 'autosummary_dummy_inherited_module' assert context['objname'] == 'InheritedAttrClass' assert context['name'] == 'InheritedAttrClass' From 988457918973362d4ce0f98267339f08c5468904 Mon Sep 17 00:00:00 2001 From: satr Date: Wed, 25 Sep 2024 16:53:03 +0100 Subject: [PATCH 19/33] Only return the first instance of inheritance --- sphinx/ext/autosummary/generate.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index 55f28033086..c5ef7ee62e0 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -382,6 +382,7 @@ def generate_autosummary_content( ns['inherited_methods'].append(cl_str) elif i in attr_string: ns['inherited_attributes'].append(cl_str) + inherited_set.remove(i) if modname is None or qualname is None: modname, qualname = _split_full_qualified_name(name) From 5421b261fc94919fe6ca01389c4defac8c568b84 Mon Sep 17 00:00:00 2001 From: satr Date: Wed, 25 Sep 2024 16:53:20 +0100 Subject: [PATCH 20/33] Additional tests for more conditions --- ...ummary_dummy_complex_inheritance_module.py | 79 ++++ tests/test_extensions/test_ext_autosummary.py | 342 ++++++++++++++++++ 2 files changed, 421 insertions(+) create mode 100644 tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py diff --git a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py new file mode 100644 index 00000000000..2bd4477f31b --- /dev/null +++ b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py @@ -0,0 +1,79 @@ + +class Parent: + + relation = "Family" + + def __init__(self): + self.name = "Andrew" + self.age = 35 + + def get_name(self): + return self.name + + def get_age(self): + return f"Parent class - {self.age}" + + # Test mangled name behaviour + __get_age = get_age # private copy of original get_age method + __private_parent_attribute = "Private_parent" + + +class Child(Parent): + + def __init__(self): + self.name = "Bobby" + self.age = 15 + + def get_name(self): + return self.name + + def get_age(self): + return f"Child class - {self.age}" + + @staticmethod + def addition(a, b): + return a + b + + +class Baby(Child): + + # Test a private attribute + __private_baby_name = "Private1234" + + def __init__(self): + self.name = "Charlie" + self.age = 2 + + def get_age(self): + return f"Baby class - {self.age}" + + class BabyInnerClass(): + baby_inner_attribute = "An attribute of an inner class" + + +class Job: + + def __init__(self): + self.salary = 10 + + def get_salary(self): + return self.salary + + +class Architect(Job): + + def __init__(self): + self.salary = 20 + + def get_age(self): + return f"Architect age - {self.age}" + +# Test a class that inherits multiple classes +class Jerry(Architect, Child): + + def __init__(self): + self.name = "Jerry" + self.age = 25 + + +__all__ = ["Parent", "Child", "Baby", "Job", "Architect", "Jerry"] diff --git a/tests/test_extensions/test_ext_autosummary.py b/tests/test_extensions/test_ext_autosummary.py index fef9a129857..788721b9912 100644 --- a/tests/test_extensions/test_ext_autosummary.py +++ b/tests/test_extensions/test_ext_autosummary.py @@ -566,6 +566,348 @@ def assert_all_a_in_b(a, b): assert context['objtype'] == 'class' +@pytest.mark.sphinx(testroot='ext-autosummary') +def test_autosummary_generate_content_for_module_imported_members_complex_inheritance( + app, +): + import autosummary_dummy_complex_inheritance_module + + template_jerry = Mock() + + generate_autosummary_content( + name='autosummary_dummy_complex_inheritance_module.Jerry', + obj=autosummary_dummy_complex_inheritance_module.Jerry, + parent=None, + template=template_jerry, + template_name=None, + imported_members=True, + app=app, + recursive=False, + context={}, + ) + assert template_jerry.render.call_args[0][0] == 'class' + + context = template_jerry.render.call_args[0][1] + + assert context['name'] == 'Jerry' + assert context['module'] == 'autosummary_dummy_complex_inheritance_module' + assert context['fullname'] == 'autosummary_dummy_complex_inheritance_module.Jerry' + + assert context['attributes'] == ['relation'] + assert context['methods'] == ['__init__', 'addition', 'get_age', 'get_name','get_salary'] + + assert context['all_attributes'] == [ + '__annotations__', + '__dict__', + '__doc__', + '__module__', + '__weakref__', + 'relation', + ] + assert context['all_methods'] == [ + '__delattr__', + '__dir__', + '__eq__', + '__format__', + '__ge__', + '__getattribute__', + '__getstate__', + '__gt__', + '__hash__', + '__init__', + '__init_subclass__', + '__le__', + '__lt__', + '__ne__', + '__new__', + '__reduce__', + '__reduce_ex__', + '__repr__', + '__setattr__', + '__sizeof__', + '__str__', + '__subclasshook__', + 'addition', + 'get_age', + 'get_name', + 'get_salary' + ] + + assert context['inherited_attributes'] == [ + 'autosummary_dummy_complex_inheritance_module.Parent.relation' + ] + assert context['inherited_methods'] == [ + 'autosummary_dummy_complex_inheritance_module.Architect.get_age', + 'autosummary_dummy_complex_inheritance_module.Job.get_salary', + 'autosummary_dummy_complex_inheritance_module.Child.addition', + 'autosummary_dummy_complex_inheritance_module.Child.get_name', + ] + + assert context['inherited_qualnames'] == [ + 'autosummary_dummy_complex_inheritance_module.Architect.get_age', + 'autosummary_dummy_complex_inheritance_module.Job.__dict__', + 'autosummary_dummy_complex_inheritance_module.Job.__weakref__', + 'autosummary_dummy_complex_inheritance_module.Job.get_salary', + 'autosummary_dummy_complex_inheritance_module.Child.addition', + 'autosummary_dummy_complex_inheritance_module.Child.get_name', + 'autosummary_dummy_complex_inheritance_module.Parent.relation', + 'builtins.object.__class__', + 'builtins.object.__delattr__', + 'builtins.object.__dir__', + 'builtins.object.__eq__', + 'builtins.object.__format__', + 'builtins.object.__ge__', + 'builtins.object.__getattribute__', + 'builtins.object.__getstate__', + 'builtins.object.__gt__', + 'builtins.object.__hash__', + 'builtins.object.__init_subclass__', + 'builtins.object.__le__', + 'builtins.object.__lt__', + 'builtins.object.__ne__', + 'builtins.object.__new__', + 'builtins.object.__reduce__', + 'builtins.object.__reduce_ex__', + 'builtins.object.__repr__', + 'builtins.object.__setattr__', + 'builtins.object.__sizeof__', + 'builtins.object.__str__', + 'builtins.object.__subclasshook__', + ] + + assert context['inherited_members'] == [ + '__class__', + '__delattr__', + '__dict__', + '__dir__', + '__eq__', + '__format__', + '__ge__', + '__getattribute__', + '__getstate__', + '__gt__', + '__hash__', + '__init_subclass__', + '__le__', + '__lt__', + '__ne__', + '__new__', + '__reduce__', + '__reduce_ex__', + '__repr__', + '__setattr__', + '__sizeof__', + '__str__', + '__subclasshook__', + '__weakref__', + 'addition', + 'get_age', + 'get_name', + 'get_salary', + 'relation', + ] + + assert context['members'] == [ + '__class__', + '__delattr__', + '__dict__', + '__dir__', + '__doc__', + '__eq__', + '__format__', + '__ge__', + '__getattribute__', + '__getstate__', + '__gt__', + '__hash__', + '__init__', + '__init_subclass__', + '__le__', + '__lt__', + '__module__', + '__ne__', + '__new__', + '__reduce__', + '__reduce_ex__', + '__repr__', + '__setattr__', + '__sizeof__', + '__str__', + '__subclasshook__', + '__weakref__', + 'addition', + 'get_age', + 'get_name', + 'get_salary', + 'relation', + ] + + template_baby = Mock() + + generate_autosummary_content( + name='autosummary_dummy_complex_inheritance_module.Baby', + obj=autosummary_dummy_complex_inheritance_module.Baby, + parent=None, + template=template_baby, + template_name=None, + imported_members=True, + app=app, + recursive=False, + context={}, + ) + + context2 = template_baby.render.call_args[0][1] + + assert context2['name'] == 'Baby' + assert context2['module'] == 'autosummary_dummy_complex_inheritance_module' + assert context2['fullname'] == 'autosummary_dummy_complex_inheritance_module.Baby' + + assert context2['attributes'] == ['relation'] + assert context2['methods'] == ['__init__', 'addition', 'get_age', 'get_name'] + + assert context2['all_attributes'] == [ + '__private_baby_name', + '__annotations__', + '__dict__', + '__doc__', + '__module__', + '__weakref__', + 'relation', + ] + assert context2['all_methods'] == [ + '__delattr__', + '__dir__', + '__eq__', + '__format__', + '__ge__', + '__getattribute__', + '__getstate__', + '__gt__', + '__hash__', + '__init__', + '__init_subclass__', + '__le__', + '__lt__', + '__ne__', + '__new__', + '__reduce__', + '__reduce_ex__', + '__repr__', + '__setattr__', + '__sizeof__', + '__str__', + '__subclasshook__', + 'addition', + 'get_age', + 'get_name', + ] + + assert context2['inherited_attributes'] == [ + 'autosummary_dummy_complex_inheritance_module.Parent.relation' + ] + assert context2['inherited_methods'] == [ + 'autosummary_dummy_complex_inheritance_module.Child.addition', + 'autosummary_dummy_complex_inheritance_module.Child.get_name', + ] + + assert context2['inherited_qualnames'] == [ + 'autosummary_dummy_complex_inheritance_module.Child.addition', + 'autosummary_dummy_complex_inheritance_module.Child.get_name', + 'autosummary_dummy_complex_inheritance_module.Parent.__dict__', + 'autosummary_dummy_complex_inheritance_module.Parent.__weakref__', + 'autosummary_dummy_complex_inheritance_module.Parent.relation', + 'builtins.object.__class__', + 'builtins.object.__delattr__', + 'builtins.object.__dir__', + 'builtins.object.__eq__', + 'builtins.object.__format__', + 'builtins.object.__ge__', + 'builtins.object.__getattribute__', + 'builtins.object.__getstate__', + 'builtins.object.__gt__', + 'builtins.object.__hash__', + 'builtins.object.__init_subclass__', + 'builtins.object.__le__', + 'builtins.object.__lt__', + 'builtins.object.__ne__', + 'builtins.object.__new__', + 'builtins.object.__reduce__', + 'builtins.object.__reduce_ex__', + 'builtins.object.__repr__', + 'builtins.object.__setattr__', + 'builtins.object.__sizeof__', + 'builtins.object.__str__', + 'builtins.object.__subclasshook__', + ] + + assert context2['inherited_members'] == [ + '__class__', + '__delattr__', + '__dict__', + '__dir__', + '__eq__', + '__format__', + '__ge__', + '__getattribute__', + '__getstate__', + '__gt__', + '__hash__', + '__init_subclass__', + '__le__', + '__lt__', + '__ne__', + '__new__', + '__reduce__', + '__reduce_ex__', + '__repr__', + '__setattr__', + '__sizeof__', + '__str__', + '__subclasshook__', + '__weakref__', + 'addition', + 'get_name', + 'relation', + ] + + assert context2['members'] == [ + 'BabyInnerClass', + '__private_baby_name', + '__annotations__', + '__class__', + '__delattr__', + '__dict__', + '__dir__', + '__doc__', + '__eq__', + '__format__', + '__ge__', + '__getattribute__', + '__getstate__', + '__gt__', + '__hash__', + '__init__', + '__init_subclass__', + '__le__', + '__lt__', + '__module__', + '__ne__', + '__new__', + '__reduce__', + '__reduce_ex__', + '__repr__', + '__setattr__', + '__sizeof__', + '__str__', + '__subclasshook__', + '__weakref__', + 'addition', + 'get_age', + 'get_name', + 'relation', + ] + + @pytest.mark.sphinx('dummy', testroot='ext-autosummary') def test_autosummary_generate(app): app.build(force_all=True) From a34b6481890ee6f37da4f32943c2bb4258a5b8c6 Mon Sep 17 00:00:00 2001 From: satr Date: Wed, 25 Sep 2024 16:54:05 +0100 Subject: [PATCH 21/33] Clarification on members including private and template example --- doc/usage/extensions/autosummary.rst | 34 ++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/doc/usage/extensions/autosummary.rst b/doc/usage/extensions/autosummary.rst index 25b01c412c1..eb25fb260e8 100644 --- a/doc/usage/extensions/autosummary.rst +++ b/doc/usage/extensions/autosummary.rst @@ -293,13 +293,13 @@ The following variables are available in the templates: .. data:: members - List containing names of all members of the module or class. Only available - for modules and classes. + List containing names of all members of the module or class including private + ones. Only available for modules and classes. .. data:: inherited_members - List containing names of all inherited members of class. Only available for - classes. + List containing names of all inherited members of class including private ones. + Only available for classes. .. versionadded:: 1.8.0 @@ -350,6 +350,32 @@ The following variables are available in the templates: 'mypackage.test.foo.do_something']`` * ``inherited_attributes`` returns ``['mypackage.test.foo.foo_attr']`` + These parameters could then be used in a Sphinx template `class.rst` like the following + + .. code-block:: RST + :dedent: 0 + + .. currentmodule:: {{ module }} + + .. autoclass:: {{ objname }} + :show-inheritance: + + .. rubric:: Methods + .. autosummary:: + :toctree: + :nosignatures: + {% for item in methods %} + {% if item not in inherited_members %} + {{objname}}.{{ item }} + {%- endif %} + {%- endfor %} + + .. rubric:: Inherited Methods + .. autosummary:: + {% for item in inherited_methods %} + {{item}} + {%- endfor %} + .. versionadded:: 7.3.0 .. data:: inherited_methods From 6f3fbc347a03252a85655912cc416d9507f90aec Mon Sep 17 00:00:00 2001 From: satr Date: Wed, 25 Sep 2024 16:55:42 +0100 Subject: [PATCH 22/33] ruff format --- tests/test_extensions/test_ext_autosummary.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/test_extensions/test_ext_autosummary.py b/tests/test_extensions/test_ext_autosummary.py index 788721b9912..9f7bafc1275 100644 --- a/tests/test_extensions/test_ext_autosummary.py +++ b/tests/test_extensions/test_ext_autosummary.py @@ -594,7 +594,13 @@ def test_autosummary_generate_content_for_module_imported_members_complex_inheri assert context['fullname'] == 'autosummary_dummy_complex_inheritance_module.Jerry' assert context['attributes'] == ['relation'] - assert context['methods'] == ['__init__', 'addition', 'get_age', 'get_name','get_salary'] + assert context['methods'] == [ + '__init__', + 'addition', + 'get_age', + 'get_name', + 'get_salary', + ] assert context['all_attributes'] == [ '__annotations__', @@ -630,7 +636,7 @@ def test_autosummary_generate_content_for_module_imported_members_complex_inheri 'addition', 'get_age', 'get_name', - 'get_salary' + 'get_salary', ] assert context['inherited_attributes'] == [ From 9037a2263b1a0153032c18150d3ffc4b1f43bf03 Mon Sep 17 00:00:00 2001 From: satr Date: Wed, 25 Sep 2024 16:59:48 +0100 Subject: [PATCH 23/33] lint corrections --- doc/usage/extensions/autosummary.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/usage/extensions/autosummary.rst b/doc/usage/extensions/autosummary.rst index eb25fb260e8..26875c54fa4 100644 --- a/doc/usage/extensions/autosummary.rst +++ b/doc/usage/extensions/autosummary.rst @@ -293,7 +293,7 @@ The following variables are available in the templates: .. data:: members - List containing names of all members of the module or class including private + List containing names of all members of the module or class including private ones. Only available for modules and classes. .. data:: inherited_members @@ -350,16 +350,17 @@ The following variables are available in the templates: 'mypackage.test.foo.do_something']`` * ``inherited_attributes`` returns ``['mypackage.test.foo.foo_attr']`` - These parameters could then be used in a Sphinx template `class.rst` like the following + These parameters could then be used in a Sphinx template ``class.rst`` like + the following .. code-block:: RST :dedent: 0 - + .. currentmodule:: {{ module }} .. autoclass:: {{ objname }} :show-inheritance: - + .. rubric:: Methods .. autosummary:: :toctree: From 58ff1e39eb70ddcd62996655472a741d07671abc Mon Sep 17 00:00:00 2001 From: satr Date: Tue, 29 Oct 2024 11:18:14 +0530 Subject: [PATCH 24/33] add in version dependent attributes --- ...autosummary_dummy_complex_inheritance_module.py | 12 ++++++++++++ tests/test_extensions/test_ext_autosummary.py | 14 ++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py index 2bd4477f31b..78d30ca8b19 100644 --- a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py +++ b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py @@ -1,3 +1,4 @@ +import sys class Parent: @@ -77,3 +78,14 @@ def __init__(self): __all__ = ["Parent", "Child", "Baby", "Job", "Architect", "Jerry"] + + +if sys.version_info[:2] >= (3, 14): + built_in_attr = ['__annotate__', '__annotations__', '__dict__', '__doc__', '__firstlineno__', + '__module__', '__static_attributes__', '__weakref__', 'relation'] +elif sys.version_info[:2] >= (3, 13): + built_in_attr = ['__annotations__', '__dict__', '__doc__', '__firstlineno__', '__module__', + '__static_attributes__', '__weakref__', 'relation'] +elif sys.version_info[:2] >= (3, 12): + built_in_attr = ['__annotations__', '__dict__', '__doc__', '__module__', '__weakref__', + 'relation'] diff --git a/tests/test_extensions/test_ext_autosummary.py b/tests/test_extensions/test_ext_autosummary.py index a7a2655da5b..aec5331c576 100644 --- a/tests/test_extensions/test_ext_autosummary.py +++ b/tests/test_extensions/test_ext_autosummary.py @@ -573,6 +573,8 @@ def test_autosummary_generate_content_for_module_imported_members_complex_inheri ): import autosummary_dummy_complex_inheritance_module + built_in_attr = autosummary_dummy_complex_inheritance_module.built_in_attr + template_jerry = Mock() generate_autosummary_content( @@ -604,11 +606,7 @@ def test_autosummary_generate_content_for_module_imported_members_complex_inheri ] assert context['all_attributes'] == [ - '__annotations__', - '__dict__', - '__doc__', - '__module__', - '__weakref__', + *built_in_attr, 'relation', ] assert context['all_methods'] == [ @@ -774,11 +772,7 @@ def test_autosummary_generate_content_for_module_imported_members_complex_inheri assert context2['all_attributes'] == [ '__private_baby_name', - '__annotations__', - '__dict__', - '__doc__', - '__module__', - '__weakref__', + *built_in_attr, 'relation', ] assert context2['all_methods'] == [ From 3c9b0bbe003939210a04783b9a6f4e8dbce8f19e Mon Sep 17 00:00:00 2001 From: satr Date: Tue, 29 Oct 2024 11:21:07 +0530 Subject: [PATCH 25/33] ruff --- tests/test_extensions/test_ext_autosummary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_extensions/test_ext_autosummary.py b/tests/test_extensions/test_ext_autosummary.py index aec5331c576..a819d6631e5 100644 --- a/tests/test_extensions/test_ext_autosummary.py +++ b/tests/test_extensions/test_ext_autosummary.py @@ -574,7 +574,7 @@ def test_autosummary_generate_content_for_module_imported_members_complex_inheri import autosummary_dummy_complex_inheritance_module built_in_attr = autosummary_dummy_complex_inheritance_module.built_in_attr - + template_jerry = Mock() generate_autosummary_content( From 336d3e35b9d6088f48c91224d6676ef71b3da940 Mon Sep 17 00:00:00 2001 From: satr Date: Tue, 29 Oct 2024 11:26:01 +0530 Subject: [PATCH 26/33] update for 3_11 and remove extra term --- .../autosummary_dummy_complex_inheritance_module.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py index 78d30ca8b19..0b94d059268 100644 --- a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py +++ b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py @@ -82,10 +82,9 @@ def __init__(self): if sys.version_info[:2] >= (3, 14): built_in_attr = ['__annotate__', '__annotations__', '__dict__', '__doc__', '__firstlineno__', - '__module__', '__static_attributes__', '__weakref__', 'relation'] + '__module__', '__static_attributes__', '__weakref__'] elif sys.version_info[:2] >= (3, 13): built_in_attr = ['__annotations__', '__dict__', '__doc__', '__firstlineno__', '__module__', - '__static_attributes__', '__weakref__', 'relation'] -elif sys.version_info[:2] >= (3, 12): - built_in_attr = ['__annotations__', '__dict__', '__doc__', '__module__', '__weakref__', - 'relation'] + '__static_attributes__', '__weakref__'] +elif sys.version_info[:2] >= (3, 11): + built_in_attr = ['__annotations__', '__dict__', '__doc__', '__module__', '__weakref__'] \ No newline at end of file From ceb2b991779e58cf967672942e5424afca3f1af8 Mon Sep 17 00:00:00 2001 From: satr Date: Tue, 29 Oct 2024 12:05:52 +0530 Subject: [PATCH 27/33] add in members too --- ...ummary_dummy_complex_inheritance_module.py | 17 +++++- tests/test_extensions/test_ext_autosummary.py | 57 +------------------ 2 files changed, 17 insertions(+), 57 deletions(-) diff --git a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py index 0b94d059268..ca3110617ca 100644 --- a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py +++ b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py @@ -79,12 +79,23 @@ def __init__(self): __all__ = ["Parent", "Child", "Baby", "Job", "Architect", "Jerry"] +members_3_11 = ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', + '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', + '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', + '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', + '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] +members_3_13 = ['__firstlineno__', '__static_attributes__'] + if sys.version_info[:2] >= (3, 14): - built_in_attr = ['__annotate__', '__annotations__', '__dict__', '__doc__', '__firstlineno__', + built_in_attr = ['__annotate__', '__annotations__', '__dict__', '__doc__', '__firstlineno__', '__module__', '__static_attributes__', '__weakref__'] + built_in_members = (members_3_11 + members_3_13).sort() elif sys.version_info[:2] >= (3, 13): - built_in_attr = ['__annotations__', '__dict__', '__doc__', '__firstlineno__', '__module__', + built_in_attr = ['__annotations__', '__dict__', '__doc__', '__firstlineno__', '__module__', '__static_attributes__', '__weakref__'] + built_in_members = (members_3_11 + members_3_13).sort() elif sys.version_info[:2] >= (3, 11): - built_in_attr = ['__annotations__', '__dict__', '__doc__', '__module__', '__weakref__'] \ No newline at end of file + built_in_attr = ['__annotations__', '__dict__', '__doc__', '__module__', '__weakref__'] + built_in_members = members_3_11 + diff --git a/tests/test_extensions/test_ext_autosummary.py b/tests/test_extensions/test_ext_autosummary.py index a819d6631e5..11db8a1afa5 100644 --- a/tests/test_extensions/test_ext_autosummary.py +++ b/tests/test_extensions/test_ext_autosummary.py @@ -574,6 +574,7 @@ def test_autosummary_generate_content_for_module_imported_members_complex_inheri import autosummary_dummy_complex_inheritance_module built_in_attr = autosummary_dummy_complex_inheritance_module.built_in_attr + built_in_members = autosummary_dummy_complex_inheritance_module.built_in_members template_jerry = Mock() @@ -713,33 +714,7 @@ def test_autosummary_generate_content_for_module_imported_members_complex_inheri ] assert context['members'] == [ - '__class__', - '__delattr__', - '__dict__', - '__dir__', - '__doc__', - '__eq__', - '__format__', - '__ge__', - '__getattribute__', - '__getstate__', - '__gt__', - '__hash__', - '__init__', - '__init_subclass__', - '__le__', - '__lt__', - '__module__', - '__ne__', - '__new__', - '__reduce__', - '__reduce_ex__', - '__repr__', - '__setattr__', - '__sizeof__', - '__str__', - '__subclasshook__', - '__weakref__', + *built_in_members, 'addition', 'get_age', 'get_name', @@ -875,33 +850,7 @@ def test_autosummary_generate_content_for_module_imported_members_complex_inheri 'BabyInnerClass', '__private_baby_name', '__annotations__', - '__class__', - '__delattr__', - '__dict__', - '__dir__', - '__doc__', - '__eq__', - '__format__', - '__ge__', - '__getattribute__', - '__getstate__', - '__gt__', - '__hash__', - '__init__', - '__init_subclass__', - '__le__', - '__lt__', - '__module__', - '__ne__', - '__new__', - '__reduce__', - '__reduce_ex__', - '__repr__', - '__setattr__', - '__sizeof__', - '__str__', - '__subclasshook__', - '__weakref__', + *built_in_members, 'addition', 'get_age', 'get_name', From 479ff7dcb363cc4ea14039e488a39a9c1441d27b Mon Sep 17 00:00:00 2001 From: satr Date: Tue, 29 Oct 2024 12:20:38 +0530 Subject: [PATCH 28/33] Simplify way to add new builtin members --- ...ummary_dummy_complex_inheritance_module.py | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py index ca3110617ca..74f6a5a6b5b 100644 --- a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py +++ b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py @@ -79,23 +79,26 @@ def __init__(self): __all__ = ["Parent", "Child", "Baby", "Job", "Architect", "Jerry"] -members_3_11 = ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', - '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', - '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', - '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', +members_3_11 = ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', + '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', + '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', + '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] -members_3_13 = ['__firstlineno__', '__static_attributes__'] +attr_3_11 = ['__annotations__', '__dict__', '__doc__', '__module__', '__weakref__'] + + +def concat_and_sort(list1, list2): + return sorted(list1 + list2) -if sys.version_info[:2] >= (3, 14): - built_in_attr = ['__annotate__', '__annotations__', '__dict__', '__doc__', '__firstlineno__', - '__module__', '__static_attributes__', '__weakref__'] - built_in_members = (members_3_11 + members_3_13).sort() -elif sys.version_info[:2] >= (3, 13): - built_in_attr = ['__annotations__', '__dict__', '__doc__', '__firstlineno__', '__module__', - '__static_attributes__', '__weakref__'] - built_in_members = (members_3_11 + members_3_13).sort() -elif sys.version_info[:2] >= (3, 11): - built_in_attr = ['__annotations__', '__dict__', '__doc__', '__module__', '__weakref__'] - built_in_members = members_3_11 +built_in_attr = attr_3_11 +built_in_members = members_3_11 + +if sys.version_info[:2] >= (3, 13): + add_3_13 = ['__firstlineno__', '__static_attributes__'] + built_in_attr = concat_and_sort(built_in_attr, add_3_13) + built_in_members = concat_and_sort(built_in_members, add_3_13) + +if sys.version_info[:2] >= (3, 14): + built_in_attr = concat_and_sort(built_in_attr, ['__annotate__']) From 49875980ea6514f3a9b88f0a23382e0813db37f5 Mon Sep 17 00:00:00 2001 From: satr Date: Tue, 29 Oct 2024 12:29:18 +0530 Subject: [PATCH 29/33] tweak for 3_14 test --- .../autosummary_dummy_complex_inheritance_module.py | 3 +++ tests/test_extensions/test_ext_autosummary.py | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py index 74f6a5a6b5b..ce266805065 100644 --- a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py +++ b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py @@ -100,5 +100,8 @@ def concat_and_sort(list1, list2): built_in_attr = concat_and_sort(built_in_attr, add_3_13) built_in_members = concat_and_sort(built_in_members, add_3_13) +built_in_members2 = members_3_11 + if sys.version_info[:2] >= (3, 14): built_in_attr = concat_and_sort(built_in_attr, ['__annotate__']) + built_in_members2 = concat_and_sort(built_in_members, ['__annotate__']) \ No newline at end of file diff --git a/tests/test_extensions/test_ext_autosummary.py b/tests/test_extensions/test_ext_autosummary.py index 11db8a1afa5..3a9c4f784b6 100644 --- a/tests/test_extensions/test_ext_autosummary.py +++ b/tests/test_extensions/test_ext_autosummary.py @@ -575,6 +575,7 @@ def test_autosummary_generate_content_for_module_imported_members_complex_inheri built_in_attr = autosummary_dummy_complex_inheritance_module.built_in_attr built_in_members = autosummary_dummy_complex_inheritance_module.built_in_members + built_in_members2 = autosummary_dummy_complex_inheritance_module.built_in_members2 template_jerry = Mock() @@ -850,7 +851,7 @@ def test_autosummary_generate_content_for_module_imported_members_complex_inheri 'BabyInnerClass', '__private_baby_name', '__annotations__', - *built_in_members, + *built_in_members2, 'addition', 'get_age', 'get_name', From a3adf19ecccbcd85698faea83b03ae57178fbb53 Mon Sep 17 00:00:00 2001 From: satr Date: Tue, 29 Oct 2024 12:30:34 +0530 Subject: [PATCH 30/33] fix 3_14 --- .../autosummary_dummy_complex_inheritance_module.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py index ce266805065..ff4abe77acc 100644 --- a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py +++ b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py @@ -100,8 +100,8 @@ def concat_and_sort(list1, list2): built_in_attr = concat_and_sort(built_in_attr, add_3_13) built_in_members = concat_and_sort(built_in_members, add_3_13) -built_in_members2 = members_3_11 +built_in_members2 = built_in_members if sys.version_info[:2] >= (3, 14): built_in_attr = concat_and_sort(built_in_attr, ['__annotate__']) - built_in_members2 = concat_and_sort(built_in_members, ['__annotate__']) \ No newline at end of file + built_in_members2 = concat_and_sort(built_in_members2, ['__annotate__']) \ No newline at end of file From d6abcbe58d4d3223921c8efd8ae6362b51f4f12c Mon Sep 17 00:00:00 2001 From: satr Date: Tue, 29 Oct 2024 13:56:08 +0530 Subject: [PATCH 31/33] correct order of members2 --- .../autosummary_dummy_complex_inheritance_module.py | 4 ++-- tests/test_extensions/test_ext_autosummary.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py index ff4abe77acc..388b73ad76c 100644 --- a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py +++ b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py @@ -94,13 +94,13 @@ def concat_and_sort(list1, list2): built_in_attr = attr_3_11 built_in_members = members_3_11 +built_in_members2 = ['__annotations__', *members_3_11] if sys.version_info[:2] >= (3, 13): add_3_13 = ['__firstlineno__', '__static_attributes__'] built_in_attr = concat_and_sort(built_in_attr, add_3_13) built_in_members = concat_and_sort(built_in_members, add_3_13) - -built_in_members2 = built_in_members + built_in_members2 = concat_and_sort(built_in_members2, add_3_13) if sys.version_info[:2] >= (3, 14): built_in_attr = concat_and_sort(built_in_attr, ['__annotate__']) diff --git a/tests/test_extensions/test_ext_autosummary.py b/tests/test_extensions/test_ext_autosummary.py index 3a9c4f784b6..5a924aa6008 100644 --- a/tests/test_extensions/test_ext_autosummary.py +++ b/tests/test_extensions/test_ext_autosummary.py @@ -850,7 +850,6 @@ def test_autosummary_generate_content_for_module_imported_members_complex_inheri assert context2['members'] == [ 'BabyInnerClass', '__private_baby_name', - '__annotations__', *built_in_members2, 'addition', 'get_age', From 73827e250fdffb63d1e87bc863f23945bd8bd9ba Mon Sep 17 00:00:00 2001 From: satr Date: Tue, 29 Oct 2024 14:10:46 +0530 Subject: [PATCH 32/33] Improved comment --- .../autosummary_dummy_complex_inheritance_module.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py index 388b73ad76c..192038a2c21 100644 --- a/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py +++ b/tests/roots/test-ext-autosummary/autosummary_dummy_complex_inheritance_module.py @@ -79,6 +79,10 @@ def __init__(self): __all__ = ["Parent", "Child", "Baby", "Job", "Architect", "Jerry"] +# The following is used to process the expected builtin members for different +# versions of Python. The base list is for v3.11 (the latest testing when added) +# and new builtin attributes/methods in later versions can be appended below. + members_3_11 = ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', @@ -94,6 +98,7 @@ def concat_and_sort(list1, list2): built_in_attr = attr_3_11 built_in_members = members_3_11 +# The second test has an extra builtin member built_in_members2 = ['__annotations__', *members_3_11] if sys.version_info[:2] >= (3, 13): From 242f21af25b4793ea1c09298b5ae55ccfa3c2112 Mon Sep 17 00:00:00 2001 From: satr Date: Tue, 29 Oct 2024 14:11:04 +0530 Subject: [PATCH 33/33] Improved docstring for inherited_qualnames --- doc/usage/extensions/autosummary.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/usage/extensions/autosummary.rst b/doc/usage/extensions/autosummary.rst index 26875c54fa4..2a0dee02080 100644 --- a/doc/usage/extensions/autosummary.rst +++ b/doc/usage/extensions/autosummary.rst @@ -305,9 +305,9 @@ The following variables are available in the templates: .. data:: inherited_qualnames - List containing the fully qualified names of each inherited member. Will return - just the closest parent from which this class was inherited. Only available - for classes. + List containing the fully qualified names of each inherited member including + private ones. Will return just the closest parent from which this class was + inherited. Only available for classes. The following example assumes that this code block has been written as part of a module ``mypackage.test``