Add support for Pydantic models in stubgen#19095
Conversation
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
stubgen
|
Hello @JelleZijlstra! Hope you're doing well 🙂 |
|
Hello @hauntsaninja! Hope you're doing well! |
|
Hi @sobolevn! You're my last hope 🙂 |
|
|
||
| class User(BaseUser): | ||
| name: str | ||
| email: str |
There was a problem hiding this comment.
| email: str | |
| email: str = '@' |
There was a problem hiding this comment.
There is an issue connected with this change. Currently, the code only sets processing_pydantic_model = True when the direct base class is pydantic.BaseModel, but it doesn't handle cases where a class inherits from another class that inherits from pydantic.BaseModel. I tried a few ideas but they aren't working. Could you please give me a clue how to tackle the problem?
There was a problem hiding this comment.
Hi @sobolevn, do you have any idea how to detect the indirect inheritance from pydantic.BaseModel? Besides that, do you know why ellipses aren't propagated for the attributes with default values in general? I guess it might be relevant for all classes, not only pydantic descendants.
There was a problem hiding this comment.
What is "indirect inheritance"?
There was a problem hiding this comment.
Maybe it's not the correct term, but I mean that if we have:
class BaseUser(BaseModel):
pass
class User(BaseUser):
passBaseUser directly inherited from BaseModel (and base_type_expr contains this info), whereas User indirectly inherited from BaseModel (and base_type_expr doesn't contain info about BaseModel).
There was a problem hiding this comment.
We can inspect the mro of a TypeInfo
There was a problem hiding this comment.
Hi @sobolevn! I pushed the changes with Pydantic inheritance detection via mro. Unfortunately, mro contains the following list: [<TypeInfo main.User>, <TypeInfo main.BaseUser>, <TypeInfo builtins.object>] and no pydantic.BaseModel. Could you help me to identify the reason?
| name: str | ||
| email: str | ||
|
|
||
| [case testPydanticModelWithMethods] |
There was a problem hiding this comment.
We can just add some methods to existing models. Let's reduce the amount of tests without reducing test features.
|
|
||
| def _inherits_from_pydantic_basemodel(self, class_def: ClassDef) -> bool: | ||
| """Check if a class directly or indirectly inherits from pydantic.BaseModel""" | ||
| for base_type_expr in class_def.base_type_exprs: |
There was a problem hiding this comment.
question: why do we need this branch?
There was a problem hiding this comment.
Hi @sobolevn! Because without it, the check for direct inheritance doesn't work. As I wrote previously, mro contains the following list: [<TypeInfo main.User>, <TypeInfo main.BaseUser>, <TypeInfo builtins.object>] and no pydantic.BaseModel. I would be happy to know the reason, but have no idea.
This PR adds support for generating stubs for Pydantic models in
stubgen.Changes
pydantic.BaseModeldirectly or indirectlyFixes #16968