Reputation: 7994
I'm trying to understand if the following snippet doesn't exhibit a bug in heapq.heappush :
import heapq
x = []
heapq.heappush(x, 1)
print(x)
try:
heapq.heappush(x, "a")
except:
pass
print(x) # [1, 'a']
Here, I'm trying to build a heap with non-comparable items. As expected, the second call to heappush is throwing an exception. However, I notice that the second item was inserted in the array anyway. This array was supposed to always contain a heap, and now it isn't a heap anymore.
Shouldn't heappush method undo the insert of "a" in case it can't finish the heapify process on insertion ?
Consider the case where you have a multi-threaded system relying on this. Assume I have some workers that are dequeueing from the heap, and some worker processes that are inserting in the heap. This means that if a worker is incorrectly inserting an invalid type, the worker will raise an excpetion as expected, but the underlying data-structure is still corrupted
Upvotes: 2
Views: 149
Reputation: 4730
Although it may be opinionated to some degree, I believe most other Python veterans will agree with me.
No it's not a bug. When an exception occurs in a function or method, there's no guarantee that the state of the variables is restored to the previous one. You can also see this for the core API list.sort()
in the following example.
a = [2, 1, 4, 'a', 4, 3]
try:
a.sort()
except:
pass
print(a)
# This will output "[1, 2, 4, 'a', 4, 3]".
As a side note, putting non-comparable objects into a priority queue is an abnormal operation, usually a mistake by a programmer, which is a candidate for an assertion. If the library has to handle this case, it will be inefficient for the users because most of the time the additional code will be dead code and will be a burden to the maintainer.
Upvotes: 3