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

Inferring a more precise type on assignment to a variable with Any type #2928

Open
JukkaL opened this issue Mar 1, 2017 · 5 comments
Open

Comments

@JukkaL
Copy link
Collaborator

JukkaL commented Mar 1, 2017

Mypy infers the type Any for y after the second assignment:

from typing import Any

def f(x: Any) -> None:
    y = x
    y = 1
    reveal_type(y)  # Any

Inferring int as the type might be less surprising. However, if a variable is explicitly declared with an Any type, such as x in the above example, it's less clear what would be the right thing to do.

A more general solution would allow redefining variables with arbitrary new types (#1174).

@gvanrossum
Copy link
Member

It seems that in general variables whose initial type is Any are untouched by the binder and always remain typed as Any? That doesn't feel right or consistent. IMO it should mean that anything can be assigned to such a variable, not that we should ignore tracking assignments.

As a work-around, if the initial type is object you can also assign anything to a variable, and it does get tracked by the binder. But I don't like the long-lasting effect of Any here.

@JukkaL
Copy link
Collaborator Author

JukkaL commented Mar 1, 2017

The Any type can come from a skipped module, so using object is not a good workaround in general.

@ddfisher
Copy link
Collaborator

ddfisher commented Mar 2, 2017

One thing to note is that we don't distinguish between variables that have type annotations and variables that set their type from the first assignment. The example would look a lot more reasonable if it was:

from typing import Any

def f(x: Any) -> None:
    y = x  # type: Any
    y = 1
    reveal_type(y)  # Any

In this case example (where the type is explicit), I don't think it makes sense to reduce Any's use as an escape hatch. There's an argument to be made for behaving differently with and without an explicit type annotation, but that comes with a cost in complexity and user education. My initial inclination is it's not worthwhile here.

@gvanrossum
Copy link
Member

This is an old argument (so far carried out in private I think) but I don't think the explicit # type: Any should override the subsequent assignment of a value of a given type either. I like to see the analogy between

y = x # (inferred or declared Any)
y = 1
reveal_type(y)

and

y = x # (inferred or declared Any)
assert isinstance(y, int)
reveal_type(y)

I think both of these should reveal the same type (int).

(In fact, if anything, the assert has less of a runtime guarantee about y's "int-less" than the straight assignment, since python -O doesn't compile code for assert.)

@JukkaL
Copy link
Collaborator Author

JukkaL commented Jan 28, 2020

This would be nice to fix, on one hand. On the other hand, this could generate a lot of false positives in existing code that type checks cleanly, so I'm not sure if fixing this is actually worth it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants