summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2024-07-17 14:52:08 -0400
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2024-07-18 08:41:55 +0200
commit8fb7d30456d664b336d602db2085af1f6433ab35 (patch)
tree0a1a60f9f8e32d4326802d5f9b085f1302398fca
parent5eef80b56e8b3635a071d644fcc9acacdd71025c (diff)
[5.1.x] Fixed #35603 -- Prevented F.__contains__() from hanging.
Regression in 94b6f101f7dc363a8e71593570b17527dbb9f77f. Backport of 6b3f55446fdc62bd277903fd188a1781e4d92d29 from main.
-rw-r--r--django/db/models/expressions.py5
-rw-r--r--tests/expressions/tests.py5
2 files changed, 10 insertions, 0 deletions
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index 4ee22420d9..7779173f3c 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -884,6 +884,11 @@ class F(Combinable):
def __getitem__(self, subscript):
return Sliced(self, subscript)
+ def __contains__(self, other):
+ # Disable old-style iteration protocol inherited from implementing
+ # __getitem__() to prevent this method from hanging.
+ raise TypeError(f"argument of type '{self.__class__.__name__}' is not iterable")
+
def resolve_expression(
self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False
):
diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py
index 3538900092..64103f14db 100644
--- a/tests/expressions/tests.py
+++ b/tests/expressions/tests.py
@@ -1302,6 +1302,11 @@ class FTests(SimpleTestCase):
self.assertNotEqual(f, value)
self.assertNotEqual(value, f)
+ def test_contains(self):
+ msg = "argument of type 'F' is not iterable"
+ with self.assertRaisesMessage(TypeError, msg):
+ "" in F("name")
+
class ExpressionsTests(TestCase):
def test_F_reuse(self):