Skip to content
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

quartodoc ignores imported attributes #298

Closed
JanPalasek opened this issue Oct 19, 2023 · 5 comments
Closed

quartodoc ignores imported attributes #298

JanPalasek opened this issue Oct 19, 2023 · 5 comments

Comments

@JanPalasek
Copy link

Problem

When I only import attributes (and specify them to __all__) in a rendered, quartodoc ignores them and doesn't render its documentation.

# module.py

from othermodule import CONSTANT, NOT_SHOWN_CONSTANT

__all__ = ["CONSTANT"]
# _quarto.yaml
quartodoc:
  ...
  sections:
    - title: Some title
      contents:
        - module

This is a problem because often in packages you have "private part of the package", and you only expose the "public" part via imports like that. For example you have a structure like this:

package/
  subpackage/
    __init__.py  # everything imported in here
    _internal.py 

Solution

Similar to pdoc: what to render can be decided based on contents of __all__. For example NOT_SHOWN_CONSTANT shouldn't be rendered because it is not in __all__.

@machow
Copy link
Owner

machow commented Oct 19, 2023

Hey! Does the include_imports option work?

# _quarto.yaml
quartodoc:
  ...
  sections:
    - title: Some title
      contents:
        - name: module
          include_imports: true

I think that should tell it to include objects imported into the module. This is analogous to sphinx's import-members option.

Sorry for the confusion. I think it's there so packages that document per module don't accidentally document functions multiple times, but I can see how it's frustrating to debug :/. (In the same vein, classes don't document inherited members by default).

If you want, you can set the option everywhere.

@JanPalasek
Copy link
Author

@machow Thanks for the quick response. I didn't find it in the documentation. I believe it will work, I will close the issue tomorrow when I get to try it.

Does it automatically ignore third-party imports? What if I used it on module like this:

# package/module.py
from sklearn.pipeline import Pipeline
from my_package.other_module import CONSTANT

__all__ = ["CONSTANT"]

@JanPalasek
Copy link
Author

JanPalasek commented Oct 20, 2023

@machow I'm afraid it doesn't work.

I have a rather complex and private case, so I'll try to simplify it for reproducibility.

# package/module.py
import asyncio
# _quarto.yaml
quartodoc:
  package: package
  ...
  sections:
    - title: Some modules
      contents:
        - name: module
          include_imports: true

It raises error:

Error
Traceback (most recent call last):
  File "/path/to/project/venv/lib/python3.10/site-packages/griffe/dataclasses.py", line 1214, in _resolve_target
    resolved = self.modules_collection.get_member(self.target_path)
  File "/path/to/project/venv/lib/python3.10/site-packages/griffe/mixins.py", line 76, in get_member
    return self.members[parts[0]]  # type: ignore[attr-defined]
KeyError: 'asyncio'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/path/to/project/venv/bin/quartodoc", line 8, in <module>
    sys.exit(cli())
  File "/path/to/project/venv/lib/python3.10/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
  File "/path/to/project/venv/lib/python3.10/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
  File "/path/to/project/venv/lib/python3.10/site-packages/click/core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/path/to/project/venv/lib/python3.10/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/path/to/project/venv/lib/python3.10/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/__main__.py", line 214, in build
    doc_build()
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/autosummary.py", line 515, in build
    blueprint = blueprint(self.layout, dynamic=self.dynamic, parser=self.parser)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/blueprint.py", line 431, in blueprint
    return trans.visit(el)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/blueprint.py", line 185, in visit
    return super().visit(el)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/utils.py", line 45, in visit
    result = self.enter(el)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/blueprint.py", line 222, in enter
    return super().enter(el)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/utils.py", line 67, in enter
    result = self.visit(value)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/blueprint.py", line 185, in visit
    return super().visit(el)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/utils.py", line 45, in visit
    result = self.enter(el)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/utils.py", line 86, in enter
    result = self.visit(child)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/blueprint.py", line 185, in visit
    return super().visit(el)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/utils.py", line 45, in visit
    result = self.enter(el)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/utils.py", line 67, in enter
    result = self.visit(value)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/blueprint.py", line 185, in visit
    return super().visit(el)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/utils.py", line 45, in visit
    result = self.enter(el)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/utils.py", line 86, in enter
    result = self.visit(child)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/blueprint.py", line 185, in visit
    return super().visit(el)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/utils.py", line 45, in visit
    result = self.enter(el)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 489, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "/path/to/project/venv/lib/python3.10/site-packages/plum/function.py", line 399, in __call__
    return _convert(method(*args, **kw_args), return_type)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/blueprint.py", line 272, in enter
    raw_members = self._fetch_members(el, obj)
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/blueprint.py", line 355, in _fetch_members
    options = {k: v for k, v in options.items() if v.docstring is not None}
  File "/path/to/project/venv/lib/python3.10/site-packages/quartodoc/builder/blueprint.py", line 355, in <dictcomp>
    options = {k: v for k, v in options.items() if v.docstring is not None}
  File "/path/to/project/venv/lib/python3.10/site-packages/griffe/dataclasses.py", line 966, in docstring
    return self.final_target.docstring
  File "/path/to/project/venv/lib/python3.10/site-packages/griffe/dataclasses.py", line 1190, in final_target
    target = target.target  # type: ignore[assignment]
  File "/path/to/project/venv/lib/python3.10/site-packages/griffe/dataclasses.py", line 1162, in target
    self.resolve_target()
  File "/path/to/project/venv/lib/python3.10/site-packages/griffe/dataclasses.py", line 1208, in resolve_target
    self._resolve_target()
  File "/path/to/project/venv/lib/python3.10/site-packages/griffe/dataclasses.py", line 1216, in _resolve_target
    raise AliasResolutionError(self) from error
griffe.exceptions.AliasResolutionError: Could not resolve alias package.module pointing at asyncio (in /path/to/project/package/module.py:9)

Versions

  • quartodoc: 0.6.4
  • quarto: 1.3.433
  • python: 3.10

@machow
Copy link
Owner

machow commented Oct 20, 2023

Currently it ignores third party imports, and all non-external functions in the module can be members. (The net effect is that I think your example should do what you want).

I added a fix to PR #300, which uses __all__ to get the members for modules. Will release in the next hour or so!

edit: released https://github.com/machow/quartodoc/releases/tag/v0.6.5

@machow
Copy link
Owner

machow commented Jan 22, 2024

It seems like this should be fixed in the current version. I tested using this code:

from quartodoc import Auto, blueprint, MdRenderer, preview
bp = blueprint(Auto(name = "quartodoc.tests.example_alias_target__nested", include_imports = True))

# note that the tabulate function, which was imported into the module
# gets rendered in the API doc page for the module
print(MdRenderer().render(bp))

Definitely let me know if it's still an issue, and I can dig into it more.

@machow machow closed this as completed Jan 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants