From a4b9eb7847d0cfe72abad03a8e7069a46c2e3756 Mon Sep 17 00:00:00 2001 From: Frank Pecher Date: Tue, 29 Mar 2022 11:36:47 +0200 Subject: [PATCH 01/15] added support for nested classes; this is basically a newer version of angeloskath's commit 467350c12894e66d45151e274db79e2cb7df5906. --- pdoc/__init__.py | 39 +++++++++++++++++++++++++++++++++++++-- pdoc/templates/html.mako | 4 ++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/pdoc/__init__.py b/pdoc/__init__.py index 0f05b2c0..aad4021e 100644 --- a/pdoc/__init__.py +++ b/pdoc/__init__.py @@ -950,6 +950,19 @@ def classes(self, sort=True) -> List['Class']: """ return self._filter_doc_objs(Class, sort) + def all_classes(self, sort=True) -> List['Class']: + """ + Returns all documented classes in the module even the ones defined + in other classes. + """ + stack = self.classes(sort)[::-1] + results = [] + while stack: + c = stack.pop() + results.append(c) + stack.extend(c.classes(sort=sort)[::-1]) + return results + def functions(self, sort=True) -> List['Function']: """ Returns all documented module-level functions in the module, @@ -1005,9 +1018,9 @@ class Class(Doc): """ Representation of a class' documentation. """ - __slots__ = ('doc', '_super_members') + __slots__ = ('doc', 'cls', '_super_members') - def __init__(self, name: str, module: Module, obj, *, docstring: str = None): + def __init__(self, name: str, module: Module, obj, *, docstring: str = None, cls: 'Class' = None): assert inspect.isclass(obj) if docstring is None: @@ -1017,6 +1030,12 @@ def __init__(self, name: str, module: Module, obj, *, docstring: str = None): docstring = f'{inspect.getdoc(obj) or ""}\n\n{init_doc}'.strip() super().__init__(name, module, obj, docstring=docstring) + + self.cls = cls + """ + The `pdoc.Class` object if this class is defined in a class. If not, + this is None. + """ self.doc: Dict[str, Union[Function, Variable]] = {} """A mapping from identifier name to a `pdoc.Doc` objects.""" @@ -1063,6 +1082,14 @@ def definition_order_index( if _is_function(obj): self.doc[name] = Function( name, self.module, obj, cls=self) + elif inspect.isclass(obj): + self.doc[name] = Class( + self.name + "." + name, + self.module, + obj, + cls=self, + docstring=inspect.getdoc(obj) + ) else: self.doc[name] = Variable( name, self.module, @@ -1157,6 +1184,14 @@ def _filter_doc_objs(self, type: Type[T], include_inherited=True, result = [obj for obj in _filter_type(type, self.doc) if (include_inherited or not obj.inherits) and filter_func(obj)] return sorted(result) if sort else result + + def classes(self, include_inherited=False, sort=False): + """Returns the classes nested in this class.""" + return self._filter_doc_objs( + Class, + include_inherited=include_inherited, + sort=sort + ) def class_variables(self, include_inherited=True, sort=True) -> List['Variable']: """ diff --git a/pdoc/templates/html.mako b/pdoc/templates/html.mako index f0517880..ae91fc65 100644 --- a/pdoc/templates/html.mako +++ b/pdoc/templates/html.mako @@ -98,7 +98,7 @@ <%def name="show_module(module)"> <% variables = module.variables(sort=sort_identifiers) - classes = module.classes(sort=sort_identifiers) + classes = module.all_classes(sort=sort_identifiers) functions = module.functions(sort=sort_identifiers) submodules = module.submodules() %> @@ -279,7 +279,7 @@ <%def name="module_index(module)"> <% variables = module.variables(sort=sort_identifiers) - classes = module.classes(sort=sort_identifiers) + classes = module.all_classes(sort=sort_identifiers) functions = module.functions(sort=sort_identifiers) submodules = module.submodules() supermodule = module.supermodule From c0925960477c4be69d15e1440cb021a4001d9124 Mon Sep 17 00:00:00 2001 From: Frank Pecher Date: Fri, 1 Apr 2022 00:20:56 +0200 Subject: [PATCH 02/15] fixed lint problems --- .gitignore | 1 + pdoc/__init__.py | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 7ae782e1..776f836e 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ htmlcov .*_cache/* html/* +/.mypy_cache/ diff --git a/pdoc/__init__.py b/pdoc/__init__.py index aad4021e..5c8b6469 100644 --- a/pdoc/__init__.py +++ b/pdoc/__init__.py @@ -1020,7 +1020,8 @@ class Class(Doc): """ __slots__ = ('doc', 'cls', '_super_members') - def __init__(self, name: str, module: Module, obj, *, docstring: str = None, cls: 'Class' = None): + def __init__(self, name: str, module: Module, obj, *, docstring: str = None, + cls: 'Class' = None): assert inspect.isclass(obj) if docstring is None: @@ -1030,12 +1031,12 @@ def __init__(self, name: str, module: Module, obj, *, docstring: str = None, cls docstring = f'{inspect.getdoc(obj) or ""}\n\n{init_doc}'.strip() super().__init__(name, module, obj, docstring=docstring) - + self.cls = cls """ The `pdoc.Class` object if this class is defined in a class. If not, this is None. - """ + """ self.doc: Dict[str, Union[Function, Variable]] = {} """A mapping from identifier name to a `pdoc.Doc` objects.""" @@ -1184,7 +1185,7 @@ def _filter_doc_objs(self, type: Type[T], include_inherited=True, result = [obj for obj in _filter_type(type, self.doc) if (include_inherited or not obj.inherits) and filter_func(obj)] return sorted(result) if sort else result - + def classes(self, include_inherited=False, sort=False): """Returns the classes nested in this class.""" return self._filter_doc_objs( From 8ff7b29fb899cfcd965257c2c33d6b0c6ba3780d Mon Sep 17 00:00:00 2001 From: Frank Pecher Date: Fri, 1 Apr 2022 10:05:30 +0200 Subject: [PATCH 03/15] fixed warnings issued by CI linting step --- pdoc/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pdoc/__init__.py b/pdoc/__init__.py index aad4021e..ca8774ff 100644 --- a/pdoc/__init__.py +++ b/pdoc/__init__.py @@ -1037,7 +1037,7 @@ def __init__(self, name: str, module: Module, obj, *, docstring: str = None, cls this is None. """ - self.doc: Dict[str, Union[Function, Variable]] = {} + self.doc: Dict[str, Union[Function, Variable, Class]] = {} """A mapping from identifier name to a `pdoc.Doc` objects.""" # Annotations for filtering. @@ -1239,8 +1239,8 @@ def inherited_members(self) -> List[Tuple['Class', List[Doc]]]: return sorted(((cast(Class, k), sorted(g)) for k, g in groupby((i.inherits for i in self.doc.values() if i.inherits), - key=lambda i: i.cls)), # type: ignore - key=lambda x, _mro_index=self.mro().index: _mro_index(x[0])) # type: ignore + key=lambda i: i.cls)), + key=lambda x, _mro_index=self.mro().index: _mro_index(x[0])) # type: ignore def _fill_inheritance(self): """ From 46832715fbaf37b5c24176b0a5575eeb23276da2 Mon Sep 17 00:00:00 2001 From: Frank Pecher Date: Fri, 1 Apr 2022 20:19:36 +0200 Subject: [PATCH 04/15] fixed lint problems --- pdoc/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdoc/__init__.py b/pdoc/__init__.py index 20517f19..906c6d85 100644 --- a/pdoc/__init__.py +++ b/pdoc/__init__.py @@ -1241,7 +1241,7 @@ def inherited_members(self) -> List[Tuple['Class', List[Doc]]]: for k, g in groupby((i.inherits for i in self.doc.values() if i.inherits), key=lambda i: i.cls)), - key=lambda x, _mro_index=self.mro().index: _mro_index(x[0])) # type: ignore + key=lambda x, _mro_index=self.mro().index: _mro_index(x[0])) # type: ignore def _fill_inheritance(self): """ From e2308b09b14685a3fa3904d7b6096cba003a7de2 Mon Sep 17 00:00:00 2001 From: Frank Pecher Date: Mon, 4 Apr 2022 16:56:27 +0200 Subject: [PATCH 05/15] removed argument from call --- pdoc/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pdoc/__init__.py b/pdoc/__init__.py index 20517f19..79a23026 100644 --- a/pdoc/__init__.py +++ b/pdoc/__init__.py @@ -1088,8 +1088,7 @@ def definition_order_index( self.name + "." + name, self.module, obj, - cls=self, - docstring=inspect.getdoc(obj) + cls=self ) else: self.doc[name] = Variable( From 1ac854cb953c071841ff593f9866b4d51f42f80e Mon Sep 17 00:00:00 2001 From: Frank Pecher Date: Mon, 4 Apr 2022 17:44:51 +0200 Subject: [PATCH 06/15] removed accidental new entry in .gitignore; renamed Class.classes() to Class._classes() and Class.all_classes() to Class.classes() --- .gitignore | 1 - pdoc/__init__.py | 10 +++++----- pdoc/templates/html.mako | 4 ++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 776f836e..7ae782e1 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,3 @@ htmlcov .*_cache/* html/* -/.mypy_cache/ diff --git a/pdoc/__init__.py b/pdoc/__init__.py index 79a23026..762f5431 100644 --- a/pdoc/__init__.py +++ b/pdoc/__init__.py @@ -943,19 +943,19 @@ def variables(self, sort=True) -> List['Variable']: """ return self._filter_doc_objs(Variable, sort) - def classes(self, sort=True) -> List['Class']: + def _classes(self, sort=True) -> List['Class']: """ Returns all documented module-level classes in the module, optionally sorted alphabetically, as a list of `pdoc.Class`. """ return self._filter_doc_objs(Class, sort) - def all_classes(self, sort=True) -> List['Class']: + def classes(self, sort=True) -> List['Class']: """ - Returns all documented classes in the module even the ones defined - in other classes. + Returns all documented classes in the module and all their + nested classes. """ - stack = self.classes(sort)[::-1] + stack = self._classes(sort)[::-1] results = [] while stack: c = stack.pop() diff --git a/pdoc/templates/html.mako b/pdoc/templates/html.mako index ae91fc65..f0517880 100644 --- a/pdoc/templates/html.mako +++ b/pdoc/templates/html.mako @@ -98,7 +98,7 @@ <%def name="show_module(module)"> <% variables = module.variables(sort=sort_identifiers) - classes = module.all_classes(sort=sort_identifiers) + classes = module.classes(sort=sort_identifiers) functions = module.functions(sort=sort_identifiers) submodules = module.submodules() %> @@ -279,7 +279,7 @@ <%def name="module_index(module)"> <% variables = module.variables(sort=sort_identifiers) - classes = module.all_classes(sort=sort_identifiers) + classes = module.classes(sort=sort_identifiers) functions = module.functions(sort=sort_identifiers) submodules = module.submodules() supermodule = module.supermodule From 08982dbd0dc2ffcaaf2cec353f008211d9ec9cfe Mon Sep 17 00:00:00 2001 From: Frank Pecher Date: Tue, 5 Apr 2022 16:58:03 +0200 Subject: [PATCH 07/15] created test case for nested classes support --- pdoc/__init__.py | 2 +- pdoc/test/__init__.py | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/pdoc/__init__.py b/pdoc/__init__.py index 20517f19..906c6d85 100644 --- a/pdoc/__init__.py +++ b/pdoc/__init__.py @@ -1241,7 +1241,7 @@ def inherited_members(self) -> List[Tuple['Class', List[Doc]]]: for k, g in groupby((i.inherits for i in self.doc.values() if i.inherits), key=lambda i: i.cls)), - key=lambda x, _mro_index=self.mro().index: _mro_index(x[0])) # type: ignore + key=lambda x, _mro_index=self.mro().index: _mro_index(x[0])) # type: ignore def _fill_inheritance(self): """ diff --git a/pdoc/test/__init__.py b/pdoc/test/__init__.py index c98d0c8e..c867820c 100644 --- a/pdoc/test/__init__.py +++ b/pdoc/test/__init__.py @@ -3,6 +3,7 @@ """ import doctest import enum +import importlib import inspect import os import shutil @@ -1026,6 +1027,41 @@ class G(F[int]): self.assertEqual(pdoc.Class('F', mod, F).docstring, """baz\n\nbar""") self.assertEqual(pdoc.Class('G', mod, G).docstring, """foo\n\nbar""") + def test_nested_classes(self): + m_name = 'M' + m_spec = importlib.util.spec_from_loader(m_name, loader=None) + m_module = importlib.util.module_from_spec(m_spec) + code = ''' +class A: + """Class A documentation""" + class B: + """ Class A.B documentation""" + class C: + """ Class A.B.C documentation""" + pass +''' + exec(code, m_module.__dict__) + + A = m_module.A + B = A.B + C = B.C + + sys.modules[m_name] = m_module + + try: + mod = pdoc.Module('M', context=pdoc.Context()) + print([c.qualname for c in mod.classes()]) + self.assertEqual([c.qualname for c in mod.classes()], ['A', 'A.B', 'A.B.C']) + self.assertEqual([c.qualname for c in pdoc.Class('A', mod, A).classes()], ['A.B']) + self.assertEqual([c.qualname for c in pdoc.Class('B', mod, B).classes()], ['A.B.C']) + self.assertEqual([c.qualname for c in pdoc.Class('C', mod, C).classes()], []) + + self.assertEqual(pdoc.Class('A', mod, A).docstring, "Class A documentation") + self.assertEqual(pdoc.Class('B', mod, B).docstring, "Class A.B documentation") + self.assertEqual(pdoc.Class('C', mod, C).docstring, "Class A.B.C documentation") + finally: + del sys.modules[m_name] + @ignore_warnings def test_Class_params(self): class C: From 7c28ca4214b56648495601153a8a0c9b3c471180 Mon Sep 17 00:00:00 2001 From: Frank Pecher Date: Wed, 6 Apr 2022 11:08:46 +0200 Subject: [PATCH 08/15] fixed visibility of nested classes --- pdoc/__init__.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/pdoc/__init__.py b/pdoc/__init__.py index 920cee98..c5ddb60b 100644 --- a/pdoc/__init__.py +++ b/pdoc/__init__.py @@ -712,7 +712,15 @@ def is_from_this_module(obj): if _is_function(obj): self.doc[name] = Function(name, self, obj) elif inspect.isclass(obj): - self.doc[name] = Class(name, self, obj) + cl = Class(name, self, obj) + self.doc[name] = cl + # Also add all nested classes of the class just found to the + # module context, otherwise some classes will be recognized + # as "External" even though they were correctly recognized + # as "Class" during an earlier scanning process + # (=> Module.find_ident()). + for ncl in cl.all_nested_classes(): + self.doc[f'{name}.{ncl.name}'] = ncl elif name in var_docstrings: self.doc[name] = Variable(name, self, var_docstrings[name], obj=obj) @@ -955,12 +963,10 @@ def classes(self, sort=True) -> List['Class']: Returns all documented classes in the module and all their nested classes. """ - stack = self._classes(sort)[::-1] results = [] - while stack: - c = stack.pop() + for c in self._classes(sort)[::-1]: results.append(c) - stack.extend(c.classes(sort=sort)[::-1]) + results += c.all_nested_classes() return results def functions(self, sort=True) -> List['Function']: @@ -1230,6 +1236,19 @@ def functions(self, include_inherited=True, sort=True) -> List['Function']: Function, include_inherited, lambda dobj: not dobj.is_method, sort) + def all_nested_classes(self, include_inherited=True, sort=True) -> List['Class']: + """ + Returns an optionally-sorted list of `pdoc.Class` objects that + represent this class' nested classes. + """ + stack = self.classes(sort)[::-1] + results = [] + while stack: + c = stack.pop() + results.append(c) + stack.extend(c.classes(sort=sort)[::-1]) + return results + def inherited_members(self) -> List[Tuple['Class', List[Doc]]]: """ Returns all inherited members as a list of tuples From 2445d5ab7a8ef8124c3e2ce42a9cae95dca69848 Mon Sep 17 00:00:00 2001 From: Frank Pecher Date: Wed, 6 Apr 2022 11:56:52 +0200 Subject: [PATCH 09/15] fixed Module.classes() returning the same class more than once --- pdoc/__init__.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/pdoc/__init__.py b/pdoc/__init__.py index c5ddb60b..59c93908 100644 --- a/pdoc/__init__.py +++ b/pdoc/__init__.py @@ -951,24 +951,13 @@ def variables(self, sort=True) -> List['Variable']: """ return self._filter_doc_objs(Variable, sort) - def _classes(self, sort=True) -> List['Class']: + def classes(self, sort=True) -> List['Class']: """ - Returns all documented module-level classes in the module, + Returns all documented classes in the module, optionally sorted alphabetically, as a list of `pdoc.Class`. """ return self._filter_doc_objs(Class, sort) - def classes(self, sort=True) -> List['Class']: - """ - Returns all documented classes in the module and all their - nested classes. - """ - results = [] - for c in self._classes(sort)[::-1]: - results.append(c) - results += c.all_nested_classes() - return results - def functions(self, sort=True) -> List['Function']: """ Returns all documented module-level functions in the module, From 8ef5e2592c0b69a67b65c6eea9a90e2dff95f747 Mon Sep 17 00:00:00 2001 From: frank101010 <52856343+frank101010@users.noreply.github.com> Date: Wed, 6 Apr 2022 13:02:05 +0200 Subject: [PATCH 10/15] Update pdoc/test/__init__.py Co-authored-by: kernc --- pdoc/test/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pdoc/test/__init__.py b/pdoc/test/__init__.py index c867820c..fcbed364 100644 --- a/pdoc/test/__init__.py +++ b/pdoc/test/__init__.py @@ -1050,7 +1050,6 @@ class C: try: mod = pdoc.Module('M', context=pdoc.Context()) - print([c.qualname for c in mod.classes()]) self.assertEqual([c.qualname for c in mod.classes()], ['A', 'A.B', 'A.B.C']) self.assertEqual([c.qualname for c in pdoc.Class('A', mod, A).classes()], ['A.B']) self.assertEqual([c.qualname for c in pdoc.Class('B', mod, B).classes()], ['A.B.C']) From da5e790fd49fa38220e50c7673324c89a0dfd4ad Mon Sep 17 00:00:00 2001 From: Frank Pecher Date: Wed, 6 Apr 2022 13:09:14 +0200 Subject: [PATCH 11/15] applied review suggestions --- pdoc/__init__.py | 6 +++--- pdoc/test/__init__.py | 10 ++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/pdoc/__init__.py b/pdoc/__init__.py index 59c93908..a5ef7b67 100644 --- a/pdoc/__init__.py +++ b/pdoc/__init__.py @@ -719,8 +719,8 @@ def is_from_this_module(obj): # as "External" even though they were correctly recognized # as "Class" during an earlier scanning process # (=> Module.find_ident()). - for ncl in cl.all_nested_classes(): - self.doc[f'{name}.{ncl.name}'] = ncl + for ncl in cl._nested_classes(): + self.doc[ncl.name] = ncl elif name in var_docstrings: self.doc[name] = Variable(name, self, var_docstrings[name], obj=obj) @@ -1225,7 +1225,7 @@ def functions(self, include_inherited=True, sort=True) -> List['Function']: Function, include_inherited, lambda dobj: not dobj.is_method, sort) - def all_nested_classes(self, include_inherited=True, sort=True) -> List['Class']: + def _nested_classes(self, include_inherited=True, sort=True) -> List['Class']: """ Returns an optionally-sorted list of `pdoc.Class` objects that represent this class' nested classes. diff --git a/pdoc/test/__init__.py b/pdoc/test/__init__.py index fcbed364..d37918b1 100644 --- a/pdoc/test/__init__.py +++ b/pdoc/test/__init__.py @@ -1034,11 +1034,21 @@ def test_nested_classes(self): code = ''' class A: """Class A documentation""" + x: str class B: """ Class A.B documentation""" class C: """ Class A.B.C documentation""" pass + class D(A.B.C): + """ Class A.B.D documentation""" + pass + class E(A.B): + """ Class A.E documentation""" + pass +class F(A): + """ Class F documentation""" + pass ''' exec(code, m_module.__dict__) From 54db3eb0fe192fa94b072b125c8599cd6d2ec2cc Mon Sep 17 00:00:00 2001 From: Frank Pecher Date: Wed, 6 Apr 2022 14:52:25 +0200 Subject: [PATCH 12/15] adapted test__all__ to new nested class handling; added more checks to test_nested_classes --- pdoc/test/__init__.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/pdoc/test/__init__.py b/pdoc/test/__init__.py index d37918b1..4d0a9322 100644 --- a/pdoc/test/__init__.py +++ b/pdoc/test/__init__.py @@ -722,7 +722,7 @@ def test__all__(self): mod = pdoc.Module(module) with self.assertWarns(UserWarning): # Only B is used but __pdoc__ contains others pdoc.link_inheritance() - self.assertEqual(list(mod.doc.keys()), ['B']) + self.assertEqual(list(mod.doc.keys()), ['B', 'B.C']) def test_find_ident(self): mod = pdoc.Module(EXAMPLE_MODULE) @@ -1034,20 +1034,17 @@ def test_nested_classes(self): code = ''' class A: """Class A documentation""" - x: str + x: str = '' class B: """ Class A.B documentation""" class C: """ Class A.B.C documentation""" pass - class D(A.B.C): - """ Class A.B.D documentation""" - pass - class E(A.B): - """ Class A.E documentation""" - pass -class F(A): - """ Class F documentation""" + +class D(A): + pass + +class E(A.B.C): pass ''' exec(code, m_module.__dict__) @@ -1055,12 +1052,14 @@ class F(A): A = m_module.A B = A.B C = B.C + D = m_module.D + E = m_module.E sys.modules[m_name] = m_module try: mod = pdoc.Module('M', context=pdoc.Context()) - self.assertEqual([c.qualname for c in mod.classes()], ['A', 'A.B', 'A.B.C']) + self.assertEqual([c.qualname for c in mod.classes()], ['A', 'A.B', 'A.B.C', 'D', 'E']) self.assertEqual([c.qualname for c in pdoc.Class('A', mod, A).classes()], ['A.B']) self.assertEqual([c.qualname for c in pdoc.Class('B', mod, B).classes()], ['A.B.C']) self.assertEqual([c.qualname for c in pdoc.Class('C', mod, C).classes()], []) @@ -1068,6 +1067,14 @@ class F(A): self.assertEqual(pdoc.Class('A', mod, A).docstring, "Class A documentation") self.assertEqual(pdoc.Class('B', mod, B).docstring, "Class A.B documentation") self.assertEqual(pdoc.Class('C', mod, C).docstring, "Class A.B.C documentation") + + # D inherits doc from A + self.assertEqual([c.qualname for c in pdoc.Class('D', mod, D).mro()], ['A']) + self.assertEqual(pdoc.Class('D', mod, D).docstring, "Class A documentation") + + # E inherits doc from A.B.C + self.assertEqual([c.qualname for c in pdoc.Class('E', mod, E).mro()], ['A.B.C']) + self.assertEqual(pdoc.Class('E', mod, E).docstring, "Class A.B.C documentation") finally: del sys.modules[m_name] From ad471f4fc74f620751825ceb34c7daec23a8a907 Mon Sep 17 00:00:00 2001 From: Frank Pecher Date: Tue, 19 Apr 2022 14:08:14 +0200 Subject: [PATCH 13/15] adapted Class.classes() default arguments to other classes() defaults. --- pdoc/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdoc/__init__.py b/pdoc/__init__.py index a5ef7b67..f058342c 100644 --- a/pdoc/__init__.py +++ b/pdoc/__init__.py @@ -1180,7 +1180,7 @@ def _filter_doc_objs(self, type: Type[T], include_inherited=True, if (include_inherited or not obj.inherits) and filter_func(obj)] return sorted(result) if sort else result - def classes(self, include_inherited=False, sort=False): + def classes(self, include_inherited=True, sort=True): """Returns the classes nested in this class.""" return self._filter_doc_objs( Class, From f353e5c2a8190c702b6b838207dd73f110fe5d55 Mon Sep 17 00:00:00 2001 From: Frank Pecher Date: Tue, 19 Apr 2022 14:15:04 +0200 Subject: [PATCH 14/15] improved test --- pdoc/test/__init__.py | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/pdoc/test/__init__.py b/pdoc/test/__init__.py index 4d0a9322..bdede54b 100644 --- a/pdoc/test/__init__.py +++ b/pdoc/test/__init__.py @@ -1044,7 +1044,7 @@ class C: class D(A): pass -class E(A.B.C): +class E(A.B): pass ''' exec(code, m_module.__dict__) @@ -1058,26 +1058,40 @@ class E(A.B.C): sys.modules[m_name] = m_module try: - mod = pdoc.Module('M', context=pdoc.Context()) + mod = pdoc.Module('M') + pdoc.link_inheritance() + + pdoc_A = mod.find_ident('A') + pdoc_B = mod.find_ident('A.B') + pdoc_C = mod.find_ident('A.B.C') + pdoc_D = mod.find_ident('D') + pdoc_E = mod.find_ident('E') + self.assertEqual([c.qualname for c in mod.classes()], ['A', 'A.B', 'A.B.C', 'D', 'E']) - self.assertEqual([c.qualname for c in pdoc.Class('A', mod, A).classes()], ['A.B']) - self.assertEqual([c.qualname for c in pdoc.Class('B', mod, B).classes()], ['A.B.C']) - self.assertEqual([c.qualname for c in pdoc.Class('C', mod, C).classes()], []) + self.assertEqual([c.qualname for c in pdoc_A.classes()], ['A.B']) + self.assertEqual([c.qualname for c in pdoc_B.classes()], ['A.B.C']) + self.assertEqual([c.qualname for c in pdoc_C.classes()], []) - self.assertEqual(pdoc.Class('A', mod, A).docstring, "Class A documentation") - self.assertEqual(pdoc.Class('B', mod, B).docstring, "Class A.B documentation") - self.assertEqual(pdoc.Class('C', mod, C).docstring, "Class A.B.C documentation") + self.assertEqual(pdoc_A.docstring, "Class A documentation") + self.assertEqual(pdoc_B.docstring, "Class A.B documentation") + self.assertEqual(pdoc_C.docstring, "Class A.B.C documentation") # D inherits doc from A - self.assertEqual([c.qualname for c in pdoc.Class('D', mod, D).mro()], ['A']) - self.assertEqual(pdoc.Class('D', mod, D).docstring, "Class A documentation") + self.assertEqual([c.qualname for c in pdoc_D.mro()], ['A']) + self.assertEqual(pdoc_D.docstring, "Class A documentation") + self.assertEqual([c.qualname for c in pdoc_D.classes(include_inherited=False)], []) + self.assertEqual([c.qualname for c in pdoc_D.classes(debug=True)], ['A.B', 'A.B.C']) # E inherits doc from A.B.C - self.assertEqual([c.qualname for c in pdoc.Class('E', mod, E).mro()], ['A.B.C']) + self.assertEqual([c.qualname for c in pdoc_E.mro()], ['A.B.C']) self.assertEqual(pdoc.Class('E', mod, E).docstring, "Class A.B.C documentation") + self.assertEqual([c.qualname for c in pdoc_E.classes(include_inherited=False)], []) + self.assertEqual([c.qualname for c in pdoc_E.classes()], ['E.C']) finally: del sys.modules[m_name] + self.assertFalse(True) + @ignore_warnings def test_Class_params(self): class C: From 22190cb8360efa0fd24cdb92f3d3d85ac54c55e0 Mon Sep 17 00:00:00 2001 From: Frank Pecher Date: Tue, 19 Apr 2022 14:37:49 +0200 Subject: [PATCH 15/15] removed unused code, improved comment --- pdoc/__init__.py | 2 +- pdoc/test/__init__.py | 18 +++++------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/pdoc/__init__.py b/pdoc/__init__.py index f058342c..6dd73e8e 100644 --- a/pdoc/__init__.py +++ b/pdoc/__init__.py @@ -1181,7 +1181,7 @@ def _filter_doc_objs(self, type: Type[T], include_inherited=True, return sorted(result) if sort else result def classes(self, include_inherited=True, sort=True): - """Returns the classes nested in this class.""" + """Returns the classes immediately nested in this class.""" return self._filter_doc_objs( Class, include_inherited=include_inherited, diff --git a/pdoc/test/__init__.py b/pdoc/test/__init__.py index bdede54b..1c2f818f 100644 --- a/pdoc/test/__init__.py +++ b/pdoc/test/__init__.py @@ -1049,12 +1049,6 @@ class E(A.B): ''' exec(code, m_module.__dict__) - A = m_module.A - B = A.B - C = B.C - D = m_module.D - E = m_module.E - sys.modules[m_name] = m_module try: @@ -1080,18 +1074,16 @@ class E(A.B): self.assertEqual([c.qualname for c in pdoc_D.mro()], ['A']) self.assertEqual(pdoc_D.docstring, "Class A documentation") self.assertEqual([c.qualname for c in pdoc_D.classes(include_inherited=False)], []) - self.assertEqual([c.qualname for c in pdoc_D.classes(debug=True)], ['A.B', 'A.B.C']) + self.assertEqual([c.qualname for c in pdoc_D.classes()], ['A.B']) - # E inherits doc from A.B.C - self.assertEqual([c.qualname for c in pdoc_E.mro()], ['A.B.C']) - self.assertEqual(pdoc.Class('E', mod, E).docstring, "Class A.B.C documentation") + # E inherits doc from A.B + self.assertEqual([c.qualname for c in pdoc_E.mro()], ['A.B']) + self.assertEqual(pdoc_E.docstring, "Class A.B documentation") self.assertEqual([c.qualname for c in pdoc_E.classes(include_inherited=False)], []) - self.assertEqual([c.qualname for c in pdoc_E.classes()], ['E.C']) + self.assertEqual([c.qualname for c in pdoc_E.classes()], ['A.B.C']) finally: del sys.modules[m_name] - self.assertFalse(True) - @ignore_warnings def test_Class_params(self): class C: