2

I have a function take any NamedTuple class (not object) as input. here people recommend to use Type[base_class] as hint, but it does not work for NamedTuple:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
from typing import Type, NamedTuple

class A:
    pass

class B(A):
    pass

class C(A):
    pass

def process_any_subclass_type_of_A(cls: Type[A]):
    if cls == B:
        pass
    elif cls == C:
        pass

process_any_subclass_type_of_A(B) # works fine

class test_t(NamedTuple):
    x: str
    y: str

def func1(cls: Type[NamedTuple]):
    print(cls)
    

func1(test_t) # mypy show error Argument 1 to "func1" has incompatible type "Type[test_t]"; expected "Type[NamedTuple]"

Isn't the test_t is subclass of NamedTuple? Why A is working but not NamedTuple?

Updates: the NamedTuple is a meta class. Then the question will be how can I type hint a set of class derived from same metaclass?

Wang
  • 7,250
  • 4
  • 35
  • 66
  • 2
    unfortunately, `NamedTuple` isn't a (real) type. The correct parent class here is just `tuple`... For instance, try `test_t.mro()` and you'll get `[__main__.test_t, tuple, object]`... and `isinstance(test_t, NamedTuple)` is false. – juanpa.arrivillaga Mar 31 '21 at 18:58
  • 2
    See [this answer to a different question that has more information on what I mean by "isnt a real type"](https://stackoverflow.com/questions/60707607/weird-mro-result-when-inheriting-directly-from-typing-namedtuple/60883973#60883973) – juanpa.arrivillaga Mar 31 '21 at 19:01
  • @MadPhysicist yeaaa I'm just not exactly sure on the subtleties involved here vis a vis static type checking, all I know is that you should not treat `NamedTuple` as a type, even though it *is* a type in the sense that `isintance(NamedTuple, type)`, it's sort of an aberration, but I think it's just one of those "practicality beats purity" situations – juanpa.arrivillaga Mar 31 '21 at 19:04
  • I went ahead and closed this. The linked question uses somewhat more specific language, but the answers fully cover all aspects of this question. – Mad Physicist Mar 31 '21 at 19:05
  • 1
    NamedTuple is not a metaclass. You've misunderstood things. – user2357112 Mar 31 '21 at 19:09

0 Answers0