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: Tuple comparison masking exception
Type: behavior Stage:
Components: Interpreter Core Versions: Python 2.4, Python 2.7, Python 2.6, Python 2.5
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: fdrake, gary, rhettinger, stutzbach
Priority: normal Keywords:

Created on 2008-09-10 20:32 by fdrake, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (3)
msg72981 - (view) Author: Fred Drake (fdrake) (Python committer) Date: 2008-09-10 20:32
There's a strange condition where cmp() of tuples of unorderable values
returns -1 even though using the unorderable values raises an exception.

If I have these two unorderable values, cmp() raises an expected exception:

  >>> s0 = frozenset(['testing 0'])
  >>> s1 = frozenset(['testing 1'])
  >>> cmp(s0, s1)
  Traceback (most recent call last):
    File "<stdin>", line 1, in ?
  TypeError: cannot compare sets using cmp()

Comparing tuples of the values returns -1:

  >>> cmp((s0,), (s1,))
  -1

Py3k does raise a TypeError, but the message is indecipherable:

  >>> cmp((s0,), (s1,))
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  TypeError: unorderable types: 'tuple' != 'tuple'

(The Py3k message for the set comparison is the same as for Python 2.)

I believe that this is an error; the exception from the underlying item
comparison should be propagated.
msg84438 - (view) Author: Daniel Stutzbach (stutzbach) (Python committer) Date: 2009-03-29 22:23
I don't think the compare is actually masking an exception.

The set type defines a tp_richcompare routine that gets called when
comparing them as members of a tuple, but the set type also defines a
tp_compare routine that does nothing but raise an exception.

Another side effect is that sets are comparable using < etc., but not
with cmp():

>>> s0 = frozenset(['testing 0'])
>>> s1 = frozenset(['testing 1'])
>>> s0 < s1
False
>>> cmp(s0, s1)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: cannot compare sets using cmp()

cmp() is gone in 3.0.1 so I've removed Python 3.0 from the versions.

I'm not sure why tp_compare and tp_richcompare work differently.  Maybe
Raymond could shed some light?
msg86440 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2009-04-24 23:48
Daniel, you're basically on the money.  No exception is getting masked.

The rich comparison operations for sets are defined as subset/superset
operations.  So, those operations are not useful for total orderings
used by min/max/sorted/bisect/heapq/cmp and tuple comparisons.  We can't
stop those tools from calling the rich comparisons but we can and do
raise a TypeError when cmp() is called directly on two sets.
History
Date User Action Args
2022-04-11 14:56:39adminsetgithub: 48079
2009-04-24 23:48:49rhettingersetstatus: open -> closed
resolution: not a bug
messages: + msg86440
2009-03-29 22:23:35stutzbachsetnosy: + rhettinger, stutzbach

messages: + msg84438
versions: + Python 2.7, - Python 3.0
2008-09-16 00:05:29garysetnosy: + gary
2008-09-10 20:32:35fdrakecreate