mirror of
https://github.com/kennethreitz/pydantic.git
synced 2026-06-05 23:00:18 +00:00
92d7689271
* add construct method, fix #48 * adding copy method * adding pickle support, fix #40 * tweak copy and add fields copy test * adding docs for immutability, values and copy * add docs for pickle
129 lines
2.7 KiB
Python
129 lines
2.7 KiB
Python
import pickle
|
|
|
|
import pytest
|
|
|
|
from pydantic import BaseModel
|
|
|
|
|
|
class Model(BaseModel):
|
|
a: float = ...
|
|
b: int = 10
|
|
|
|
|
|
def test_simple_construct():
|
|
m = Model.construct(a=40, b=10)
|
|
assert m.a == 40
|
|
assert m.b == 10
|
|
|
|
|
|
def test_construct_missing():
|
|
m = Model.construct(a='not a float')
|
|
assert m.a == 'not a float'
|
|
with pytest.raises(AttributeError) as exc_info:
|
|
print(m.b)
|
|
|
|
assert "'Model' object has no attribute 'b'" in str(exc_info)
|
|
|
|
|
|
def test_simple_copy():
|
|
m = Model(a=24)
|
|
m2 = m.copy()
|
|
|
|
assert m.a == m2.a == 24
|
|
assert m.b == m2.b == 10
|
|
assert m == m2
|
|
assert m.__fields__ == m2.__fields__
|
|
|
|
|
|
class ModelTwo(BaseModel):
|
|
a: float
|
|
b: int = 10
|
|
c: str = 'foobar'
|
|
d: Model
|
|
|
|
|
|
def test_copy_exclude():
|
|
m = ModelTwo(a=24, d=Model(a='12'))
|
|
m2 = m.copy(exclude={'b'})
|
|
|
|
assert m.a == m2.a == 24
|
|
assert isinstance(m2.d, Model)
|
|
assert m2.d.a == 12
|
|
|
|
assert hasattr(m2, 'c')
|
|
assert not hasattr(m2, 'b')
|
|
assert set(m.values().keys()) == {'a', 'b', 'c', 'd'}
|
|
assert set(m2.values().keys()) == {'a', 'c', 'd'}
|
|
|
|
assert m != m2
|
|
|
|
|
|
def test_copy_include():
|
|
m = ModelTwo(a=24, d=Model(a='12'))
|
|
m2 = m.copy(include={'a'})
|
|
|
|
assert m.a == m2.a == 24
|
|
assert set(m.values().keys()) == {'a', 'b', 'c', 'd'}
|
|
assert set(m2.values().keys()) == {'a'}
|
|
|
|
assert m != m2
|
|
|
|
|
|
def test_copy_include_exclude():
|
|
m = ModelTwo(a=24, d=Model(a='12'))
|
|
m2 = m.copy(include={'a', 'b', 'c'}, exclude={'c'})
|
|
|
|
assert set(m.values().keys()) == {'a', 'b', 'c', 'd'}
|
|
assert set(m2.values().keys()) == {'a', 'b'}
|
|
|
|
|
|
def test_copy_update():
|
|
m = ModelTwo(a=24, d=Model(a='12'))
|
|
m2 = m.copy(update={'a': 'different'})
|
|
|
|
assert m.a == 24
|
|
assert m2.a == 'different'
|
|
assert set(m.values().keys()) == set(m2.values().keys()) == {'a', 'b', 'c', 'd'}
|
|
|
|
assert m != m2
|
|
|
|
|
|
def test_simple_pickle():
|
|
m = Model(a='24')
|
|
b = pickle.dumps(m)
|
|
m2 = pickle.loads(b)
|
|
assert m.a == m2.a == 24
|
|
assert m.b == m2.b == 10
|
|
assert m == m2
|
|
assert m is not m2
|
|
assert tuple(m) == (('a', 24.0), ('b', 10))
|
|
assert tuple(m2) == (('a', 24.0), ('b', 10))
|
|
assert m.__fields__ == m2.__fields__
|
|
|
|
|
|
def test_recursive_pickle():
|
|
m = ModelTwo(a=24, d=Model(a='123.45'))
|
|
m2 = pickle.loads(pickle.dumps(m))
|
|
assert m == m2
|
|
|
|
assert m.d.a == 123.45
|
|
assert m2.d.a == 123.45
|
|
assert m.__fields__ == m2.__fields__
|
|
|
|
|
|
def test_immutable_copy():
|
|
class Model(BaseModel):
|
|
a: int
|
|
b: int
|
|
|
|
class Config:
|
|
allow_mutation = False
|
|
|
|
m = Model(a=40, b=10)
|
|
assert m == m.copy()
|
|
|
|
m2 = m.copy(update={'b': 12})
|
|
assert str(m2) == 'Model a=40 b=12'
|
|
with pytest.raises(TypeError):
|
|
m2.b = 13
|