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.

classification
Title: `bool(Counter({'a': 0})) is True`
Type: behavior Stage: test needed
Components: Library (Lib) Versions: Python 3.3, Python 3.4
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: cool-RR, ezio.melotti, mrabarnett, rhettinger
Priority: normal Keywords:

Created on 2011-04-05 18:57 by cool-RR, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (8)
msg133076 - (view) Author: Ram Rachum (cool-RR) * Date: 2011-04-05 18:57
bool(Counter({'a': 0'})) is True.

Is this wise? I want to be able to do:

    if my_counter:
        whatever

To check whether my counter has any elements. Currently this seems to be impossible because of this bug.

Will we have to keep this weird behavior because of backwards compatibility? If so, perhaps `.elements` could be turned into a smart object so we could at least do `if my_counter.elements():` and get the expected result.

If you want a patch let me know and I'll write one.
msg133077 - (view) Author: Ram Rachum (cool-RR) * Date: 2011-04-05 19:01
Before coding a test I want to know whether we can even make this change with regards to backwards compatibility.
msg133079 - (view) Author: Matthew Barnett (mrabarnett) * (Python triager) Date: 2011-04-05 19:13
It depends on what kind of object it's like. If it's like a dict then your example is clearly not empty, but if it's like a set then it /is/ empty, in which case it's empty if:

    all(count == 0 for count in my_counter.values())
msg133081 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2011-04-05 19:27
Sorry, this is at odds with how Guido wants bool to work with containers.  The bool check is all about whether or not a container is empty, not about its contents.
msg133082 - (view) Author: Ram Rachum (cool-RR) * Date: 2011-04-05 19:30
Hmm... So how about making `elements` a smart object which will implement `__bool__`? Then we could give it a `__len__` too and be rid of issue11733.
msg133086 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2011-04-05 20:44
We could do that, but that's not the Python way :-)

Really, you should be posting recipes somewhere else to see if there is interest and uptake.  The tracker is not the right place to toss one random idea after another.

We need to place some value on API simplicity.  At its core, a Counter is just a dict with an __missing__ method to supply implied zeros.  Much of its ease of use, speed, and flexibility all derive from that basic design.  For the most part, the best thing that could happen to this API is to become stable and remain completely untouched.  I only added subtract() in Py3.2 because there was substantial demand for it; otherwise, all the other ideas for expansion were rejected.
msg133093 - (view) Author: Ram Rachum (cool-RR) * Date: 2011-04-05 21:17
How is it "not the Python way"? Why is it okay to make `dict.keys` into a smart object but it's not okay to make `Counter.elements` a smart object?

These are not random ideas. I'm using `Counter` in a contract project and I find the need to make `if counter:` checks.

I'll ask on Python-ideas to get people's opinions.
msg133098 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2011-04-05 23:39
> How is it "not the Python way"? 

Because having an API within an API greatly complexifies the interface, making harder to implement, harder to understand, and harder to learn.

> Why is it okay to make `dict.keys` into a smart object
> but it's not okay to make `Counter.elements` a smart object?

That was the exception, not the rule.  For the most part,
we don't do multi-level APIs unless there is a *compelling*
reason.  In the case of dict views, there was already a
known successful model in Java using this API and Guido
liked it.  Subsequent experience in teaching Python shows
that people have a hard time grasping it as first.
History
Date User Action Args
2022-04-11 14:57:15adminsetgithub: 55984
2011-04-05 23:39:10rhettingersetmessages: + msg133098
2011-04-05 21:17:00cool-RRsetmessages: + msg133093
2011-04-05 20:44:16rhettingersetmessages: + msg133086
2011-04-05 19:30:44cool-RRsetmessages: + msg133082
2011-04-05 19:27:13rhettingersetstatus: open -> closed
resolution: not a bug
messages: + msg133081
2011-04-05 19:13:41mrabarnettsetnosy: + mrabarnett
messages: + msg133079
2011-04-05 19:01:12cool-RRsetmessages: + msg133077
2011-04-05 18:58:50ezio.melottisetnosy: + rhettinger, ezio.melotti

type: behavior
stage: test needed
2011-04-05 18:57:54cool-RRsettitle: `bool(Counter({'a': 0'})) is True` -> `bool(Counter({'a': 0})) is True`
2011-04-05 18:57:10cool-RRcreate