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 Elizabeth Uselton)

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.

Change History (1)

comment:1 by Elizabeth Uselton, 5 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top