mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-28 20:03:43 +03:00
Provide a stable and consistent sort order for Range objects.
This matches postgres server-side behaviour and helps client applications that need to sort based on the primary key of tables where the primary key is or contains a range.
This commit is contained in:
parent
66f85b5832
commit
d469c32503
|
@ -133,12 +133,21 @@ class Range(object):
|
|||
def __hash__(self):
|
||||
return hash((self._lower, self._upper, self._bounds))
|
||||
|
||||
def __lt__(self, other):
|
||||
raise TypeError(
|
||||
'Range objects cannot be ordered; please refer to the PostgreSQL'
|
||||
' documentation to perform this operation in the database')
|
||||
# as the postgres docs describe for the server-side stuff,
|
||||
# ordering is rather arbitrary, but will remain stable
|
||||
# and consistent.
|
||||
|
||||
__le__ = __gt__ = __ge__ = __lt__
|
||||
def __lt__(self, other):
|
||||
if not isinstance(other, Range):
|
||||
return False
|
||||
return ((self._lower, self._upper, self._bounds) <
|
||||
(other._lower, other._upper, other._bounds))
|
||||
|
||||
def __le__(self, other):
|
||||
if not isinstance(other, Range):
|
||||
return False
|
||||
return ((self._lower, self._upper, self._bounds) <=
|
||||
(other._lower, other._upper, other._bounds))
|
||||
|
||||
|
||||
def register_range(pgrange, pyrange, conn_or_curs, globally=False):
|
||||
|
|
|
@ -1225,12 +1225,65 @@ class RangeTestCase(unittest.TestCase):
|
|||
self.assertEqual(Range(10, 20), IntRange(10, 20))
|
||||
self.assertEqual(PositiveIntRange(10, 20), IntRange(10, 20))
|
||||
|
||||
def test_not_ordered(self):
|
||||
# as the postgres docs describe for the server-side stuff,
|
||||
# ordering is rather arbitrary, but will remain stable
|
||||
# and consistent.
|
||||
|
||||
def test_ordering_lt(self):
|
||||
from psycopg2.extras import Range
|
||||
self.assertRaises(TypeError, lambda: Range(empty=True) < Range(0,4))
|
||||
self.assertRaises(TypeError, lambda: Range(1,2) > Range(0,4))
|
||||
self.assertRaises(TypeError, lambda: Range(1,2) <= Range())
|
||||
self.assertRaises(TypeError, lambda: Range(1,2) >= Range())
|
||||
self.assertTrue(Range(empty=True) < Range(0, 4))
|
||||
self.assertFalse(Range(1, 2) < Range(0, 4))
|
||||
self.assertTrue(Range(0, 4) < Range(1, 2))
|
||||
self.assertFalse(Range(1, 2) < Range())
|
||||
self.assertTrue(Range() < Range(1, 2))
|
||||
self.assertFalse(Range(1) < Range(upper=1))
|
||||
self.assertFalse(Range() < Range())
|
||||
self.assertFalse(Range(empty=True) < Range(empty=True))
|
||||
self.assertFalse(Range(1, 2) < Range(1, 2))
|
||||
self.assertTrue(1 < Range(1, 2))
|
||||
self.assertFalse(Range(1, 2) < 1)
|
||||
|
||||
def test_ordering_gt(self):
|
||||
from psycopg2.extras import Range
|
||||
self.assertFalse(Range(empty=True) > Range(0, 4))
|
||||
self.assertTrue(Range(1, 2) > Range(0, 4))
|
||||
self.assertFalse(Range(0, 4) > Range(1, 2))
|
||||
self.assertTrue(Range(1, 2) > Range())
|
||||
self.assertFalse(Range() > Range(1, 2))
|
||||
self.assertTrue(Range(1) > Range(upper=1))
|
||||
self.assertFalse(Range() > Range())
|
||||
self.assertFalse(Range(empty=True) > Range(empty=True))
|
||||
self.assertFalse(Range(1, 2) > Range(1, 2))
|
||||
self.assertFalse(1 > Range(1, 2))
|
||||
self.assertTrue(Range(1, 2) > 1)
|
||||
|
||||
def test_ordering_le(self):
|
||||
from psycopg2.extras import Range
|
||||
self.assertTrue(Range(empty=True) <= Range(0, 4))
|
||||
self.assertFalse(Range(1, 2) <= Range(0, 4))
|
||||
self.assertTrue(Range(0, 4) <= Range(1, 2))
|
||||
self.assertFalse(Range(1, 2) <= Range())
|
||||
self.assertTrue(Range() <= Range(1, 2))
|
||||
self.assertFalse(Range(1) <= Range(upper=1))
|
||||
self.assertTrue(Range() <= Range())
|
||||
self.assertTrue(Range(empty=True) <= Range(empty=True))
|
||||
self.assertTrue(Range(1, 2) <= Range(1, 2))
|
||||
self.assertTrue(1 <= Range(1, 2))
|
||||
self.assertFalse(Range(1, 2) <= 1)
|
||||
|
||||
def test_ordering_ge(self):
|
||||
from psycopg2.extras import Range
|
||||
self.assertFalse(Range(empty=True) >= Range(0, 4))
|
||||
self.assertTrue(Range(1, 2) >= Range(0, 4))
|
||||
self.assertFalse(Range(0, 4) >= Range(1, 2))
|
||||
self.assertTrue(Range(1, 2) >= Range())
|
||||
self.assertFalse(Range() >= Range(1, 2))
|
||||
self.assertTrue(Range(1) >= Range(upper=1))
|
||||
self.assertTrue(Range() >= Range())
|
||||
self.assertTrue(Range(empty=True) >= Range(empty=True))
|
||||
self.assertTrue(Range(1, 2) >= Range(1, 2))
|
||||
self.assertFalse(1 >= Range(1, 2))
|
||||
self.assertTrue(Range(1, 2) >= 1)
|
||||
|
||||
|
||||
def skip_if_no_range(f):
|
||||
|
|
Loading…
Reference in New Issue
Block a user