-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
List[<nothing>] error #3283
Comments
Maybe @ddfisher understands this? IMO it's always an error when |
Unfortunately, currently it is quite easy to get T = TypeVar('T')
def fun(x: List[T]) -> T:
...
fun(1) # Error: Argument 1 to "fun" has incompatible type "int"; expected List[<uninhabited>] I think such errors are quite cryptic, so I set priority to high here. |
My understanding is that this is a failure of type variable inference -- the context mechanism isn't working fully here. Prior to #3024, I think these error messages would reference The fact that there's an error here at all is a problem with the context mechanism (perhaps related to Unions?). |
In the original example, it looks like we don't infer a type because it's ambiguous due to the union type context. This is a known issue, though it might only be mentioned in a comment in the code. Here's a simpler repro:
Here I can see a few plausible options:
In @ilevkivskyi's example there is no context that can be used to infer things, so maybe we should fail type inference and generate an error about not being able to infer a value for a type variable. Alternatively, we could pick an arbitrary type variable value such as inferring |
@JukkaL If |
That's what I thought too -- after all if you use PEP 526 and write
then a's type is indeed However the point here is more subtle -- with the union-of-lists type, any append to the variable later will then flagged as an error. But perhaps we can adapt the machinery for partial types to our needs here? If a later line appends an int, change a to List[int], if a later line appends a str, change it to List[str]. Once changed to a non-union type, type-check with that type (so that appending an int and then a str is invalid). This would have the same limitations of the existing partial type inferencing machinery (e.g. if you use an operation it doesn't understand, it falls back to "Need annotation for type variable" -- would have to be changed for this case) but I think it would work relatively well. I'd also like to challenge this a bit: what would be a real-world use case for writing such a statement in the first place? If we can't think of any, we could just make it an error. |
Mypy internally infers |
Something like this might be kind of reasonable: def f(x: Union[List[str], List[bytes]]) -> None:
if <whatever>:
x = []
... I think that we could just as well fail to infer a type for the expression and require a cast. This should be fine: from typing import Union, List, cast
a = cast(List[int], []) # type: Union[List[int], List[str]] This would also be fine, without a cast: from typing import Union, List, cast
temp = [] # type: List[int]
a = temp # type: Union[List[int], List[str]] We already require casts semi-frequently so requiring it for an unusual edge case doesn't sound too bad. However, it would be better to generate an error message that would at least hint at a solution. |
My use case is a sort of pandas dataframe. Because each list (column) only has one type (datetime or float, never both in the same list), the typing shouldn't be |
The idea that we could allow union types appeared in three separate contexts recently:
The general idea that I see in these three cases is that we could use unions in simple cases instead of avoiding them. It looks like users actually don't find them scary (and even like them in case of TypeScript). |
The Pandas dataframe example might be better served with TypedDict. ( @jcrmatos beware that TypedDict still has some unfinished features. They're on the road map.) |
I agree that we'll probably need to have more support for union use cases, at least because strict optional checking makes unions a very common thing. Every user who uses strict optional checking needs to be understand unions anyway so there's now less need to avoid them. |
And it would be correct to do so, in general. For example:
Even this is perfrectly reasonable IMO; what does the user expect when they declare a union and try to use it as if it's not:
Of course, in some cases mypy may be able to bind it more narrowly, but that's like a bonus feature, not something that the user should expect to happen in arbitrary situations:
Ah I see, we just use different wording. I completely agree with you, it's just that when I say |
The errors now have |
Hello,
Already showed this in Gitter and was told to open the issue here.
My env is Win7P+SP1 x64, Py 3.5.2 32b and mypy 0.501.
I have the following situation:
With the following code mypy doesn't return an error (which is correct):
But with the following code mypy returns a strange error
Best regards,
JM
The text was updated successfully, but these errors were encountered: