Skip to content

Instantly share code, notes, and snippets.

@samuelcolvin
Last active March 16, 2023 15:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samuelcolvin/1f52e597428106a863030679ca778d5a to your computer and use it in GitHub Desktop.
Save samuelcolvin/1f52e597428106a863030679ca778d5a to your computer and use it in GitHub Desktop.
"""
pydantic-core: 01fdec6d2242fdf7205663d566be5ba990d1d459 - the custom-dataclass-validator branch
and pydantic: 519800fa5167a57681ba3b202503751aa0f17347 - the dataclasses-v2 branch
"""
from typing import TypeVar
import pytest
from pydantic import BaseModel, ValidationError
try:
import email_validator
except ImportError:
email_validator = None
T = TypeVar('T')
def test_generic_recursive_models_triple(create_module):
@create_module
def module():
from typing import Generic, TypeVar, Union
from pydantic import BaseModel
T1 = TypeVar('T1')
T2 = TypeVar('T2')
T3 = TypeVar('T3')
class A1(BaseModel, Generic[T1]):
a1: 'A2[T1]'
model_config = dict(undefined_types_warning=False)
class A2(BaseModel, Generic[T2]):
a2: 'A3[T2]'
model_config = dict(undefined_types_warning=False)
class A3(BaseModel, Generic[T3]):
a3: Union['A1[T3]', T3]
model_config = dict(undefined_types_warning=False)
A1.model_rebuild()
A1 = module.A1
with pytest.raises(ValidationError) as exc_info:
A1[str].model_validate({'a1': {'a2': {'a3': 1}}})
assert exc_info.value.errors() == [
{
'input': 1,
'loc': ('a1', 'a2', 'a3', 'A1[str]'),
'msg': 'Input should be a valid dictionary',
'type': 'dict_type',
},
{'input': 1, 'loc': ('a1', 'a2', 'a3', 'str'), 'msg': 'Input should be a valid string', 'type': 'string_type'},
]
A1[int].model_validate({'a1': {'a2': {'a3': 1}}})
def test_generic_recursive_models_complicated(create_module):
@create_module
def module():
from typing import Generic, TypeVar, Union
from pydantic import BaseModel
T1 = TypeVar('T1')
T2 = TypeVar('T2')
T3 = TypeVar('T3')
class A1(BaseModel, Generic[T1]):
a1: T1 # 'A2[T1]'
model_config = dict(undefined_types_warning=False)
class A2(BaseModel, Generic[T2]):
a2: 'A3[T2]'
model_config = dict(undefined_types_warning=False)
class A3(BaseModel, Generic[T3]):
a3: Union[A1[T3], T3]
model_config = dict(undefined_types_warning=False)
A1.model_rebuild()
S1 = TypeVar('S1')
S2 = TypeVar('S2')
class B1(BaseModel, Generic[S1]):
a1: 'B2[S1]'
model_config = dict(undefined_types_warning=False)
class B2(BaseModel, Generic[S2]):
a2: 'B1[S2]'
model_config = dict(undefined_types_warning=False)
B1.model_rebuild()
V1 = TypeVar('V1')
V2 = TypeVar('V2')
V3 = TypeVar('V3')
class M1(BaseModel, Generic[V1, V2]):
a: int
b: B1[V2]
m: 'M2[V1]'
model_config = dict(undefined_types_warning=False)
class M2(BaseModel, Generic[V3]):
m: Union[M1[V3, int], V3]
model_config = dict(undefined_types_warning=False)
M1.model_rebuild()
M1 = module.M1
assert collect_invalid_schemas(M1.__pydantic_core_schema__) == []
def test_key():
class ApplePie(BaseModel):
"""
This is a test.
"""
a: float
b: int = 10
s = {
'type': 'object',
'properties': {'a': {'type': 'number', 'title': 'A'}, 'b': {'type': 'integer', 'title': 'B', 'default': 10}},
'required': ['a'],
'title': 'ApplePie',
'description': 'This is a test.',
}
assert ApplePie.__schema_cache__.keys() == set()
assert ApplePie.model_json_schema() == s
assert ApplePie.__schema_cache__.keys() == {(True, '#/$defs/{model}')}
assert ApplePie.model_json_schema() == s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment