(
field_info: FieldInfo,
ns_resolver: NsResolver,
typevars_map: Mapping[TypeVar, Any],
*,
lenient: bool,
)
| 481 | |
| 482 | |
| 483 | def _recreate_field_info( |
| 484 | field_info: FieldInfo, |
| 485 | ns_resolver: NsResolver, |
| 486 | typevars_map: Mapping[TypeVar, Any], |
| 487 | *, |
| 488 | lenient: bool, |
| 489 | ) -> FieldInfo: |
| 490 | FieldInfo_ = import_cached_field_info() |
| 491 | |
| 492 | existing_desc = field_info.description |
| 493 | if lenient: |
| 494 | ann = _generics.replace_types(field_info._original_annotation, typevars_map) |
| 495 | ann, evaluated = _typing_extra.try_eval_type( |
| 496 | ann, |
| 497 | *ns_resolver.types_namespace, |
| 498 | ) |
| 499 | else: |
| 500 | # Not the best pattern, maybe we could ship our own `eval_type()`, |
| 501 | # that would replace the type variables on the fly during evaluation. |
| 502 | ann = _typing_extra.eval_type( |
| 503 | field_info._original_annotation, |
| 504 | *ns_resolver.types_namespace, |
| 505 | ) |
| 506 | ann = _generics.replace_types(ann, typevars_map) |
| 507 | ann = _typing_extra.eval_type( |
| 508 | ann, |
| 509 | *ns_resolver.types_namespace, |
| 510 | ) |
| 511 | evaluated = True |
| 512 | |
| 513 | if (assign := field_info._original_assignment) is PydanticUndefined: |
| 514 | new_field = FieldInfo_.from_annotation(ann, _source=AnnotationSource.CLASS) |
| 515 | else: |
| 516 | new_field = FieldInfo_.from_annotated_attribute(ann, assign, _source=AnnotationSource.CLASS) |
| 517 | new_field._original_assignment = assign |
| 518 | new_field._original_annotation = ann |
| 519 | # The description might come from the docstring if `use_attribute_docstrings` was `True`: |
| 520 | new_field.description = new_field.description if new_field.description is not None else existing_desc |
| 521 | if not evaluated: |
| 522 | new_field._complete = False |
| 523 | |
| 524 | return new_field |
| 525 | |
| 526 | |
| 527 | def collect_dataclass_fields( |
no test coverage detected