mirror of
https://github.com/kennethreitz/pydantic.git
synced 2026-06-05 23:00:18 +00:00
Fix field of a type that has a default value (#880)
* fix type field * update changes * add testcase * separate test for type fields
This commit is contained in:
committed by
Samuel Colvin
parent
6a0e5313cb
commit
46db1efdfc
@@ -0,0 +1 @@
|
||||
Fix field of a type that has a default value.
|
||||
+6
-2
@@ -18,7 +18,7 @@ from .parse import Protocol, load_file, load_str_bytes
|
||||
from .schema import model_schema
|
||||
from .types import PyObject, StrBytes
|
||||
from .typing import AnyCallable, AnyType, ForwardRef, is_classvar, resolve_annotations, update_field_forward_refs
|
||||
from .utils import GetterDict, ValueItems, truncate, validate_field_name
|
||||
from .utils import GetterDict, ValueItems, lenient_issubclass, truncate, validate_field_name
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .class_validators import ValidatorListDict
|
||||
@@ -175,7 +175,11 @@ class ModelMetaclass(ABCMeta):
|
||||
elif is_valid_field(ann_name):
|
||||
validate_field_name(bases, ann_name)
|
||||
value = namespace.get(ann_name, ...)
|
||||
if isinstance(value, untouched_types) and ann_type != PyObject:
|
||||
if (
|
||||
isinstance(value, untouched_types)
|
||||
and ann_type != PyObject
|
||||
and not lenient_issubclass(getattr(ann_type, '__origin__', None), Type)
|
||||
):
|
||||
continue
|
||||
fields[ann_name] = ModelField.infer(
|
||||
name=ann_name,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import re
|
||||
from decimal import Decimal
|
||||
from enum import Enum
|
||||
from typing import Any, Dict, List, Optional, Set, Tuple, Union
|
||||
from typing import Any, Dict, List, Optional, Set, Tuple, Type, Union
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -957,15 +957,50 @@ def test_init_inspection():
|
||||
Foobar(x=1)
|
||||
|
||||
|
||||
def test_ignored_type():
|
||||
def foobar():
|
||||
def test_type_on_annotation():
|
||||
class FooBar:
|
||||
pass
|
||||
|
||||
class Model(BaseModel):
|
||||
a: int = foobar
|
||||
b: int
|
||||
a: int = int
|
||||
b: Type[int]
|
||||
c: Type[int] = int
|
||||
d: FooBar = FooBar
|
||||
e: Type[FooBar]
|
||||
f: Type[FooBar] = FooBar
|
||||
|
||||
assert Model.__fields__.keys() == {'b'}
|
||||
assert Model.__fields__.keys() == {'b', 'c', 'e', 'f'}
|
||||
|
||||
|
||||
def test_assign_type():
|
||||
class Parent:
|
||||
def echo(self):
|
||||
return 'parent'
|
||||
|
||||
class Child(Parent):
|
||||
def echo(self):
|
||||
return 'child'
|
||||
|
||||
class Different:
|
||||
def echo(self):
|
||||
return 'different'
|
||||
|
||||
class Model(BaseModel):
|
||||
v: Type[Parent] = Parent
|
||||
|
||||
assert Model(v=Parent).v().echo() == 'parent'
|
||||
assert Model().v().echo() == 'parent'
|
||||
assert Model(v=Child).v().echo() == 'child'
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
Model(v=Different)
|
||||
assert exc_info.value.errors() == [
|
||||
{
|
||||
'loc': ('v',),
|
||||
'msg': 'subclass of Parent expected',
|
||||
'type': 'type_error.subclass',
|
||||
'ctx': {'expected_class': 'Parent'},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def test_optional_subfields():
|
||||
|
||||
Reference in New Issue
Block a user