diff --git a/lib/_range.py b/lib/_range.py index 818cb15a..01e5c902 100644 --- a/lib/_range.py +++ b/lib/_range.py @@ -115,6 +115,22 @@ class Range(object): if self._upper is None: return False return self._bounds[1] == ']' + def __contains__(self, x): + if self._empty: return False + if self._lower is not None: + if self._bounds[0] == '[': + if x < self._lower: return False + else: + if x <= self._lower: return False + + if self._upper is not None: + if self._bounds[1] == ']': + if x > self._upper: return False + else: + if x >= self._upper: return False + + return True + def register_range(pgrange, pyrange, conn_or_curs, globally=False): """Register a typecaster and an adapter for range a range type. diff --git a/tests/test_types_extras.py b/tests/test_types_extras.py index 1826ad2c..d55acb91 100755 --- a/tests/test_types_extras.py +++ b/tests/test_types_extras.py @@ -859,6 +859,35 @@ class RangeTestCase(unittest.TestCase): self.assertRaises(ValueError, Range, bounds='(') self.assertRaises(ValueError, Range, bounds='[}') + def test_in(self): + from psycopg2.extras import Range + r = Range(empty=True) + self.assert_(10 not in r) + + r = Range(10, 20) + self.assert_(9 not in r) + self.assert_(10 in r) + self.assert_(11 in r) + self.assert_(19 in r) + self.assert_(20 not in r) + self.assert_(21 not in r) + + r = Range(10, 20, '(]') + self.assert_(9 not in r) + self.assert_(10 not in r) + self.assert_(11 in r) + self.assert_(19 in r) + self.assert_(20 in r) + self.assert_(21 not in r) + + r = Range(20, 10) + self.assert_(9 not in r) + self.assert_(10 not in r) + self.assert_(11 not in r) + self.assert_(19 not in r) + self.assert_(20 not in r) + self.assert_(21 not in r) + def skip_if_no_range(f): def skip_if_no_range_(self):