Closed jaspergreener closed 2 years ago
Hi @jaspergreener, thank you very much for the detailed bug report, suggestions and workarounds. The current Python handler uses pytkdocs to extract data, and pytkdocs is... not the best. I've been working on an much improved version, Griffe, and it should actually be available soon. I believe the new handler will fix this kind of issues, so I won't work on resolving this in pytkdocs for now. But I'll leave the issue open :slightly_smiling_face:
This is likely solved by the new handler. Feedback appreciated!
Very happy with the quick response! I'll give it a try and let you know in this issue :)
The new handler isn't working for me, unfortunately. It seems to fail on generating documentation for a class inheriting from a pydantic.BaseModel
:
INFO - Cleaning site directory
INFO - Building documentation to directory: /home/user/PycharmProjects/greener-projects-be/docs/site
ERROR - Error reading page 'administration.md': <class '_ast.keyword'>
Traceback (most recent call last):
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/mkdocs/__main__.py", line 187, in build_command
build.build(config.load_config(**kwargs), dirty=not clean)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/mkdocs/commands/build.py", line 292, in build
_populate_page(file.page, config, files, dirty)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/mkdocs/commands/build.py", line 174, in _populate_page
page.render(config, files)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/mkdocs/structure/pages.py", line 174, in render
self.content = md.convert(self.markdown)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/markdown/core.py", line 264, in convert
root = self.parser.parseDocument(self.lines).getroot()
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/markdown/blockparser.py", line 90, in parseDocument
self.parseChunk(self.root, '\n'.join(lines))
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/markdown/blockparser.py", line 105, in parseChunk
self.parseBlocks(parent, text.split('\n\n'))
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/markdown/blockparser.py", line 123, in parseBlocks
if processor.run(parent, blocks) is not False:
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/mkdocstrings/extension.py", line 120, in run
html, handler, data = self._process_block(identifier, block, heading_level)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/mkdocstrings/extension.py", line 185, in _process_block
data: CollectorItem = handler.collector.collect(identifier, selection)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/mkdocstrings_handlers/python/collector.py", line 69, in collect
loader.load_module(module_name)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/loader.py", line 131, in load_module
top_module = self._load_module_path(package.name, package.path, submodules=submodules)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/loader.py", line 287, in _load_module_path
self._load_submodules(module)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/loader.py", line 292, in _load_submodules
self._load_submodule(module, subparts, subpath)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/loader.py", line 303, in _load_submodule
member_parent[subparts[-1]] = self._load_module_path(
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/loader.py", line 283, in _load_module_path
module = self._visit_module(code, module_name, module_path, parent)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/loader.py", line 326, in _visit_module
module = visit(
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/visitor.py", line 78, in visit
return Visitor(
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/visitor.py", line 158, in get_module
self.visit(top_node)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/visitor.py", line 169, in visit
super().visit(node)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/base.py", line 19, in visit
getattr(self, f"visit_{node.kind}", self.generic_visit)(node) # type: ignore[attr-defined]
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/visitor.py", line 200, in visit_module
self.generic_visit(node)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/visitor.py", line 182, in generic_visit
self.visit(child)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/visitor.py", line 169, in visit
super().visit(node)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/base.py", line 19, in visit
getattr(self, f"visit_{node.kind}", self.generic_visit)(node) # type: ignore[attr-defined]
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/visitor.py", line 236, in visit_classdef
self.generic_visit(node)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/visitor.py", line 182, in generic_visit
self.visit(child)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/visitor.py", line 169, in visit
super().visit(node)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/base.py", line 19, in visit
getattr(self, f"visit_{node.kind}", self.generic_visit)(node) # type: ignore[attr-defined]
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/visitor.py", line 502, in visit_annassign
self.handle_attribute(node, get_annotation(node.annotation, parent=self.current))
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/nodes.py", line 681, in get_annotation
return _get_annotation(node, parent)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/nodes.py", line 666, in _get_annotation
return _node_annotation_map[type(node)](node, parent)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/nodes.py", line 621, in _get_subscript_annotation
subscript = _get_annotation(node.slice, parent)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/nodes.py", line 666, in _get_annotation
return _node_annotation_map[type(node)](node, parent)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/nodes.py", line 648, in _get_index_annotation
return _get_annotation(node.value, parent)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/nodes.py", line 666, in _get_annotation
return _node_annotation_map[type(node)](node, parent)
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/nodes.py", line 580, in _get_call_annotation
kwargs = Expression(*[_get_annotation(kwarg, parent) for kwarg in node.keywords])
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/nodes.py", line 580, in <listcomp>
kwargs = Expression(*[_get_annotation(kwarg, parent) for kwarg in node.keywords])
File "/home/user/PycharmProjects/greener-projects-be/venv3.8/lib/python3.8/site-packages/griffe/agents/nodes.py", line 666, in _get_annotation
return _node_annotation_map[type(node)](node, parent)
KeyError: <class '_ast.keyword'>
Process finished with exit code 1
Griffe tries to get an annotation for an AST Keyword, but has no annotation implementation for not keywords: the node annotation map does not contains type ast.keyword.
@pawamoy If you like, I could report this in a separate issue.
@jaspergreener Yes please! On the griffe repository preferably :slightly_smiling_face: And thanks a lot for testing the new handler :smile:
Describe the bug I am trying to use mkdocs + mkdocstrings to generate documentation for my codebase. My codebase uses graphene for setting up a GraphQL backend.
mkdocstrings cannot generate documentation based on docstring for classes that inherit from any of graphene's types, due to AttributeErrors:
The attribute error is thrown because pytkdocs' Loader tries to interpret a '_meta' attribute as a Django meta field, see
pytkdocs/loader.py:539
:("_meta.get_fields", ["django-model"], self.get_django_field_documentation)
.In my case, there is a '_meta' field, but it has no 'get_fields' attribute.
To Reproduce github_bug.py:
index.md:
Generate documentation with mkdoc using
mkdoc build
ormkdoc serve
Expected behavior I can generate documentation also for classes that inherit from graphene types.
Since the library is already making assumptions about the existence of Django (and other metaprogramming frameworks), I think it would just suffice to produce a warning about this situation: if the _meta attribute has no 'get_fields' method, warn the user that IF they are using Django, there might be something wrong. Maybe just catch the AttributeError.
System (please complete the following information):
pytkdocs
version 0.15graphene
version 2.1.8Workaround I have a workaround, abusing
setup_commands
for the mkdocstrings "python" handler, in order to patch my Graphene objects. I assign a 'get_fields' method to graphene'sBaseOptions
class, which is instantiated as a '_meta' attribute for a lot of Graphene objects.How to patch: fix_mkdoc_for_graphene.py:
setup_commands in mkdoc.yml: