summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authord-kiss <speakupness@gmail.com>2018-02-03 18:48:18 +0200
committerd-kiss <speakupness@gmail.com>2018-02-03 18:48:18 +0200
commitfd8c5d1232beb881d2deaf59f3a07c138f2e189e (patch)
treec65a6eac544e6de622dcc803892d147e8d0516e8
parent4db30fce6b89fbe31bca46a7b7a14ff1316c0661 (diff)
downloadnatsort-fd8c5d1232beb881d2deaf59f3a07c138f2e189e.tar.gz
Added algorithm-based caching to natcmp()
-rw-r--r--natsort/natsort.py22
-rw-r--r--test_natsort/test_natsort_cmp.py2
2 files changed, 20 insertions, 4 deletions
diff --git a/natsort/natsort.py b/natsort/natsort.py
index 20d3ea0..b634f87 100644
--- a/natsort/natsort.py
+++ b/natsort/natsort.py
@@ -678,7 +678,7 @@ def order_by_index(seq, index, iter=False):
return (seq[i] for i in index) if iter else [seq[i] for i in index]
if float(sys.version[:3]) < 3:
- def natcmp(x, y, alg=0, **kwargs):
+ class natcmp(object):
"""
Compare two objects using a key and an algorithm.
@@ -713,5 +713,21 @@ if float(sys.version[:3]) < 3:
>>> natcmp(one, two)
-1
"""
- key = natsort_keygen(alg=alg, **kwargs)
- return py23_cmp(key(x), key(y))
+ cached_keys = {}
+
+ def __new__(cls, x, y, alg=0, *args, **kwargs):
+ try:
+ alg = _args_to_enum(**kwargs) | alg
+ except TypeError:
+ msg = ("natsort_keygen: 'alg' argument must be "
+ "from the enum 'ns'")
+ raise ValueError(msg + ', got {0}'.format(py23_str(alg)))
+
+ # Add the _DUMB option if the locale library is broken.
+ if alg & ns.LOCALEALPHA and natsort.compat.locale.dumb_sort():
+ alg |= ns._DUMB
+
+ if alg not in cls.cached_keys:
+ cls.cached_keys[alg] = natsort_keygen(alg=alg)
+
+ return py23_cmp(cls.cached_keys[alg](x), cls.cached_keys[alg](y))
diff --git a/test_natsort/test_natsort_cmp.py b/test_natsort/test_natsort_cmp.py
index 74bb61b..4f544e0 100644
--- a/test_natsort/test_natsort_cmp.py
+++ b/test_natsort/test_natsort_cmp.py
@@ -63,7 +63,7 @@ def test__natcmp_works_the_same_for_floats_as_cmp(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)
+ strings = [str(var) for var in a_list]
natcmp_sorted = sorted(strings, cmp=partial(natcmp, alg=ns.REAL))
assert sorted(a_list) == [int(var) for var in natcmp_sorted]