classification
Title: Restore default implementation of __ne__ in Counter
Type: Stage: patch review
Components: Library (Lib) Versions: Python 3.10
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: rhettinger, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2020-07-26 08:25 by serhiy.storchaka, last changed 2020-07-26 19:27 by rhettinger.

Pull Requests
URL Status Linked Edit
PR 21627 open serhiy.storchaka, 2020-07-26 08:30
Messages (4)
msg374306 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2020-07-26 08:25
Currently collections.Counter implements both __eq__ and __ne__ methods. The problem is that if you subclass Counter and override its __eq__ method you will need to implement also the __ne__ method. Usually you do not need to implement __ne__ because the implementation inherited from the object class does the right thing in most cases (unless you implement NumPy or symbolic expressions). Also, the Python implementation of Counter.__ne__ is a tiny bit slower than the C implementation of object.__ne__.

Counter.__ne__ was added because the implementation of __ne__ inherited from dict did not work correct for Counter. But we can just restore the default implementation:

    __ne__ = object.__ne__

Of all Python classes in the stdlib which implement __eq__ only Counter, WeakRef and some mock classes implement also __ne__. In case of Counter I think it is not necessary.
msg374333 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2020-07-26 17:14
> The problem is that if you subclass Counter and override 
> its __eq__ method you will need to implement also the
> __ne__ method. 

I don't think that is true.  The current code for __ne__ calls "==" and inverts the result.

Also, the docstring for the current __ne__ code is useful because it documents the effect of missing counts.  That information would be lost with the PR.
msg374336 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2020-07-26 17:51
The current code returns NotImplemented for non-Counter. If we want to implement equality comparison with other class we have to override __ne__.
msg374340 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2020-07-26 19:27
> The current code returns NotImplemented for non-Counter.
> If we want to implement equality comparison with other 
> class we have to override __ne__.

I'm fine with that.  It is not an undue burden and it provides a nudge to be explicit and intentional about the decision.

Setting __ne__ = object.__ne__ is a neat trick, but it is surprising given
Counter's __mro__ and it loses the helpful docstring describing the effect of zero counts.
History
Date User Action Args
2020-07-26 19:27:03rhettingersetmessages: + msg374340
2020-07-26 17:51:04serhiy.storchakasetmessages: + msg374336
2020-07-26 17:14:45rhettingersetassignee: rhettinger
messages: + msg374333
2020-07-26 08:30:01serhiy.storchakasetkeywords: + patch
stage: patch review
pull_requests: + pull_request20768
2020-07-26 08:25:52serhiy.storchakacreate