summaryrefslogtreecommitdiffstats
path: root/Lib/functools.py
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2010-04-05 18:56:31 (GMT)
committerRaymond Hettinger <python@rcn.com>2010-04-05 18:56:31 (GMT)
commitc50846aaef3e38d466ac9a0a87f72f09238e2061 (patch)
treef6ae48bcfbabb5107c971c240f3b06a549084f98 /Lib/functools.py
parent5daab45158094e577b9791cda7d8a0f4e34f45cb (diff)
downloadcpython-c50846aaef3e38d466ac9a0a87f72f09238e2061.zip
cpython-c50846aaef3e38d466ac9a0a87f72f09238e2061.tar.gz
cpython-c50846aaef3e38d466ac9a0a87f72f09238e2061.tar.bz2
Forward port total_ordering() and cmp_to_key().
Diffstat (limited to 'Lib/functools.py')
-rw-r--r--Lib/functools.py47
1 files changed, 47 insertions, 0 deletions
diff --git a/Lib/functools.py b/Lib/functools.py
index a54f030..539dc90 100644
--- a/Lib/functools.py
+++ b/Lib/functools.py
@@ -49,3 +49,50 @@ def wraps(wrapped,
"""
return partial(update_wrapper, wrapped=wrapped,
assigned=assigned, updated=updated)
+
+def total_ordering(cls):
+ 'Class decorator that fills-in missing ordering methods'
+ convert = {
+ '__lt__': [('__gt__', lambda self, other: other < self),
+ ('__le__', lambda self, other: not other < self),
+ ('__ge__', lambda self, other: not self < other)],
+ '__le__': [('__ge__', lambda self, other: other <= self),
+ ('__lt__', lambda self, other: not other <= self),
+ ('__gt__', lambda self, other: not self <= other)],
+ '__gt__': [('__lt__', lambda self, other: other > self),
+ ('__ge__', lambda self, other: not other > self),
+ ('__le__', lambda self, other: not self > other)],
+ '__ge__': [('__le__', lambda self, other: other >= self),
+ ('__gt__', lambda self, other: not other >= self),
+ ('__lt__', lambda self, other: not self >= other)]
+ }
+ roots = set(dir(cls)) & set(convert)
+ assert roots, 'must define at least one ordering operation: < > <= >='
+ root = max(roots) # prefer __lt __ to __le__ to __gt__ to __ge__
+ for opname, opfunc in convert[root]:
+ if opname not in roots:
+ opfunc.__name__ = opname
+ opfunc.__doc__ = getattr(int, opname).__doc__
+ setattr(cls, opname, opfunc)
+ return cls
+
+def cmp_to_key(mycmp):
+ 'Convert a cmp= function into a key= function'
+ class K(object):
+ 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