Skip to content

Type of 'and' expressions may be too general #2716

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
JukkaL opened this issue Jan 19, 2017 · 3 comments
Closed

Type of 'and' expressions may be too general #2716

JukkaL opened this issue Jan 19, 2017 · 3 comments

Comments

@JukkaL
Copy link
Collaborator

JukkaL commented Jan 19, 2017

Mypy complains about this code, but perhaps it shouldn't (I'm assuming no --strict-optional):

class A: pass

def f(a: A, b: bool) -> bool:
    return a and b  # Incompatible return value type (got "Union[A, bool]", expected "bool")

f may return a bool object (if a is not None) or None (if a is None) but it can never return an A instance (unless a subclass of A defines __bool__ -- which we might not care about) so the inferred type for the return value may not be what we want.

I think I saw some real-world false positives caused by this, though I didn't look very carefully.

When using --strict-optional, we'll probably require using bool(...) around the return value since the type would otherwise be Optional[bool], which is not compatible with bool.

(I remember having a similar earlier discussion but couldn't find an existing issue.)

@ddfisher
Copy link
Collaborator

With --strict-optional, a can't be None, so bool(...) shouldn't be necessary.

We already have a mechanism for tracking truthiness and falseness for things like this, so I think this proposal boils down to saying that user-defined classes that don't define a __bool__ should always be considered truthy. This touches on the issue of how we feel about subclasses adding new dunder methods that we don't expect. We decided not to worry about that for callable (see: #2627), but I think it'd be a good idea to think about the general case carefully, make a decision, and then document it clearly before moving forward here.

@JukkaL
Copy link
Collaborator Author

JukkaL commented Jan 19, 2017

I forgot to mention that the strict optional alternative would use a: Optional[A].

The reason why I'm thinking about ignoring the possibility of a subclass defining __bool__ is that we do a similar things elsewhere, such as assuming that there isn't multiple inheritance in some cases when type checking overloaded functions, and we make some optimistic assumptions about operator methods and their reverse variants. In the early days mypy tried to be very correct, but this made mypy complain about code that users considered correct, so mypy was made more lenient. This looks like another case where leniency might be the better option. We can run some queries against large code repositories to see if it's common to introduce __bool__ in a subclass.

At least object is special and subclasses clearly may define __bool__. Also, at least some ABCs might also complicate the picture. It's not obvious whether this is the right thing to do in general, or whether it makes sense to come up with some ad-hoc rules about ABCs or similar.

@JukkaL
Copy link
Collaborator Author

JukkaL commented Jan 28, 2020

This doesn't seem to cause trouble too frequently, and there has been no activity in a long time, so I'm closing the issue.

@JukkaL JukkaL closed this as completed Jan 28, 2020
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

2 participants