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

Unexpected behaviour when using None as generic argument #2230

Closed
dmoisset opened this issue Oct 7, 2016 · 6 comments
Closed

Unexpected behaviour when using None as generic argument #2230

dmoisset opened this issue Oct 7, 2016 · 6 comments
Labels
bug mypy got something wrong topic-strict-optional

Comments

@dmoisset
Copy link
Contributor

dmoisset commented Oct 7, 2016

I'm trying the following code

from typing import Dict, List

def f() -> Dict[None, None]:
    return {}

def g() -> List[None]:
    return []

a = f()
b = g()

Which reports 4 errors (2 for list and 2 for dict) which I think are all incorrect:

foo.py: note: In function "f":
foo.py:4: error: Incompatible return value type (got Dict[object, object], expected Dict[None, None])
foo.py: note: In function "g":
foo.py:7: error: Incompatible return value type (got List[object], expected List[None])
foo.py: note: At top level:
foo.py:9: error: Need type annotation for variable
foo.py:10: error: Need type annotation for variable
  • The error on lines 4, 7 appear to say that the empty container does not match the given type, while it should (the valid values of Dict[None, None] should be {} and {None: None}, the valid values for List[None] should be [] and [None]*k for any natural number k)
  • The assignments demand a type annotation, although the type of the expression has been fully specified.

Using generics different than None works fine.

@dmoisset
Copy link
Contributor Author

dmoisset commented Oct 7, 2016

As a clarification, this happens with --strict-optional

@gvanrossum
Copy link
Member

gvanrossum commented Oct 7, 2016 via email

@ddfisher
Copy link
Collaborator

ddfisher commented Oct 7, 2016

There are two things going on here:

  1. Inference isn't working properly with contexts containing None (i.e. [] is being incorrectly inferred as List[object] instead of List[None]. This is a bug.
  2. Currently, we've decided that partial types containing None (aside from plain None) should demand a type annotation if they don't receive enough information to be inferred as specific Optional types. This generally results in better error messages. Here's an example:
from typing import List, Optional

def f(lst: List[Optional[int]]): pass
x = [None]
f(x)

Currently, this gives a Need type annotation for variable on x = [None]. If we didn't demand a type annotation for x, we could potentially give this error on f(x) instead: Argument 1 to "f" has incompatible type List[None]; expected List[Optional[int]]. This could be a reasonable change to make, though I think collections of None are relatively rare.

@dmoisset
Copy link
Contributor Author

OK, I understand the motivation behind 2. Perhaps a more explicit error message would have helped, I got used to read "Need type annotation for variable" as "mypy doesn't have enough information to infer this type", but in this case is "mypy decided to not infer this type because it will be probably wrong".

The example I mentioned is also a bit different because b can be exactly inferred as List[None]; there is no ambiguity as there is in the [None] expression you assigned to x, given the explicitness in the return type of g()... My guess is that that return type shouldn't be flagged as partial, which from a quick look would avoid the warning, am I correct?

JukkaL pushed a commit that referenced this issue Oct 11, 2016
@gnprice gnprice added topic-strict-optional bug mypy got something wrong labels Oct 13, 2016
@gvanrossum
Copy link
Member

Right now only the last two error messages still appear.

@ddfisher
Copy link
Collaborator

I'm going to close this issue because problem 1 is fixed. I've made a new issue to track problem 2: #2246.

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

No branches or pull requests

4 participants