diff options
| author | Simon Charette <charette.s@gmail.com> | 2025-02-07 16:34:17 -0500 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2025-02-15 16:24:00 +0100 |
| commit | 8b1e324ca4aa1ae0721f6f5dcfba8325a751ef3c (patch) | |
| tree | 66d8f6a003e209d4159efd1b7e7d119372faf583 /tests | |
| parent | e62301091de8c6da45ab4a9d09080ba88229d2d0 (diff) | |
[5.2.x] Fixed #36173 -- Stabilized identity of Concat with an explicit output_field.
When Expression.__init__() overrides make use of *args, **kwargs
captures their argument values are respectively bound as a tuple and
dict instances. These composite values might themselves contain values
that require special identity treatments such as Concat(output_field)
as it's a Field instance.
Refs #30628 which introduced bound Field differentiation but lacked
argument captures handling.
Thanks erchenstein for the report.
Backport of df2c4952df6d93c575fb8a3c853dc9d4c2449f36 from main
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/db_functions/text/test_concat.py | 14 | ||||
| -rw-r--r-- | tests/expressions/tests.py | 23 |
2 files changed, 37 insertions, 0 deletions
diff --git a/tests/db_functions/text/test_concat.py b/tests/db_functions/text/test_concat.py index 6e4cb91d3a..ffcd19fad6 100644 --- a/tests/db_functions/text/test_concat.py +++ b/tests/db_functions/text/test_concat.py @@ -107,3 +107,17 @@ class ConcatTests(TestCase): ctx.captured_queries[0]["sql"].count("::text"), 1 if connection.vendor == "postgresql" else 0, ) + + def test_equal(self): + self.assertEqual( + Concat("foo", "bar", output_field=TextField()), + Concat("foo", "bar", output_field=TextField()), + ) + self.assertNotEqual( + Concat("foo", "bar", output_field=TextField()), + Concat("foo", "bar", output_field=CharField()), + ) + self.assertNotEqual( + Concat("foo", "bar", output_field=TextField()), + Concat("bar", "foo", output_field=TextField()), + ) diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index cfa33b6f45..89601de85b 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -1433,6 +1433,29 @@ class SimpleExpressionTests(SimpleTestCase): Expression(TestModel._meta.get_field("other_field")), ) + class InitCaptureExpression(Expression): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # The identity of expressions that obscure their __init__() signature + # with *args and **kwargs cannot be determined when bound with + # different combinations or *args and **kwargs. + self.assertNotEqual( + InitCaptureExpression(IntegerField()), + InitCaptureExpression(output_field=IntegerField()), + ) + + # However, they should be considered equal when their bindings are + # equal. + self.assertEqual( + InitCaptureExpression(IntegerField()), + InitCaptureExpression(IntegerField()), + ) + self.assertEqual( + InitCaptureExpression(output_field=IntegerField()), + InitCaptureExpression(output_field=IntegerField()), + ) + def test_hash(self): self.assertEqual(hash(Expression()), hash(Expression())) self.assertEqual( |
