Files
pydantic/docs/usage/postponed_annotations.md
T
Yurii Karabas 415eb54f96 Try to evaluate forward refs after model created (#2588)
* Try to evaluate forward refs after model created

* Upadate docs and remove code duplication

* Update changes/2588-uriyyo.md

Co-authored-by: Eric Jolibois <em.jolibois@gmail.com>

* Update docs/usage/postponed_annotations.md

Co-authored-by: Eric Jolibois <em.jolibois@gmail.com>

* Remove unused import

Co-authored-by: Eric Jolibois <em.jolibois@gmail.com>
2021-12-05 14:20:48 +00:00

66 lines
2.3 KiB
Markdown

!!! note
Both postponed annotations via the future import and `ForwardRef` require python 3.7+.
Postponed annotations (as described in [PEP563](https://www.python.org/dev/peps/pep-0563/))
"just work".
```py
{!.tmp_examples/postponed_annotations_main.py!}
```
_(This script is complete, it should run "as is")_
Internally, *pydantic* will call a method similar to `typing.get_type_hints` to resolve annotations.
In cases where the referenced type is not yet defined, `ForwardRef` can be used (although referencing the
type directly or by its string is a simpler solution in the case of
[self-referencing models](#self-referencing-models)).
In some cases, a `ForwardRef` won't be able to be resolved during model creation.
For example, this happens whenever a model references itself as a field type.
When this happens, you'll need to call `update_forward_refs` after the model has been created before it can be used:
```py
{!.tmp_examples/postponed_annotations_forward_ref.py!}
```
_(This script is complete, it should run "as is")_
!!! warning
To resolve strings (type names) into annotations (types), *pydantic* needs a namespace dict in which to
perform the lookup. For this it uses `module.__dict__`, just like `get_type_hints`.
This means *pydantic* may not play well with types not defined in the global scope of a module.
For example, this works fine:
```py
{!.tmp_examples/postponed_annotations_works.py!}
```
While this will break:
```py
{!.tmp_examples/postponed_annotations_broken.py!}
```
Resolving this is beyond the call for *pydantic*: either remove the future import or declare the types globally.
## Self-referencing Models
Data structures with self-referencing models are also supported. Self-referencing fields will be automatically
resolved after model creation.
Within the model, you can refer to the not-yet-constructed model using a string:
```py
{!.tmp_examples/postponed_annotations_self_referencing_string.py!}
```
_(This script is complete, it should run "as is")_
Since `python 3.7`, you can also refer it by its type, provided you import `annotations` (see
[above](postponed_annotations.md) for support depending on Python
and *pydantic* versions).
```py
{!.tmp_examples/postponed_annotations_self_referencing_annotations.py!}
```
_(This script is complete, it should run "as is")_