Skip to content

Commit

Permalink
feat: support default_factory with BaseModel.construct
Browse files Browse the repository at this point in the history
  • Loading branch information
PrettyWood committed Jul 22, 2020
1 parent e985857 commit cf0f0a5
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 2 deletions.
1 change: 1 addition & 0 deletions changes/1732-PrettyWood.md
@@ -0,0 +1 @@
support `default_factory` with `BaseModel.construct`
5 changes: 4 additions & 1 deletion pydantic/main.py
Expand Up @@ -527,7 +527,10 @@ def construct(cls: Type['Model'], _fields_set: Optional['SetStr'] = None, **valu
Default values are respected, but no other validation is performed.
"""
m = cls.__new__(cls)
object.__setattr__(m, '__dict__', {**deepcopy(cls.__field_defaults__), **values})
# default field values
fields_values = {name: field.get_default() for name, field in cls.__fields__.items() if not field.required}
fields_values.update(values)
object.__setattr__(m, '__dict__', fields_values)
if _fields_set is None:
_fields_set = set(values.keys())
object.__setattr__(m, '__fields_set__', _fields_set)
Expand Down
12 changes: 11 additions & 1 deletion tests/test_construction.py
Expand Up @@ -3,7 +3,7 @@

import pytest

from pydantic import BaseModel
from pydantic import BaseModel, Field


class Model(BaseModel):
Expand Down Expand Up @@ -275,3 +275,13 @@ class X(BaseModel):
# deep['deep_thing'] gets modified
assert x.deep['deep_thing'] == [1, 2, 3]
assert y.deep['deep_thing'] == [1, 2, 3]


def test_construct_default_factory():
class Model(BaseModel):
foo: List[int] = Field(default_factory=list)
bar: str = 'Baz'

m = Model.construct()
assert m.foo == []
assert m.bar == 'Baz'

0 comments on commit cf0f0a5

Please sign in to comment.