Skip to content

Subclass to a class inheriting from GenericModel - no validation at instantiation #1229

@Esadruhn

Description

@Esadruhn

Bug

There is a bug, or maybe a feature request, with inheritance and Generics.

If I define a class that inherits from GenericModel and a subclass, then when I instanciate the subclass there is no check on the generic type.

From what I saw in the code, it is because the checks are done in the metaclass __new__ method (generics are treated as Optional[Any] at that point), and the generic type is defined afterwards, in the __getitem__ method.

Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":

             pydantic version: 1.4
            pydantic compiled: False
                 install path: $HOME/envs/thenv/lib/python3.7/site-packages/pydantic
               python version: 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 16:52:21)  [Clang 6.0 (clang-600.0.57)]
                     platform: Darwin-19.3.0-x86_64-i386-64bit
     optional deps. installed: ['typing-extensions']

This test passes - no inheritance

def test_case_no_inheritance():
    TypeX = TypeVar('TypeX')

    SampleTypeX = list

    class MyBaseClass(GenericModel, Generic[TypeX]):
        X: TypeX

    with pytest.raises(pydantic.error_wrappers.ValidationError):
        MyBaseClass[SampleTypeX](X=1)

Failed test case - inheritance

import pydantic
from pydantic.main import ModelMetaclass
from pydantic.generics import GenericModel
import pytest

def test_case():
    TypeX = TypeVar('TypeX')

    SampleTypeX = list

    class MyBaseClass(GenericModel, Generic[TypeX]):
        X: TypeX

    class ExampleMeta(ModelMetaclass):
        # This metaclass is not necessary for the test, it illustrates that we get the 'generic_type' in __getitem__
        def __getitem__(self, generic_type):
            return type('Example', (Example,), {'_my_types': (SampleTypeX, generic_type)})

    class Example(MyBaseClass[TypeX], metaclass=ExampleMeta):
        pass

    Example[SampleTypeX](X=[0, 1, 2])

    with pytest.raises(pydantic.error_wrappers.ValidationError):
        Example[SampleTypeY](X=1)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug V1Bug related to Pydantic V1.X

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions