Fixed #29166 -- Fixed crash in When() expression with a list argument.
Thanks Matthew Pava for the report and Tim Graham and Carlton Gibson for
reviews.
Regression in 19b2dfd1bf
.
This commit is contained in:
parent
3fb718f17d
commit
54f80430be
|
@ -369,7 +369,12 @@ class BaseExpression:
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
path, args, kwargs = self.deconstruct()
|
path, args, kwargs = self.deconstruct()
|
||||||
return hash((path,) + args + tuple(kwargs.items()))
|
kwargs = kwargs.copy()
|
||||||
|
output_field = type(kwargs.pop('output_field', None))
|
||||||
|
return hash((path, output_field) + args + tuple([
|
||||||
|
(key, tuple(value)) if isinstance(value, list) else (key, value)
|
||||||
|
for key, value in kwargs.items()
|
||||||
|
]))
|
||||||
|
|
||||||
|
|
||||||
class Expression(BaseExpression, Combinable):
|
class Expression(BaseExpression, Combinable):
|
||||||
|
|
|
@ -21,3 +21,6 @@ Bugfixes
|
||||||
* Made ``Q.deconstruct()`` deterministic with multiple keyword arguments
|
* Made ``Q.deconstruct()`` deterministic with multiple keyword arguments
|
||||||
(:ticket:`29125`). You may need to modify ``Q``'s in existing migrations, or
|
(:ticket:`29125`). You may need to modify ``Q``'s in existing migrations, or
|
||||||
accept an autogenerated migration.
|
accept an autogenerated migration.
|
||||||
|
|
||||||
|
* Fixed a regression where a ``When()`` expression with a list argument crashes
|
||||||
|
(:ticket:`29166`).
|
||||||
|
|
|
@ -1288,6 +1288,24 @@ class CaseDocumentationExamples(TestCase):
|
||||||
transform=attrgetter('name', 'account_type')
|
transform=attrgetter('name', 'account_type')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_hash(self):
|
||||||
|
expression_1 = Case(
|
||||||
|
When(account_type__in=[Client.REGULAR, Client.GOLD], then=1),
|
||||||
|
default=2,
|
||||||
|
output_field=models.IntegerField(),
|
||||||
|
)
|
||||||
|
expression_2 = Case(
|
||||||
|
When(account_type__in=(Client.REGULAR, Client.GOLD), then=1),
|
||||||
|
default=2,
|
||||||
|
output_field=models.IntegerField(),
|
||||||
|
)
|
||||||
|
expression_3 = Case(When(account_type__in=[Client.REGULAR, Client.GOLD], then=1), default=2)
|
||||||
|
expression_4 = Case(When(account_type__in=[Client.PLATINUM, Client.GOLD], then=2), default=1)
|
||||||
|
self.assertEqual(hash(expression_1), hash(expression_2))
|
||||||
|
self.assertNotEqual(hash(expression_2), hash(expression_3))
|
||||||
|
self.assertNotEqual(hash(expression_1), hash(expression_4))
|
||||||
|
self.assertNotEqual(hash(expression_3), hash(expression_4))
|
||||||
|
|
||||||
|
|
||||||
class CaseWhenTests(SimpleTestCase):
|
class CaseWhenTests(SimpleTestCase):
|
||||||
def test_only_when_arguments(self):
|
def test_only_when_arguments(self):
|
||||||
|
|
Loading…
Reference in New Issue