Skip to content

Submodule functions in __all__ get correctly hoisted to top-level docs, but not submodule variables #774

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
mjbaldwin opened this issue Feb 8, 2025 · 4 comments
Labels

Comments

@mjbaldwin
Copy link

Problem Description

I have a package with lots of modules within. In the package __init__.py, I define __all__ with all of the functions I want to expose to the user. This works great, and pdoc puts all the functions in a single list under "API Documentation". Exactly what I want.

The problem is that I also include a single settings dictionary variable imported from a submodule, alongside all the functions imported from submodules. I include that in __all__, but for some reason pdoc then creates a separate "Submodules" section of the documentation that lists "settings" underneath, that links to a separate page, that documents the variable.

I absolutely want to include the variable documentation -- I just want it to be listed next to the functions in the order it is specified in __all__. I don't see any reason for forcing variables that aren't functions into submodule listings, so this seems to be a bug?

Expected behavior: non-function variables in __all__ get included alongside function variables
Actual behavior: non-function variables in __all__ are still being documented as belonging to submodules

System Information

pdoc: 15.0.1
Python: 3.12.8
Platform: macOS-15.2-arm64-arm-64bit

@mjbaldwin mjbaldwin added the bug label Feb 8, 2025
@mjbaldwin
Copy link
Author

Oh, and perhaps a follow-up/related bug -- if I pass !pkgname. to pdoc to suppress all submodules (so I can document the settings in my readme instead), it still shows a big "Submodules" section in the table of contents, but it's empty. Seems like if there are no submodules, then there's shouldn't be any submodules section?

Image

@mhils
Copy link
Member

mhils commented Feb 9, 2025

I absolutely want to include the variable documentation -- I just want it to be listed next to the functions in the order it is specified in __all__. I don't see any reason for forcing variables that aren't functions into submodule listings, so this seems to be a bug?

This needs a reproducer.

Oh, and perhaps a follow-up/related bug -- if I pass !pkgname. to pdoc to suppress all submodules (so I can document the settings in my readme instead), it still shows a big "Submodules" section in the table of contents, but it's empty. Seems like if there are no submodules, then there's shouldn't be any submodules section?

Agreed, that's a bug in the template. Contributions welcome!

@mjbaldwin
Copy link
Author

This needs a reproducer.

Attached.

2025-02-10 - pdoc variable.zip

Results look like:

Image

Agreed, that's a bug in the template. Contributions welcome!

I'm not sure. When I change the command in the reproducer to:

pdoc ../testpkg !testpkg. -o ./generated

And then directly under line 46 of module.html.jinja2 where it says {% if module.submodules %} I add:

{{ module.submodules }}

Then it outputs:

[<module testpkg.config <var config = {'a': 0, 'b': 1}> >]

So the bug is possibly that it is passing a submodule in the first place when there should be none?

Alternatively, you only print "public" submodules:

{% for submodule in module.submodules if is_public(submodule) | trim %}
    <li>{{ submodule.taken_from | link(text=submodule.name) }}</li>
{% endfor %}

So perhaps {% if module.submodules %} needs to be replaced with a conditional that tests not just for submodules, but if there are public submodules?

I don't have the broader understanding of pdoc to know which you intend.

@mhils
Copy link
Member

mhils commented Feb 12, 2025

So the bug is possibly that it is passing a submodule in the first place when there should be none?

yeah, it shouldn't be passed in the first place, it should be filtered out here:

pdoc/pdoc/extract.py

Lines 50 to 55 in 4991583

if isinstance(spec, str) and spec.startswith("!"):
ignore_pattern = re.compile(spec[1:])
all_modules = {
k: v for k, v in all_modules.items() if not ignore_pattern.match(k)
}
continue

Maybe some bug in the Module.submodules implementation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants