pdoc3 / pdoc3/pdoc

Whitelisting with __all__

Open
#230 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug good first issue Hacktoberfest
Dominant language
Python
Stars
1.2k
Forks
146
PR merge metrics
No merged PRs in 30d

Description

Expected Behavior

A global variable not included in __all__ but whitelisted in __pdoc__ is included in the documentation.

Actual Behavior

It is not.

Steps to Reproduce
  1. See the following minimal example (and save it as example.py ;)).
  2. Generate the documentation, e.g. python3 -m pdoc example.py --html -f .
__all__ = []

variable = 1
"""Documentation"""

__pdoc__ = {}
__pdoc__['variable'] = True
Additional info
  • pdoc version: 0.8.3
  • I can probably replace "global variable" with "anything"
Kind of working patch
diff --git a/pdoc/__init__.py b/pdoc/__init__.py
index 82f36de..37f9c1d 100644
--- a/pdoc/__init__.py
+++ b/pdoc/__init__.py
@@ -598,6 +598,10 @@ class Module(Doc):
 
         var_docstrings, _ = _pep224_docstrings(self)
 
+        def is_from_this_module(obj):
+            mod = inspect.getmodule(inspect.unwrap(obj))
+            return mod is None or mod.__name__ == self.obj.__name__
+
         # Populate self.doc with this module's public members
         if hasattr(self.obj, '__all__'):
             public_objs = []
@@ -607,11 +611,11 @@ class Module(Doc):
                 except AttributeError:
                     warn("Module {!r} doesn't contain identifier `{}` "
                          "exported in `__all__`".format(self.module, name))
+            public_objs += [(name, inspect.unwrap(obj))
+                           for name, obj in inspect.getmembers(self.obj)
+                           if ((_is_whitelisted(name, self)) and
+                               (is_from_this_module(obj) or name in var_docstrings))]
         else:
-            def is_from_this_module(obj):
-                mod = inspect.getmodule(inspect.unwrap(obj))
-                return mod is None or mod.__name__ == self.obj.__name__
-
             public_objs = [(name, inspect.unwrap(obj))
                            for name, obj in inspect.getmembers(self.obj)
                            if ((_is_public(name) or _is_whitelisted(name, self)) and

(This was just an quick experiment. It throws warnings, I have no idea about the pdoc codebase, therefore no pull request, sorry. I do, however, release this copying of a few lines of code under whatever free license you prefer ;))

That works for my use case, but for example the namedtuple example from the documentation yields
pdoc/__init__.py:244: UserWarning: Couldn't read PEP-224 variable docstrings from <Class 'counterpar.Table'>: could not find class definition warn("Couldn't read PEP-224 variable docstrings from {!r}: {}".format(doc_obj, exc)) (the generated documentation looks okay though).
Again, no idea about pdocs structure, so I did not run any tests or anything like that.

Why I think this should work

From the documentation:

pdoc only extracts public API documentation. If a module defines __all__, then only the identifiers contained in this list are considered public.

Conversely, if __pdoc__[key] = True, then key (and its public members) will be included in the documentation of the module. This can be used to include documentation of private objects[...]

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in pdoc/init.py around Module's public member collection and review the minimal example using all and pdoc. Run python3 -m pdoc example.py --html -f to reproduce the behavior. Done means a whitelisted global omitted from all appears in the generated documentation without introducing the reported warning.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
documentation
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.