This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2014年05月01日 14:31 by exarkun, last changed 2022年04月11日 14:58 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| method-not-operator.patch | martin.panter, 2015年01月11日 06:39 | review | ||
| method-not-operator-2.patch | serhiy.storchaka, 2015年01月24日 16:45 | review | ||
| Messages (15) | |||
|---|---|---|---|
| msg217699 - (view) | Author: Jean-Paul Calderone (exarkun) * (Python committer) | Date: 2014年05月01日 14:31 | |
$ ~/Projects/cpython/3.4/python -c ' class Foo(object): def __ne__(self, other): return "yup" def __eq__(self, other): return "nope" class Bar(object): pass print(object() != Foo(), object() == Foo()) print(Bar() != Foo(), Bar() == Foo()) ' yup nope False nope $ The output I would expect from this is yup nope yup nope That is, even when the type of the left-hand argument is not a base class of the type of the right-hand argument, delegation to the right-hand argument is sensible if the left-hand argument does not implement the comparison. Note that the output also demonstrates that this is already the behavior for `==`. Only `!=` seems to suffer from this issue. |
|||
| msg217700 - (view) | Author: Benjamin Peterson (benjamin.peterson) * (Python committer) | Date: 2014年05月01日 14:40 | |
That's because the implicit default __ne__ on Bar returns the opposite of __eq__. |
|||
| msg217727 - (view) | Author: Josh Rosenberg (josh.r) * (Python triager) | Date: 2014年05月01日 21:18 | |
Why would an subclass of object that doesn't redefine either __eq__ or __ne__ have a different behavior for inequality than object itself? Bar never defined __eq__, so it shouldn't have an implicit __ne__ any more than object itself does... Saying that Bar has an implicit __ne__ that object doesn't is answering how this happens, but it's not a why; is there a reason why this should be the case, or is this a bug (either in spec or in code) that should be fixed? |
|||
| msg217729 - (view) | Author: Benjamin Peterson (benjamin.peterson) * (Python committer) | Date: 2014年05月01日 21:41 | |
The reason ``object() != Foo()`` "works" is that Foo is a subtype of object(), so the specialized __ne__ of Foo is called immediately without trying object.__ne__. I don't know whether it's a bug. |
|||
| msg217730 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2014年05月01日 21:47 | |
I don't think it's a bug. The subclass-goes-first behavior is very intentional. The implicit __ne__ returning the boolean inverse of __eq__ is what fooled me when I looked at it. Or did you mean that following the subclass rule in the case where object is the other class is possibly suspect? |
|||
| msg217731 - (view) | Author: Benjamin Peterson (benjamin.peterson) * (Python committer) | Date: 2014年05月01日 21:52 | |
The subclass behavior is a red herring. I meant maybe object.__ne__ should check if the other object has a __ne__ method before falling back on ``not object.__eq__()``. |
|||
| msg217732 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2014年05月01日 22:24 | |
Oh, I see. Yes, that would seem more consistent. |
|||
| msg233827 - (view) | Author: Martin Panter (martin.panter) * (Python committer) | Date: 2015年01月11日 00:29 | |
There is a bit of analysis of the object.__ne__() implementation in Issue 4395. If my understanding is correct, I think it is a bug that object.__ne__(self, other) evaluates "not self == other". It should evaluate "not self.__eq__(other)" instead, so that NotImplemented can be caught, allowing the reflected other.__ne__(self) method to be tried. |
|||
| msg233837 - (view) | Author: Martin Panter (martin.panter) * (Python committer) | Date: 2015年01月11日 06:39 | |
This patch should fix the problem I think. Before the __ne__() implementation was calling the "==" operator; now it calls the __eq__() method instead. Also includes extra test for Issue 4395 to avoid having conficting patches. |
|||
| msg234618 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2015年01月24日 15:31 | |
Particular case of this bug: >>> class A: ... def __eq__(self, other): return NotImplemented ... >>> A().__eq__(object()) NotImplemented >>> A().__ne__(object()) True The second result should be NotImplemented. Martin's patch LGTM except few style nitpicks to tests. |
|||
| msg234620 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2015年01月24日 16:45 | |
There are few incorrect implementations of __ne__ in the stdlib. Updated patch removes them. May be we should remove all implementations of __ne__ which are redundant now. |
|||
| msg234700 - (view) | Author: Martin Panter (martin.panter) * (Python committer) | Date: 2015年01月25日 22:31 | |
I looked over your __ne__ removals from the library, and they all seem sensible to me. |
|||
| msg234718 - (view) | Author: Roundup Robot (python-dev) (Python triager) | Date: 2015年01月26日 08:07 | |
New changeset e516badfd3b2 by Serhiy Storchaka in branch '3.4': Issue #21408: The default __ne__() now returns NotImplemented if __eq__() https://hg.python.org/cpython/rev/e516badfd3b2 New changeset 7e9880052401 by Serhiy Storchaka in branch 'default': Issue #21408: The default __ne__() now returns NotImplemented if __eq__() https://hg.python.org/cpython/rev/7e9880052401 |
|||
| msg234720 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2015年01月26日 08:16 | |
Thank you for your contribution Martin. |
|||
| msg235101 - (view) | Author: Roundup Robot (python-dev) (Python triager) | Date: 2015年01月31日 10:24 | |
New changeset 3603bae63c13 by Serhiy Storchaka in branch 'default': Issue #23326: Removed __ne__ implementations. Since fixing default __ne__ https://hg.python.org/cpython/rev/3603bae63c13 |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:58:03 | admin | set | github: 65607 |
| 2015年01月31日 10:24:05 | python-dev | set | messages: + msg235101 |
| 2015年01月26日 08:16:19 | serhiy.storchaka | set | status: open -> closed versions: + Python 3.5, - Python 3.3 messages: + msg234720 resolution: fixed stage: commit review -> resolved |
| 2015年01月26日 08:07:11 | python-dev | set | nosy:
+ python-dev messages: + msg234718 |
| 2015年01月25日 22:31:40 | martin.panter | set | messages: + msg234700 |
| 2015年01月24日 16:45:38 | serhiy.storchaka | set | files:
+ method-not-operator-2.patch messages: + msg234620 |
| 2015年01月24日 15:31:45 | serhiy.storchaka | set | nosy:
+ serhiy.storchaka messages: + msg234618 assignee: serhiy.storchaka stage: commit review |
| 2015年01月24日 15:18:29 | serhiy.storchaka | link | issue23268 dependencies |
| 2015年01月11日 06:39:42 | martin.panter | set | files:
+ method-not-operator.patch keywords: + patch messages: + msg233837 |
| 2015年01月11日 02:01:27 | Arfrever | set | nosy:
+ Arfrever |
| 2015年01月11日 00:29:01 | martin.panter | set | messages: + msg233827 |
| 2015年01月10日 10:25:56 | martin.panter | set | nosy:
+ martin.panter |
| 2014年05月01日 23:34:33 | flox | set | nosy:
+ flox |
| 2014年05月01日 22:24:36 | r.david.murray | set | messages: + msg217732 |
| 2014年05月01日 21:52:06 | benjamin.peterson | set | messages: + msg217731 |
| 2014年05月01日 21:47:31 | r.david.murray | set | nosy:
+ r.david.murray messages: + msg217730 |
| 2014年05月01日 21:41:43 | benjamin.peterson | set | messages: + msg217729 |
| 2014年05月01日 21:18:01 | josh.r | set | nosy:
+ josh.r messages: + msg217727 |
| 2014年05月01日 14:40:38 | benjamin.peterson | set | nosy:
+ benjamin.peterson messages: + msg217700 |
| 2014年05月01日 14:31:27 | exarkun | create | |