-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Add support for Pydantic models in stubgen
#19095
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
base: master
Are you sure you want to change the base?
Changes from 7 commits
8c3c144
fa941b5
55ea42f
40b8b6d
d80e430
c05768c
2f57b1d
806cce8
7012189
a7f95cd
b522da8
00bbd68
86bb31b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -4718,3 +4718,121 @@ class DCMeta(type): ... | |||||
|
||||||
class DC(metaclass=DCMeta): | ||||||
x: str | ||||||
|
||||||
[case testPydanticBaseModel] | ||||||
import pydantic | ||||||
|
||||||
class User(pydantic.BaseModel): | ||||||
id: int | ||||||
name: str | ||||||
active: bool = True | ||||||
optional_field: str | None = None | ||||||
[out] | ||||||
import pydantic | ||||||
|
||||||
class User(pydantic.BaseModel): | ||||||
id: int | ||||||
name: str | ||||||
active: bool = ... | ||||||
optional_field: str | None = ... | ||||||
|
||||||
[case testPydanticBaseModelWithAnnotationsOnly] | ||||||
teplandr marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
import pydantic | ||||||
|
||||||
class ConfigSettings(pydantic.BaseModel): | ||||||
# Fields without initialization | ||||||
db_name: str | ||||||
port: int | ||||||
debug: bool | ||||||
[out] | ||||||
import pydantic | ||||||
|
||||||
class ConfigSettings(pydantic.BaseModel): | ||||||
db_name: str | ||||||
port: int | ||||||
debug: bool | ||||||
|
||||||
[case testPydanticNestedBaseModel] | ||||||
from pydantic import BaseModel | ||||||
|
||||||
class Address(BaseModel): | ||||||
street: str | ||||||
city: str | ||||||
|
||||||
class User(BaseModel): | ||||||
name: str | ||||||
age: int | ||||||
address: Address | None = None | ||||||
[out] | ||||||
from pydantic import BaseModel | ||||||
|
||||||
class Address(BaseModel): | ||||||
street: str | ||||||
city: str | ||||||
|
||||||
class User(BaseModel): | ||||||
name: str | ||||||
age: int | ||||||
address: Address | None = ... | ||||||
|
||||||
[case testPydanticBaseModelComplex] | ||||||
teplandr marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
from pydantic import BaseModel | ||||||
from typing import Dict, List, Optional, Union | ||||||
|
||||||
class Item(BaseModel): | ||||||
name: str | ||||||
description: Optional[str] = None | ||||||
tags: List[str] = [] | ||||||
properties: Dict[str, Union[str, int, float, bool]] = {} | ||||||
[out] | ||||||
from pydantic import BaseModel | ||||||
|
||||||
class Item(BaseModel): | ||||||
name: str | ||||||
description: str | None = ... | ||||||
tags: list[str] = ... | ||||||
properties: dict[str, str | int | float | bool] = ... | ||||||
|
||||||
[case testPydanticBaseModelInheritance] | ||||||
from pydantic import BaseModel | ||||||
|
||||||
class BaseUser(BaseModel): | ||||||
id: int | ||||||
active: bool = True | ||||||
|
||||||
class User(BaseUser): | ||||||
name: str | ||||||
email: str | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is an issue connected with this change. Currently, the code only sets There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is "indirect inheritance"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe it's not the correct term, but I mean that if we have: class BaseUser(BaseModel):
pass
class User(BaseUser):
pass BaseUser 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. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can inspect the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @sobolevn! I pushed the changes with Pydantic inheritance detection via |
||||||
[out] | ||||||
from pydantic import BaseModel | ||||||
|
||||||
class BaseUser(BaseModel): | ||||||
id: int | ||||||
active: bool = ... | ||||||
|
||||||
class User(BaseUser): | ||||||
name: str | ||||||
email: str | ||||||
teplandr marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
[case testPydanticModelWithMethods] | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can just add some methods to existing models. Let's reduce the amount of tests without reducing test features. |
||||||
from pydantic import BaseModel | ||||||
|
||||||
class User(BaseModel): | ||||||
id: int | ||||||
name: str | ||||||
|
||||||
def get_display_name(self) -> str: | ||||||
return f"User {self.name}" | ||||||
teplandr marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
@property | ||||||
def display_id(self) -> str: | ||||||
return f"ID: {self.id}" | ||||||
teplandr marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
[out] | ||||||
from pydantic import BaseModel | ||||||
|
||||||
class User(BaseModel): | ||||||
id: int | ||||||
name: str | ||||||
def get_display_name(self) -> str: ... | ||||||
@property | ||||||
def display_id(self) -> str: ... |
Uh oh!
There was an error while loading. Please reload this page.