Skip to content
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

False positive: variable re-assigned with different type treated as of previous type #9700

Closed
ponbaton opened this issue Nov 5, 2020 · 8 comments
Labels
bug mypy got something wrong

Comments

@ponbaton
Copy link

ponbaton commented Nov 5, 2020

Bug Report

If you reassign a variable with a different (probably compatible) type, mypy still treats it as if it did not change the type

To Reproduce

Analyze this:

from typing import Tuple


class C:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    @classmethod
    def other_ctor(cls, x, y):
        return cls(x, y)


def will_fail(arg: Tuple[int, int]):
    arg = C.other_ctor(*arg)
    print(arg.x + arg.y)

Expected Behavior

Success: no issues found in 1 source file

Actual Behavior

>mypy break_mypy\failure.py
break_mypy\failure.py:16: error: "Tuple[int, int]" has no attribute "x"
break_mypy\failure.py:16: error: "Tuple[int, int]" has no attribute "y"
Found 2 errors in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: 0.790
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini (and other config files): default, freshly installed
  • Python version used: python 3.6.6 @ Win10 v1909, python 3.7.9 @ Ubuntu 16.04

Additional info

This version without classmethod constructor gives yet another error:

from typing import Tuple


class C:
    def __init__(self, x, y):
        self.x = x
        self.y = y


def will_fail(arg: Tuple[int, int]):
    arg = C(*arg)
    print(arg.x + arg.y)
break_mypy\failure.py:11: error: Incompatible types in assignment (expression has type "C", variable has type "Tuple[int, int]")
break_mypy\failure.py:12: error: "Tuple[int, int]" has no attribute "x"
break_mypy\failure.py:12: error: "Tuple[int, int]" has no attribute "y"
Found 3 errors in 1 file (checked 1 source file)

C was originally a wrapper subclass of namedtuple, but I removed it while working on the MVE.

One more example with namedtuple:

from collections import namedtuple
from typing import Tuple


class C(namedtuple('CNt', 'x y')):
    @classmethod
    def other_ctor(cls, x, y):
        return cls(x, y)


def will_not_fail(arg: Tuple[int, int]):
    arg = C(*arg)
    print(arg.x + arg.y)


def will_fail(arg: Tuple[int, int]):
    arg = C.other_ctor(*arg)
    print(arg.x + arg.y)
break_mypy\failure.py:18: error: "Tuple[int, int]" has no attribute "x"
break_mypy\failure.py:18: error: "Tuple[int, int]" has no attribute "y"
Found 2 errors in 1 file (checked 1 source file)
@ponbaton ponbaton added the bug mypy got something wrong label Nov 5, 2020
@JelleZijlstra
Copy link
Member

Try using the --allow-redefinition flag.

@ponbaton
Copy link
Author

ponbaton commented Nov 6, 2020

Hmm, it works, thanks. The original error messages are a bit misleading though: most of the time the do not even point to redefinition problems

Is this the indended behavior? Is it documented somewhere?

@ponbaton
Copy link
Author

ponbaton commented Nov 6, 2020

The behavior when mypy does not always detect fields in the re-assigned type (sometimes it does, sometimes it does not) still looks like a bug to me. Have a look at the example with namedtuple

@ponbaton
Copy link
Author

ponbaton commented Nov 6, 2020

@JelleZijlstra, could you re-open the issue?

@JelleZijlstra
Copy link
Member

That's just because mypy keeps the original declared type.

@ponbaton
Copy link
Author

ponbaton commented Nov 6, 2020

Then again: is it documented behavior or an implementation detail? I think it is very confusing and should be documented or fixed

@JelleZijlstra JelleZijlstra reopened this Nov 16, 2020
@JelleZijlstra
Copy link
Member

OK, let's reopen as a documentation issue.

@hauntsaninja
Copy link
Collaborator

I believe this is just #2008 again. We recently had a big discussion about this, and agreed that the behaviour needs to change.
There's also an open issue already for documentation of the existing behaviour: #7252

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

3 participants