Skip to content

Augmented assignment leads to type complaints #2098

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
JdeH opened this issue Sep 5, 2016 · 6 comments
Closed

Augmented assignment leads to type complaints #2098

JdeH opened this issue Sep 5, 2016 · 6 comments
Labels
bug mypy got something wrong

Comments

@JdeH
Copy link
Contributor

JdeH commented Sep 5, 2016

Hi,

I am using mypy 0.4.4. It seems augmented assignments aren't yet dealt with correctly.

weight0 = 65.5
weight0 = 65
weight0 *= 0.5                  # Gives error, unsup operand types for * ("int" and "float")
weight1 = 65.5
weight1 = 65
weight1 = weight1 * 0.5    # Gives no error
@gvanrossum
Copy link
Member

gvanrossum commented Sep 6, 2016 via email

@elazarg
Copy link
Contributor

elazarg commented Sep 6, 2016

The error is not directly related to augmented assignment, I think. Mypy assumes that the second assignment kills the first

x = 65.5  # type: float
reveal_type(x)  # E: Revealed type is 'builtins.float'
x = 65
reveal_type(x)  # E: Revealed type is 'builtins.int'

Just like any other case of compatible assignment. So how is that different from the simpler case

x = 65
x += 5.0  # E: Unsupported operand types for + ("int" and "float")

Allowing the latter (inferring float without any other hint) can easily miss real type errors.

@JdeH
Copy link
Contributor Author

JdeH commented Sep 6, 2016

@elazarg:

If that's the cause, why then is

weight1 = 65.5
weight1 = 65
weight1 = weight1 * 0.5    # Gives no error

considered correct?

@elazarg
Copy link
Contributor

elazarg commented Sep 6, 2016

I think that because x = x * 0.5 is an assignment, mypy considers it as introducing a "new variable", whereas x *= 0.5 is a method call, and it operates on a previously defined variable.

In other words, x = x * 0.5 contains two distinct variables with possibly distinct types, and x *= 0.5 contains a single variable.

@JukkaL
Copy link
Collaborator

JukkaL commented Sep 6, 2016

It seems that *= doesn't rebind the variable type, unlike =. However, I think that it should.

= doesn't actually introduce new variable but it does introduce a new "type binding" for a variable. This means that the new binding must be compatible with the declared or inferred type of the variable -- mypy doesn't currently let you arbitrarily redefine a variable.

@JdeH
Copy link
Contributor Author

JdeH commented Sep 6, 2016

Indeed from a 'user' point of view, the disparity between simple assignment and augmented assignment is hard to comprehend. At least for me it was... So if it could be avoided I think it would be an improvement.

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

4 participants