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

Stricter equality checks? #1271

Closed
averagehat opened this issue Mar 4, 2016 · 9 comments · Fixed by #6370
Closed

Stricter equality checks? #1271

averagehat opened this issue Mar 4, 2016 · 9 comments · Fixed by #6370

Comments

@averagehat
Copy link

It would be nice if there was a way to enforce a constraint on __eq__ -- maybe a warning? I almost never want to do the following

def test_operator(): # type: () -> None
    1 == "1"
# produces no complaints

While that check may make sense in a world of vanilla python, I'd argue it doesn't make much sense within mypy's world (especially if the arguments are explicitly typed as different types; i.e., one is not a subtype of the other).

@gvanrossum
Copy link
Member

gvanrossum commented Mar 4, 2016 via email

@JukkaL
Copy link
Collaborator

JukkaL commented Mar 4, 2016

The operators !=, is and is not are similar. Also, mypy doesn't complain about things like 1 in ['x'] since it doesn't raise a runtime exception.

@wcooley
Copy link

wcooley commented Jun 2, 2016

Attempting to specify a type other than Any or object with __eq__ results in an error message like this:

foo.py: note: In class "Foo":
foo.py:4: error: Argument 1 of "__eq__" incompatible with supertype "object"

(I'm adding this in case someone else is searching for this error.)

@dgoldstein0
Copy link

+1 would love to see this - had to troubleshoot a bug today that turned out to a stray , making an equality check fail because one side had accidentally become a tuple.

@ilevkivskyi
Copy link
Member

It looks like this appears often, so I raise priority to high.

@nharkins
Copy link

+1, would love this feature. just had a bug with a missing parens, i.e. if func != 0:

@jstasiak
Copy link
Contributor

Kind of similar to the above: I did forget a few times that obj.thing is a method, not a property, wrote if obj.thing: and got an always-on block of code.

@efroemling
Copy link

+1 would love to see this too. I'm replacing a bunch of old string values with more type-safe enum objects and would love to get errors in places where my code needs updating, such as: if obj.enum_value == 'my_old_hard_coded_string_value'

@ilevkivskyi
Copy link
Member

@jstasiak Your case is a bit different, it is like #2073

ilevkivskyi added a commit that referenced this issue Feb 15, 2019
…6370)

Fixes #1271

The new per-file flag `--strict-equality` disables equality, identity, and container checks between non-overlapping types. In general the implementation is straightforward. Here are some corner cases I have found:
* `Any` should be always safe.
* Type promotions should be ignored, `b'abc == 'abc'` should be an error.
* Checks like `if x is not None: ...`, are special cased to not be errors if `x` has non-optional type.
* `Optional[str]` and `Optional[bytes]` should be considered non-overlapping for the purpose of this flag.
* For structural containers and custom `__eq__()` (i.e. incompatible with `object.__eq__()`) I suppress the non-overlapping types error, if there is already an error originating from the method call check.

Note that I updated `typing-full.pyi` so that `Sequence` inherits from `Container` (this is needed by some added tests, and also matches real stubs). This however caused necessary changes in a bunch of builtins fixtures.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants