Skip to content

Commit

Permalink
Handle sorting of broken objects more gracefully.
Browse files Browse the repository at this point in the history
  • Loading branch information
viktordick committed Oct 2, 2018
1 parent 4f7ae52 commit 35501ac
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/zope/sequencesort/ssort.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,10 @@ def __call__(self, o1, o2):
# if not multsort - i is 0, and the 0th element is the key
c1, c2 = o1[i], o2[i]
func, multiplier = self.sf_list[i][1:3]
if c1 is _Smallest:
return -1
elif c2 is _Smallest:
return 1
n = func(c1, c2)
if n:
return n * multiplier
Expand Down
56 changes: 56 additions & 0 deletions src/zope/sequencesort/tests/test_ssort.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@
# pylint:disable=blacklisted-name
# pylint:disable=protected-access

# for sorting objects that are sortable but do not have any other attributes
# or string-like behavior
class _Broken(object):
def __lt__(self, other):
return True
def __eq__(self, other):
return other is self

class _OK(object):
def __init__(self, _id):
self.id = _id

class Test_sort(unittest.TestCase):

Expand Down Expand Up @@ -211,6 +222,51 @@ def myCmp(s1, s2):
),
RES_W_CUSTOM_COMPARATOR)

def test_w_sort_broken(self):
_broken = _Broken()
_ok = _OK('test')
self.assertEqual(
self._callFUT([_ok, _broken]),
[_broken, _ok]
)

def test_w_sort_broken_with_key(self):
_broken = _Broken()
_ok = _OK('test')
self.assertEqual(
self._callFUT([_ok, _broken], [('id',),]),
[_broken, _ok]
)

def test_w_sort_broken_with_key_locale(self):
# testing actual unicode literals to be sorted correctly has the
# problem that one can not assume that there is any locale actually
# installed on the system. But we can test if a broken object can be
# compared with a correct one even for a sorting that assumes stringy
# behavior
_broken = _Broken()
v1 = _OK(u'test')
self.assertEqual(
self._callFUT([v1,_broken], [('id','locale',),]),
[_broken, v1]
)
self.assertEqual(
self._callFUT([_broken,v1], [('id','locale',),]),
[_broken, v1]
)

def test_w_sort_broken_with_key_locale_nocase(self):
_broken = _Broken()
v1 = _OK(u'test')
self.assertEqual(
self._callFUT([v1,_broken], [('id','locale_nocase',),]),
[_broken, v1]
)
self.assertEqual(
self._callFUT([_broken,v1], [('id','locale_nocase',),]),
[_broken, v1]
)


class Test_make_sortfunctions(unittest.TestCase):

Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ basepython =
python3.6
commands =
coverage run -m zope.testrunner --test-path=src
coverage report --fail-under=100
coverage report --show-missing --fail-under=100
deps =
{[testenv]deps}
coverage
Expand Down

0 comments on commit 35501ac

Please sign in to comment.