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?

Tommy
  • 245
  • 4
  • 11
  • consider: `issubclass(SomeNamedTuple, typing.NamedTuple)` is `False` and `issubclass(SomeNamedTuple, tuple)` is `True`. Relevant issue: https://github.com/python/mypy/issues/3915 Basically, `NamedTuple` is not a real class/type – juanpa.arrivillaga Mar 18 '19 at 19:23
  • Possible duplicate: https://stackoverflow.com/questions/50766461/whats-the-difference-between-namedtuple-and-namedtuple – juanpa.arrivillaga Mar 18 '19 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` – Nickolay Jun 17 '21 at 08:21

0 Answers0