Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ateraz opened this issue Aug 30, 2019 · 1 comment · Fixed by #7444
Closed

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

ateraz opened this issue Aug 30, 2019 · 1 comment · Fixed by #7444
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code good-first-issue priority-1-normal topic-type-variables

Comments

@ateraz
Copy link
Contributor

ateraz commented Aug 30, 2019

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.

@JukkaL
Copy link
Collaborator

JukkaL commented Sep 2, 2019

Yes, this is a bug. The simplest fix would be to add an isinstance(upper_bound, TupleType) check and update item to point to the fallback. Do you want to give it a try?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code good-first-issue priority-1-normal topic-type-variables
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants