Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
4 tasks done
choogeboom opened this issue Oct 14, 2020 · 0 comments · Fixed by #2006
Closed
4 tasks done

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

choogeboom opened this issue Oct 14, 2020 · 0 comments · Fixed by #2006

Comments

@choogeboom
Copy link
Contributor

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')
choogeboom added a commit to wayfair-contribs/pydantic that referenced this issue Oct 14, 2020
samuelcolvin pushed a commit that referenced this issue Oct 25, 2020
* Allow generics to extend concrete classes. fixes #2005

* Update the docs

* Updote the changes

* Convert double quotes to single quotes

* Fix formatting

* Add a check for data

* Update example

* Add a skip_36 decorator that got accidentally deleted when resolving conflicts.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant