Skip to content

Commit

Permalink
Changed total ordering decorator to a PartialOrderingMixin instead. T…
Browse files Browse the repository at this point in the history
…his was required since ranges are not totally ordered anymore. This should fix test suite for PyPy
  • Loading branch information
runfalk committed Mar 23, 2017
1 parent d55df71 commit 004a38c
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 45 deletions.
2 changes: 2 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Released on <unreleased>

This release is a preparation for a stable 1.0 release.

- Fixed comparison operators when working with empty or unbounded ranges. They
would previously raise exceptions.
- Renamed classes to match :pep:`8#class-names` conventions. This does not apply
to classes that works on built-in that does not follow :pep:`8#class-names`.
- Optimized :meth:`~spans.types.Range.overlap`, 1.3x speedup.
Expand Down
51 changes: 12 additions & 39 deletions spans/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"date_from_iso_week",
"find_slots",
"PicklableSlotMixin",
"sane_total_ordering",
]

def date_from_iso_week(year, week, day_of_week=None):
Expand Down Expand Up @@ -59,57 +58,31 @@ def __setstate__(self, data):
setattr(self, attr, value)


def sane_total_ordering(cls):
def __ge__(self, other):
gt = self.__gt__(other)
if gt is NotImplemented:
return NotImplemented
elif gt:
return True

eq = self.__eq__(other)
if eq is NotImplemented:
return NotImplemented
return eq

class PartialOrderingMixin(object):
def __le__(self, other):
lt = self.__lt__(other)
if lt is NotImplemented:
return NotImplemented
elif lt:
return True

eq = self.__eq__(other)
if eq is NotImplemented:

if lt is NotImplemented and eq is NotImplemented:
return NotImplemented
return eq
return lt is True or eq is True

def __gt__(self, other):
le = __le__(self, other)
le = self.__le__(other)
if le is NotImplemented:
return NotImplemented

return not le

def __ge__(self, other):
gt = self.__gt__(other)
eq = self.__eq__(other)
if gt is NotImplemented and eq is NotImplemented:
return NotImplemented
return gt is True or eq is True

def __ne__(self, other):
eq = self.__eq__(other)
if eq is NotImplemented:
return NotImplemented

return not eq

ops = [(f.__name__, f) for f in [__ge__, __le__, __gt__]]
predefined = set(dir(cls))

if "__lt__" not in predefined:
raise ValueError("Must define __lt__")

for func in [__ge__, __le__, __gt__, __ne__]:
name = func.__name__

# Test if class actually has overridden the default rich comparison
# implementation
if name not in predefined or getattr(cls, name) is getattr(object, name):
setattr(cls, name, func)

return cls
5 changes: 2 additions & 3 deletions spans/settypes.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from itertools import chain

from ._compat import add_metaclass
from ._utils import sane_total_ordering
from ._utils import PartialOrderingMixin
from .types import Range
from .types import *
from .types import DiscreteRange, OffsetableRangeMixin
Expand Down Expand Up @@ -127,9 +127,8 @@ def offset(self, offset):
return self.__class__(r.offset(offset) for r in self)


@sane_total_ordering
@add_metaclass(MetaRangeSet)
class RangeSet(object):
class RangeSet(PartialOrderingMixin):
"""
A range set works a lot like a range with some differences:
Expand Down
5 changes: 2 additions & 3 deletions spans/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from datetime import date, datetime, timedelta

from ._compat import *
from ._utils import date_from_iso_week, PicklableSlotMixin, sane_total_ordering
from ._utils import date_from_iso_week, PartialOrderingMixin, PicklableSlotMixin


__all__ = [
Expand All @@ -23,8 +23,7 @@
_empty_internal_range = _internal_range(None, None, False, False, True)


@sane_total_ordering
class Range(PicklableSlotMixin):
class Range(PartialOrderingMixin, PicklableSlotMixin):
"""
Abstract base class of all ranges.
Expand Down

0 comments on commit 004a38c

Please sign in to comment.