Skip to content

Commit

Permalink
Don't always require typing.Generic as a base for partially parametri…
Browse files Browse the repository at this point in the history
…zed models (#7119)
  • Loading branch information
dmontagu committed Aug 15, 2023
1 parent bcd9c89 commit 0454fab
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pydantic/_internal/_model_construction.py
Expand Up @@ -133,8 +133,8 @@ def wrapped_model_post_init(self: BaseModel, __context: Any) -> None:
if __pydantic_generic_metadata__:
cls.__pydantic_generic_metadata__ = __pydantic_generic_metadata__
else:
parameters = getattr(cls, '__parameters__', ())
parent_parameters = getattr(cls, '__pydantic_generic_metadata__', {}).get('parameters', ())
parameters = getattr(cls, '__parameters__', None) or parent_parameters
if parameters and parent_parameters and not all(x in parameters for x in parent_parameters):
combined_parameters = parent_parameters + tuple(x for x in parameters if x not in parent_parameters)
parameters_str = ', '.join([str(x) for x in combined_parameters])
Expand Down
31 changes: 31 additions & 0 deletions tests/test_generics.py
Expand Up @@ -2561,3 +2561,34 @@ class SimpleGenericModel(BaseModel, Generic[T]):

class Concrete(SimpleGenericModel[BaseModel]):
pass


def test_no_generic_base():
T = TypeVar('T')

class A(BaseModel, Generic[T]):
a: T

class B(A[T]):
b: T

class C(B[int]):
pass

assert C(a='1', b='2').model_dump() == {'a': 1, 'b': 2}
with pytest.raises(ValidationError) as exc_info:
C(a='a', b='b')
assert exc_info.value.errors(include_url=False) == [
{
'input': 'a',
'loc': ('a',),
'msg': 'Input should be a valid integer, unable to parse string as an integer',
'type': 'int_parsing',
},
{
'input': 'b',
'loc': ('b',),
'msg': 'Input should be a valid integer, unable to parse string as an integer',
'type': 'int_parsing',
},
]

0 comments on commit 0454fab

Please sign in to comment.