mirror of
https://github.com/kennethreitz/pydantic.git
synced 2026-06-05 23:00:18 +00:00
No dict update (#1244)
* update_forward_refs now modifies only a copy of __dict__ of cls.__module__ * changes * test for update_forward_refs * fixed brackets * black changes fixed * make format Co-authored-by: Samuel Colvin <s@muelcolvin.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
`update_forward_refs()` method of BaseModel now copies `__dict__` of class module instead of modyfying it
|
||||
+1
-1
@@ -646,7 +646,7 @@ class BaseModel(metaclass=ModelMetaclass):
|
||||
"""
|
||||
Try to update ForwardRefs on fields based on this Model, globalns and localns.
|
||||
"""
|
||||
globalns = sys.modules[cls.__module__].__dict__
|
||||
globalns = sys.modules[cls.__module__].__dict__.copy()
|
||||
globalns.setdefault(cls.__name__, cls)
|
||||
for f in cls.__fields__.values():
|
||||
update_field_forward_refs(f, globalns=globalns, localns=localns)
|
||||
|
||||
@@ -330,10 +330,7 @@ def test_alias_priority():
|
||||
a: str = Field(..., alias='a_field_child')
|
||||
|
||||
class Config:
|
||||
fields = {
|
||||
'a': dict(alias='a_config_child'),
|
||||
'b': dict(alias='b_config_child'),
|
||||
}
|
||||
fields = {'a': dict(alias='a_config_child'), 'b': dict(alias='b_config_child')}
|
||||
|
||||
@staticmethod
|
||||
def alias_generator(x):
|
||||
|
||||
+10
-12
@@ -35,21 +35,21 @@ def test_args():
|
||||
foo(1, 'x')
|
||||
|
||||
assert exc_info.value.errors() == [
|
||||
{'loc': ('b',), 'msg': 'value is not a valid integer', 'type': 'type_error.integer'},
|
||||
{'loc': ('b',), 'msg': 'value is not a valid integer', 'type': 'type_error.integer'}
|
||||
]
|
||||
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
foo(1, 2, 3)
|
||||
|
||||
assert exc_info.value.errors() == [
|
||||
{'loc': ('args',), 'msg': '2 positional arguments expected but 3 given', 'type': 'type_error'},
|
||||
{'loc': ('args',), 'msg': '2 positional arguments expected but 3 given', 'type': 'type_error'}
|
||||
]
|
||||
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
foo(1, 2, apple=3)
|
||||
|
||||
assert exc_info.value.errors() == [
|
||||
{'loc': ('kwargs',), 'msg': "unexpected keyword argument: 'apple'", 'type': 'type_error'},
|
||||
{'loc': ('kwargs',), 'msg': "unexpected keyword argument: 'apple'", 'type': 'type_error'}
|
||||
]
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ def test_kwargs():
|
||||
foo(a=1, b='x')
|
||||
|
||||
assert exc_info.value.errors() == [
|
||||
{'loc': ('b',), 'msg': 'value is not a valid integer', 'type': 'type_error.integer'},
|
||||
{'loc': ('b',), 'msg': 'value is not a valid integer', 'type': 'type_error.integer'}
|
||||
]
|
||||
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
@@ -141,7 +141,7 @@ def foo(a, b, /, c=None):
|
||||
'loc': ('v__positional_only',),
|
||||
'msg': "positional-only argument passed as keyword argument: 'b'",
|
||||
'type': 'type_error',
|
||||
},
|
||||
}
|
||||
]
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
module.foo(a=1, b=2)
|
||||
@@ -150,7 +150,7 @@ def foo(a, b, /, c=None):
|
||||
'loc': ('v__positional_only',),
|
||||
'msg': "positional-only arguments passed as keyword arguments: 'a', 'b'",
|
||||
'type': 'type_error',
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -165,19 +165,19 @@ def test_args_name():
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
foo(1, 2, apple=4)
|
||||
assert exc_info.value.errors() == [
|
||||
{'loc': ('v__kwargs',), 'msg': "unexpected keyword argument: 'apple'", 'type': 'type_error'},
|
||||
{'loc': ('v__kwargs',), 'msg': "unexpected keyword argument: 'apple'", 'type': 'type_error'}
|
||||
]
|
||||
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
foo(1, 2, apple=4, banana=5)
|
||||
assert exc_info.value.errors() == [
|
||||
{'loc': ('v__kwargs',), 'msg': "unexpected keyword arguments: 'apple', 'banana'", 'type': 'type_error'},
|
||||
{'loc': ('v__kwargs',), 'msg': "unexpected keyword arguments: 'apple', 'banana'", 'type': 'type_error'}
|
||||
]
|
||||
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
foo(1, 2, 3)
|
||||
assert exc_info.value.errors() == [
|
||||
{'loc': ('v__args',), 'msg': '2 positional arguments expected but 3 given', 'type': 'type_error'},
|
||||
{'loc': ('v__args',), 'msg': '2 positional arguments expected but 3 given', 'type': 'type_error'}
|
||||
]
|
||||
|
||||
|
||||
@@ -202,9 +202,7 @@ def test_async():
|
||||
loop.run_until_complete(run())
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
loop.run_until_complete(foo('x'))
|
||||
assert exc_info.value.errors() == [
|
||||
{'loc': ('b',), 'msg': 'field required', 'type': 'value_error.missing'},
|
||||
]
|
||||
assert exc_info.value.errors() == [{'loc': ('b',), 'msg': 'field required', 'type': 'value_error.missing'}]
|
||||
|
||||
|
||||
def test_string_annotation():
|
||||
|
||||
+11
-1
@@ -1,5 +1,6 @@
|
||||
import sys
|
||||
from enum import Enum
|
||||
from typing import Any, Callable, ClassVar, List, Mapping, Type
|
||||
from typing import Any, Callable, ClassVar, List, Mapping, Optional, Type
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
import pytest
|
||||
@@ -995,6 +996,15 @@ def test_custom_init_subclass_params():
|
||||
assert NewModel.something == 2
|
||||
|
||||
|
||||
def test_update_forward_refs_does_not_modify_module_dict():
|
||||
class MyModel(BaseModel):
|
||||
field: Optional['MyModel']
|
||||
|
||||
MyModel.update_forward_refs()
|
||||
|
||||
assert 'MyModel' not in sys.modules[MyModel.__module__].__dict__
|
||||
|
||||
|
||||
def test_two_defaults():
|
||||
with pytest.raises(ValueError, match='^cannot specify both default and default_factory$'):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user