5

What is the correct way to define a Generic NamedTuple in using the typing module python 3.7?

I can define

from typing import TypeVar, Generic, NamedTuple

T = TypeVar("T")

class C(Generic[T], NamedTuple):
    """NameTuple and Generic ???"""
    x: T

c = C(1)
print(c)  # prints "C(x=1)", as expected

However, I cannot use the C[T] as a type hint:

# raises TypeError: 'type' object is not subscriptable
def f(c: C[int]):
    print("from f:", c)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
vpquant
  • 81
  • 3
  • 1
    Unless I'm mistaken, the metaclass conflict mentioned in [Generic NamedTuple in Python 3.6](https://stackoverflow.com/questions/50530959/generic-namedtuple-in-python-3-6) does not apply to python 3.7, where `__class_getitem__` is used as detailed in *PEP 560*. It seems that `typing.NamedTupleMeta` calls [collections.namedtuple()](https://github.com/python/cpython/blob/f45813df52207ae870fda86475976a9b42857592/Lib/collections/__init__.py#L460) which uses `type(...)` with no other base classe than `tuple`. I don't see a workaround - hence the question here... (I don't think it's a duplicate) – vpquant Mar 12 '19 at 21:13
  • @MartijnPieters this doesn't look like a duplicate ^^^ – joel Sep 28 '19 at 14:05
  • @JoelBerkeley: Yes, Python 3.7 added `__class_getitem__`, but the problem is still the same; the metaclasses between `NamedTuple` and `Generic` conflict. The `NamedTuple` metaclass will always return a subclass of `tuple`, so the `Generic` base is lost, and so no `__class_getitem__` method is available. Python 3.7 *does not fix the problem*. – Martijn Pieters Sep 28 '19 at 14:55
  • @JoelBerkeley: and the answer on the dupe has a work-around that works just as well in Python 3.7. – Martijn Pieters Sep 28 '19 at 15:14
  • @vpquant: put differently: sorry, you are mistaken. The metaclass conflict still applies. – Martijn Pieters Sep 28 '19 at 15:15

0 Answers0