Opened 5 years ago
Last modified 5 years ago
#30651 closed Cleanup/optimization
Model.__eq__ never returns NotImplemented — at Initial Version
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
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.