Skip to content

GenericModel - Allow subclasses of concrete generics to be generic #2005

@choogeboom

Description

@choogeboom

Checks

  • I added a descriptive title to this issue
  • I have searched (google, github) for similar issues and couldn't find anything
  • I have read and followed the docs and still think this feature/change is needed
  • After submitting this, I commit to one of:
    • Look through open issues and helped at least one other person
    • Hit the "watch" button on this repo to receive notifications and I commit to help at least 2 people that ask questions in the future
    • Implement a Pull Request for a confirmed bug

Feature Request

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

             pydantic version: 1.6.1
            pydantic compiled: False
                 install path: /wayfair/home/ch438l/pydantic/pydantic
               python version: 3.6.8 (default, Aug 10 2019, 06:54:07)  [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
                     platform: Linux-3.10.0-862.3.2.el7.x86_64-x86_64-with-centos-7.5.1804-Core
     optional deps. installed: ['typing-extensions', 'email-validator', 'devtools']

I'd like to be able to define a generic model, then create a subclass of that generic model that both fills in the type parameter of the superclass, while introducing new type parameters. Here's a currently failing test case that illustrates the issue:

@skip_36
def test_generic_subclass_of_concrete_generic():
    T = TypeVar("T")
    U = TypeVar("U")

    class GenericBaseModel(GenericModel, Generic[T]):
        data: T

    class GenericSub(GenericBaseModel[int], Generic[U]):
        extra: U

    GenericSub[str]

Currently that test case fails with TypeError: Cannot parameterize a concrete instantiation of a generic model

This happens because GenericBaseModel[int].__concrete__ gets set to True, and GenericSub inherits it.

This can easily be fixed with the following change to generics.py:

        if cls.__concrete__:
            raise TypeError('Cannot parameterize a concrete instantiation of a generic model')

Should become

        if cls.__concrete__ and typing.Generic not in cls.__bases__:
            raise TypeError('Cannot parameterize a concrete instantiation of a generic model')

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions