From 31975cfa38689dc0a45fe26d0563eb7b5b3bda6c Mon Sep 17 00:00:00 2001 From: Frazer McLean Date: Fri, 15 Nov 2024 13:07:00 -0500 Subject: [PATCH] Add Range.__contains__ ### Description Fixes #12093 ### Checklist This pull request is: - [ ] A documentation / typographical / small typing error fix - Good to go, no issue or tests are needed - [x] A short code fix - please include the issue number, and create an issue if none exists, which must include a complete example of the issue. one line code fixes without an issue and demonstration will not be accepted. - Please include: `Fixes: #` in the commit message - please include tests. one line code fixes without tests will not be accepted. - [ ] A new feature implementation - please include the issue number, and create an issue if none exists, which must include a complete example of how the feature would look. - Please include: `Fixes: #` in the commit message - please include tests. **Have a nice day!** Closes: #12094 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/12094 Pull-request-sha: 3f900e96b95c6dbd20ee6f5aa3f49dd6124ffba9 Change-Id: I4c3945eec6a931acd0a8c1682988c5f26e96a499 --- doc/build/changelog/unreleased_20/12093.rst | 6 ++++++ lib/sqlalchemy/dialects/postgresql/ranges.py | 2 ++ test/dialect/postgresql/test_types.py | 15 +++++++++++++++ 3 files changed, 23 insertions(+) create mode 100644 doc/build/changelog/unreleased_20/12093.rst diff --git a/doc/build/changelog/unreleased_20/12093.rst b/doc/build/changelog/unreleased_20/12093.rst new file mode 100644 index 0000000000..b9ec3b1f88 --- /dev/null +++ b/doc/build/changelog/unreleased_20/12093.rst @@ -0,0 +1,6 @@ +.. change:: + :tags: usecase, postgresql + :ticket: 12093 + + The :class:`_postgresql.Range` type now supports ``__contains__``. + Pull request courtesy of Frazer McLean. diff --git a/lib/sqlalchemy/dialects/postgresql/ranges.py b/lib/sqlalchemy/dialects/postgresql/ranges.py index b793ca49f1..fa0c0c5df8 100644 --- a/lib/sqlalchemy/dialects/postgresql/ranges.py +++ b/lib/sqlalchemy/dialects/postgresql/ranges.py @@ -360,6 +360,8 @@ class Range(Generic[_T]): else: return self._contains_value(value) + __contains__ = contains + def overlaps(self, other: Range[_T]) -> bool: "Determine whether this range overlaps with `other`." diff --git a/test/dialect/postgresql/test_types.py b/test/dialect/postgresql/test_types.py index 2523765673..2c5bd98fde 100644 --- a/test/dialect/postgresql/test_types.py +++ b/test/dialect/postgresql/test_types.py @@ -4377,12 +4377,14 @@ class _RangeComparisonFixtures(_RangeTests): ) is_true(range_.contains(values["il"])) + is_true(values["il"] in range_) is_false( range_.contains(Range(lower=values["ll"], upper=values["ih"])) ) is_false(range_.contains(values["rh"])) + is_false(values["rh"] in range_) is_true(range_ == range_) is_false(range_ != range_) @@ -4430,6 +4432,7 @@ class _RangeComparisonFixtures(_RangeTests): ) r, expected = connection.execute(q).first() eq_(r.contains(v), expected) + eq_(v in r, expected) _common_ranges_to_test = ( lambda r, e: Range(empty=True), @@ -4490,6 +4493,12 @@ class _RangeComparisonFixtures(_RangeTests): f"{r1}.contains({r2}): got {py_contains}," f" expected {pg_contains}", ) + r2_in_r1 = r2 in r1 + eq_( + r2_in_r1, + pg_contains, + f"{r2} in {r1}: got {r2_in_r1}, expected {pg_contains}", + ) py_contained = r1.contained_by(r2) eq_( py_contained, @@ -4503,6 +4512,12 @@ class _RangeComparisonFixtures(_RangeTests): f"{r2}.contains({r1}: got {r2.contains(r1)}," f" expected {pg_contained})", ) + r1_in_r2 = r1 in r2 + eq_( + r1_in_r2, + pg_contained, + f"{r1} in {r2}: got {r1_in_r2}, expected {pg_contained}", + ) @testing.combinations( *_common_ranges_to_test, -- 2.47.3