autodoc_pydantic icon indicating copy to clipboard operation
autodoc_pydantic copied to clipboard

Support reused validators

Open GlenNicholls opened this issue 3 years ago • 8 comments

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.

GlenNicholls avatar May 19 '22 16:05 GlenNicholls

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 avatar May 25 '22 17:05 mansenfranzen

@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.

GlenNicholls avatar May 25 '22 20:05 GlenNicholls

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).

GlenNicholls avatar May 25 '22 20:05 GlenNicholls

Okay thanks for checking - then it's definitely related to autodoc_pydantic. I will come back to you soon.

mansenfranzen avatar May 25 '22 20:05 mansenfranzen

Awesome, thank you for looking into this!

GlenNicholls avatar May 25 '22 20:05 GlenNicholls

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.

GlenNicholls avatar May 25 '22 20:05 GlenNicholls

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.

mansenfranzen avatar Jun 12 '22 18:06 mansenfranzen

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 avatar Jul 06 '22 20:07 mansenfranzen

@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!

GlenNicholls avatar Sep 29 '22 18:09 GlenNicholls

Thanks for revisiting this issue :-). PR is merged and will be included in the next release (probably next week).

mansenfranzen avatar Sep 30 '22 19:09 mansenfranzen