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
Update documentation for generics support in V2 #6685
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -104,7 +104,8 @@ Models possess the following methods and attributes: | |
See [JSON Schema](json_schema.md). | ||
* `model_parametrized_name()`: compute the class name for parametrizations of generic classes. | ||
* `model_post_init()`: perform additional initialization after the model is initialized. | ||
* `model_rebuild()`: rebuild the model schema. | ||
* `model_rebuild()`: rebuild the model schema, which also supports building recursive generic models. | ||
See [Rebuild model schema](#rebuild-model-schema). | ||
* `model_validate()`: a utility for loading any object into a model with error handling if the object is not a | ||
dictionary. See [Helper functions](#helper-functions). | ||
* `model_validate_json()`: a utility for validating the given JSON data against the Pydantic model. See | ||
|
@@ -158,6 +159,49 @@ print(m.model_dump()) | |
|
||
For self-referencing models, see [postponed annotations](postponed_annotations.md#self-referencing-or-recursive-models). | ||
|
||
## Rebuild model schema | ||
|
||
The model schema can be rebuilt using `model_rebuild()`. This is useful for building recursive generic models. | ||
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 need to tell users when it's useful. Something like "we try to determine when this is necessary and error if it wasn't done but you may want to call model_rebuild() proactively when dealing with recursive and/or generics. |
||
|
||
```py | ||
from pydantic import BaseModel, PydanticUserError | ||
|
||
|
||
class Foo(BaseModel): | ||
x: 'Bar' | ||
|
||
|
||
try: | ||
Foo.model_json_schema() | ||
except PydanticUserError as e: | ||
print(e) | ||
""" | ||
`Foo` is not fully defined; you should define `Bar`, then call `Foo.model_rebuild()`. | ||
|
||
For further information visit https://errors.pydantic.dev/2/u/class-not-fully-defined | ||
""" | ||
|
||
|
||
class Bar(BaseModel): | ||
pass | ||
|
||
|
||
Foo.model_rebuild() | ||
print(Foo.model_json_schema()) | ||
""" | ||
{ | ||
'$defs': {'Bar': {'properties': {}, 'title': 'Bar', 'type': 'object'}}, | ||
'properties': {'x': {'$ref': '#/$defs/Bar'}}, | ||
'required': ['x'], | ||
'title': 'Foo', | ||
'type': 'object', | ||
} | ||
""" | ||
``` | ||
|
||
Pydantic tries to determine when this is necessary automatically and error if it wasn't done, but you may want to | ||
call `model_rebuild()` proactively when dealing with recursive models or generics. | ||
|
||
## Arbitrary class instances | ||
|
||
(Formerly known as "ORM Mode"/`from_orm`.) | ||
|
@@ -730,6 +774,13 @@ print(concrete_model(a=1, b=1)) | |
#> a=1 b=1 | ||
``` | ||
|
||
!!! warning | ||
While it may not raise an error, we strongly advise against using parametrized generics in isinstance checks. | ||
|
||
For example, you should not do `isinstance(my_model, MyGenericModel[int])`. However, it is fine to do `isinstance(my_model, MyGenericModel)`. (Note that, for standard generics, it would raise an error to do a subclass check with a parameterized generic.) | ||
|
||
If you need to perform isinstance checks against parametrized generics, you can do this by subclassing the parametrized generic class. This looks like `class MyIntModel(MyGenericModel[int]): ...` and `isinstance(my_model, MyIntModel)`. | ||
|
||
If a Pydantic model is used in a `TypeVar` constraint, [`SerializeAsAny`](serialization.md#serializing-with-duck-typing) can be used to | ||
serialize it using the concrete model instead of the model `TypeVar` is bound to. | ||
|
||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe worth noting that if you use the dataclass as a field of a BaseModel or via FastAPI you don't need a TypeAdapter