Skip to content

Using a class inherited from tuple as a bound in TypeVar #7427

Closed
@ateraz

Description

@ateraz

I think I've encountered mypy bug. Here's the code I'm trying to check with mypy (sorry if it's big, I think additional code helps debugging):

from typing import NamedTuple, Type, TypeVar

# case 1 - inheriting from custom class, mypy check passes.
T1 = TypeVar("T1", bound="B")

class A:
    pass

class B(A):
    @classmethod
    def method(cls) -> None:
        print("B class method")

    @classmethod
    def factory(cls: Type[T1]) -> T1:
        cls.method()
        return cls()

# case 2 - inheriting from named tuple, mypy check fails.
T2 = TypeVar("T2", bound="C")

class C(NamedTuple):
    @classmethod
    def method(cls) -> None:
        print("C class method")

    @classmethod
    def factory(cls: Type[T2]) -> T2:
        cls.method()  # error: "Type[T2]" has no attribute "method"
        return cls()
  • What is the actual behavior/output?
$ mypy test.py
test.py:29: error: "Type[T2]" has no attribute "method"
  • What is the behavior/output you expect?
    no errors
  • What are the versions of mypy and Python you are using?
    python 3.7.3, mypy both 0.720 and 0.730+dev.811c201551ecb151f83e982da3ad8f46fa2ebe84
  • What are the mypy flags you are using?
    no flags

I've been able to track the error till this line mypy/checkmember.py#L261. In first case upper_bound is test.B, but in second it's Tuple[, fallback=test.C] and fallback is not checked. I'm not sure how to proceed from here though because it's probably not safe to always check a fallback.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions