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: Heapq + functools.partial : TypeError: unorderable types
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.4
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: josh.r, martin.panter, socketpair
Priority: normal Keywords:

Created on 2015-07-18 12:00 by socketpair, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (5)
msg246894 - (view) Author: Марк Коренберг (socketpair) * Date: 2015-07-18 12:00
>>> import heapq
>>> from functools import partial
>>> qwe = [(0, lambda x: 42), (0, lambda x: 56)]
>>> heapq.heapify(qwe)
>>>
>>> qwe = [(0, partial(lambda x: 42)), (0, partial(lambda x: 56))]
>>> heapq.heapify(qwe)
Traceback (most recent call last):
  File "/usr/lib/python3.4/code.py", line 90, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
TypeError: unorderable types: functools.partial() < functools.partial()


So it is not realiable to use heapq if element of the array is (int, callable)
msg246896 - (view) Author: Марк Коренберг (socketpair) * Date: 2015-07-18 12:10
Exactly the same with bound class methods
msg246897 - (view) Author: Josh Rosenberg (josh.r) * (Python triager) Date: 2015-07-18 12:32
Neither of those example should work (and neither do on my 3.4.0 installation). Heaps must have sortable components; you could only include callables (which are not sortable) in the tuples being sorted if you guarantee that some element(s) before the callable will ensure the elements are ordered without falling back on comparing the callable members. This isn't a bug; heapq.heapify() *should* fail in this case, and in any case where sorted() would fail due to uncomparable objects.
msg246898 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2015-07-18 13:00
I can’t compare non-partial functions either. How did your first heapify() call succeed?

Python 3.4.3 (default, Mar 25 2015, 17:13:50) 
[GCC 4.9.2 20150304 (prerelease)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import heapq
>>> from functools import partial
>>> qwe = [(0, lambda x: 42), (0, lambda x: 56)]
>>> heapq.heapify(qwe)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: function() < function()
>>> (lambda x: 42) < (lambda x: 56)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: function() < function()

This is not a problem specific to “heapq”. This is how function objects, lambda objects, bound class methods, etc, are meant to work. Python doesn’t implement ordering comparisons for them. This is kind of explained at <https://docs.python.org/dev/reference/expressions.html#comparisons>. See Issue 12067 if you want to help improve this section of the documentation.

If you don’t care about the order, perhaps you could ensure the first item in each tuple is unique, or add a dummy item in the middle that ensures the tuples have a definite order:

>>> (0, 0, lambda x: 42) < (0, 1, lambda x: 56)
True
msg255595 - (view) Author: Марк Коренберг (socketpair) * Date: 2015-11-29 20:40
Yes, this is not a bug. Python 3.5 works as expected.

Orderable lambda is the bug in python2.7.
History
Date User Action Args
2022-04-11 14:58:19adminsetgithub: 68848
2015-11-29 20:40:48socketpairsetmessages: + msg255595
2015-07-18 13:00:10martin.pantersetstatus: open -> closed

nosy: + martin.panter
messages: + msg246898

resolution: not a bug
2015-07-18 12:32:51josh.rsetnosy: + josh.r
messages: + msg246897
2015-07-18 12:10:41socketpairsetmessages: + msg246896
2015-07-18 12:00:50socketpaircreate