|
8 | 8 | import typing_extensions |
9 | 9 |
|
10 | 10 | from .datetime_utils import serialize_datetime |
11 | | -from .pydantic_utilities import IS_PYDANTIC_V2, pydantic_v1 |
| 11 | +from .pydantic_utilities import pydantic_v1 |
12 | 12 |
|
13 | 13 |
|
14 | 14 | class UnionMetadata: |
@@ -46,49 +46,39 @@ def construct( |
46 | 46 | _fields_set = set(values.keys()) |
47 | 47 |
|
48 | 48 | for name, field in cls.__fields__.items(): |
| 49 | + # Key here is only used to pull data from the values dict |
| 50 | + # you should always use the NAME of the field to for field_values, etc. |
| 51 | + # because that's how the object is constructed from a pydantic perspective |
49 | 52 | key = field.alias |
50 | | - if ( |
| 53 | + if key is None or ( |
51 | 54 | key not in values and config.allow_population_by_field_name |
52 | 55 | ): # Added this to allow population by field name |
53 | 56 | key = name |
54 | 57 |
|
55 | 58 | if key in values: |
56 | | - if ( |
57 | | - values[key] is None and not field.required |
58 | | - ): # Moved this check since None value can be passed for Optional nested field |
59 | | - fields_values[name] = field.get_default() |
60 | | - else: |
61 | | - type_ = typing.cast(typing.Type, field.outer_type_) # type: ignore |
62 | | - fields_values[name] = construct_type(object_=values[key], type_=type_) |
| 59 | + type_ = typing.cast(typing.Type, field.outer_type_) # type: ignore |
| 60 | + fields_values[name] = construct_type(object_=values[key], type_=type_) |
63 | 61 | _fields_set.add(name) |
64 | | - elif not field.required: |
| 62 | + else: |
65 | 63 | default = field.get_default() |
66 | 64 | fields_values[name] = default |
67 | 65 |
|
68 | 66 | # If the default values are non-null act like they've been set |
69 | 67 | # This effectively allows exclude_unset to work like exclude_none where |
70 | 68 | # the latter passes through intentionally set none values. |
71 | 69 | if default != None: |
72 | | - _fields_set.add(key) |
| 70 | + _fields_set.add(name) |
73 | 71 |
|
74 | 72 | # Add extras back in |
75 | | - _extra = {} |
| 73 | + alias_fields = [field.alias for field in cls.__fields__.values()] |
76 | 74 | for key, value in values.items(): |
77 | | - if key not in _fields_set: |
78 | | - _extra[key] = value |
79 | | - # In v2 we'll need to exclude extra fields from fields_values |
80 | | - if not IS_PYDANTIC_V2: |
81 | | - _fields_set.add(key) |
82 | | - fields_values[key] = value |
83 | | - |
84 | | - if IS_PYDANTIC_V2: |
85 | | - object.__setattr__(m, "__pydantic_private__", None) |
86 | | - object.__setattr__(m, "__pydantic_extra__", _extra) |
87 | | - object.__setattr__(m, "__pydantic_fields_set__", _fields_set) |
| 75 | + if key not in alias_fields and key not in cls.__fields__: |
| 76 | + _fields_set.add(key) |
| 77 | + fields_values[key] = value |
88 | 78 |
|
89 | 79 | object.__setattr__(m, "__dict__", fields_values) |
90 | | - object.__setattr__(m, "__fields_set__", _fields_set) |
91 | 80 | m._init_private_attributes() |
| 81 | + object.__setattr__(m, "__fields_set__", _fields_set) |
92 | 82 | return m |
93 | 83 |
|
94 | 84 |
|
|
0 commit comments