From d26db69cbd8cc884552b330455ce038097ee4444 Mon Sep 17 00:00:00 2001 From: aiko1895 Date: Sat, 31 Mar 2012 15:49:48 +0300 Subject: [PATCH 1/3] added backport of total_ordering to work with 2.6 --- rq/queue.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/rq/queue.py b/rq/queue.py index f359595..a8c27d4 100644 --- a/rq/queue.py +++ b/rq/queue.py @@ -1,9 +1,36 @@ import times -from functools import total_ordering from .connections import get_current_connection from .job import Job from .exceptions import NoSuchJobError, UnpickleError, InvalidJobOperationError +""" Backport to work with Python 2.6 """ +def total_ordering(cls): + """Class decorator that fills in missing ordering methods""" + convert = { + '__lt__': [('__gt__', lambda self, other: not (self < other or self == other)), + ('__le__', lambda self, other: self < other or self == other), + ('__ge__', lambda self, other: not self < other)], + '__le__': [('__ge__', lambda self, other: not self <= other or self == other), + ('__lt__', lambda self, other: self <= other and not self == other), + ('__gt__', lambda self, other: not self <= other)], + '__gt__': [('__lt__', lambda self, other: not (self > other or self == other)), + ('__ge__', lambda self, other: self > other or self == other), + ('__le__', lambda self, other: not self > other)], + '__ge__': [('__le__', lambda self, other: (not self >= other) or self == other), + ('__gt__', lambda self, other: self >= other and not self == other), + ('__lt__', lambda self, other: not self >= other)] + } + roots = set(dir(cls)) & set(convert) + 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 + opfunc.__doc__ = getattr(int, opname).__doc__ + setattr(cls, opname, opfunc) + return cls + def get_failed_queue(connection=None): """Returns a handle to the special failed queue.""" From 4885458dde35e6b58e5eb5c9a1090c6ed2abbc95 Mon Sep 17 00:00:00 2001 From: Vincent Driessen Date: Sun, 1 Apr 2012 08:57:40 +0200 Subject: [PATCH 2/3] Move this hack to a separate file. --- rq/compat.py | 41 +++++++++++++++++++++++++++++++++++++++++ rq/queue.py | 29 +---------------------------- 2 files changed, 42 insertions(+), 28 deletions(-) create mode 100644 rq/compat.py diff --git a/rq/compat.py b/rq/compat.py new file mode 100644 index 0000000..6d02402 --- /dev/null +++ b/rq/compat.py @@ -0,0 +1,41 @@ +import sys + + +def is_python_version(*versions): + for version in versions: + if (sys.version_info[0] == version[0] and + sys.version_info >= version): + return True + return False + + +# functools.total_ordering is only available from Python 2.7 and 3.2 +if is_python_version((2, 7), (3, 2)): + from functools import total_ordering +else: + def total_ordering(cls): # noqa + """Class decorator that fills in missing ordering methods""" + convert = { + '__lt__': [('__gt__', lambda self, other: not (self < other or self == other)), # noqa + ('__le__', lambda self, other: self < other or self == other), # noqa + ('__ge__', lambda self, other: not self < other)], + '__le__': [('__ge__', lambda self, other: not self <= other or self == other), # noqa + ('__lt__', lambda self, other: self <= other and not self == other), # noqa + ('__gt__', lambda self, other: not self <= other)], + '__gt__': [('__lt__', lambda self, other: not (self > other or self == other)), # noqa + ('__ge__', lambda self, other: self > other or self == other), # noqa + ('__le__', lambda self, other: not self > other)], + '__ge__': [('__le__', lambda self, other: (not self >= other) or self == other), # noqa + ('__gt__', lambda self, other: self >= other and not self == other), # noqa + ('__lt__', lambda self, other: not self >= other)] + } + roots = set(dir(cls)) & set(convert) + if not roots: + raise ValueError('must define at least one ordering operation: < > <= >=') # noqa + 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 diff --git a/rq/queue.py b/rq/queue.py index a8c27d4..6940b9b 100644 --- a/rq/queue.py +++ b/rq/queue.py @@ -2,34 +2,7 @@ import times from .connections import get_current_connection from .job import Job from .exceptions import NoSuchJobError, UnpickleError, InvalidJobOperationError - -""" Backport to work with Python 2.6 """ -def total_ordering(cls): - """Class decorator that fills in missing ordering methods""" - convert = { - '__lt__': [('__gt__', lambda self, other: not (self < other or self == other)), - ('__le__', lambda self, other: self < other or self == other), - ('__ge__', lambda self, other: not self < other)], - '__le__': [('__ge__', lambda self, other: not self <= other or self == other), - ('__lt__', lambda self, other: self <= other and not self == other), - ('__gt__', lambda self, other: not self <= other)], - '__gt__': [('__lt__', lambda self, other: not (self > other or self == other)), - ('__ge__', lambda self, other: self > other or self == other), - ('__le__', lambda self, other: not self > other)], - '__ge__': [('__le__', lambda self, other: (not self >= other) or self == other), - ('__gt__', lambda self, other: self >= other and not self == other), - ('__lt__', lambda self, other: not self >= other)] - } - roots = set(dir(cls)) & set(convert) - 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 - opfunc.__doc__ = getattr(int, opname).__doc__ - setattr(cls, opname, opfunc) - return cls +from .compat import total_ordering def get_failed_queue(connection=None): From 25d3f94c9f696f066833cd24eb931cd7d267f421 Mon Sep 17 00:00:00 2001 From: Vincent Driessen Date: Sun, 1 Apr 2012 09:25:27 +0200 Subject: [PATCH 3/3] Use the true Python 2.7 stdlib implementation instead. --- rq/compat.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rq/compat.py b/rq/compat.py index 6d02402..a10576f 100644 --- a/rq/compat.py +++ b/rq/compat.py @@ -16,17 +16,17 @@ else: def total_ordering(cls): # noqa """Class decorator that fills in missing ordering methods""" convert = { - '__lt__': [('__gt__', lambda self, other: not (self < other or self == other)), # noqa - ('__le__', lambda self, other: self < other or self == other), # noqa + '__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: not self <= other or self == other), # noqa - ('__lt__', lambda self, other: self <= other and not self == other), # noqa + '__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: not (self > other or self == other)), # noqa - ('__ge__', lambda self, other: self > other or self == other), # noqa + '__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: (not self >= other) or self == other), # noqa - ('__gt__', lambda self, other: self >= other and not self == other), # noqa + '__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)