-
Notifications
You must be signed in to change notification settings - Fork 242
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
How should type checkers type check equality? #378
Comments
If we warn about I would suggest adding strict types for equality methods to typeshed stubs only if they are really strict for these objects at run-time. |
I think it is OK to warn that Adding special cases like this to typecheckers doesn't seem sustainable, If we want to distinguish between always True or always False and other comparisons, then the best approach is add the information to typeshed. For example, if
then a simple checker would just see |
If we let each type checker figure out this separately, we still have the question of how to annotate We have at least these options:
I think that the existing approach (1) is good enough, and the alternatives aren't (at least significantly) better. However, (3) or (3) + (4) would arguably be more correct ways to do this. |
I like the idea of @markshannon. It is practical and simple to understand for a reader. Alternatively, one can use self type in the typeshed for |
Note that mypy now has an experimental |
Is this something that needs more discussion? I am going to close this for now, but please reopen or bring it up on typing-sig if you still think this is an issue. |
Right now typeshed defines equality to be defined for each pair of types, even though something like
n == (m,)
is almost certainly a bug if bothn
andm
are integers, for example. There is no runtime error, so not rejecting it would also be somewhat reasonable (also, a subclass ofint
might plausibly returnTrue
when compared against a tuple, though this more of a theoretical concern). It's unclear how type checkers should deal with these. As equality checking is very common, and anecdotally errors related to equality checking are not infrequent, we may want to spell out how this should be done in PEP 484, so that all tools would handle these consistently.Here are some options:
__eq__
and__ne__
accept arbitrary objects.__eq__
and__ne__
accept arbitrary objects, but require type checkers to have special, well-defined rules for type checking==
and!=
operations so that we can rejectn == (m,)
and other similar cases consistently.__eq__
and__ne__
. This may require special rules for these methods, since we may want to narrow down the argument type in a subclass (as it should be possible to compareobject
toobject
), but normally method argument types vary contravariantly so this is not allowed. For example,int.__eq__
would only acceptint
arguments, since this seems to returnNotImplemented
for other argument types. It's still unclear what the exact rules for type checking__eq__
and__ne__
should be.typing
to represent "comparable types" or "equatable types". For example, I might want to define functionisequal(x, y)
that takes two arguments that can be of arbitrary types as long as they might compare equal to each other.isequal(1, 1.1)
should be okay butisequal(1, 'x')
should be rejected. We'd then use this concept to type check==
and!=
as well. This could be useful for things like__contains__
. If the result of anin
operation is known to beFalse
statically, we should perhaps reject it as well.Also see python/mypy#1271 and the conversation in python/typeshed#874.
The text was updated successfully, but these errors were encountered: