8000 Check if `FieldInfo` is complete after applying type variable map · pydantic/pydantic@8fbe658 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8fbe658

Browse files
committed
Check if FieldInfo is complete after applying type variable map
Backport of: #11855
1 parent 12b371a commit 8fbe658

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

pydantic/_internal/_fields.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,9 @@ def rebuild_model_fields(
307307
308308
This function should be called whenever a model with incomplete fields is encountered.
309309
310+
Raises:
311+
NameError: If one of the annotations failed to evaluate.
312+
310313
Note:
311314
This function *doesn't* mutate the model fields in place, as it can be called during
312315
schema generation, where you don't want to mutate other model's fields.

pydantic/fields.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -692,8 +692,12 @@ def apply_typevars_map(
692692
pydantic._internal._generics.replace_types is used for replacing the typevars with
693693
their concrete types.
694694
"""
695-
annotation, _ = _typing_extra.try_eval_type(self.annotation, globalns, localns)
696-
self.annotation = _generics.replace_types(annotation, typevars_map)
695+
annotation = _generics.replace_types(self.annotation, typevars_map)
696+
annotation, evaluated = _typing_extra.try_eval_type(annotation, globalns, localns)
697+
self.annotation = annotation
698+
if not evaluated:
699+
self._complete = False
700+
self._original_annotation = self.annotation
697701

698702
def __repr_args__(self) -> ReprArgs:
699703
yield 'annotation', _repr.PlainRepr(_repr.display_as_type(self.annotation))

tests/test_forward_ref.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import re
44
import sys
55
import typing
6-
from typing import Any, Optional
6+
from typing import Any, Generic, Optional, TypeVar
77

88
import pytest
99

@@ -1232,6 +1232,29 @@ class SubChild(Child):
12321232
)
12331233

12341234

1235+
@pytest.mark.skipif(
1236+
sys.version_info < (3, 11),
1237+
reason=(
1238+
'Forward refs inside PEP 585 generics are not evaluated (see https://github.com/python/cpython/pull/30900).'
1239+
),
1240+
)
1241+
def test_forward_ref_in_class_parameter() -> None:
1242+
"""https://github.com/pydantic/pydantic/issues/11854"""
1243+
T = TypeVar('T')
1244+
1245+
class Model(BaseModel, Generic[T]):
1246+
f: T
1247+
1248+
M = Model[list['Undefined']]
1249+
1250+
assert not M.__pydantic_fields_complete__
1251+
1252+
M.model_rebuild(_types_namespace={'Undefined': int})
1253+
1254+
assert M.__pydantic_fields_complete__
1255+
assert M.model_fields['f'].annotation == list[int]
1256+
1257+
12351258
def test_uses_the_local_namespace_when_generating_schema():
12361259
def func():
12371260
A = int

0 commit comments

Comments
 (0)
0