autodoc_pydantic
autodoc_pydantic copied to clipboard
Support reused validators
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.
Thanks for reporting this! Have you tried building the documentation for the same code without autodoc_pydantic being activated (with plain sphinx autodoc)? I guess the same warning occurs again. If 's that the case, then this issue is rather related to the sphinx core then to autodoc_pydantic extension. Could you please test it on your example?
@mansenfranzen
Have you tried building the documentation for the same code without autodoc_pydantic being activated (with plain sphinx autodoc)?
I just did. However, I noticed that with the e.g. _normalize_name above, the class method didn't display in the generated page. Once I changed to normalize_name, it correctly displayed the docstring of normalize in the classmethod normalize_name for both classes. Note that I did not see the warning or any errors with autodoc_pydantic disabled for either case.
Once I enabled autodoc_pydantic, both cases above (sunder/non-sunder for classmethod name) yielded the same warning.
I think the warning is a hint WARNING: py:obj reference target not found: example.Consumer.normalize. Instead of normalize, it should be linking to the correct classmethod normalize_name (or _normalize_name for the original example).
Okay thanks for checking - then it's definitely related to autodoc_pydantic. I will come back to you soon.
Awesome, thank you for looking into this!
I also just noticed something else, not sure if this helps at all. With pydantic enabled, the generated page is showing normalize_name as a classmethod with normalize's docstring for both classes Consumer and Producer, it just doesn't properly register the classmethod normalize_name as a validator and displays that name's validator is normalize when it should instead be normalize_name local to the class.
If this is not clear, lmk and I can add the above example to one of my modules to show screenshots of what I mean by the above info.
Thanks for your additional information. I can now confirm that it is a bug in autodoc_pydantic which does not handle reused validators correctly.
To properly handle this use case I will need to add a new configuration property like autodoc_pydantic_validators_hide_reused to prevent showing the classmethod (_normalize_name) while correctly linking to the reused function (normalize). This may take some time until release v1.8.0.
This bug is addressed via #136 while adding two new configuration properties autodoc_pydantic_model_hide_reused_validator and autodoc_pydantic_settings_hide_reused_validator.
You will also find a new a new example with detailed information in the current dev docs here. Any comments, improvement suggestions are highly welcome ;-).
Before merging the related PR, it would be great if you could test the bugfix on your site. To do so, please install the current dev release in your doc-building-environment via pip install git+https://github.com/mansenfranzen/[email protected] and rebuild your docs.
@mansenfranzen I have tested with our docs and this appears to work. I used a fairly simple example, but it does work correctly now. Thanks for working on this!
Thanks for revisiting this issue :-). PR is merged and will be included in the next release (probably next week).