summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authord-kiss <speakupness@gmail.com>2018-01-27 21:30:00 +0200
committerd-kiss <speakupness@gmail.com>2018-01-27 21:30:00 +0200
commit1dceb88ceb6791d4f986f18d10bdd6611f69f5c4 (patch)
tree7d1c8170f57cc7c78aed66355f4597c94d7b07b9
parent3eb6de3c6d611ca5917e40572a351762da921504 (diff)
downloadnatsort-1dceb88ceb6791d4f986f18d10bdd6611f69f5c4.tar.gz
Added natcmp as inteded.
-rw-r--r--natsort/__init__.py2
-rw-r--r--natsort/natsort.py39
-rw-r--r--test_natsort/test_natsort_cmp.py62
3 files changed, 103 insertions, 0 deletions
diff --git a/natsort/__init__.py b/natsort/__init__.py
index db640a2..c1c41e8 100644
--- a/natsort/__init__.py
+++ b/natsort/__init__.py
@@ -23,6 +23,7 @@ from natsort.natsort import (
as_ascii,
as_utf8,
ns,
+ natcmp,
)
from natsort.utils import chain_functions
from natsort._version import __version__
@@ -40,6 +41,7 @@ __all__ = [
'index_realsorted',
'order_by_index',
'decoder',
+ 'natcmp',
'as_ascii',
'as_utf8',
'ns',
diff --git a/natsort/natsort.py b/natsort/natsort.py
index 15358e7..31ce058 100644
--- a/natsort/natsort.py
+++ b/natsort/natsort.py
@@ -674,3 +674,42 @@ def order_by_index(seq, index, iter=False):
"""
return (seq[i] for i in index) if iter else [seq[i] for i in index]
+
+
+def natcmp(x, y, alg=0, **kwargs):
+ """
+ Compare two objects using a key and an algorithm.
+
+ Parameters
+ ----------
+ x : object
+ First object to compare.
+
+ y : object
+ Second object to compare.
+
+ alg : ns enum, optional
+ This option is used to control which algorithm `natsort`
+ uses when sorting. For details into these options, please see
+ the :class:`ns` class documentation. The default is `ns.INT`.
+
+ Returns
+ -------
+ out: int
+ 0 if x and y are equal, 1 if x > y, -1 if y > x.
+
+ See Also
+ --------
+ natsort_keygen : Generates the key that makes natural sorting possible.
+
+ Examples
+ --------
+ Use `natcmp` just like the builtin `cmp`::
+
+ >>> one = 1
+ >>> two = 2
+ >>> natcmp(one, two)
+ -1
+ """
+ key = natsort_keygen(alg=alg, **kwargs)
+ return cmp(key(x), key(y))
diff --git a/test_natsort/test_natsort_cmp.py b/test_natsort/test_natsort_cmp.py
new file mode 100644
index 0000000..86fc56d
--- /dev/null
+++ b/test_natsort/test_natsort_cmp.py
@@ -0,0 +1,62 @@
+import sys
+from functools import partial
+
+import pytest
+from hypothesis import given
+from hypothesis.strategies import floats, integers, lists
+
+from natsort import natcmp, ns
+
+PY_VERSION = float(sys.version[:3])
+
+
+@pytest.mark.skipif(PY_VERSION >= 3.0, reason='cmp() deprecated in Python 3')
+def test__classes_can_be_compared():
+ class Comparable:
+ def __init__(self, value):
+ self.value = value
+
+ def __cmp__(self, other):
+ return natcmp(self.value, other.value)
+
+ one = Comparable("1")
+ two = Comparable("2")
+ another_two = Comparable("2")
+ ten = Comparable("10")
+
+ assert ten > two == another_two > one
+
+
+@pytest.mark.skipif(PY_VERSION >= 3.0, reason='cmp() deprecated in Python 3')
+def test__classes_can_utilize_max_or_min():
+ class Comparable:
+ def __init__(self, value):
+ self.value = value
+
+ def __cmp__(self, other):
+ return natcmp(self.value, other.value)
+
+ comparables = [Comparable(i) for i in range(10)]
+ assert max(comparables) == comparables[-1]
+ assert min(comparables) == comparables[0]
+
+
+@pytest.mark.skipif(PY_VERSION >= 3.0, reason='cmp() deprecated in Python 3')
+@given(integers(), integers())
+def test__natcmp_works_the_same_for_integers_as_cmp(x, y):
+ assert cmp(x, y) == natcmp(x, y)
+
+
+@pytest.mark.skipif(PY_VERSION >= 3.0, reason='cmp() deprecated in Python 3')
+@given(floats(allow_nan=False), floats(allow_nan=False))
+def test__natcmp_works_the_same_for_floats_as_cmp(x, y):
+ assert cmp(x, y) == natcmp(x, y)
+
+
+@pytest.mark.skipif(PY_VERSION >= 3.0, reason='cmp() deprecated in Python 3')
+@given(lists(elements=integers()))
+def test_sort_strings_with_numbers(a_list):
+ strings = map(str, a_list)
+ natcmp_sorted = sorted(strings, cmp=partial(natcmp, alg=ns.REAL))
+
+ assert sorted(a_list) == map(int, natcmp_sorted)