Skip to content

Commit

Permalink
fix model_construct with validation_alias (pydantic#9144)
Browse files Browse the repository at this point in the history
Co-authored-by: ornariece <37-ornariece@users.noreply.git.malined.com>
  • Loading branch information
2 people authored and NeevCohen committed Apr 7, 2024
1 parent bb9c423 commit 7573df6
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
13 changes: 7 additions & 6 deletions pydantic/main.py
Expand Up @@ -222,9 +222,12 @@ def model_construct(cls: type[Model], _fields_set: set[str] | None = None, **val
fields_set = set()

for name, field in cls.model_fields.items():
if field.alias and field.alias in values:
if field.alias is not None and field.alias in values:
fields_values[name] = values.pop(field.alias)
fields_set.add(name)
elif field.validation_alias is not None and field.validation_alias in values:
fields_values[name] = values.pop(field.validation_alias)
fields_set.add(name)
elif name in values:
fields_values[name] = values.pop(name)
fields_set.add(name)
Expand All @@ -233,11 +236,9 @@ def model_construct(cls: type[Model], _fields_set: set[str] | None = None, **val
if _fields_set is None:
_fields_set = fields_set

_extra: dict[str, Any] | None = None
if cls.model_config.get('extra') == 'allow':
_extra = {}
for k, v in values.items():
_extra[k] = v
_extra: dict[str, Any] | None = (
{k: v for k, v in values.items()} if cls.model_config.get('extra') == 'allow' else None
)
_object_setattr(m, '__dict__', fields_values)
_object_setattr(m, '__pydantic_fields_set__', _fields_set)
if not cls.__pydantic_root_model__:
Expand Down
20 changes: 20 additions & 0 deletions tests/test_construction.py
Expand Up @@ -74,6 +74,26 @@ class Foo(BaseModel):
assert instance.model_dump_json() == instance_construct.model_dump_json()


def test_construct_with_aliases():
class MyModel(BaseModel):
x: int = Field(alias='x_alias')

my_model = MyModel.model_construct(x_alias=1)
assert my_model.x == 1
assert my_model.model_fields_set == {'x'}
assert my_model.model_dump() == {'x': 1}


def test_construct_with_validation_aliases():
class MyModel(BaseModel):
x: int = Field(validation_alias='x_alias')

my_model = MyModel.model_construct(x_alias=1)
assert my_model.x == 1
assert my_model.model_fields_set == {'x'}
assert my_model.model_dump() == {'x': 1}


def test_large_any_str():
class Model(BaseModel):
a: bytes
Expand Down

0 comments on commit 7573df6

Please sign in to comment.