Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Any way to hide Pydantic 2.0 class internals? #715

Closed
aaronsteers opened this issue Jul 12, 2024 · 9 comments · Fixed by #748
Closed

Any way to hide Pydantic 2.0 class internals? #715

aaronsteers opened this issue Jul 12, 2024 · 9 comments · Fixed by #748
Labels

Comments

@aaronsteers
Copy link

Problem Description

My class declaration has no members declared explicitly. However, the pdoc text generated includes some garbage internals from the Pydantic class, while not actually documenting any of the superclass's members. I would like to just globally suppress these:

  • model_config
  • model_post_init
  • model_fields
  • model_computed_fields

My class documentation index looks like this since migrating to Pydantic 2.0:

image

Since I'm not declaring these directly in my own code, I don't have a way to suppress them with a @private annotation or similar.

Steps to reproduce the behavior:

Create a class from Pydantic 2.0 BaseModel.

System Information

Paste the output of "pdoc --version" here.

pdoc: 14.5.1
Python: 3.10.12
Platform: macOS-14.5-arm64-arm-64bit
@elliot-100
Copy link

elliot-100 commented Jul 12, 2024

This seems to work (with a caveat re #714 ) if you add it to the superclass:

def model_fields(self):
    """@private"""
    pass

@mhils
Copy link
Member

mhils commented Jul 12, 2024

My suggestion here would be to use a custom template that overrides is_public:

{#
We can also adjust which members are documented by overriding the is_public macro.
In this example, the private function `Dog.__lt__` is exposed publicly.
However, doing this is not recommended, see https://pdoc.dev/docs/pdoc.html#control-what-is-documented.
#}
{% macro is_public(doc) %}
{% if doc.qualname == "Dog.__lt__" %}
true
{% else %}
{{ default_is_public(doc) }}
{% endif %}
{% endmacro %}

@JPHutchins
Copy link

My suggestion here would be to use a custom template that overrides is_public:

{#
We can also adjust which members are documented by overriding the is_public macro.
In this example, the private function `Dog.__lt__` is exposed publicly.
However, doing this is not recommended, see https://pdoc.dev/docs/pdoc.html#control-what-is-documented.
#}
{% macro is_public(doc) %}
{% if doc.qualname == "Dog.__lt__" %}
true
{% else %}
{{ default_is_public(doc) }}
{% endif %}
{% endmacro %}

I've found that this example syntax is not quite right. The inline comments of default_is_public state that false is given by an empty string rather than a literal boolean.

{#
We can also adjust which members are documented by overriding the is_public macro.
#}
{% macro is_public(doc) %}
    {% if doc.name.startswith("model_") %}
        {# False #}
    {% else %}
        {{ default_is_public(doc) }}
    {% endif %}
{% endmacro %}

I'm not sure what's right, but this is what finally worked for me.

@JPHutchins
Copy link

I'll be looking into filtering at the BaseModel inheritance as well since it is irrelevant to users.

image

@JPHutchins
Copy link

Thinking about it more, what I'm really looking for is filtering out inheritance that's not in the repo. That is, it can't be linked to. For example, it's not helpful to tell my users about all the builtin methods on a bytes object 🤣

image

@mhils
Copy link
Member

mhils commented Oct 11, 2024

Thinking about it more, what I'm really looking for is filtering out inheritance that's not in the repo.

This actually sounds like pretty sensible default behavior! Let's ship a release with this and see if someone thinks different. :)

@elliot-100
Copy link

elliot-100 commented Oct 11, 2024

I don't think it is correct to link #748 to this. The reported issue was specifically about particular members of Pydantic classes.

I've just tested with my Pydantic 2.9.2 (latest) class, and with pydoc 14.7.0 or 15.0.0 I get these members rendered:

model_config
model_fields
model_computed_fields

(Note I don't get model_post_init__() as per original issue, I'd have to check on why)

The change to pydoc 15.0.0 does hide the additional 'inherited members' area as shown in @JPHutchins screenshots, but that's not the same thing.

Edit: PS I do appreciate the change in #748 general of course 👍

@JPHutchins
Copy link

I have since tried mkdocs (mkdocstrings) and can say that it errs in the opposite direction, where docstrings and members are not inherited. There's a plugin that CAN inherit docstrings, but only from within the repo, which caused me all sorts of problems. Eventually I did some LLM script hack garbage: https://github.com/intercreate/smpclient/blob/d318220d9dd70f1861cae73d2b7b24a6c3388132/docs/_generate_requests_docstrings.py

I know it's useless to say, but this all needs to be standardized in the language; pdoc and mkdocstrings are doing a great job, but it's really hard without any specs!

It led me to find PEP 727, which I support: https://discuss.python.org/t/pep-727-documentation-metadata-in-typing/32566

@mhils
Copy link
Member

mhils commented Oct 11, 2024

I don't think it is correct to link #748 to this. The reported issue was specifically about particular members of Pydantic classes.

Eh, you are correct. I did not look further up in the thread. I'll reroute things to the PR. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants