New implementation of Range sorting that works for Python 2.5 to 3.3, at least.

This commit is contained in:
Chris Withers 2014-02-18 20:55:00 +00:00
parent bae508ffa6
commit e60266c4c5
3 changed files with 54 additions and 14 deletions

View File

@ -139,15 +139,35 @@ class Range(object):
def __lt__(self, other): def __lt__(self, other):
if not isinstance(other, Range): if not isinstance(other, Range):
return NotImplemented
for attr in self.__slots__:
self_value = getattr(self, attr)
other_value = getattr(other, attr)
if self_value == other_value:
pass
elif self_value is None:
return True
elif other_value is None:
return False
else:
return self_value < other_value
return False return False
return ((self._lower, self._upper, self._bounds) <
(other._lower, other._upper, other._bounds))
def __le__(self, other): def __le__(self, other):
if not isinstance(other, Range): if not isinstance(other, Range):
return NotImplemented
for attr in self.__slots__:
self_value = getattr(self, attr)
other_value = getattr(other, attr)
if self_value == other_value:
pass
elif self_value is None:
return True
elif other_value is None:
return False return False
return ((self._lower, self._upper, self._bounds) <= else:
(other._lower, other._upper, other._bounds)) return self_value <= other_value
return True
def register_range(pgrange, pyrange, conn_or_curs, globally=False): def register_range(pgrange, pyrange, conn_or_curs, globally=False):

View File

@ -13,6 +13,7 @@
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details. # License for more details.
from __future__ import with_statement
import re import re
import sys import sys
@ -22,6 +23,7 @@ from functools import wraps
from testutils import unittest, skip_if_no_uuid, skip_before_postgres from testutils import unittest, skip_if_no_uuid, skip_before_postgres
from testutils import ConnectingTestCase, decorate_all_tests from testutils import ConnectingTestCase, decorate_all_tests
from testutils import py3_raises_typeerror
import psycopg2 import psycopg2
import psycopg2.extras import psycopg2.extras
@ -1240,7 +1242,9 @@ class RangeTestCase(unittest.TestCase):
self.assert_(not Range() < Range()) self.assert_(not Range() < Range())
self.assert_(not Range(empty=True) < Range(empty=True)) self.assert_(not Range(empty=True) < Range(empty=True))
self.assert_(not Range(1, 2) < Range(1, 2)) self.assert_(not Range(1, 2) < Range(1, 2))
with py3_raises_typeerror():
self.assert_(1 < Range(1, 2)) self.assert_(1 < Range(1, 2))
with py3_raises_typeerror():
self.assert_(not Range(1, 2) < 1) self.assert_(not Range(1, 2) < 1)
def test_gt_ordering(self): def test_gt_ordering(self):
@ -1254,7 +1258,9 @@ class RangeTestCase(unittest.TestCase):
self.assert_(not Range() > Range()) self.assert_(not Range() > Range())
self.assert_(not Range(empty=True) > Range(empty=True)) self.assert_(not Range(empty=True) > Range(empty=True))
self.assert_(not Range(1, 2) > Range(1, 2)) self.assert_(not Range(1, 2) > Range(1, 2))
with py3_raises_typeerror():
self.assert_(not 1 > Range(1, 2)) self.assert_(not 1 > Range(1, 2))
with py3_raises_typeerror():
self.assert_(Range(1, 2) > 1) self.assert_(Range(1, 2) > 1)
def test_le_ordering(self): def test_le_ordering(self):
@ -1268,7 +1274,9 @@ class RangeTestCase(unittest.TestCase):
self.assert_(Range() <= Range()) self.assert_(Range() <= Range())
self.assert_(Range(empty=True) <= Range(empty=True)) self.assert_(Range(empty=True) <= Range(empty=True))
self.assert_(Range(1, 2) <= Range(1, 2)) self.assert_(Range(1, 2) <= Range(1, 2))
with py3_raises_typeerror():
self.assert_(1 <= Range(1, 2)) self.assert_(1 <= Range(1, 2))
with py3_raises_typeerror():
self.assert_(not Range(1, 2) <= 1) self.assert_(not Range(1, 2) <= 1)
def test_ge_ordering(self): def test_ge_ordering(self):
@ -1282,7 +1290,9 @@ class RangeTestCase(unittest.TestCase):
self.assert_(Range() >= Range()) self.assert_(Range() >= Range())
self.assert_(Range(empty=True) >= Range(empty=True)) self.assert_(Range(empty=True) >= Range(empty=True))
self.assert_(Range(1, 2) >= Range(1, 2)) self.assert_(Range(1, 2) >= Range(1, 2))
with py3_raises_typeerror():
self.assert_(not 1 >= Range(1, 2)) self.assert_(not 1 >= Range(1, 2))
with py3_raises_typeerror():
self.assert_(Range(1, 2) >= 1) self.assert_(Range(1, 2) >= 1)

View File

@ -329,3 +329,13 @@ def script_to_py3(script):
f2.close() f2.close()
os.remove(filename) os.remove(filename)
class py3_raises_typeerror(object):
def __enter__(self):
pass
def __exit__(self, type, exc, tb):
if sys.version_info[0] >= 3:
assert type is TypeError
return True