mkdocstrings / python

A Python handler for mkdocstrings.
https://mkdocstrings.github.io/python
ISC License
180 stars 33 forks source link

bug: AliasResolutionError: Could not resolve alias errors when doing simple re-exports #168

Closed Ark-kun closed 3 months ago

Ark-kun commented 3 months ago

Description of the bug

We commonly re-export members from other modules. Most submodules like that work fine (e.g. vertexai.generative_models or vertexai.preview.generative_models). However, I've noticed that our main module (vertexai) showed no members (despite them having docstrings). Later I found another problematic module (vertexai.preview.tuning).

I've tried to force mkdocstrings to show the missing member by pointing to that member and got AliasResolutionError.

An example of a re-export: https://github.com/googleapis/python-aiplatform/blob/main/vertexai/__init__.py

from google.cloud.aiplatform import init
from vertexai import preview

__all__ = [
    "init",
    "preview",
]

To Reproduce

pip install google-cloud-aiplatform==1.52

Example 1:

Contents of docs/index.md

::: vertexai.init

Error:

Traceback (most recent call last):
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\griffe\dataclasses.py", line 1373, in _resolve_target
    resolved = self.modules_collection.get_member(self.target_path)
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\griffe\mixins.py", line 78, in get_member
    return self.members[parts[0]].get_member(parts[1:])  # type: ignore[attr-defined]
KeyError: 'google'

...

  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\griffe\dataclasses.py", line 1375, in _resolve_target
    raise AliasResolutionError(self) from error
griffe.exceptions.AliasResolutionError: Could not resolve alias vertexai.init pointing at google.cloud.aiplatform.init (in C:\Users\User\AppData\Local\Programs\Python\Python310\Lib\site-packages\vertexai\__init__.py:21)

Example 2:

Contents of docs/index.md

::: vertexai.preview.tuning.sft.train

Error:

Traceback (most recent call last):
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\griffe\dataclasses.py", line 1373, in _resolve_target
    resolved = self.modules_collection.get_member(self.target_path)
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\griffe\mixins.py", line 78, in get_member
    return self.members[parts[0]].get_member(parts[1:])  # type: ignore[attr-defined]
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\griffe\mixins.py", line 78, in get_member
    return self.members[parts[0]].get_member(parts[1:])  # type: ignore[attr-defined]
KeyError: 'tuning'

...

  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\griffe\dataclasses.py", line 1375, in _resolve_target
    raise AliasResolutionError(self) from error
griffe.exceptions.AliasResolutionError: Could not resolve alias vertexai.preview.tuning.sft.train pointing at vertexai.tuning._supervised_tuning.train (in C:\Users\User\AppData\Local\Programs\Python\Python310\Lib\site-packages\vertexai\preview\tuning\sft.py:19)

Example 3:

Contents of docs/index.md

::: vertexai.preview.tuning.TuningJob

Error:

Traceback (most recent call last):
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\griffe\dataclasses.py", line 1373, in _resolve_target
    resolved = self.modules_collection.get_member(self.target_path)
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\griffe\mixins.py", line 78, in get_member
    return self.members[parts[0]].get_member(parts[1:])  # type: ignore[attr-defined]
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\griffe\mixins.py", line 78, in get_member
    return self.members[parts[0]].get_member(parts[1:])  # type: ignore[attr-defined]
KeyError: 'tuning'

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

Traceback (most recent call last):
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\mkdocs\livereload\__init__.py", line 211, in _build_loop
    self.builder()
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\mkdocs\commands\serve.py", line 67, in builder
    build(config, serve_url=None if is_clean else serve_url, dirty=is_dirty)
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\mkdocs\commands\build.py", line 310, in build
    _populate_page(file.page, config, files, dirty)
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\mkdocs\commands\build.py", line 167, in _populate_page
    page.render(config, files)
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\mkdocs\structure\pages.py", line 285, in render
    self.content = md.convert(self.mUserdown)
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\mUserdown\core.py", line 357, in convert
    root = self.parser.parseDocument(self.lines).getroot()
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\mUserdown\blockparser.py", line 117, in parseDocument
    self.parseChunk(self.root, '\n'.join(lines))
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\mUserdown\blockparser.py", line 136, in parseChunk
    self.parseBlocks(parent, text.split('\n\n'))
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\mUserdown\blockparser.py", line 158, in parseBlocks
    if processor.run(parent, blocks) is not False:
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\mkdocstrings\extension.py", line 128, in run
    html, handler, data = self._process_block(identifier, block, heading_level)
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\mkdocstrings\extension.py", line 224, in _process_block
    rendered = handler.render(data, options)
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\mkdocstrings_handlers\python\handler.py", line 348, in render
    template_name = rendering.do_get_template(self.env, data)
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\mkdocstrings_handlers\python\rendering.py", line 469, in do_get_template
    extra_data = getattr(obj, "extra", {}).get("mkdocstrings", {})
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\griffe\dataclasses.py", line 962, in extra
    return self.final_target.extra
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\griffe\dataclasses.py", line 1339, in final_target
    target = target.target  # type: ignore[assignment]
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\griffe\dataclasses.py", line 1308, in target
    self.resolve_target()
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\griffe\dataclasses.py", line 1367, in resolve_target
    self._resolve_target()
  File "C:\Users\User\AppData\Local\Programs\Python\Python310\lib\site-packages\griffe\dataclasses.py", line 1375, in _resolve_target
    raise AliasResolutionError(self) from error
griffe.exceptions.AliasResolutionError: Could not resolve alias vertexai.preview.tuning.TuningJob pointing at vertexai.tuning._tuning.TuningJob (in C:\Users\User\AppData\Local\Programs\Python\Python310\Lib\site-packages\vertexai\preview\tuning\__init__.py:19)

Expected behavior

I expect the exception to not occur.

Environment information

python -m mkdocstrings.debug  # | xclip -selection clipboard
- __System__: Windows-10-10.0.19045-SP0
- __Python__: cpython 3.10.2 (C:\Users\User\AppData\Local\Programs\Python\Python310\python.exe)
- __Environment variables__:
- __Installed packages__:
  - `mkdocstrings` v0.25.1
Ark-kun commented 3 months ago

Using load_external_modules: true fixes Example 1 (and makes init show up), but does not fix issues and errors with Examples 2 or 3.

pawamoy commented 3 months ago

Hi @Ark-kun, thanks for the report.

You're missing an __init__.py module in vertexai/tuning. Griffe therefore considers its submodules not to be importable, see https://github.com/mkdocstrings/griffe/blob/e5572d2eb1dd8dbe8f9b43b33119bd9becc4a4d9/src/griffe/loader.py#L593.

You can see this debug log with the following command:

griffe dump vertexai -o/dev/null -LDEBUG

...which will show you a few other places potentially missing an __init__.py module :slightly_smiling_face:

pawamoy commented 3 months ago

Closing for now, let me know if adding __init__ modules doesn't solve your issue.

slyons commented 1 month ago

I'm also seeing this with a pyo3 project, but it may be related to an underlying griffe issue