Skip to content

Error when preserving generic type behaviour in subclasses (when not supported at runtime) #8523

Closed

Description

@rwarren

This is a bug report.

  • mypy = 0.770
  • python = 3.8.2
  • I did not try running mypy from git master

The docs for "Using classes that are generic in stubs but not at runtime" (here) clearly indicate how to subclass classes that are defined to be generic in their stubs but don't actually support generics in their runtime code.

The shown method (conditionally defining a typed subclass) works great when you want to lock the type down in your subclass. However, if you want to maintain the subclass as a generic it does not work (mypy reports an error).

Here is failing case (with mypy --strict), where the only variation from the canonical example is using a generic TypeVar instead of a str as the type for the Queue:

from queue import Queue
from typing import TYPE_CHECKING, TypeVar

_T = TypeVar("_T")
if TYPE_CHECKING:
    MyQueueBase = Queue[_T]  # change _T to str here and it works perfectly (per the docs)
else:
    MyQueueBase = Queue
class MyQueue(MyQueueBase): pass  # mypy error is on this line (9)

mypy reports an error as follows (when the base is Queue[_T]):

$ python --version
Python 3.8.2
$ mypy --version
mypy 0.770
$ mypy --strict ./generic_subclass_example.py 
generic_subclass_example.py:9: error: Missing type parameters for generic type "MyQueueBase"
Found 1 error in 1 file (checked 1 source file)

Note that without --strict there is no error (not sure which of the flags causes it).

Activity

  1. msullivan commented on Mar 17, 2020

    @msullivan
    Collaborator

    The relevant error flag is --disallow-any-generics.

    I am actually not totally sure what the best way to handle this is?

  2. msullivan commented on Mar 17, 2020

    @msullivan
    Collaborator

    How about this unfortunate hack (that creates another class in the hierarchy unfortunately)

    from queue import Queue
    from typing import TYPE_CHECKING, TypeVar, Generic
    
    _T = TypeVar("_T")
    if TYPE_CHECKING:
        class MyQueueBase(Queue[_T]): pass
    else:
        class MyQueueBase(Generic[_T], Queue): pass
    
    class MyQueue(MyQueueBase[_T]): pass
    
  3. added a commit that references this issue on Nov 28, 2020
    8142da0
  4. added a commit that references this issue on Jan 6, 2021
    6e8c0cd
  5. added a commit that references this issue on Jan 19, 2021
    a7d4c67
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions