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

jinja2.exceptions.TemplateNotFound: alias.html #451

Closed
joaompinto opened this issue Jul 3, 2022 · 33 comments
Closed

jinja2.exceptions.TemplateNotFound: alias.html #451

joaompinto opened this issue Jul 3, 2022 · 33 comments
Labels
bug Something isn't working

Comments

@joaompinto
Copy link

Describe the bug

While running mkdocs build I get an exception:

$ mkdocs build
INFO     -  Cleaning site directory
INFO     -  Building documentation to directory: C:\Users\lameg\kubekind\site
WARNING  -  mkdocstrings_handlers: 1 aliases were still unresolved after 2 iterations
ERROR    -  mkdocstrings: Template 'alias.html' not found for 'python' handler and theme 'material'.
ERROR    -  Error reading page 'index.md': alias.html
Traceback (most recent call last):
  File "C:\Users\lameg\miniforge3\lib\runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\lameg\miniforge3\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "C:\Users\lameg\miniforge3\Scripts\mkdocs.exe\__main__.py", line 7, in <module>
  File "C:\Users\lameg\miniforge3\lib\site-packages\click\core.py", line 1137, in __call__
    return self.main(*args, **kwargs)
  File "C:\Users\lameg\miniforge3\lib\site-packages\click\core.py", line 1062, in main
    rv = self.invoke(ctx)
  File "C:\Users\lameg\miniforge3\lib\site-packages\click\core.py", line 1668, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "C:\Users\lameg\miniforge3\lib\site-packages\click\core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "C:\Users\lameg\miniforge3\lib\site-packages\click\core.py", line 763, in invoke
    return __callback(*args, **kwargs)
  File "C:\Users\lameg\miniforge3\lib\site-packages\mkdocs\__main__.py", line 192, in build_command
    build.build(config.load_config(**kwargs), dirty=not clean)
  File "C:\Users\lameg\miniforge3\lib\site-packages\mkdocs\commands\build.py", line 292, in build
    _populate_page(file.page, config, files, dirty)
  File "C:\Users\lameg\miniforge3\lib\site-packages\mkdocs\commands\build.py", line 174, in _populate_page
    page.render(config, files)
  File "C:\Users\lameg\miniforge3\lib\site-packages\mkdocs\structure\pages.py", line 175, in render
    self.content = md.convert(self.markdown)
  File "C:\Users\lameg\miniforge3\lib\site-packages\markdown\core.py", line 264, in convert
    root = self.parser.parseDocument(self.lines).getroot()
  File "C:\Users\lameg\miniforge3\lib\site-packages\markdown\blockparser.py", line 90, in parseDocument
    self.parseChunk(self.root, '\n'.join(lines))
  File "C:\Users\lameg\miniforge3\lib\site-packages\markdown\blockparser.py", line 105, in parseChunk
    self.parseBlocks(parent, text.split('\n\n'))
  File "C:\Users\lameg\miniforge3\lib\site-packages\markdown\blockparser.py", line 123, in parseBlocks
    if processor.run(parent, blocks) is not False:
  File "C:\Users\lameg\miniforge3\lib\site-packages\mkdocstrings\extension.py", line 121, in run
    html, handler, data = self._process_block(identifier, block, heading_level)
  File "C:\Users\lameg\miniforge3\lib\site-packages\mkdocstrings\extension.py", line 209, in _process_block
    rendered = handler.render(data, options)
  File "C:\Users\lameg\miniforge3\lib\site-packages\mkdocstrings_handlers\python\handler.py", line 215, in render
    template = self.env.get_template(f"{data.kind.value}.html")
  File "C:\Users\lameg\miniforge3\lib\site-packages\jinja2\environment.py", line 1010, in get_template
    return self._load_template(name, globals)
  File "C:\Users\lameg\miniforge3\lib\site-packages\jinja2\environment.py", line 969, in _load_template
    template = self.loader.load(self, name, self.make_globals(globals))
  File "C:\Users\lameg\miniforge3\lib\site-packages\jinja2\loaders.py", line 126, in load
    source, filename, uptodate = self.get_source(environment, name)
  File "C:\Users\lameg\miniforge3\lib\site-packages\jinja2\loaders.py", line 218, in get_source
    raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: alias.html

To Reproduce
Steps to reproduce the behavior:

git clone git@github.com:joaompinto/kubekind.git
cd kubekind
pip install mkdocs mkdocstrings mkdocstrings[python]
mkdocs build

Expected behavior
A clear and concise description of what you expected to happen.

Information (please complete the following information):

  • OS: Windows 10
  • mkdocstrings 0.19.0
@joaompinto joaompinto added the unconfirmed This bug was not reproduced yet label Jul 3, 2022
@motey
Copy link

motey commented Aug 17, 2022

Same error here, any new ideas?

@motey
Copy link

motey commented Aug 17, 2022

Ok, could work around this error by NOT using indirect imports (hope this is the correct term)

Lets have an example

/myProj
-__init__.py
    -/main
        -__init__.py
        -main.py
    -/sub1
        -__init__.py
        -sub1.py <-- "sub1Class" in here

content of /myProj/main/__init__.py

from myProj.sub1.sub1 import sub1Class

and in the mkdoc md file i referenced the class as

::: myProj.main.sub1Class
    :docstring:
    :members:

which provoked the error.

when changin the class reference to

::: myProj.sub1.sub1.sub1Class
    :docstring:
    :members:

the error was gone

@pawamoy
Copy link
Member

pawamoy commented Aug 17, 2022

Sorry for the delay and thank you for the workaround. I'll eventually get to this as it's clearly a bug.

@pawamoy pawamoy added bug Something isn't working and removed unconfirmed This bug was not reproduced yet labels Aug 17, 2022
@motey
Copy link

motey commented Aug 17, 2022

Thanks a lot. i'll try to find some time the next days to setup a simplified project-repo to reproduce the error.

@motey
Copy link

motey commented Aug 18, 2022

Ok, looks like my claim was wrong. I could NOT reproduce the error via indirect imports.

https://github.com/motey/mkdocstrings-451

@HacKanCuBa
Copy link

hmmm still happening, I arrived here after checking out #404, no solution for now :(

@pawamoy
Copy link
Member

pawamoy commented Dec 4, 2022

The original issue reported by @joaompinto seems to happen because __init__.py modules are missing from both resources and storage. The underlying tool, Griffe, considers it an error and skips the modules in these folders (Griffe does not accept namespace packages inside of regular packages).

This is shown by the logs, in verbose mode:

% mkdocs build -v
DEBUG    -  Loading configuration file: /media/data/dev/kubekind/mkdocs.yml
DEBUG    -  Loaded theme configuration for 'material' from '/media/data/dev/kubekind/.venv/lib/python3.11/site-packages/material/mkdocs_theme.yml': {'language': 'en', 'direction': None, 'features': [], 'palette': {'primary': None,
            'accent': None}, 'font': {'text': 'Roboto', 'code': 'Roboto Mono'}, 'icon': None, 'favicon': 'assets/images/favicon.png', 'include_search_page': False, 'search_index_only': True, 'static_templates': ['404.html']}
DEBUG    -  Config value 'config_file_path' = '/media/data/dev/kubekind/mkdocs.yml'
DEBUG    -  Config value 'site_name' = 'My Docs'
DEBUG    -  Config value 'nav' = None
DEBUG    -  Config value 'pages' = None
DEBUG    -  Config value 'site_url' = None
DEBUG    -  Config value 'site_description' = None
DEBUG    -  Config value 'site_author' = None
DEBUG    -  Config value 'theme' = Theme(name='material', dirs=['/media/data/dev/kubekind/.venv/lib/python3.11/site-packages/material', '/media/data/dev/kubekind/.venv/lib/python3.11/site-packages/mkdocs/templates'],
            static_templates=['404.html', 'sitemap.xml'], name='material', locale=Locale(language='en', territory=''), language='en', direction=None, features=[], palette={'primary': None, 'accent': None}, font={'text': 'Roboto', 'code':
            'Roboto Mono'}, icon=None, favicon='assets/images/favicon.png', include_search_page=False, search_index_only=True)
DEBUG    -  Config value 'docs_dir' = '/media/data/dev/kubekind/docs'
DEBUG    -  Config value 'site_dir' = '/media/data/dev/kubekind/site'
DEBUG    -  Config value 'copyright' = None
DEBUG    -  Config value 'google_analytics' = None
DEBUG    -  Config value 'dev_addr' = _IpAddressValue(host='127.0.0.1', port=8000)
DEBUG    -  Config value 'use_directory_urls' = True
DEBUG    -  Config value 'repo_url' = None
DEBUG    -  Config value 'repo_name' = None
DEBUG    -  Config value 'edit_uri_template' = None
DEBUG    -  Config value 'edit_uri' = None
DEBUG    -  Config value 'extra_css' = []
DEBUG    -  Config value 'extra_javascript' = []
DEBUG    -  Config value 'extra_templates' = []
DEBUG    -  Config value 'markdown_extensions' = ['toc', 'tables', 'fenced_code']
DEBUG    -  Config value 'mdx_configs' = {}
DEBUG    -  Config value 'strict' = False
DEBUG    -  Config value 'remote_branch' = 'gh-pages'
DEBUG    -  Config value 'remote_name' = 'origin'
DEBUG    -  Config value 'extra' = {}
DEBUG    -  Config value 'plugins' = {'search': <material.plugins.search.plugin.SearchPlugin object at 0x7f40421c6a10>, 'mkdocstrings': <mkdocstrings.plugin.MkdocstringsPlugin object at 0x7f4042be9350>}
DEBUG    -  Config value 'hooks' = {}
DEBUG    -  Config value 'watch' = []
DEBUG    -  Running 2 `config` events
DEBUG    -  mkdocstrings: Adding extension to the list
DEBUG    -  mkdocstrings: Added a subdued autorefs instance <mkdocs_autorefs.plugin.AutorefsPlugin object at 0x7f4041f96550>
DEBUG    -  mkdocs_autorefs.plugin: Adding AutorefsExtension to the list
DEBUG    -  Running 1 `pre_build` events
INFO     -  Cleaning site directory
INFO     -  Building documentation to directory: /media/data/dev/kubekind/site
DEBUG    -  Reading markdown pages.
DEBUG    -  Reading: index.md
DEBUG    -  Running 1 `page_markdown` events
DEBUG    -  mkdocstrings: Matched '::: kubekind.Pod'
DEBUG    -  mkdocstrings: Using handler 'python'
DEBUG    -  mkdocstrings: Collecting data
DEBUG    -  griffe: Found kubekind: loading
DEBUG    -  griffe: Loading path kubekind/__init__.py
DEBUG    -  griffe: Loading path kubekind/kind.py
DEBUG    -  griffe: Loading path kubekind/__main__.py
DEBUG    -  griffe: Skip kubekind/resources/container.py, it is not importable. Missing __init__ module?
DEBUG    -  griffe: Skip kubekind/resources/pod.py, it is not importable. Missing __init__ module?
DEBUG    -  griffe: Skip kubekind/storage/volumemount.py, it is not importable. Missing __init__ module?
DEBUG    -  griffe: Skip kubekind/storage/emptydir.py, it is not importable. Missing __init__ module?
DEBUG    -  griffe: Alias resolution error for kubekind.Container -> kubekind.resources.container.Container
DEBUG    -  griffe: Alias resolution error for kubekind.Pod -> kubekind.resources.pod.Pod
DEBUG    -  griffe: Iteration 1 finished, 0 aliases resolved, still 2 to go
DEBUG    -  griffe: Alias resolution error for kubekind.Container -> kubekind.resources.container.Container
DEBUG    -  griffe: Alias resolution error for kubekind.Pod -> kubekind.resources.pod.Pod
DEBUG    -  griffe: Iteration 2 finished, 0 aliases resolved, still 2 to go
WARNING  -  mkdocstrings_handlers: 2 aliases were still unresolved after 2 iterations
DEBUG    -  mkdocstrings: Updating renderer's env
DEBUG    -  mkdocstrings: Rendering templates
ERROR    -  mkdocstrings: Template 'alias.html' not found for 'python' handler and theme 'material'.
ERROR    -  Error reading page 'index.md': alias.html
Traceback (most recent call last):
...

Or running Griffe directly:

% griffe dump kubekind -o/dev/null -LDEBUG
INFO       Loading package kubekind
DEBUG      Found kubekind: loading
DEBUG      Loading path kubekind/__init__.py
DEBUG      Loading path kubekind/kind.py
DEBUG      Loading path kubekind/__main__.py
DEBUG      Skip kubekind/resources/container.py, it is not importable. Missing __init__ module?
DEBUG      Skip kubekind/resources/pod.py, it is not importable. Missing __init__ module?
DEBUG      Skip kubekind/storage/volumemount.py, it is not importable. Missing __init__ module?
DEBUG      Skip kubekind/storage/emptydir.py, it is not importable. Missing __init__ module?
INFO       Finished loading packages

So the easy solution is to add the missing __init__.py modules.

@motey @HacKanCuBa can you confirm the issue is caused by missing __init__.py modules as well on your side?
If not, could you provide a public repository from which I can replicate the issue? Thanks.

@HacKanCuBa
Copy link

HacKanCuBa commented Dec 6, 2022

mkdocs build -v

Hmmm interesting, I do not see that griffe issue in my log:

...
INFO     -  Cleaning site directory
INFO     -  Building documentation to directory: /home/hackan/Workspace/blake2signer/docs/site
DEBUG    -  An external link to 'https://blake2signer.hackan.net/en/stable/' is included in the
            'nav' configuration.
DEBUG    -  An external link to 'https://blake2signer.hackan.net/en/latest/' is included in the
            'nav' configuration.
DEBUG    -  An external link to 'https://readthedocs.org/projects/blake2signer/' is included in
            the 'nav' configuration.
DEBUG    -  Reading markdown pages.
DEBUG    -  Reading: index.md
DEBUG    -  Running 1 `page_markdown` events
DEBUG    -  Running 1 `page_content` events
DEBUG    -  Reading: bases.md
DEBUG    -  Running 1 `page_markdown` events
DEBUG    -  mkdocstrings: Matched '::: blake2signer.bases.Base'
DEBUG    -  mkdocstrings: Using handler 'python'
DEBUG    -  mkdocstrings: Collecting data
DEBUG    -  griffe: Found blake2signer: loading
DEBUG    -  griffe: Loading path /home/hackan/Workspace/blake2signer/blake2signer/__init__.py
DEBUG    -  griffe: Loading path /home/hackan/Workspace/blake2signer/blake2signer/signers.py
DEBUG    -  griffe: Loading path /home/hackan/Workspace/blake2signer/blake2signer/utils.py
DEBUG    -  griffe: Loading path /home/hackan/Workspace/blake2signer/blake2signer/interfaces.py
DEBUG    -  griffe: Loading path
            /home/hackan/Workspace/blake2signer/blake2signer/compressors.py
DEBUG    -  griffe: Loading path /home/hackan/Workspace/blake2signer/blake2signer/errors.py
DEBUG    -  griffe: Loading path /home/hackan/Workspace/blake2signer/blake2signer/encoders.py
DEBUG    -  griffe: Loading path /home/hackan/Workspace/blake2signer/blake2signer/bases.py
DEBUG    -  griffe: Loading path
            /home/hackan/Workspace/blake2signer/blake2signer/serializers.py
DEBUG    -  griffe: Loading path /home/hackan/Workspace/blake2signer/blake2signer/mixins.py
DEBUG    -  griffe: Loading path
            /home/hackan/Workspace/blake2signer/blake2signer/hashers/__init__.py
DEBUG    -  griffe: Loading path
            /home/hackan/Workspace/blake2signer/blake2signer/tests/__init__.py
DEBUG    -  griffe: Loading path
            /home/hackan/Workspace/blake2signer/blake2signer/hashers/blake3_package.py
DEBUG    -  griffe: Loading path
            /home/hackan/Workspace/blake2signer/blake2signer/hashers/blakehashers.py
DEBUG    -  griffe: Loading path
            /home/hackan/Workspace/blake2signer/blake2signer/tests/test_hashers.py
DEBUG    -  griffe: Loading path
            /home/hackan/Workspace/blake2signer/blake2signer/tests/test_signer.py
DEBUG    -  griffe: Loading path
            /home/hackan/Workspace/blake2signer/blake2signer/tests/test_serializersigner.py
DEBUG    -  griffe: Loading path
            /home/hackan/Workspace/blake2signer/blake2signer/tests/test_timestampsigner.py
DEBUG    -  griffe: Loading path
            /home/hackan/Workspace/blake2signer/blake2signer/tests/test_utils.py
DEBUG    -  griffe: Loading path
            /home/hackan/Workspace/blake2signer/blake2signer/tests/bases.py
DEBUG    -  griffe: Alias blake2signer.Blake2SerializerSigner was resolved to
            blake2signer.signers.Blake2SerializerSigner
DEBUG    -  griffe: Alias blake2signer.Blake2Signature was resolved to
            blake2signer.signers.Blake2Signature
DEBUG    -  griffe: Alias blake2signer.Blake2SignatureDump was resolved to
            blake2signer.signers.Blake2SignatureDump
DEBUG    -  griffe: Alias blake2signer.Blake2Signer was resolved to
            blake2signer.signers.Blake2Signer
DEBUG    -  griffe: Alias blake2signer.Blake2TimestampSigner was resolved to
            blake2signer.signers.Blake2TimestampSigner
DEBUG    -  griffe: Alias resolution error for blake2signer.hashers.blake3 -> blake3.blake3
DEBUG    -  griffe: Alias blake2signer.hashers.has_blake3 was resolved to
            blake2signer.hashers.blake3_package.has_blake3
DEBUG    -  griffe: Alias blake2signer.hashers.BLAKE2Hasher was resolved to
            blake2signer.hashers.blakehashers.BLAKE2Hasher
DEBUG    -  griffe: Alias blake2signer.hashers.BLAKE3Hasher was resolved to
            blake2signer.hashers.blakehashers.BLAKE3Hasher
DEBUG    -  griffe: Alias blake2signer.hashers.HasherChoice was resolved to
            blake2signer.hashers.blakehashers.HasherChoice
DEBUG    -  griffe: Iteration 1 finished, 9 aliases resolved, still 1 to go
DEBUG    -  griffe: Alias resolution error for blake2signer.hashers.blake3 -> blake3.blake3
DEBUG    -  griffe: Iteration 2 finished, 0 aliases resolved, still 1 to go
WARNING  -  mkdocstrings_handlers: 1 aliases were still unresolved after 2 iterations
DEBUG    -  mkdocstrings: Updating renderer's env
DEBUG    -  mkdocstrings: Rendering templates
...

This line caught my attention: Alias resolution error for blake2signer.hashers.blake3 -> blake3.blake3: blake2signer.hashers.blake3 does not exists per se, hashers is a module, and blake3 is an import from a submodule in __init__.py: from .blake3_package import blake3. It seems that Griffe is having issues w/ that.
This is referenced in a doc file as: ::: blake2signer.hashers, and blake3 does not appear in the rendered docs.
If I instead reference directly blake2signer.hashers.blake3, as ::: blake2signer.hashers.blake3, I get this exception, and the build fails:

...
DEBUG    -  griffe: Alias resolution error for blake2signer.hashers.blake3 -> blake3.blake3
DEBUG    -  griffe: Alias blake2signer.hashers.has_blake3 was resolved to
            blake2signer.hashers.blake3_package.has_blake3
DEBUG    -  griffe: Alias blake2signer.hashers.BLAKE2Hasher was resolved to
            blake2signer.hashers.blakehashers.BLAKE2Hasher
DEBUG    -  griffe: Alias blake2signer.hashers.BLAKE3Hasher was resolved to
            blake2signer.hashers.blakehashers.BLAKE3Hasher
DEBUG    -  griffe: Alias blake2signer.hashers.HasherChoice was resolved to
            blake2signer.hashers.blakehashers.HasherChoice
DEBUG    -  griffe: Iteration 1 finished, 9 aliases resolved, still 1 to go
DEBUG    -  griffe: Alias resolution error for blake2signer.hashers.blake3 -> blake3.blake3
DEBUG    -  griffe: Iteration 2 finished, 0 aliases resolved, still 1 to go
WARNING  -  mkdocstrings_handlers: 1 aliases were still unresolved after 2 iterations
...
DEBUG    -  mkdocstrings: Using handler 'python'
DEBUG    -  mkdocstrings: Collecting data
DEBUG    -  mkdocstrings: Rendering templates
ERROR    -  mkdocstrings: Template 'alias.html' not found for 'python' handler and theme
            'material'.
ERROR    -  Error reading page 'hashers.md': alias.html
Traceback (most recent call last):
...
    raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: alias.html

This is from my open-source project, you can build the docs yourself if needed: https://gitlab.com/hackancuba/blake2signer/

  1. Clone the repo: git clone git@gitlab.com:hackancuba/blake2signer.git
  2. Go into project dir, ignore main project: cd blake2signer
  3. Go into docs subdir: cd docs
  4. Install deps: poetry install (a .venv dir is automatically created locally by Poetry)
  5. Run mkdocs: poetry run mkdocs build -v

@pawamoy
Copy link
Member

pawamoy commented Dec 10, 2022

Can you try again with Griffe installed from master branch? poetry run pip install git+https://github.com/mkdocstrings/griffe

I've fixed several things, did not get the chance to release yet.

@HacKanCuBa
Copy link

HacKanCuBa commented Dec 12, 2022

Can you try again with Griffe installed from master branch? poetry run pip install git+https://github.com/mkdocstrings/griffe

I've fixed several things, did not get the chance to release yet.

Interestingly, the log changed a bit, but yet it still throws the warning (or the error when I force it to reference directly the offending file).

...
mkdocstrings: Matched '::: blake2signer.bases.Base'
DEBUG    -  mkdocstrings: Using handler 'python'
DEBUG    -  mkdocstrings: Collecting data
DEBUG    -  griffe: Found blake2signer: loading
DEBUG    -  griffe: Loading path /tmp/blake2signer/blake2signer/blake2signer/__init__.py
DEBUG    -  griffe: Loading path /tmp/blake2signer/blake2signer/blake2signer/utils.py
DEBUG    -  griffe: Loading path /tmp/blake2signer/blake2signer/blake2signer/signers.py
DEBUG    -  griffe: Loading path /tmp/blake2signer/blake2signer/blake2signer/serializers.py
DEBUG    -  griffe: Loading path /tmp/blake2signer/blake2signer/blake2signer/mixins.py
DEBUG    -  griffe: Loading path /tmp/blake2signer/blake2signer/blake2signer/interfaces.py
DEBUG    -  griffe: Loading path /tmp/blake2signer/blake2signer/blake2signer/errors.py
DEBUG    -  griffe: Loading path /tmp/blake2signer/blake2signer/blake2signer/encoders.py
DEBUG    -  griffe: Loading path /tmp/blake2signer/blake2signer/blake2signer/compressors.py
DEBUG    -  griffe: Loading path /tmp/blake2signer/blake2signer/blake2signer/bases.py
DEBUG    -  griffe: Loading path /tmp/blake2signer/blake2signer/blake2signer/tests/__init__.py
DEBUG    -  griffe: Loading path
            /tmp/blake2signer/blake2signer/blake2signer/hashers/__init__.py
DEBUG    -  griffe: Loading path
            /tmp/blake2signer/blake2signer/blake2signer/tests/test_utils.py
DEBUG    -  griffe: Loading path
            /tmp/blake2signer/blake2signer/blake2signer/tests/test_timestampsigner.py
DEBUG    -  griffe: Loading path
            /tmp/blake2signer/blake2signer/blake2signer/tests/test_signer.py
DEBUG    -  griffe: Loading path
            /tmp/blake2signer/blake2signer/blake2signer/tests/test_serializersigner.py
DEBUG    -  griffe: Loading path
            /tmp/blake2signer/blake2signer/blake2signer/tests/test_hashers.py
DEBUG    -  griffe: Loading path /tmp/blake2signer/blake2signer/blake2signer/tests/bases.py
DEBUG    -  griffe: Loading path
            /tmp/blake2signer/blake2signer/blake2signer/hashers/blakehashers.py
DEBUG    -  griffe: Loading path
            /tmp/blake2signer/blake2signer/blake2signer/hashers/blake3_package.py
DEBUG    -  griffe: Alias blake2signer.Blake2SerializerSigner was resolved to
            blake2signer.signers.Blake2SerializerSigner
DEBUG    -  griffe: Alias blake2signer.Blake2Signature was resolved to
            blake2signer.signers.Blake2Signature
DEBUG    -  griffe: Alias blake2signer.Blake2SignatureDump was resolved to
            blake2signer.signers.Blake2SignatureDump
DEBUG    -  griffe: Alias blake2signer.Blake2Signer was resolved to
            blake2signer.signers.Blake2Signer
DEBUG    -  griffe: Alias blake2signer.Blake2TimestampSigner was resolved to
            blake2signer.signers.Blake2TimestampSigner
DEBUG    -  griffe: Alias blake2signer.hashers.has_blake3 was resolved to
            blake2signer.hashers.blake3_package.has_blake3
DEBUG    -  griffe: Alias blake2signer.hashers.BLAKE2Hasher was resolved to
            blake2signer.hashers.blakehashers.BLAKE2Hasher
DEBUG    -  griffe: Alias blake2signer.hashers.BLAKE3Hasher was resolved to
            blake2signer.hashers.blakehashers.BLAKE3Hasher
DEBUG    -  griffe: Alias blake2signer.hashers.HasherChoice was resolved to
            blake2signer.hashers.blakehashers.HasherChoice
DEBUG    -  griffe: Iteration 1 finished, 9 aliases resolved, still 1 to go
DEBUG    -  griffe: Iteration 2 finished, 0 aliases resolved, still 1 to go
WARNING  -  mkdocstrings_handlers: 1 aliases were still unresolved after 2 iterations
DEBUG    -  mkdocstrings: Updating renderer's env
...

@pawamoy
Copy link
Member

pawamoy commented Dec 15, 2022

So, what's the issue? You don't want the X aliases were still unresolved after N iterations message to be logged as a warning? We can turn it to a DEBUG one 🙂

@HacKanCuBa
Copy link

HacKanCuBa commented Dec 15, 2022

haha no, that's not the issue. if i want to show docs for the object in question, it crashes instead of giving a warning (see the second part of my prev comment).
And I actually want to show some docs for it :P
It's currently just being omitted, which is fine, but could be better :)

@pawamoy
Copy link
Member

pawamoy commented Dec 15, 2022

I see, thanks for the explanation! (I'll still change the warning to a debug statement)

So, Griffe does not try to load external packages when resolving aliases. If you want to force it to load blake3, so that you are able to document its objects directly or through aliases (objects from blake3 imported in your own code), you'll have to add at least one autodoc instruction beginning with blake3, for example:

::: blake3.some.small.object
    options:
      shot_root_toc_entry: false

<!-- you can then hide it with something like
<style>.doc-object:has(> #blake3.some.small.object) {display: none;}</style>
-->

Obviously, blake3 needs to be installed when building the docs.

I'm planning on adding a configuration option to tell Griffe to (pre)load additional modules without having to resort to that workaround 🙂

UPDATE: well, I just tried with blake3.blake3.AUTO but Griffe crashes when trying to load it. The inspector seems to think the blake3 submodule comes from builtins. I'll have to investigate.

@HacKanCuBa
Copy link

yes, thanks!
BTW, I think a warning is perfectly fine there, I would certainly leave it as it is, because it is indicating an actual issue :)

@pawamoy
Copy link
Member

pawamoy commented Dec 15, 2022

Yeah you're right, I don't understand right now why the warning is not more often displayed though. Anyway, bad news: blake3 (which is compiled) is lying about the parent module of blake3.blake3.blake3: it says it's builtins. Not sure what hackery they actually do 😕 I guess I'll have to special case it in Griffe, but that doesn't make me so happy 😂

@HacKanCuBa
Copy link

Yeah you're right, I don't understand right now why the warning is not more often displayed though. Anyway, bad news: blake3 (which is compiled) is lying about the parent module of blake3.blake3.blake3: it says it's builtins. Not sure what hackery they actually do 😕 I guess I'll have to special case it in Griffe, but that doesn't make me so happy 😂

hahaha damn. hmmm, well, the Zen says that no special case is special enough :P
I could manually add some docs, and be done w/ it :)

@HacKanCuBa
Copy link

BTW, thanks so much for this!

@pawamoy
Copy link
Member

pawamoy commented Dec 15, 2022

You're welcome! You can also open a new issue with just the link to this comment, this way I don't forget about it 🙂

@pawamoy pawamoy closed this as completed Dec 15, 2022
@HacKanCuBa
Copy link

I have bad news: I did a quick test w/ latest blake3 and griffe@master, and this is still happening.
I'll keep digging, and open an issue directly in griffe. Thanks for everything!

@pawamoy
Copy link
Member

pawamoy commented Dec 18, 2022

Meh 😕 OK, thanks for reporting back, I'll continue to investigate as well.

@pawamoy
Copy link
Member

pawamoy commented Dec 18, 2022

I wonder if this is because @oconnor663 set the parent to module to blake3 instead of blake3.blake3 🤔

@pawamoy
Copy link
Member

pawamoy commented Dec 18, 2022

Or we simply hit the design flaw of Griffe where modules and members of the same name cannot coexist, while this is possible in Python itself.

@pawamoy
Copy link
Member

pawamoy commented Dec 18, 2022

Well, it's the former. If we patch the module of the blake3 class to be blake3.blake3 instead of blake3, it's correctly inspected instead of being marked as an alias to blake3.blake3.

If we don't, Griffe thinks that blake3.blake3.blake3 is an alias to blake3.blake3, the alias is correctly resolved, but then this module does not have the members of the class (obviously), resulting in a collection error.

@pawamoy
Copy link
Member

pawamoy commented Dec 18, 2022

If blake3 patches the module (again 🙏 🙇 ❤️), then you can enable the md_in_html Markdown extension in mkdocs.yml and use this:

# Hashers

<div style="display: none;" markdown=1>

::: blake3
    options:
        members: false
        show_root_heading: false
        show_root_toc_entry: false

</div>

::: blake2signer.hashers
    options:
        merge_init_into_class: true
        filters: ["!^_"]

@oconnor663
Copy link

oconnor663 commented Dec 18, 2022

I'm pretty new to the behavior of __module__, so it's certainly possible I did the wrong thing here. But intuitively it seems correct that the module should be blake3. That's consistent with the following toy example:

blake42.py

class blake42:
    pass

main.py

from blake42 import blake42
print(repr(blake42.__module__))
$ python3 main.py
'blake42'

I don't think anyone expects main.py to print blake42.blake42, but then I'm confused reading the thread above. What am I missing?

@oconnor663
Copy link

See also the pure-C port, which uses Python's C API directly. There we set .tp_name = "blake3.blake3", and Python infers based on the dots that __module__ should be "blake3".

@pawamoy
Copy link
Member

pawamoy commented Dec 18, 2022

Your toy example is correct, however your code/project has one more layer:

blake3/  # <- module == blake3
    __init__.py  # <- imports blake3 class from compiled blake3 below
    blake3.cpython-311-x86_64-linux-gnu.so  # <- module == blake3.blake3

Generally, it seems that objects do have the full, canonical path to the module they are defined in as value for __module__. Some examples:

>>> from griffe import load_git  # indirect import
>>> load_git.__module__
'griffe.git'

>>> from griffe.agents.base import BaseVisitor  # direct import
>>> BaseVisitor.__module__
'griffe.agents.base'

@oconnor663
Copy link

Ah interesting. It looks like that's an implementation detail of the Maturin build tool. I've opened a discussion question about best practices here: PyO3/maturin#1365. Please chime in if you have any thoughts about Maturin/PyO3, or if you can clarify exactly how the mkdocs tool is getting confused. (I'm not familiar with it.)

@oconnor663
Copy link

oconnor663 commented Dec 20, 2022

The Maturin maintainer has asked for repro steps here: PyO3/maturin#1365 (comment). Could someone from this thread add a mkdocs repro to that thread?

oconnor663 added a commit to oconnor663/blake3-py that referenced this issue Dec 20, 2022
This is a correction of 07c389f, which
originally set `__module__` to "blake3". For all the details, see:
- mkdocstrings/mkdocstrings#451
- PyO3/maturin#1365

The C implementation is unchanged, so `__module__` is still "blake3"
there.
oconnor663 added a commit to oconnor663/blake3-py that referenced this issue Dec 20, 2022
Changes since 0.3.2:
- Change `blake3.__module__` from "blake3" to "blake3.blake3". This is
  the correct canonical path, related to some Maturin implementation
  details. This is intended to help tooling that relies on canonical
  paths, but most regular callers don't need to worry about this. See
  mkdocstrings/mkdocstrings#451 for an example
  of a tool that needs to know this.
oconnor663 added a commit to oconnor663/blake3-py that referenced this issue Dec 20, 2022
Changes since 0.3.2:
- Change `blake3.__module__` from "blake3" to "blake3.blake3". This is
  the correct canonical path, related to some Maturin implementation
  details. This is intended to help tooling that relies on canonical
  paths, but most regular callers don't need to worry about this. See
  mkdocstrings/mkdocstrings#451 for an example
  of a tool that needs to know this.
- Update PyO3 to v0.17.
@oconnor663
Copy link

Just published blake3 v0.3.3 with __module__ set to blake3.blake3. Could you give this another try?

@pawamoy
Copy link
Member

pawamoy commented Dec 20, 2022

Seems to be working fine! I'll let @HacKanCuBa confirm 🙂

@HacKanCuBa
Copy link

HacKanCuBa commented Dec 20, 2022

If blake3 patches the module (again 🙏 🙇 ❤️), then you can enable the md_in_html Markdown extension in mkdocs.yml and use this:

# Hashers

<div style="display: none;" markdown=1>

::: blake3
    options:
        members: false
        show_root_heading: false
        show_root_toc_entry: false

</div>

::: blake2signer.hashers
    options:
        merge_init_into_class: true
        filters: ["!^_"]

Indeed, it does work when I do something like explained here :D 🥳

It still fails if I use ::: blake2signer.hashers.blake3 instead of ::: blake3, but this is good enough 😅

@pawamoy
Copy link
Member

pawamoy commented Dec 20, 2022

As I tried to explain before, ::: blake2signer.hashers.blake3 will not make Griffe load the blake3 package, so you won't have any information about the blake3 class.

The idea is that later, you'll be able to use something like this:

# mkdocs.yml
plugins:
- mkdocstrings:
    handlers:
      python:
        preload: [blake3]

...so that you don't have to rely on this hidden div hack 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants