DanielStutzbach/blist

sortedset with some types of elements: wrong/inconsistent behavior related to presence of elements (e.g. cannot remove/discard properly!)

Opened this issue · 1 comments

zuo commented
Python 3.3.1 (default, Sep 25 2013, 19:29:01) 
[GCC 4.7.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from blist import sortedset
>>> from unittest.mock import sentinel
>>> s = sortedset({sentinel.x})
>>> s
sortedset([sentinel.x])
>>> list(s)
[sentinel.x]
>>> # ...Nice, but:
>>> sentinel.x in s
False
>>> s
sortedset([sentinel.x])
>>> # ...So let's try to remove the element:
>>> s.remove(sentinel.x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.3/collections/abc.py", line 323, in remove
    raise KeyError(value)
KeyError: sentinel.x
>>> s
sortedset([sentinel.x])
>>> list(s)
[sentinel.x]
>>> s.discard(sentinel.x)
>>> s
sortedset([sentinel.x])
>>> list(s)
[sentinel.x]
>>> sentinel.x in s
False
>>> bool(s)
True
zuo commented

Now I see that the problem is with elements whose type does not implement the __lt/le/gt/ge__ methods.

An explicit error is raised when you try to add more than one element -- and it's of course the correct behaviour, as in Python 3.x you cannot </<=/>/>=-compare object which do not support these operations explicitly.

But still, the behavior described above (for 1-element sortedsets) is IMHO surprising and at least weird (once you added such an element you cannot remove it!). I believe that raising an error when user tries to initialize-with-or-add an element that does not support </<=/>/>= operations would be much better than allowing to enter such an inconsistent state.