-
-
Notifications
You must be signed in to change notification settings - Fork 63
Description
When I write a new module, with Python docstrings (in Google style), I want to render these docstrings on my docs page. This is typical. However, the challenge is in the resolution of Aliases through Griffe. Specifically, Griffe forces the loading and resolution of every single module which I am importing in to my script; even if those imported docs are not even necessary for my documentation.
Let me give you an example:
import pandas as pd
import numpy as np
def my_fancy_func():
"""
Some documentation in Google style
"""
return pd.DataFrame({'a': [1, 2, 3], 'b': ['a', 'b', 'c']})In the above scenario, we have one module which imports two libraries: pandas and numpy, and one super simple function with basic documentation.
Now, when I try to load this documentation using the command:
mkdocs serveI receive a HUGE and super complicated error:
(.venv) name@MACHINE:/path-to-dir$ mkdocs serve
INFO - DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
File "/path-to-dir/.venv/lib/python3.10/site-packages/mike/mkdocs_plugin.py", line 6, in <module>
from pkg_resources import iter_entry_points
File "/path-to-dir/.venv/lib/python3.10/site-packages/pkg_resources/__init__.py", line 118, in <module>
warnings.warn(
INFO - Building documentation...
INFO - Cleaning site directory
INFO - DeprecationWarning: invalid escape sequence '\_'
File "/path-to-dir/.venv/lib/python3.10/site-packages/griffe/agents/visitor.py", line 177, in get_module
top_node = compile(self.code, mode="exec", filename=str(self.filepath), flags=ast.PyCF_ONLY_AST, optimize=1)
File "/path-to-dir/.venv/lib/python3.10/site-packages/pyspark/pandas/supported_api_gen.py", line 355, in
return func_str[:-1] + "\_" # noqa: W605
ERROR - Error reading page 'docs/code/processing_times.md': Could not resolve alias src.databricks_helpers.processing_times.pd pointing at pandas (in
src/databricks_helpers/processing_times.py:5)
Traceback (most recent call last):
File "/path-to-dir/.venv/lib/python3.10/site-packages/griffe/dataclasses.py", line 1116, in _resolve_target
resolved = self.modules_collection.get_member(self.target_path)
File "/path-to-dir/.venv/lib/python3.10/site-packages/griffe/mixins.py", line 77, in get_member
return self.members[parts[0]] # type: ignore[attr-defined]
KeyError: 'pandas'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/path-to-dir/.venv/bin/mkdocs", line 10, in <module>
sys.exit(cli())
File "/path-to-dir/.venv/lib/python3.10/site-packages/click/core.py", line 1157, in __call__
return self.main(*args, **kwargs)
File "/path-to-dir/.venv/lib/python3.10/site-packages/click/core.py", line 1078, in main
rv = self.invoke(ctx)
File "/path-to-dir/.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-dir/.venv/lib/python3.10/site-packages/click/core.py", line 1434, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/path-to-dir/.venv/lib/python3.10/site-packages/click/core.py", line 783, in invoke
return __callback(*args, **kwargs)
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocs/__main__.py", line 270, in serve_command
serve.serve(**kwargs)
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocs/commands/serve.py", line 86, in serve
builder(config)
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocs/commands/serve.py", line 67, in builder
build(config, live_server=None if is_clean else server, dirty=is_dirty)
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocs/commands/build.py", line 322, in build
_populate_page(file.page, config, files, dirty)
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocs/commands/build.py", line 175, in _populate_page
page.render(config, files)
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocs/structure/pages.py", line 271, in render
self.content = md.convert(self.markdown)
File "/path-to-dir/.venv/lib/python3.10/site-packages/markdown/core.py", line 254, in convert
root = self.parser.parseDocument(self.lines).getroot()
File "/path-to-dir/.venv/lib/python3.10/site-packages/markdown/blockparser.py", line 84, in parseDocument
self.parseChunk(self.root, '\n'.join(lines))
File "/path-to-dir/.venv/lib/python3.10/site-packages/markdown/blockparser.py", line 99, in parseChunk
self.parseBlocks(parent, text.split('\n\n'))
File "/path-to-dir/.venv/lib/python3.10/site-packages/markdown/blockparser.py", line 117, in parseBlocks
if processor.run(parent, blocks) is not False:
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocstrings/extension.py", line 125, in run
html, handler, data = self._process_block(identifier, block, heading_level)
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocstrings/extension.py", line 221, in _process_block
rendered = handler.render(data, options)
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocstrings_handlers/python/handler.py", line 338, in render
return template.render(
File "/path-to-dir/.venv/lib/python3.10/site-packages/jinja2/environment.py", line 1301, in render
self.environment.handle_exception()
File "/path-to-dir/.venv/lib/python3.10/site-packages/jinja2/environment.py", line 936, in handle_exception
raise rewrite_traceback_stack(source=source)
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocstrings_handlers/python/templates/material/module.html", line 1, in top-level template code
{% extends "_base/module.html" %}
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocstrings_handlers/python/templates/material/_base/module.html", line 55, in top-level template code
{% block contents scoped %}
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocstrings_handlers/python/templates/material/_base/module.html", line 62, in block 'contents'
{% block children scoped %}
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocstrings_handlers/python/templates/material/_base/module.html", line 65, in block 'children'
{% include "children.html" with context %}
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocstrings_handlers/python/templates/material/children.html", line 1, in top-level template code
{% extends "_base/children.html" %}
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocstrings_handlers/python/templates/material/_base/children.html", line 110, in top-level template code
{% for child in obj.all_members
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocstrings_handlers/python/rendering.py", line 184, in do_order_members
return sorted(members, key=order_map[order])
File "/path-to-dir/.venv/lib/python3.10/site-packages/mkdocstrings_handlers/python/rendering.py", line 40, in _sort_key_source
return item.lineno if item.lineno is not None else -1
File "/path-to-dir/.venv/lib/python3.10/site-packages/griffe/dataclasses.py", line 816, in lineno
return self.final_target.lineno
File "/path-to-dir/.venv/lib/python3.10/site-packages/griffe/dataclasses.py", line 1092, in final_target
target = target.target # type: ignore[assignment]
File "/path-to-dir/.venv/lib/python3.10/site-packages/griffe/dataclasses.py", line 1064, in target
self.resolve_target()
File "/path-to-dir/.venv/lib/python3.10/site-packages/griffe/dataclasses.py", line 1110, in resolve_target
self._resolve_target()
File "/path-to-dir/.venv/lib/python3.10/site-packages/griffe/dataclasses.py", line 1118, in _resolve_target
raise AliasResolutionError(self) from error
griffe.exceptions.AliasResolutionError: Could not resolve alias src.databricks_helpers.processing_times.pd pointing at pandas (in src/databricks_helpers/processing_times.py:5)Which confuses me a lot. Why is my rendering failing because it's pointing at Pandas?
Through a LOT of searching through your documentation, I finally found how to resolve it. I needed to list pandas in the preload_modules section on the mkdocs.yml config file.
Like this:
plugins:
- autorefs
- mkdocstrings:
default_handler: python
handlers:
python:
options:
allow_inspection: true
docstring_style: google
docstring_options:
replace_admonitions: no
show_root_heading: true
show_root_toc_entry: false
show_root_full_path: true
show_source: true
show_object_full_path: false
show_signature_annotations: true
show_category_heading: true
show_if_no_docstring: true
heading_level: 3
members_order: source
group_by_category: false
paths:
- src/databricks_helpers
preload_modules:
- __future__
- typeguard
- datetime
- pandas
filters:
- "!^__all__"Now, what happens when I do mkdocs serve, is that it takes over 2 minutes to load the docs eeeeeevery single time I save my files, which greatly reduces my efficiency in building my docs. The reason for this is that mkdocstrings-python will re-load every single module listed in preload_modules every single time one of the underlying files changes listed in paths. And because Pandas takes sooooooo long to load (that's a separate issue from this one), then therefore these mkdocstrings processes will also take so long to load them.
But I question why this is even necessary? The pandas package is not necessary for my docs rendering at all. It's needed for Unit Testing, that's fine. But not for docs rendering... So why does it even need to be preloaded? It's so that Griffe will be to render the Alias Resolution, right? But I don't want it to. I just want to build my docs quickly and easily.
Therefore, I'd like to recommend an additional option here to skip the Alias resolution process in Griffe. Therefore, I do not need to add my additional packages in this preload_modules section.
One other use case to consider is in packages that are not even loaded in to my local virtual environment. One such example is the DBUtils package, necessary for various processes on DataBricks environment. But when coding on my local PC, this pacakage is not installable, because it's only available in DataBricks workspace. But I need to include the import statement in my modules because when that package is run on DataBricks later, then that dbutils package will be available. However, as soon as I add this import statement to my script, then Griffe will expect to preload it... but it's not installed... so therefore Griffe will not allow my docs to even be rendered. But the challenge is, I don't even need DBUtils for my docs?? So therefore, I'd like to skip this Alias Resolution part alltogether.
Please help me with this one.
Here's my package versions:
- Griffe:
griffe 0.36.2 - MkDocs:
mkdocs 1.5.3 - MkDocs-Material:
mkdocs-material 9.4.2 - MkDocStrings:
mkdocstrings 0.23.0 - MkDocStrings-Python:
mkdocstrings-python 1.7.0
Thank you.