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

Clarify the behavior of __eq__() returning NotImplemented #72971

Closed
pkch mannequin opened this issue Nov 24, 2016 · 5 comments
Closed

Clarify the behavior of __eq__() returning NotImplemented #72971

pkch mannequin opened this issue Nov 24, 2016 · 5 comments
Labels
docs Documentation in the Doc dir type-feature A feature request or enhancement

Comments

@pkch
Copy link
Mannequin

pkch mannequin commented Nov 24, 2016

BPO 28785
Nosy @pkch, @vadmium

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2016-11-24.08:14:24.477>
labels = ['type-feature', 'docs']
title = 'Clarify the behavior of __eq__() returning NotImplemented'
updated_at = <Date 2017-01-22.04:45:40.037>
user = 'https://github.com/pkch'

bugs.python.org fields:

activity = <Date 2017-01-22.04:45:40.037>
actor = 'martin.panter'
assignee = 'docs@python'
closed = False
closed_date = None
closer = None
components = ['Documentation']
creation = <Date 2016-11-24.08:14:24.477>
creator = 'max'
dependencies = []
files = []
hgrepos = []
issue_num = 28785
keywords = []
message_count = 4.0
messages = ['281616', '281625', '281628', '281714']
nosy_count = 3.0
nosy_names = ['docs@python', 'max', 'martin.panter']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue28785'
versions = ['Python 3.6']

Linked PRs

@pkch
Copy link
Mannequin Author

pkch mannequin commented Nov 24, 2016

Currently, there's no clear statement as to what exactly the fallback is in case __eq__ returns NotImplemented. It would be good to clarify the behavior of NotImplemented; at least for __eq__, but perhaps also other rich comparison methods. For example: "When NotImplemented is returned from a rich comparison method, the interpreter behaves as if the rich comparison method was not defined in the first place." See http://stackoverflow.com/questions/40780004/returning-notimplemented-from-eq for more discussion.

@pkch pkch mannequin assigned docspython Nov 24, 2016
@pkch pkch mannequin added docs Documentation in the Doc dir type-feature A feature request or enhancement labels Nov 24, 2016
@vadmium
Copy link
Member

vadmium commented Nov 24, 2016

The documentation of this that comes to mind is spread over <https://docs.python.org/3.6/reference/datamodel.html#object.\_\_eq__\> and <https://docs.python.org/3.6/reference/expressions.html#value-comparisons\>.

My understanding of how it works in general is that NotImplemented is just a simple object like None. It doesn’t have any special behaviour on its own. Similarly, if you call a special method like __eq__() manually, there is no fallback, you just get the NotImplemented object. The interpreter calls special methods like __eq__() when evaluating expressions, but the specific behaviour and how NotImplemented is interpreted varies subtly.

To evaluate a == b, if b’s class is a strict subclass of a’s class, b.__eq__(a) is tried first, otherwise a.__eq__(b) is tried first. If that call returns NotImplemented, the first fallback is to try the call. Failing that, the final fallback is the default behaviour for object() instances.

To evaluate a != b, there is another set of fallbacks in the chain, which is to try “not a.__eq__(b)”. So for __eq__(), the fallback depends on the class hierarchy, on whether a reversed call has already been made, and on whether you are evaluating == or !=.

The documentation for comparison operations was cleaned up a while ago (bpo-12067). But there is probably more room for improvement. I think the best thing would be to document the above sort of behaviour as being directly associated with operations like as == and !=, and only indirectly associated with the NotImplemented object and the __eq__() method.

@pkch
Copy link
Mannequin Author

pkch mannequin commented Nov 24, 2016

Martin - what you suggest is precisely what I had in mind (but didn't phrase it as well):

to document the above sort of behaviour as being directly associated with operations like as == and !=, and only indirectly associated with the NotImplemented object and the __eq__() method

Also a minor typo: you meant "If that call returns NotImplemented, the first fallback is to try the *reverse* call."

@vadmium
Copy link
Member

vadmium commented Nov 25, 2016

Correct, I meant to say the first fallback is the other call.

BTW your suggested text might hold for __eq__(), but for __ne__(), returning NotImplemented seems to bypass the “not a.__eq__(b)” fallback.

@vadmium vadmium changed the title Clarify the behavior of NotImplemented Clarify the behavior of __eq__() returning NotImplemented Jan 22, 2017
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Mar 3, 2024
pythonGH-110729)

(cherry picked from commit 67f742e)

Co-authored-by: Gouvernathor <44340603+Gouvernathor@users.noreply.github.com>
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Mar 3, 2024
pythonGH-110729)

(cherry picked from commit 67f742e)

Co-authored-by: Gouvernathor <44340603+Gouvernathor@users.noreply.github.com>
erlend-aasland pushed a commit that referenced this issue Mar 3, 2024
…ty (GH-110729) (#116254)

(cherry picked from commit 67f742e)

Co-authored-by: Gouvernathor <44340603+Gouvernathor@users.noreply.github.com>
erlend-aasland pushed a commit that referenced this issue Mar 3, 2024
…ty (GH-110729) (#116255)

(cherry picked from commit 67f742e)

Co-authored-by: Gouvernathor <44340603+Gouvernathor@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation in the Doc dir type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

2 participants