changeset f13813452984 in trytond:default
details: https://hg.tryton.org/trytond?cmd=changeset;node=f13813452984
description:
        Ensure values can be sorted

        The values may contain None which is not orderable so we insert a third
        argument before the value to prevent to compare None value against 
others.

        issue9381
        review303881005
diffstat:

 CHANGELOG                   |   1 +
 trytond/tests/test_tools.py |  21 ++++++++++++++++++++-
 trytond/tools/__init__.py   |   5 +++--
 trytond/tools/misc.py       |  12 ++++++++++++
 4 files changed, 36 insertions(+), 3 deletions(-)

diffs (92 lines):

diff -r 1f35ba30a768 -r f13813452984 CHANGELOG
--- a/CHANGELOG Mon Jul 13 21:21:20 2020 +0200
+++ b/CHANGELOG Tue Jul 21 00:36:40 2020 +0200
@@ -1,3 +1,4 @@
+* Add sortable_values in tools
 * Remove default colors on graph and calendar
 * Add model, record and records attributes on Wizard
 * Check read access of wizard records
diff -r 1f35ba30a768 -r f13813452984 trytond/tests/test_tools.py
--- a/trytond/tests/test_tools.py       Mon Jul 13 21:21:20 2020 +0200
+++ b/trytond/tests/test_tools.py       Tue Jul 21 00:36:40 2020 +0200
@@ -12,7 +12,7 @@
 
 from trytond.tools import (
     reduce_ids, reduce_domain, decimal_, is_instance_method, file_open,
-    strip_wildcard, lstrip_wildcard, rstrip_wildcard, slugify)
+    strip_wildcard, lstrip_wildcard, rstrip_wildcard, slugify, sortable_values)
 from trytond.tools.string_ import StringPartitioned, LazyString
 from trytond.tools.domain_inversion import (
     domain_inversion, parse, simplify, merge, concat, unique_value,
@@ -732,6 +732,25 @@
             extract_reference_models(domain, 'x'), {'model_A', 'model_B'})
         self.assertEqual(extract_reference_models(domain, 'y'), set())
 
+    def test_sortable_values(self):
+        def key(values):
+            return values
+
+        values = [
+            (('a', 1), ('b', None)),
+            (('a', 1), ('b', 3)),
+            (('a', 1), ('b', 2)),
+            ]
+
+        with self.assertRaises(TypeError):
+            sorted(values, key=key)
+        self.assertEqual(
+            sorted(values, key=sortable_values(key)), [
+                (('a', 1), ('b', 2)),
+                (('a', 1), ('b', 3)),
+                (('a', 1), ('b', None)),
+                ])
+
 
 def suite():
     func = unittest.TestLoader().loadTestsFromTestCase
diff -r 1f35ba30a768 -r f13813452984 trytond/tools/__init__.py
--- a/trytond/tools/__init__.py Mon Jul 13 21:21:20 2020 +0200
+++ b/trytond/tools/__init__.py Tue Jul 21 00:36:40 2020 +0200
@@ -8,13 +8,14 @@
 from .misc import (
     file_open, get_smtp_server, reduce_ids, reduce_domain,
     grouped_slice, is_instance_method, resolve, strip_wildcard,
-    lstrip_wildcard, rstrip_wildcard, slugify)
+    lstrip_wildcard, rstrip_wildcard, slugify, sortable_values)
 from .decimal_ import decistmt
 
 __all__ = ['file_open', 'get_smtp_server', 'reduce_ids',
     'reduce_domain', 'grouped_slice', 'is_instance_method', 'resolve',
     'strip_wildcard', 'lstrip_wildcard', 'rstrip_wildcard', 'slugify',
-    'decistmt', 'ClassProperty', 'cursor_dict', 'cached_property']
+    'decistmt', 'ClassProperty', 'cursor_dict', 'cached_property',
+    'sortable_values']
 
 
 class ClassProperty(property):
diff -r 1f35ba30a768 -r f13813452984 trytond/tools/misc.py
--- a/trytond/tools/misc.py     Mon Jul 13 21:21:20 2020 +0200
+++ b/trytond/tools/misc.py     Tue Jul 21 00:36:40 2020 +0200
@@ -13,6 +13,7 @@
 import unicodedata
 import warnings
 from array import array
+from functools import wraps
 from itertools import islice
 
 from sql import Literal
@@ -223,3 +224,14 @@
     value = unicodedata.normalize('NFKD', value)
     value = str(_slugify_strip_re.sub('', value).strip())
     return _slugify_hyphenate_re.sub(hyphenate, value)
+
+
+def sortable_values(func):
+    "Decorator that makes list of couple values sortable"
+    @wraps(func)
+    def wrapper(*args, **kwargs):
+        result = list(func(*args, **kwargs))
+        for i, (name, value) in enumerate(list(result)):
+            result[i] = (name, value is None, value)
+        return result
+    return wrapper

Reply via email to