classification
Title: bool(Q) always return True for a priority queue Q
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.8
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: porton, rhettinger, tim.peters, xtreak
Priority: normal Keywords:

Created on 2018-07-21 15:53 by porton, last changed 2018-07-22 18:37 by tim.peters. This issue is now closed.

Messages (4)
msg322103 - (view) Author: Victor Porton (porton) Date: 2018-07-21 15:53
It seems that bool(Q) always return True for a priority queue Q.

It should behave the same way as for bool(L) where L is a list, that is return False on an empty queue.

Please check also other objects in https://docs.python.org/3/library/queue.html

After the bug is fixed, the documentation should be clear that there was a change in the behavior in certain Python version.
msg322104 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2018-07-21 16:18
Relevant SO answer : https://stackoverflow.com/a/41861322/2610955

Ref : https://docs.python.org/3/reference/datamodel.html#object.__bool__

> If a class defines neither __len__() nor __bool__(), all its instances are considered true.

I don't know why it's not implemented and the SO answer comments has some discussion. Maybe this can be clarified in the doc.

➜  cpython git:(master) rlwrap ./python
Python 3.8.0a0 (heads/master:56868f9, Jul 21 2018, 14:28:31)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from queue import PriorityQueue
>>> len(PriorityQueue([1]))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'PriorityQueue' has no len()


Thanks
msg322125 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2018-07-21 22:20
The class is not documented to support __len__() or __bool__(), so this is not a bug.  There is an empty() method provided for the purposes of testing whether a queue is empty or not.  Likewise, there is a qsize() method for determining the current size.

Note, these methods have a built in race condition -- the information may be out of date by the time it is used.  In general, an EAFP approach is preferred for reliable behavior (i.e. call get() in a try/except to see whether an Empty exception is raised).

FWIW, this module's API was designed by Guido a long time ago.  Presumably, he had his reasons for choosing empty(), full(), and qsize() over the __len__() method.  Once the API has been published and then become widely used, the time for debating his API decisions is over and we work with it as published.
msg322156 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2018-07-22 18:37
I'm sure Guido designed the API to discourage subtly bug-ridden code relying on the mistaken belief that it _can_ know the queue's current size.  In the general multi-threaded context Queue is intended to be used, the only thing `.qsize()`'s caller can know is that the queue _had_ the returned size at some time in the past.  It can't know what the size is at the time the returned value is used.

Note that the docstrings still say that the `.empty()` and `.full()` methods are "likely to be removed at some point".  The only surprise to me is that `.qsize()` doesn't also say that.  As is, I still see race-ridden code on StackOverflow from time to time using `.qsize()`.  There are already plenty of warnings about that in the docs.
History
Date User Action Args
2018-07-22 18:37:48tim.peterssetnosy: + tim.peters
messages: + msg322156
2018-07-21 22:20:01rhettingersetstatus: open -> closed
versions: + Python 3.8, - Python 3.7
type: behavior -> enhancement
messages: + msg322125

resolution: rejected
stage: resolved
2018-07-21 16:18:16xtreaksetnosy: + xtreak
messages: + msg322104
2018-07-21 16:08:12serhiy.storchakasetassignee: rhettinger

nosy: + rhettinger
2018-07-21 15:53:57portoncreate