diff options
author | Raymond Hettinger <python@rcn.com> | 2010-04-05 18:56:31 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2010-04-05 18:56:31 (GMT) |
commit | c50846aaef3e38d466ac9a0a87f72f09238e2061 (patch) | |
tree | f6ae48bcfbabb5107c971c240f3b06a549084f98 /Lib/functools.py | |
parent | 5daab45158094e577b9791cda7d8a0f4e34f45cb (diff) | |
download | cpython-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.py | 47 |
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 |