Source code for pureyaml._compat.total_ordering

#!/usr/bin/env python
# coding=utf-8
"""Python2.7 ``functools.partial`` included for Python2.6"""
from __future__ import absolute_import


################################################################################
# total_ordering class decorator
################################################################################

# The total ordering functions all invoke the root magic method directly
# rather than using the corresponding operator.  This avoids possible
# infinite recursion that could occur when the operator dispatch logic
# detects a NotImplemented result and then calls a reflected method.

[docs]def _gt_from_lt(self, other): """Return a > b. Computed by @total_ordering from (not a < b) and (a != b).""" op_result = self.__lt__(other) if op_result is NotImplemented: return NotImplemented return not op_result and self != other
[docs]def _le_from_lt(self, other): """Return a <= b. Computed by @total_ordering from (a < b) or (a == b).""" op_result = self.__lt__(other) return op_result or self == other
[docs]def _ge_from_lt(self, other): """Return a >= b. Computed by @total_ordering from (not a < b).""" op_result = self.__lt__(other) if op_result is NotImplemented: return NotImplemented return not op_result
[docs]def _ge_from_le(self, other): """Return a >= b. Computed by @total_ordering from (not a <= b) or (a == b).""" op_result = self.__le__(other) if op_result is NotImplemented: return NotImplemented return not op_result or self == other
[docs]def _lt_from_le(self, other): """Return a < b. Computed by @total_ordering from (a <= b) and (a != b).""" op_result = self.__le__(other) if op_result is NotImplemented: return NotImplemented return op_result and self != other
[docs]def _gt_from_le(self, other): """Return a > b. Computed by @total_ordering from (not a <= b).""" op_result = self.__le__(other) if op_result is NotImplemented: return NotImplemented return not op_result
[docs]def _lt_from_gt(self, other): """Return a < b. Computed by @total_ordering from (not a > b) and (a != b).""" op_result = self.__gt__(other) if op_result is NotImplemented: return NotImplemented return not op_result and self != other
[docs]def _ge_from_gt(self, other): """Return a >= b. Computed by @total_ordering from (a > b) or (a == b).""" op_result = self.__gt__(other) return op_result or self == other
[docs]def _le_from_gt(self, other): """Return a <= b. Computed by @total_ordering from (not a > b).""" op_result = self.__gt__(other) if op_result is NotImplemented: return NotImplemented return not op_result
[docs]def _le_from_ge(self, other): """Return a <= b. Computed by @total_ordering from (not a >= b) or (a == b).""" op_result = self.__ge__(other) if op_result is NotImplemented: return NotImplemented return not op_result or self == other
[docs]def _gt_from_ge(self, other): """Return a > b. Computed by @total_ordering from (a >= b) and (a != b).""" op_result = self.__ge__(other) if op_result is NotImplemented: return NotImplemented return op_result and self != other
[docs]def _lt_from_ge(self, other): """Return a < b. Computed by @total_ordering from (not a >= b).""" op_result = self.__ge__(other) if op_result is NotImplemented: return NotImplemented return not op_result
# noinspection PyIncorrectDocstring
[docs]def total_ordering(cls): """Class decorator that fills in missing ordering methods""" convert = { # :off '__lt__': [('__gt__', _gt_from_lt), ('__le__', _le_from_lt), ('__ge__', _ge_from_lt)], '__le__': [('__ge__', _ge_from_le), ('__lt__', _lt_from_le), ('__gt__', _gt_from_le)], '__gt__': [('__lt__', _lt_from_gt), ('__ge__', _ge_from_gt), ('__le__', _le_from_gt)], '__ge__': [('__le__', _le_from_ge), ('__gt__', _gt_from_ge), ('__lt__', _lt_from_ge)] } # :on # Find user-defined comparisons (not those inherited from object). roots = [ # :off op for op in convert if getattr(cls, op, None) is not getattr(object, op, None) ] # :on if not roots: raise ValueError('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 setattr(cls, opname, opfunc) return cls