1

I can't seem to get a generic type working. I am subclassing Deque. Each item of the Deque will be an instance of SomeNamedTuple.

from typing import NamedTuple, Deque, TypeVar

class SomeNamedTuple(NamedTuple):
    field1: int
    field2: str

T = TypeVar("T", bound=NamedTuple)

class SomeDeque(Deque[T]):
    def some_method(self) -> None:
        if self:
            print(self[0]._fields)

mydeque = SomeDeque[SomeNamedTuple]()
$ mypy --strict foo.py
foo.py:14: error: Value of type variable "T" of "SomeDeque" cannot be "SomeNamedTuple"

I put in some debugging in mypy/applytype.py where the error is generated:

upper_bound = callable.variables[i].upper_bound
if not mypy.subtypes.is_subtype(type, upper_bound):
    if skip_unsatisfied:
        types[i] = None
    else:
        print(f'type = {type}')
        print(f'upper_bound = {upper_bound}')
        msg.incompatible_typevar_value(callable, type, callable.variables[i].name, context)

and it looks like it thinks the type is a Tuple (not NamedTuple):

$ mypy --strict foo.py                                                                                                                                                                                                                       
type = Tuple[builtins.int, builtins.str, fallback=foo.SomeNamedTuple]
upper_bound = typing.NamedTuple
foo.py:14: error: Value of type variable "T" of "SomeDeque" cannot be "SomeNamedTuple"

What am I doing wrong?

3
  • consider: issubclass(SomeNamedTuple, typing.NamedTuple) is False and issubclass(SomeNamedTuple, tuple) is True. Relevant issue: github.com/python/mypy/issues/3915 Basically, NamedTuple is not a real class/type Commented Mar 18, 2019 at 19:23
  • Possible duplicate: stackoverflow.com/questions/50766461/… Commented Mar 18, 2019 at 19:26
  • So the workaround, if one insists on using NamedTuple, is to drop the bound= and annotate the NamedTuple accesses (such as ._fields) with # type: ignore Commented Jun 17, 2021 at 8:21

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.