Skip to content

After Optional[str] == 'literal', infer that it's not optional #1825

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
gvanrossum opened this issue Jul 7, 2016 · 4 comments
Closed

After Optional[str] == 'literal', infer that it's not optional #1825

gvanrossum opened this issue Jul 7, 2016 · 4 comments

Comments

@gvanrossum
Copy link
Member

Example:

def f(a: Optional[str]) -> str:
    if a == '<string>': return a[1:-1]
    else: return ''

With --strict-optional, this produces an error:

error: Value of type None is not indexable

It would be nice if mypy understood that a is a string if this == returns True.

@ddfisher
Copy link
Collaborator

ddfisher commented Jul 21, 2016

We should probably fix this more generally with Unions:

def f(a: Union[int, str]) -> str
   if a == '<string>': return a  # mypy should understand that a must be a string here
   else: return str(a)

Are we okay with saying that equality must imply some sort of type equivalence? (In particular, that a == b implies a is either a super- or sub-class of b.)

@gvanrossum
Copy link
Member Author

I was more thinking that the join of the two types should not be object.

We should carefully introduce and test such a change because I expect it'll cause some noise in various large projects (most of which I expect to be questionable code in those projects, but some might be due to our rules needing some exception, and either wait it'll take a while to sort it all out).

FWIW the same rule should apply to x in c and x not in c -- the type of x and the type of c's items must have a non-trivial join.

@gvanrossum gvanrossum added this to the 0.5 milestone Jul 21, 2016
@dmoisset
Copy link
Contributor

dmoisset commented Aug 5, 2016

Asuming that on a == 'text', a is string is somewhat unsafe. There's a slight danger given that == can be redefined, so I could have a class with an __eq__ method that considers itself equal to string but doesn't have other string properties. A similar problem occurs with "in" given that it depends on __eq__.

The only operator where I think this could safely be done is "is" and "is not", but that doesn't cover the example.

@rwbarton
Copy link
Contributor

rwbarton commented Aug 5, 2016

In general that assumption is unsafe, but here a has type Optional[str] = Union[None, str] and it's quite reasonable to assume that == will not be redefined on None.

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

4 participants