mansenfranzen / autodoc_pydantic Goto Github PK
View Code? Open in Web Editor NEWSeamlessly integrate pydantic models in your Sphinx documentation.
License: MIT License
Seamlessly integrate pydantic models in your Sphinx documentation.
License: MIT License
Hello! Wondering if i'm doing something wrong.
I have a model with typing.ClassVar
s to indicate class, rather than instance attributes:
eg:
from pydantic import BaseModel
from abc import ABC
from typing import ClassVar, Type
from PySide2 import QtWidgets
class Input(BaseModel, ABC):
"""
Metaclass to parametrically spawn a Qt Input widget for a given type.
"""
# class variables set by subtypes
widget: ClassVar[Type[QtWidgets.QWidget]] = None
This throws the following stack:
File "./autodoc_pydantic/directives/options/composites.py", line 259, in wrapped
result = func(*args, **kwargs)
File "./autodoc_pydantic/directives/autodocumenters.py", line 539, in add_directive_header
self.add_default_value_or_marker()
File "./autodoc_pydantic/directives/autodocumenters.py", line 586, in add_default_value_or_marker
if self.needs_required_marker:
File "./autodoc_pydantic/directives/autodocumenters.py", line 549, in needs_required_marker
is_required = self.pydantic.inspect.fields.is_required(field_name)
File "./autodoc_pydantic/inspection.py", line 188, in is_required
return self.get(field_name).required
File "./autodoc_pydantic/inspection.py", line 137, in get
return self.attribute[name]
KeyError: 'widget'
So it seems like it's being seen by the fields list, but not populated into the attributes dictionary? Not sure if this is a me thing, but if not lmk how I can help with a PR :)
invalid signature for autopydantic_model ('saf.collect.beacons::PipelineRunContext[BeaconsConfig]')
make: *** [Makefile:20: coverage] Error 2
class BeaconsConfig(CollectConfigBase):
"""
Configuration schema for the beacons collect plugin.
"""
beacons: List[str]
async def collect(*, ctx: PipelineRunContext[BeaconsConfig]) -> AsyncIterator[BeaconCollectedEvent]:
"""
Method called to collect events.
"""
PipelineRunContextConfigType = TypeVar("PipelineRunContextConfigType", bound=NonMutableConfig)
class PipelineRunContext(GenericModel, Generic[PipelineRunContextConfigType]):
"""
Class representing a pipeline run context.
"""
config: PipelineRunContextConfigType
Additional keyword arguments of fields automatically appear under constraints
even when they are not a constraint.
I use an additional keyword argument to specify whether the field will be created in the yaml file.
This argument is automatically documented as a constraint when it is more of a general field information.
From the pydantic docs:
It seems that these kwargs are indeed intended for other purposes.
Is the documentation under constraints
the intended behavior or is this something that is/was just out of scope?
I notice that this extension doesn't work with reused validators, i.e. Pydantic's Reuse validators section
from pydantic import BaseModel, validator
def normalize(name: str) -> str:
"""Normalize docstring."""
return ' '.join((word.capitalize()) for word in name.split(' '))
class Producer(BaseModel):
name: str
# validators
_normalize_name = validator('name', allow_reuse=True)(normalize)
class Consumer(BaseModel):
name: str
# validators
_normalize_name = validator('name', allow_reuse=True)(normalize)
jane_doe = Producer(name='JaNe DOE')
john_doe = Consumer(name='joHN dOe')
assert jane_doe.name == 'Jane Doe'
assert john_doe.name == 'John Doe'
It looks like there is a warning. Note that below is not exactly the above case but just slightly modified from the example I'm messing with:
docstring of example.Consumer.name:1: WARNING: py:obj reference target not found: example.Consumer.normalize
The only problem is the docs don't contain a link to that function.
EDIT: Added simple docstring to normalize
for later replies to make sense.
Hello Sir,
To be honest, I'm not sure whether or not this question belong in Jupyter-Book or here. I`m facing an issue, and in a hurry to solve it. I'm using Jupyter-Book to document a library for a client. I have some bakground material/examples which I have produced with markdown/python-code (.md and ipynb), and I have the "API reference" in the last chapter using an rst-file. All works fine, except when I tried using autodoc_pydantic. All pydantic models loose their styling. I.e if I have a module containing say a regular Exception, and another class derived from a Pydantic BaseModel, the Exception will turn out like your examples, but all pydantic models look pretty wierd. They get idented properly, and I can toogle JSON schema on/off in configs, but all styling such as the blue background on the signature is lost. Have tried both automodule and autopydantic_ with same results. Any idea what is going on?
Great project, btw :)
Very best,
Stig
Hi!
Thanks for this very nice tool! It's so nice, that I'm wondering if we can make it even more powerful :)
Would it be a challenge to render any sphinx markup in the description
attribute of a Field
?
I'd love to help, but afraid that I'm a bit low on free time for the next month or two.
Running Sphinx 4.1.1
and pydantic 1.8.2
.
Enabled extensions:
'sphinx.ext.autodoc',
'sphinxcontrib.autodoc_pydantic',
'sphinx.ext.viewcode',
'sphinx.ext.todo',
'sphinx.ext.napoleon',
'sphinx_autodoc_typehints'
Sample:
from pydantic import BaseModel
class TestClass:
"""Test
Attributes:
model (TestModel): Model
"""
def __init__(self):
self.model = TestModel()
class TestModel(BaseModel):
pass
The generated document will not have a hyperlink for the TestModel
data type reference. Removing the BaseModel
class from TestModel
renders the type references with hyperlinks again.
I cannot find a way to show all fields of a model if it subclasses another BaseModel.
class MyBase(BaseModel):
field_on_base: str
class MySubclass(MyBase):
field_on_subclass: str
When generate the model's docs with autopydantic_model
both field_on_base
and field_on_subclass
is shown in the field list however only the docstring of field_on_subclass
is shown.
.. currentmodule:: tests
.. autopydantic_model:: MySubclass
Currently PydanticUndefined
is shown if there is a default factory.
Source
habapp: HABAppConfig = Field(default_factory=HABAppConfig, in_file=False)
I think PydanticUndefined
is a bit misleading since the default is not undefined.
How about [has default]
(so it's the same as with [required]
) so it's clear that the field will have a default when created.
Possible output:
The CI builds for sphinx 3.4 are currently broken. This probably occurs to newer versions of unpinned dependencies (e.g. docutils). The actual error is of minor significance and does not impact correct behavior but still breaks the CI. This needs to be fixed.
Looks like autodoc_pydantic
causes autodoc
to ignore the autodoc_member_order
config value
autodoc_pydantic
the ordering falls back to the default (alphabetical)p.s.: Awesome plugin! I was looking for an alternative for my hacky workaround to hide pydantic model signatures and got so much more 😊
Hi! I've been lending a hand to contributing to Sphinx itself and discovered that my project no longer built on the upcoming release's branch. I bisected and reported this issue as sphinx-doc/sphinx#9832 and the wonderful Jakob Andersen has tracked the problem down to a change in signature for get_signature_prefix
(https://www.sphinx-doc.org/en/master/changes.html#id2), which is apparently overwritten by autodoc_pydantic.
His comment is here: sphinx-doc/sphinx#9832 (comment)
He's written a mitigation but the behaviour will still be broken, just with a clearer error message. The release is expected to come out in the next few days. Thought you'd want a heads up!
Custom extension directives need to be added explicitly via add_object_type
to be cross referenced.
Hi
First, my doc and I would like to thank you a lot for this great lib !
I face an issue : I'm using autosummary
to have a clean doc but using autodoc_pydantic seem not compatible with autosummary
.. currentmodule:: my_module
API Reference
=============
This page gives an overview of all public :mod:`my_module` objects, functions and methods.
all classes
+++++++++++
.. autosummary::
:toctree: temp
:nosignatures:
:inherited-members:
ForecastingConfig
the results is
While the results before using autodoc_pydantic
was :
Currently forks trigger the complete CI including code coverage reports. Due to security constraints, environment secrets are not available for foreign pull requests which leads to a failure in code coverage. Hence, code coverage should be excluded from the CI for foreign pull requests.
I did not find any licence terms within the project.
Consider adding some (what about MIT? BSD? - you are the author).
Thanks for your plugin - seems very practical and looks great.
One may show the nodel JSON schema within class doc string as a collapsable code block via :model-show-json:
. This depends on the model to be completely JSON serializable. However, users may provide custom fields that are not serializable by default. This breaks the schema generation.
Currently, this is handled by intercepting such non serializable fields and replacing their types and default values to indicate an error. This is rather implicit even though there is an explicit remark in the documentation.
To improve, let's make the error handling configureable, like autodoc_pydantic_model_show_json_error_handling
to be one of:
None
?) and provide warning in the sphinx output.When I generate the html for a my model none of the fields are populating.
The docs just generate something along the lines of:
pydantic model MyModel [source]
This is my doc string.
Show Json Schema
I'm generating the page with the
..automodule:: package.MyModel :members:
Am I supposed to have a setting marked for field population?
Thanks so much for this library! I've just discovered it.
autodoc_pydantic is crashing for me in inspection.py, where checking to see if "obj" is a subclass of "BaseModel"
All of the crashes are from checking various objects from numpy. The simplest reproducible example I found is:
import numpy as np
from numpy.typing import NDArray
>> issinstance(NDArray, type) # returns True
>> issubclass(NDArray, BaseModel) # throws TypeError
As a workaround, I edited the file to put a try/except in is_pydantic_model:
459 @staticmethod
460 def is_pydantic_model(obj: Any) -> bool:
461 """Determine if object is a valid pydantic model.
462
463 """
464 try:
465 if isinstance(obj, type):
466 return issubclass(obj, BaseModel)
467 except TypeError:
468 pass
469 return False
The fallback behavior of returning False seems to work.
pydantic uses Field(default = ...)
to indicate that a field is required (see docs).
Currently autodoc_pydantic
will output things like:
field name: str = Ellipsis
which can be a bit confusing. Perhaps it could instead output something like:
field name: str [Required]
In the following case
class Foo(pydantic.BaseModel):
'''Foo class'''
x: str = pydantic.Field(description='The x.')
class Bar(Foo):
'''Bar class'''
y: int = pydantic.Field(description='The y.')
is there a way to have the documentation for Bar
show both x
and y
as the fields?
Hey all, I've encountered exception while trying to generate a pydantic models documentation. I believe it is related to a combination of factors (most likely it is related to 'bysource' sorting and usage of pydantic model as a class field):
class DataTransformer:
"""Transformer"""
PARAMS_CLS = DataTransformerConfig # DataTransformerConfig is a pydantic model
conf.py settings:
autodoc_pydantic_model_show_json = True
autodoc_pydantic_model_show_config = False
autodoc_pydantic_model_show_config_summary = False
autodoc_pydantic_model_show_config_member = False
autodoc_pydantic_model_show_validator_summary = False
autodoc_pydantic_model_show_validator_members = False
autodoc_pydantic_model_summary_list_order = 'bysource' # exception disappears after commenting this line
autodoc_pydantic_model_member_order = 'bysource'
autodoc_pydantic_model_signature_prefix = ''
autodoc_pydantic_validator_list_fields = False
autodoc_pydantic_settings_show_config_summary = False
autodoc_pydantic_settings_show_config_member = False
autodoc_pydantic_field_list_validators = False
Probably there are other factors, so 've put the complete code base to github: https://github.com/nchaly/autodoc-pydantic-
bug
Versions installed:
Build command: sphinx-build -b html docs docs/_build/html -a -E -T
Sphinx trace file:
# Sphinx version: 4.3.0
# Python version: 3.9.7 (CPython)
# Docutils version: 0.16 release
# Jinja2 version: 3.0.3
# Last messages:
# updating environment:
# [new config]
# 4 added, 0 changed, 0 removed
# reading sources... [ 25%] index
# reading sources... [ 50%] pages/generated_refs/app
# reading sources... [ 75%] pages/generated_refs/app.data_module
#
# ====================== slowest reading durations =======================
# 0.020 index
# 0.009 pages/generated_refs/app
# Loaded extensions:
# sphinx.ext.mathjax (4.3.0) from /usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/mathjax.py
# sphinxcontrib.applehelp (1.0.2) from /usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinxcontrib/applehelp/__init__.py
# sphinxcontrib.devhelp (1.0.2) from /usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinxcontrib/devhelp/__init__.py
# sphinxcontrib.htmlhelp (2.0.0) from /usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinxcontrib/htmlhelp/__init__.py
# sphinxcontrib.serializinghtml (1.1.5) from /usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinxcontrib/serializinghtml/__init__.py
# sphinxcontrib.qthelp (1.0.3) from /usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinxcontrib/qthelp/__init__.py
# alabaster (0.7.12) from /usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/alabaster/__init__.py
# sphinx.ext.doctest (4.3.0) from /usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/doctest.py
# sphinx.ext.autodoc.preserve_defaults (1.0) from /usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/autodoc/preserve_defaults.py
# sphinx.ext.autodoc.type_comment (4.3.0) from /usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/autodoc/type_comment.py
# sphinx.ext.autodoc (4.3.0) from /usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py
# sphinx.ext.autosummary (4.3.0) from /usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/autosummary/__init__.py
# sphinx.ext.napoleon (4.3.0) from /usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/napoleon/__init__.py
# sphinxcontrib.autodoc_pydantic (1.5.1) from /usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/__init__.py
Traceback (most recent call last):
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/cmd/build.py", line 280, in build_main
app.build(args.force_all, filenames)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/application.py", line 338, in build
self.builder.build_all()
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 258, in build_all
self.build(None, summary=__('all source files'), method='all')
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 308, in build
updated_docnames = set(self.read())
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 415, in read
self._read_serial(docnames)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 436, in _read_serial
self.read_doc(docname)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 476, in read_doc
doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/io.py", line 189, in read_doc
pub.publish()
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/core.py", line 217, in publish
self.document = self.reader.read(self.source, self.parser,
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/io.py", line 109, in read
self.parse()
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/readers/__init__.py", line 77, in parse
self.parser.parse(self.input, document)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/parsers.py", line 101, in parse
self.statemachine.run(inputlines, document, inliner=self.inliner)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 170, in run
results = StateMachineWS.run(self, input_lines, input_offset,
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/statemachine.py", line 241, in run
context, next_state, result = self.check_line(
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/statemachine.py", line 459, in check_line
return method(match, context, next_state)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2769, in underline
self.section(title, source, style, lineno - 1, messages)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 393, in new_subsection
newabsoffset = self.nested_parse(
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
state_machine.run(block, input_offset, memo=self.memo,
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/statemachine.py", line 241, in run
context, next_state, result = self.check_line(
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/statemachine.py", line 459, in check_line
return method(match, context, next_state)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2342, in explicit_markup
nodelist, blank_finish = self.explicit_construct(match)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2354, in explicit_construct
return method(self, expmatch)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2096, in directive
return self.run_directive(
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2146, in run_directive
result = directive_instance.run()
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/autodoc/directive.py", line 162, in run
documenter.generate(more_content=self.content)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py", line 984, in generate
self.document_members(all_members)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py", line 860, in document_members
documenter.generate(
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py", line 1774, in generate
return super().generate(more_content=more_content,
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py", line 984, in generate
self.document_members(all_members)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py", line 1765, in document_members
super().document_members(all_members)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py", line 860, in document_members
documenter.generate(
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py", line 1774, in generate
return super().generate(more_content=more_content,
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py", line 981, in generate
self.add_content(more_content)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py", line 201, in add_content
self.add_field_summary()
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py", line 300, in add_field_summary
sorted_fields = self._sort_summary_list(filtered_fields)
File "/usr/local/Caskroom/miniconda/base/envs/logml/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py", line 333, in _sort_summary_list
return sorted(names, key=sort_func)
TypeError: '<' not supported between instances of 'NoneType' and 'NoneType'
Initial setup for adding contributors via all-contributors bot.
Currently 3 tests fail with pydantic 1.9 release half an hour ago. Those tests do not seem critical however should be fixed anyway.
When using the .. currentmodule::
directive in conjunction with autopydantic_model
and certain options like :model-show-validator-members: False
raise a value error:
.. py:currentmodule:: target.example_autosummary
.. autopydantic_model:: AutoSummaryModel
:model-show-validator-members: False
This occurs because autodoc_pydantic uses a custom method to locate objects. Instead, it should rely on autdoc's object import methods.
I usually browse https://github.com/topics/sphinx-extension to discover new extensions, would be great to have this extension listed there :)
autodoc_pydantic failing builds without much information or which model is causing the issue.
Exception occurred:
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/inspection.py", line 352, in __init__
self.attribute: Dict = self.model.Config
AttributeError: 'NoneType' object has no attribute 'Config'
# Sphinx version: 4.5.0
# Python version: 3.9.12 (CPython)
# Docutils version: 0.17.1 release
# Jinja2 version: 3.1.2
# Last messages:
...
# Loaded extensions:
# sphinx.ext.mathjax (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/mathjax.py
# sphinxcontrib.applehelp (1.0.2) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/applehelp/__init__.py
# sphinxcontrib.devhelp (1.0.2) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/devhelp/__init__.py
# sphinxcontrib.htmlhelp (2.0.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/htmlhelp/__init__.py
# sphinxcontrib.serializinghtml (1.1.5) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/serializinghtml/__init__.py
# sphinxcontrib.qthelp (1.0.3) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/qthelp/__init__.py
# alabaster (0.7.12) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/alabaster/__init__.py
# sphinx.ext.autodoc.preserve_defaults (1.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/autodoc/preserve_defaults.py
# sphinx.ext.autodoc.type_comment (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/autodoc/type_comment.py
# sphinx.ext.autodoc (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py
# sphinx.ext.intersphinx (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/intersphinx.py
# sphinx.ext.todo (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/todo.py
# sphinx.ext.autosummary (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/autosummary/__init__.py
# sphinx.ext.viewcode (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/viewcode.py
# sphinx.ext.coverage (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/coverage.py
# sphinx.ext.doctest (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/doctest.py
# sphinx.ext.ifconfig (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/ifconfig.py
# sphinx.ext.napoleon (4.5.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/napoleon/__init__.py
# sphinx_rtd_theme (unknown version) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx_rtd_theme/__init__.py
# nbsphinx (0.8.8) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/nbsphinx.py
# sphinxcontrib.autodoc_pydantic (1.7.0) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/__init__.py
# recommonmark (0.7.1) from /home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/recommonmark/__init__.py
Traceback (most recent call last):
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/cmd/build.py", line 276, in build_main
app.build(args.force_all, filenames)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/application.py", line 330, in build
self.builder.build_update()
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 286, in build_update
self.build(to_build,
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 300, in build
updated_docnames = set(self.read())
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 407, in read
self._read_serial(docnames)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 428, in _read_serial
self.read_doc(docname)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 468, in read_doc
doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/io.py", line 181, in read_doc
pub.publish()
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/core.py", line 217, in publish
self.document = self.reader.read(self.source, self.parser,
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/io.py", line 101, in read
self.parse()
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/readers/__init__.py", line 78, in parse
self.parser.parse(self.input, document)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/parsers.py", line 89, in parse
self.statemachine.run(inputlines, document, inliner=self.inliner)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 170, in run
results = StateMachineWS.run(self, input_lines, input_offset,
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 239, in run
context, next_state, result = self.check_line(
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2769, in underline
self.section(title, source, style, lineno - 1, messages)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 393, in new_subsection
newabsoffset = self.nested_parse(
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
state_machine.run(block, input_offset, memo=self.memo,
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 239, in run
context, next_state, result = self.check_line(
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2769, in underline
self.section(title, source, style, lineno - 1, messages)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 393, in new_subsection
newabsoffset = self.nested_parse(
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
state_machine.run(block, input_offset, memo=self.memo,
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 239, in run
context, next_state, result = self.check_line(
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2342, in explicit_markup
nodelist, blank_finish = self.explicit_construct(match)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2354, in explicit_construct
return method(self, expmatch)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2096, in directive
return self.run_directive(
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2146, in run_directive
result = directive_instance.run()
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/autodoc/directive.py", line 165, in run
result = parse_generated_content(self.state, params.result, documenter)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/ext/autodoc/directive.py", line 108, in parse_generated_content
nested_parse_with_titles(state, content, node)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/util/nodes.py", line 340, in nested_parse_with_titles
return state.nested_parse(content, 0, node, match_titles=1)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
state_machine.run(block, input_offset, memo=self.memo,
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 239, in run
context, next_state, result = self.check_line(
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2342, in explicit_markup
nodelist, blank_finish = self.explicit_construct(match)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2354, in explicit_construct
return method(self, expmatch)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2096, in directive
return self.run_directive(
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2146, in run_directive
result = directive_instance.run()
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/domains/__init__.py", line 281, in run
return super().run()
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/directives/__init__.py", line 200, in run
self.state.nested_parse(self.content, self.content_offset, contentnode)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
state_machine.run(block, input_offset, memo=self.memo,
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 239, in run
context, next_state, result = self.check_line(
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2344, in explicit_markup
self.explicit_list(blank_finish)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2369, in explicit_list
newline_offset, blank_finish = self.nested_list_parse(
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 318, in nested_list_parse
state_machine.run(block, input_offset, memo=self.memo,
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 239, in run
context, next_state, result = self.check_line(
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2647, in explicit_markup
nodelist, blank_finish = self.explicit_construct(match)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2354, in explicit_construct
return method(self, expmatch)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2096, in directive
return self.run_directive(
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2146, in run_directive
result = directive_instance.run()
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/domains/__init__.py", line 281, in run
return super().run()
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinx/directives/__init__.py", line 181, in run
name = self.handle_signature(sig, signode)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/directives/directives.py", line 266, in handle_signature
self.replace_return_node(signode)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/directives/directives.py", line 247, in replace_return_node
inspector = ModelInspector.from_signode(signode)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/inspection.py", line 547, in from_signode
return cls(model)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/inspection.py", line 533, in __init__
self.config = ConfigInspector(self)
File "/home/jhewers/Documents/projects/jpdmgen/.tox/docs/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/inspection.py", line 352, in __init__
self.attribute: Dict = self.model.Config
AttributeError: 'NoneType' object has no attribute 'Config'
Hi,
I have a pydantic model where a field is defined as myvalue:Optional[float]
, this renders as Optional[float] [Required]
in my docs. The json schema does not list it as a required field either. Ref this section of the docs .
Another small issue I have is how to deal with derived models. (Might be in the docs, but could not find it) Ex:
class IdBase(BaseModel):
id:int
name:str
class MyOtherModels(IdBase):
somefield:float
I have a few of these that resemble tables in a relational db. MyOtherModels
does not include the fields id,name
in the docs using automodule. As id
is a primary key in the db, the field is kind of important :) Any guidance on how to solve this?
Btw, using directive :inherited-members:
does include the fields, but introduces a lot of noise int the docs. (classmethods etc from pydantic)
I'm loading the application configuration from a yaml file and want to use autodoc-pydantic to document the available settings.
It's really great that there are so many configuration options so everything can be tailored to ones needs.
However I'm missing one more thing:
Since I load from file I load the corresponding values by alias and not by name.
Would it be possible to add a configuration option which shows the alias instead of the field name?
My users have to enter the alias in the configuration file - the field name is of no use for them and might be confusing.
Example:
class General(BaseModel):
listen_only: bool = Field(False, alias='listen only')
Valid entry in yaml file
listen only: True
for code:
Node = ForwardRef('Node')
class Node(BaseModel):
left: Union[Node, Leaf]
op: str
right: Union[Node, Leaf]
there was warning /home/czaki/Projekty/PartSeg/docs/autodoc_pydantic.rst: WARNING: JSON schema can't be generated for 'PartSegCore.analysis.measurement_base.Node' because the following pydantic fields can't be serialized properly: ['left', 'right'].
in this code
autodoc_pydantic/sphinxcontrib/autodoc_pydantic/inspection.py
Lines 183 to 189 in 36ffae3
there is no check for sub_fields
:
https://github.com/samuelcolvin/pydantic/blob/fbf8002cefd1ba7b263f63545fff2e48a378189d/pydantic/typing.py#L445-L458
in my case field.type_
is typing.Union[ForwardRef('Node'), PartSegCore.analysis.measurement_base.Leaf]
but field.sub_fields
is [ModelField(name="left_ForwardRef('Node')", type=Node, required=True), ModelField(name='left_Leaf', type=Leaf, required=True)]
So all data are available in data structures.
Full error trace:
# Sphinx version: 5.0.0
# Python version: 3.8.13 (CPython)
# Docutils version: 0.17.1 release
# Jinja2 version: 3.1.2
# Last messages:
# reading sources... [ 50%] reference/app.crud.crud_role
# reading sources... [ 51%] reference/app.crud.crud_team
# reading sources... [ 53%] reference/app.crud.crud_user
# reading sources... [ 54%] reference/app.db
# reading sources... [ 56%] reference/app.db.init_db
# reading sources... [ 57%] reference/app.db.session
# reading sources... [ 59%] reference/app.initial_data
# reading sources... [ 60%] reference/app.main
# reading sources... [ 62%] reference/app.models
# reading sources... [ 63%] reference/app.models.group
# Loaded extensions:
# sphinx.ext.mathjax (5.0.0) from /Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/ext/mathjax.py
# sphinxcontrib.applehelp (1.0.2) from /Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinxcontrib/applehelp/__init__.py
# sphinxcontrib.devhelp (1.0.2) from /Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinxcontrib/devhelp/__init__.py
# sphinxcontrib.htmlhelp (2.0.0) from /Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinxcontrib/htmlhelp/__init__.py
# sphinxcontrib.serializinghtml (1.1.5) from /Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinxcontrib/serializinghtml/__init__.py
# sphinxcontrib.qthelp (1.0.3) from /Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinxcontrib/qthelp/__init__.py
# alabaster (0.7.12) from /Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/alabaster/__init__.py
# sphinx.ext.todo (5.0.0) from /Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/ext/todo.py
# sphinx.ext.viewcode (5.0.0) from /Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/ext/viewcode.py
# sphinx.ext.autodoc.preserve_defaults (1.0) from /Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/ext/autodoc/preserve_defaults.py
# sphinx.ext.autodoc.type_comment (5.0.0) from /Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/ext/autodoc/type_comment.py
# sphinx.ext.autodoc (5.0.0) from /Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py
# sphinx.ext.napoleon (5.0.0) from /Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/ext/napoleon/__init__.py
# sphinxcontrib.apidoc (0.3.0) from /Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinxcontrib/apidoc/__init__.py
# sphinxcontrib.autodoc_pydantic (1.7.1) from /Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinxcontrib/autodoc_pydantic/__init__.py
Traceback (most recent call last):
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/cmd/build.py", line 276, in build_main
app.build(args.force_all, filenames)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/application.py", line 329, in build
self.builder.build_update()
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 288, in build_update
self.build(to_build,
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 302, in build
updated_docnames = set(self.read())
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 409, in read
self._read_serial(docnames)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 430, in _read_serial
self.read_doc(docname)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 483, in read_doc
publisher.publish()
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/core.py", line 217, in publish
self.document = self.reader.read(self.source, self.parser,
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/io.py", line 103, in read
self.parse()
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/readers/__init__.py", line 78, in parse
self.parser.parse(self.input, document)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/parsers.py", line 78, in parse
self.statemachine.run(inputlines, document, inliner=self.inliner)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 170, in run
results = StateMachineWS.run(self, input_lines, input_offset,
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/statemachine.py", line 239, in run
context, next_state, result = self.check_line(
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2769, in underline
self.section(title, source, style, lineno - 1, messages)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 393, in new_subsection
newabsoffset = self.nested_parse(
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
state_machine.run(block, input_offset, memo=self.memo,
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/statemachine.py", line 239, in run
context, next_state, result = self.check_line(
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2342, in explicit_markup
nodelist, blank_finish = self.explicit_construct(match)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2354, in explicit_construct
return method(self, expmatch)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2096, in directive
return self.run_directive(
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2146, in run_directive
result = directive_instance.run()
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/ext/autodoc/directive.py", line 148, in run
documenter.generate(more_content=self.content)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 955, in generate
self.document_members(all_members)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 831, in document_members
documenter.generate(
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 1788, in generate
return super().generate(more_content=more_content,
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 955, in generate
self.document_members(all_members)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py", line 164, in document_members
super().document_members(*args, **kwargs)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 1779, in document_members
super().document_members(all_members)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 831, in document_members
documenter.generate(
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 945, in generate
self.add_directive_header(sig)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinxcontrib/autodoc_pydantic/directives/options/composites.py", line 259, in wrapped
result = func(*args, **kwargs)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py", line 539, in add_directive_header
self.add_default_value_or_marker()
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py", line 586, in add_default_value_or_marker
if self.needs_required_marker:
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py", line 549, in needs_required_marker
is_required = self.pydantic.inspect.fields.is_required(field_name)
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinxcontrib/autodoc_pydantic/inspection.py", line 188, in is_required
return self.get(field_name).required
File "/Users/pipeknight/.pyenv/versions/3.8.13/lib/python3.8/site-packages/sphinxcontrib/autodoc_pydantic/inspection.py", line 137, in get
return self.attribute[name]
KeyError: 'created_by'
My conf file:
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
import os
import sys
# Also we may load a dotenv file here
sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'fastapi-alembic-sqlmodel-async'
copyright = '2022, -'
author = '-'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.todo',
'sphinx.ext.viewcode',
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinxcontrib.apidoc',
'sphinxcontrib.autodoc_pydantic',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# Apidoc options
apidoc_module_dir = '../fastapi-alembic-sqlmodel-async'
apidoc_output_dir = 'reference'
apidoc_excluded_paths = ['tests', 'kafka_test']
apidoc_separate_modules = True
# apidoc_extra_args = ['-d 2']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'alabaster'
# html_theme = 'sphinx-rtd-theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
I have several models in my app with field named created_by
, for example:
from sqlmodel import Field, Relationship, SQLModel
class Group(SQLModel, table=True):
id: Optional[int] = Field(default=None, nullable=False, primary_key=True)
updated_at: Optional[datetime]
created_at: Optional[datetime]
created_by_id: Optional[UUID] = Field(default=None, foreign_key="user.id")
created_by: "User" = Relationship( # noqa: F821
sa_relationship_kwargs={
"lazy": "select",
"primaryjoin": "Group.created_by_id==User.id",
}
)
And for some reason this broke my docs generation. If I comment 'sphinxcontrib.autodoc_pydantic'
in conf.py
extensions, than everything works
The documentation's FAQ section should contain a link to its original github issue to provide more information if needed.
When using autodoc_pydantic with the just-released Sphinix v5.0.0, we get a TypeError:
File "/home/redacted/.venv/lib/python3.8/site-packages/sphinxcontrib/autodoc_pydantic/directives/autodocumenters.py", line 205, in add_content
super().add_content(more_content, no_docstring)
TypeError: add_content() takes 2 positional arguments but 3 were given
This appears to be changed in sphinx's autodoc extension here: sphinx-doc/sphinx@267954e#diff-e43bdd6f8f37a12d2536e09e57c5e8999cb8de18b9c7ba49126f90576c4328acR2666
It seems that autodoc_pydantic
will also need to adjust accordingly.
When using Arbitrary type we cannot serialize to a JSON Schema.
Work
PandasDataFrame = TypeVar('pd.DataFrame')
class Model(BaseModel):
pandasDF: PandasDataFrame
Doesnot work
class Model(BaseModel):
pandasDF: pd.DataFrame
class Config:
arbitrary_types_allowed = True # pd.DataFrame allowed
Following error is raised when building the docs:
ValueError: Value not declarable with JSON Schema, field: name='inputs_DataFrame' type=DataFrame required=True
Hi there,
I have a Pydantic class that inherits another Pydantic class that allows for custom handling of function serialization:
class ConfigModel(BaseModel):
class Config:
extra = Extra.forbid
use_enum_values = True
json_encoders = {
Callable: lambda fn: ".".join(
[fn.__module__, fn.__name__]
),
FunctionType: lambda fn: ".".join(
[fn.__module__, fn.__name__]
),
}
class TextConfig(ConfigModel):
symbols: Symbols = Field(default_factory=Symbols)
cleaners: List[Callable] = [lower, collapse_whitespace, nfc_normalize]
def __init__(self, **data) -> None:
"""Custom init to process cleaners"""
with contextlib.suppress(KeyError):
cleaners = data["cleaners"]
for i, c in enumerate(cleaners):
cleaners[i] = string_to_callable(c)
super().__init__(**data)
With this configuration, I can do the following:
>>> tc = TextConfig()
>>> tc.json()
'{"symbols": {"silence": ["<SIL>"], "pad": "_", "punctuation": "-\';:,.!?\\u00a1\\u00bf\\u2014\\u2026\\"\\u00ab\\u00bb\\u201c\\u201d "}, "cleaners": ["smts.utils.lower", "smts.utils.collapse_whitespace", "smts.utils.nfc_normalize"]}'
But when I try to autodoc TextConfig, I get the following:
Exception occurred:
File "pydantic/json.py", line 90, in pydantic.json.pydantic_encoder
TypeError: Object of type 'function' is not JSON serializable
The full traceback has been saved in /home/aip000/aip000/tmp/sphinx-err-u13_waob.log, if you want to report the issue to the developers.
There are ways to ignore this seemingly, but how can I get autodoc_pydantic to just use the models json serialization?
I am using pydantic.dataclasses.dataclass
because I need the __post_init__
dunder. However, I noticed that automodule does not generate the pydantic model documentation for these data classes. Looking at pydantic's docs, I can access the model using __pydantic_model__
, but I'm not sure how to get this to happen automatically with automodule
?
Hi,
I have encountered a simmilar issue as discussed in #78.
My Pydantic models have fields with type of other Pydantic models, and when using autodoc_pydantic_model_summary_list_order = 'bysource'
I still seem to get the same error.
Is there any other way to find the exact model that fails, except for the elimination method?
I am not sure what more should be provided to find my edge case, but here is the Sphinx traceback:
# Sphinx version: 5.1.1
# Python version: 3.6.8 (CPython)
# Docutils version: 0.17.1 release
# Jinja2 version: 3.0.3
# Last messages:
# reading sources... [ 56%] index
#
# reading sources... [ 62%] reference/api
#
# Loaded extensions:
# sphinx.ext.mathjax (5.1.1) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\mathjax.py
# sphinxcontrib.applehelp (1.0.2) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\applehelp\__init__.py
# sphinxcontrib.devhelp (1.0.2) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\devhelp\__init__.py
# sphinxcontrib.htmlhelp (2.0.0) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\htmlhelp\__init__.py
# sphinxcontrib.serializinghtml (1.1.5) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\serializinghtml\__init__.py
# sphinxcontrib.qthelp (1.0.3) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\qthelp\__init__.py
# alabaster (0.7.12) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\alabaster\__init__.py
# sphinx.ext.autodoc.preserve_defaults (1.0) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\preserve_defaults.py
# sphinx.ext.autodoc.type_comment (5.1.1) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\type_comment.py
# sphinx.ext.autodoc (5.1.1) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\__init__.py
# sphinx.ext.intersphinx (5.1.1) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\intersphinx.py
# sphinx_autodoc_typehints (unknown version) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx_autodoc_typehints.py
# sphinx_click (unknown version) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx_click\__init__.py
# sphinx_rtd_dark_mode (1.2.4) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx_rtd_dark_mode\__init__.py
# sphinxcontrib.autodoc_pydantic (1.7.2) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\autodoc_pydantic\__init__.py
# sphinx_rtd_theme (unknown version) from C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx_rtd_theme\__init__.py
Traceback (most recent call last):
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\cmd\build.py", line 277, in build_main
app.build(args.force_all, filenames)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\application.py", line 349, in build
self.builder.build_update()
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\builders\__init__.py", line 303, in build_update
len(to_build))
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\builders\__init__.py", line 317, in build
updated_docnames = set(self.read())
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\builders\__init__.py", line 424, in read
self._read_serial(docnames)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\builders\__init__.py", line 445, in _read_serial
self.read_doc(docname)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\builders\__init__.py", line 498, in read_doc
publisher.publish()
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\core.py", line 218, in publish
self.settings)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\io.py", line 104, in read
self.parse()
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\readers\__init__.py", line 78, in parse
self.parser.parse(self.input, document)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\parsers.py", line 78, in parse
self.statemachine.run(inputlines, document, inliner=self.inliner)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 171, in run
input_source=document['source'])
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 240, in run
context, state, transitions)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 3008, in text
self.section(title.lstrip(), source, style, lineno + 1, messages)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 395, in new_subsection
node=section_node, match_titles=True)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 282, in nested_parse
node=node, match_titles=match_titles)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 240, in run
context, state, transitions)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 3008, in text
self.section(title.lstrip(), source, style, lineno + 1, messages)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 395, in new_subsection
node=section_node, match_titles=True)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 282, in nested_parse
node=node, match_titles=match_titles)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 240, in run
context, state, transitions)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 2769, in underline
self.section(title, source, style, lineno - 1, messages)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 395, in new_subsection
node=section_node, match_titles=True)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 282, in nested_parse
node=node, match_titles=match_titles)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 240, in run
context, state, transitions)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 2769, in underline
self.section(title, source, style, lineno - 1, messages)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 395, in new_subsection
node=section_node, match_titles=True)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 282, in nested_parse
node=node, match_titles=match_titles)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 240, in run
context, state, transitions)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 2342, in explicit_markup
nodelist, blank_finish = self.explicit_construct(match)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 2354, in explicit_construct
return method(self, expmatch)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 2097, in directive
directive_class, match, type_name, option_presets)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\docutils\parsers\rst\states.py", line 2146, in run_directive
result = directive_instance.run()
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\directive.py", line 148, in run
documenter.generate(more_content=self.content)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 954, in generate
self.document_members(all_members)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 832, in document_members
check_module=members_check_module and not isattr)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 1790, in generate
all_members=all_members)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 951, in generate
self.add_content(more_content)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\autodoc_pydantic\directives\autodocumenters.py", line 221, in add_content
self.add_validators_summary()
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\autodoc_pydantic\directives\autodocumenters.py", line 344, in add_validators_summary
sorted_references = self._get_validator_summary_references()
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\autodoc_pydantic\directives\autodocumenters.py", line 316, in _get_validator_summary_references
sort_func = self._get_reference_sort_func()
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\autodoc_pydantic\directives\autodocumenters.py", line 295, in _get_reference_sort_func
idx_fields = self._get_idx_mappings(all_fields)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\autodoc_pydantic\directives\autodocumenters.py", line 280, in _get_idx_mappings
sorted_members = self._sort_summary_list(members)
File "C:\venvs\poetry\virtualenvs\prog-vnI5qaYb-py3.6\lib\site-packages\sphinxcontrib\autodoc_pydantic\directives\autodocumenters.py", line 405, in _sort_summary_list
return sorted(names, key=sort_func)
TypeError: '<' not supported between instances of 'NoneType' and 'NoneType'
Hello.
I have a sphinx with read the docs theme. When I generate documentation for my pydantic models I get a different font in the toctree for my models.
The .rst file
config_reader.py
~~~~~~~~~~~~~~~~~~~
.. automodule:: mstlv_package.config_reader
:members:
How do I configure to keep the font of RTD theme?
Thanks for creating this package, @mansenfranzen -- it's the missing link between the self-documenting objects of Pydantic and, well, actual documentation!
However, I'm not sure I've set it up correctly. Might you know why the class docstrings I'm getting have the Pydantic BaseModel docstring attached? e.g. here: https://psiresp.readthedocs.io/en/latest/_autosummary/psiresp.job.Job.html#psiresp.job.Job
If you look at the source, it includes the first part only:
https://psiresp.readthedocs.io/en/latest/_modules/psiresp/job.html#Job
Is it because I'm using autosummary
instead of autopydantic_model
or similar?
I have the following MRE:
'''Blah module'''
import typing
import pydantic
class Foo:
'''Foo class'''
class Bar(pydantic.BaseModel):
'''Bar class'''
x: str = pydantic.Field(description='The x.')
@pydantic.validator('x')
def do_nothing(cls, value: typing.Any) -> typing.Any:
return value
In my .rst file, I have
.. automodule:: blah.blah
:members:
make html
produces
File ".../autodoc_pydantic/inspection.py", line 352, in __init__
self.attribute: Dict = self.model.Config
AttributeError: type object 'Foo' has no attribute 'Config'
So, autodoc_pydantic
has somehow been led to believe that Foo
is a pydantic.BaseModel
. What's interesting is, if I remove the validator, then the error goes away.
I'm using Python 3.8.10 and autodoc_pydantic 1.7.1.
this looks like a great package!
I was just looking at the documentation and when you hit "source":
it behaves as expected taking you to the source code... but then when you hit the equivalent "docs" link to go back:
it takes you to the "Usage" section rather than the "Examples" section you came from:
otherwise looks great - can't wait to use it in my next package
I'm not fully initiated into sphinx so some terms may be slightly off so bear with me :)
I have a project that uses sphinx autoapi to build some rst files from code for docs. I figured adding sphinxcontrib.autodoc_pydantic" as an extension in conf.py would be enough to get the description from pydantic fields in the documentation... but alas it doesn't seem to make a difference.
Does this generally work with projects that generate docs via autoapi?
In my conf.py:
..
extensions = [
"autoapi.extension",
"sphinxcontrib.autodoc_pydantic",
"sphinx_rtd_theme",
]
...
html_theme = "sphinx_rtd_theme"
autoapi_type = "python"
autoapi_dirs = ["../src"]
autoapi_keep_files = True
autoapi_python_class_content = 'both'
autoapi_options = ['members', 'undoc-members', 'show-inheritance', 'show-module-summary', 'special-members', 'imported-members']
Hi! Thanks for this package, I love the results it produces!
I've been experimenting with ways to fully automate the generation of API reference documentation from source code and docstrings, a la rustdoc. I know you're aware of this, but there's no easy way to include autodoc_pydantic
output in a fully automated API reference.
The following works, of course:
.. autosummary::
:toctree: _autosummary
module_with_lots_of_stuff.AutoSummaryModel
module_with_lots_of_stuff.AutoSummarySettings
module_with_lots_of_stuff.another_module
But I would like the following:
.. autosummary::
:toctree: _autosummary
:recursive:
module_with_lots_of_stuff
I understand that the reason this doesn't work is that Sphinx doesn't let you expose new variables to the autosummary templates (as you discuss in #11). I've worked around this to some extent in the project I'm working on by adding an autosummary table with all the members not documented elsewhere in the template to the end of the module template, but it's not very good and we probably won't end up using it.
My suggestion would be to workaround the bug in Sphinx by adding a Jinja2 filter along the lines of "keep_pydantic_models" that takes an iterator of names of objects and filters out those that aren't models. So a block like the following could be added to an Autosummary template:
{% set models = members | keep_pydantic_models(module=fullname) | list %}
{% if models %}
Models
---------
{% for item in models %}
.. autopydantic_model:: item
{% endfor %}
I think you should be able to add such a filter to all templates, but I'm not super familiar. Sorry if this isn't helpful.
Thanks!
In the last few releases, autodoc has added two settings to conf.py
that are very useful:
autodoc_preserve_defaults
: Preserves default argument values as they are in code, rather than evaluating themautodoc_typehints_format
: Suppresses the module names of type hintsBy turning each of these on, a field signature could be transformed from something like this:
target_templates: List[Union[openff.bespokefit.schema.targets.TorsionProfileTargetSchema, openff.bespokefit.schema.targets.AbInitioTargetSchema, openff.bespokefit.schema.targets.VibrationTargetSchema, openff.bespokefit.schema.targets.OptGeoTargetSchema]] = [TorsionProfileTargetSchema(weight=1.0, reference_data=None, extras={}, type='TorsionProfile', attenuate_weights=True, energy_denominator=1.0, energy_cutoff=10.0)]
to
target_templates: List[Union[TorsionProfileTargetSchema, AbInitioTargetSchema, VibrationTargetSchema, OptGeoTargetSchema]] = [TorsionProfileTargetSchema()]
Which is much less intimidating and easier to read.
It would be amazing if autodoc_pydantic could support these options in pydantic models etc.
Hello! Thank you for the great work.
I was wondering if you were planning on adding support for documenting root validators, like you do field validators.
I load a str
from a yaml file and convert it into a path object.
It's possible to change certain paths so e.g. logfiles get generated in a different folder.
Currently this
logging: Path = Field(Path('log'), description='Folder where the logs will be written to')
renders like that
field logging: Optional[pathlib.Path] = WindowsPath('log')
However since the user is editing a yaml file I'd like to process both the type and the default value to be a string.
E.g. so it looks like that.
field logging: Optional[str] = 'log'
I'm aware that this is a rather special use case.
So how about a configurable callback that gets inserted here.
The callback would get the PydanticFieldDocumenter
and the default
passed in. If it returns a string that's the value for documentation, otherwise object_description
would be called.
For the type I have not yet found the code part where it happens - could you provide me with a hint?
What do you think? Is this something where I can create a PR and you see it getting merged or do you have a better idea how this can achieved?
Thank you for your help!
Currently, the varying versions to be tested (e.g. python, sphinx, pydantic) are completely defined within github actions yaml. To support local and other remote CI/CD pipelines, move the version definitions and test environment execution into tox.
Sphinx 4.0 was released just today. autodoc_pydantic should work with newest sphinx version. Additionally, the dependency on myst-parser is really not required since it is only used to convert the changelog, written in markdown, to reST. Instead, the changelog can be written in reST right away.
Since autosummary is currently not very well suited for custom autodocumenters (see #11), its functionality can't be properly used. Hence, it would make sense to provide a autosummary-like table of contents for largish models/settings to get a brief overview of all existing fields and validators instead of scrolling all over the page.
Ideally it would be possible to reuse some of the existing autosummary codebase. The new configuration could be called model-show-autosummary
or something similar.
Hello all,
I really appreciate this Sphinx extension, but recently I've been running into some issues getting my docs to build. Would appreciate any guidance on what may be going on—from the traceback, it seems like my installation is getting tripped up trying to parse root validators. I tested a few versions of autodoc_pydantic
, and it seems to appear in ≥ v.1.3
Here's the full traceback that Sphinx provided:
# Sphinx version: 4.2.0
# Python version: 3.9.7 (CPython)
# Docutils version: 0.17.1 release
# Jinja2 version: 3.0.1
# Last messages:
# failed: <lambda>() missing 1 required positional argument: 'aliased'
# building [mo]: targets for 0 po files that are out of date
# building [html]: targets for 14 source files that are out of date
# updating environment:
# [new config]
# 14 added, 0 changed, 0 removed
# reading sources... [ 7%] index
# reading sources... [ 14%] modules
# reading sources... [ 21%] nmt
# reading sources... [ 28%] nmt.common
# Loaded extensions:
# sphinx.ext.mathjax (4.2.0) from /opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/ext/mathjax.py
# sphinxcontrib.applehelp (1.0.2) from /opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinxcontrib/applehelp/__init__.py
# sphinxcontrib.devhelp (1.0.2) from /opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinxcontrib/devhelp/__init__.py
# sphinxcontrib.htmlhelp (2.0.0) from /opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinxcontrib/htmlhelp/__init__.py
# sphinxcontrib.serializinghtml (1.1.5) from /opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinxcontrib/serializinghtml/__init__.py
# sphinxcontrib.qthelp (1.0.3) from /opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinxcontrib/qthelp/__init__.py
# alabaster (0.7.12) from /opt/miniconda3/envs/nmt/lib/python3.9/site-packages/alabaster/__init__.py
# sphinx.ext.autodoc.preserve_defaults (1.0) from /opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/ext/autodoc/preserve_defaults.py
# sphinx.ext.autodoc.type_comment (4.2.0) from /opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/ext/autodoc/type_comment.py
# sphinx.ext.autodoc (4.2.0) from /opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py
# sphinx.ext.graphviz (4.2.0) from /opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/ext/graphviz.py
# sphinx.ext.imgmath (4.2.0) from /opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/ext/imgmath.py
# sphinxcontrib.napoleon (0.7) from /opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinxcontrib/napoleon/__init__.py
# sphinxcontrib.autodoc_pydantic (1.4.0) from /opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/__init__.py
# furo (2021.09.22) from /opt/miniconda3/envs/nmt/lib/python3.9/site-packages/furo/__init__.py
Traceback (most recent call last):
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/cmd/build.py", line 280, in build_main
app.build(args.force_all, filenames)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/application.py", line 343, in build
self.builder.build_update()
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 293, in build_update
self.build(to_build,
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 307, in build
updated_docnames = set(self.read())
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 414, in read
self._read_serial(docnames)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 435, in _read_serial
self.read_doc(docname)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/builders/__init__.py", line 475, in read_doc
doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/io.py", line 189, in read_doc
pub.publish()
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/core.py", line 217, in publish
self.document = self.reader.read(self.source, self.parser,
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/io.py", line 109, in read
self.parse()
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/readers/__init__.py", line 78, in parse
self.parser.parse(self.input, document)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/parsers.py", line 101, in parse
self.statemachine.run(inputlines, document, inliner=self.inliner)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 170, in run
results = StateMachineWS.run(self, input_lines, input_offset,
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/statemachine.py", line 239, in run
context, next_state, result = self.check_line(
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2769, in underline
self.section(title, source, style, lineno - 1, messages)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 393, in new_subsection
newabsoffset = self.nested_parse(
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
state_machine.run(block, input_offset, memo=self.memo,
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/statemachine.py", line 239, in run
context, next_state, result = self.check_line(
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2769, in underline
self.section(title, source, style, lineno - 1, messages)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 393, in new_subsection
newabsoffset = self.nested_parse(
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
state_machine.run(block, input_offset, memo=self.memo,
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/statemachine.py", line 239, in run
context, next_state, result = self.check_line(
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2342, in explicit_markup
nodelist, blank_finish = self.explicit_construct(match)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2354, in explicit_construct
return method(self, expmatch)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2096, in directive
return self.run_directive(
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/docutils/parsers/rst/states.py", line 2146, in run_directive
result = directive_instance.run()
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/ext/autodoc/directive.py", line 162, in run
documenter.generate(more_content=self.content)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py", line 983, in generate
self.document_members(all_members)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py", line 860, in document_members
documenter.generate(
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py", line 1773, in generate
return super().generate(more_content=more_content,
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinx/ext/autodoc/__init__.py", line 980, in generate
self.add_content(more_content)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/autodoc.py", line 241, in add_content
self.add_field_summary()
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/autodoc.py", line 331, in add_field_summary
wrapper = ModelWrapper(self.object)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/inspection.py", line 87, in __init__
self.field_validator_names = self.get_field_validator_names()
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/inspection.py", line 110, in get_field_validator_names
field_names["*"].extend(self.get_names_from_root_validators())
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/inspection.py", line 121, in get_names_from_root_validators
pre_root = get_name(self.model.__pre_root_validators__)
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/inspection.py", line 119, in get_name
return [validator[1].__name__ for validator in validators]
File "/opt/miniconda3/envs/nmt/lib/python3.9/site-packages/sphinxcontrib/autodoc_pydantic/inspection.py", line 119, in <listcomp>
return [validator[1].__name__ for validator in validators]
TypeError: 'function' object is not subscriptable
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.