Skip to content

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

Closed
@ponbaton

Description

@ponbaton

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions