Skip to content

bug: cyclic aliases detected when inspecting compiled modules #237

@elfkuzco

Description

@elfkuzco

Description of the bug

When the merge_init_into_class is set to true, mkdocs throws a CyclicAliasError as a consequence of inspecting a compiled module. The hack around it currently is to remove docstrings from the __init__ method (or the class heading) and set merge_init_into_class to `false. However, this means that documentation for such classes are missing. Furthermore, not even the attributes of the base class and children are shown in the documentation

To Reproduce

git clone git@github.com:elfkuzco/python-libzim.git -b online-api-doc
hatch shell
SIGN_APPLE=0 hatch run build-ext
mkdocs serve

Full traceback

Full traceback
Traceback (most recent call last):
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocs/livereload/__init__.py", line 211, in _build_loop
    self.builder()
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/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 "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocs/commands/build.py", line 310, in build
    _populate_page(file.page, config, files, dirty)
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocs/commands/build.py", line 167, in _populate_page
    page.render(config, files)
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocs/structure/pages.py", line 285, in render
    self.content = md.convert(self.markdown)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/markdown/core.py", line 357, in convert
    root = self.parser.parseDocument(self.lines).getroot()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/markdown/blockparser.py", line 117, in parseDocument
    self.parseChunk(self.root, '\n'.join(lines))
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/markdown/blockparser.py", line 136, in parseChunk
    self.parseBlocks(parent, text.split('\n\n'))
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/markdown/blockparser.py", line 158, in parseBlocks
    if processor.run(parent, blocks) is not False:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocstrings/extension.py", line 130, in run
    html, handler, data = self._process_block(identifier, block, heading_level)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocstrings/extension.py", line 230, in _process_block
    rendered = handler.render(data, options)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocstrings_handlers/python/handler.py", line 425, in render
    return template.render(
           ^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/jinja2/environment.py", line 1295, in render
    self.environment.handle_exception()
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/jinja2/environment.py", line 942, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocstrings_handlers/python/templates/material/module.html.jinja", line 1, in top-level template code
    {% extends "_base/module.html.jinja" %}
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja", line 83, in top-level template code
    {% block contents scoped %}
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja", line 108, in block 'contents'
    {% block children scoped %}
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja", line 115, in block 'children'
    {% include "children"|get_template with context %}
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocstrings_handlers/python/templates/material/children.html.jinja", line 1, in top-level template code
    {% extends "_base/children.html.jinja" %}
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja", line 73, in top-level template code
    {% include class|get_template with context %}
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocstrings_handlers/python/templates/material/class.html.jinja", line 1, in top-level template code
    {% extends "_base/class.html.jinja" %}
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja", line 75, in top-level template code
    {% block signature scoped %}
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja", line 85, in block 'signature'
    {% if function.overloads %}
    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/jinja2/environment.py", line 490, in getattr
    return getattr(obj, attribute)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/_griffe/models.py", line 1584, in overloads
    return cast(Union[Module, Class, Function], self.final_target).overloads
                                                ^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/_griffe/models.py", line 1697, in final_target
    target = target.target  # type: ignore[assignment]
             ^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/_griffe/models.py", line 1662, in target
    self.resolve_target()
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/_griffe/models.py", line 1729, in resolve_target
    self._resolve_target()
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/_griffe/models.py", line 1747, in _resolve_target
    self._target.aliases[self.path] = self  # type: ignore[union-attr]  # we just set the target
    ^^^^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/_griffe/models.py", line 1301, in aliases
    return self.final_target.aliases
           ^^^^^^^^^^^^^^^^^
  File "/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/lib/python3.11/site-packages/_griffe/models.py", line 1695, in final_target
    raise CyclicAliasError([*paths_seen, target.path])
_griffe.exceptions.CyclicAliasError: Cyclic aliases detected:
  libzim.ContentProvider.__init__
  libzim.writer.ContentProvider.__init__
  libzim.ContentProvider.__init__

Expected behavior

I expected the alias to end at libzim.writer.ContentProvider.__init__ but that in turn points to the libzim.ContentProvider.__init__. The class is defined in libzim.writer even though one can import it from libzim directly.

Environment information

- __System__: Linux-6.1.0-18-amd64-x86_64-with-glibc2.36
- __Python__: cpython 3.11.3 (/home/elf/.local/share/hatch/env/virtual/libzim/hfWdK34c/libzim/bin/python)
- __Environment variables__:
- __Installed packages__:
  - `griffe` v1.5.5

Additional context

I inspected the graph generated by griffe with and without the force_inspection flag and I observed that this does not happen when using the .pyi files. The graph with the force_inspection indeed seems to be a cyclic one as the __init__ methods are all aliases. This only happens when working with base classes and classes that derive them from them and is not reproducible with simple classes.

Metadata

Metadata

Assignees

Labels

unconfirmedThis bug was not reproduced yet

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions