python/samba: Add cmp_fn and cmp_to_key_fn functions for py2/py3
authorNoel Power <noel.power@suse.com>
Fri, 15 Jun 2018 12:00:15 +0000 (13:00 +0100)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 12 Jul 2018 23:12:25 +0000 (01:12 +0200)
the cmp function and the cmp paramater (e.g. to sort functions)
no longer exist in python3.

cmp_fn is provides the missing functionality of the py2 cmp builtin
function.

cmp_to_key_fn allows the key paramater (e.g. for sort) to use the
old py2 cmp function for sorting. Note: the cmp_to_key is present in
since 2.7 (hence the inclusion of the source code for this function pre
that version)

Signed-off-by: Noel Power <noel.power@suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andreas Schneider <asn@samba.org>
Signed-off-by: Joe Guo <joeg@catalyst.net.nz>
python/samba/compat.py

index 042fc86a44040f2643b14252f88c4aa290439689..3fdeec886a650a8dc8a2425c5726184674598e65 100644 (file)
@@ -22,9 +22,20 @@ import sys
 PY3 = sys.version_info[0] == 3
 
 if PY3:
+    def cmp_fn(x, y):
+        """
+        Replacement for built-in function cmp that was removed in Python 3
+
+        Compare the two objects x and y and return an integer according to
+        the outcome. The return value is negative if x < y, zero if x == y
+        and strictly positive if x > y.
+        """
+
+        return (x > y) - (x < y)
     # compat functions
     from  urllib.parse import quote as urllib_quote
     from urllib.request import urlopen as urllib_urlopen
+    from functools import cmp_to_key as cmp_to_key_fn
 
     # compat types
     integer_types = int,
@@ -36,6 +47,40 @@ if PY3:
     import io
     StringIO = io.StringIO
 else:
+
+    if sys.version_info < (2, 7):
+        def cmp_to_key_fn(mycmp):
+
+            """Convert a cmp= function into a key= function"""
+            class K(object):
+                __slots__ = ['obj']
+
+                def __init__(self, obj, *args):
+                    self.obj = obj
+
+                def __lt__(self, other):
+                    return mycmp(self.obj, other.obj) < 0
+
+                def __gt__(self, other):
+                    return mycmp(self.obj, other.obj) > 0
+
+                def __eq__(self, other):
+                    return mycmp(self.obj, other.obj) == 0
+
+                def __le__(self, other):
+                    return mycmp(self.obj, other.obj) <= 0
+
+                def __ge__(self, other):
+                    return mycmp(self.obj, other.obj) >= 0
+
+                def __ne__(self, other):
+                    return mycmp(self.obj, other.obj) != 0
+
+                def __hash__(self):
+                    raise TypeError('hash not implemented')
+            return K
+    else:
+        from functools import cmp_to_key as cmp_to_key_fn
     # compat functions
     from urllib import quote as urllib_quote
     from urllib import urlopen as urllib_urlopen
@@ -49,3 +94,4 @@ else:
     # alias
     import StringIO
     StringIO = StringIO.StringIO
+    cmp_fn = cmp