Opened 5 years ago
Last modified 5 years ago
#30651 closed Cleanup/optimization
Model.__eq__ never returns NotImplemented — at Version 1
Reported by: | Elizabeth Uselton | Owned by: | Elizabeth Uselton |
---|---|---|---|
Component: | Core (Other) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Elizabeth Uselton | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Model.__eq__
never returns NotImplemented if it encounters an object it doesn't know how to compare against. Instead, if the object it is comparing to is not a Django Model, it automatically returns False.
https://github.com/django/django/blob/master/django/db/models/base.py#L526
According to the Python 3 data model reference, a __eq__
should return NotImplemented
https://docs.python.org/3/reference/datamodel.html#object.__eq__
If a.__eq__(b)
returns NotImplemented, then b.__eq__(a)
will be tried. If both return NotImplemented, then an is check is performed, and if that fails it returns False.
This may seem like a relatively innocuous difference, but it can cause some nasty bugs. The most obvious is that for testing,
<A Django Model> == mock.ANY returns False, since by not returning NotImplemented it never even looks at the overridden __eq__
on ANY.