From 77300187f7b18bb59995f398bcfef150a9ca42c8 Mon Sep 17 00:00:00 2001 From: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com> Date: Tue, 8 Sep 2020 13:26:38 +1000 Subject: [PATCH] fix: Ensure group tasks are deeply deserialised Fixes #6341 --- celery/canvas.py | 10 +++++++++- t/integration/test_canvas.py | 3 --- t/unit/tasks/test_canvas.py | 4 ---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/celery/canvas.py b/celery/canvas.py index f8278c6002..cc4c949c04 100644 --- a/celery/canvas.py +++ b/celery/canvas.py @@ -1027,8 +1027,16 @@ class group(Signature): @classmethod def from_dict(cls, d, app=None): + # We need to mutate the `kwargs` element in place to avoid confusing + # `freeze()` implementations which end up here and expect to be able to + # access elements from that dictionary later and refer to objects + # canonicalized here + orig_tasks = d["kwargs"]["tasks"] + d["kwargs"]["tasks"] = rebuilt_tasks = type(orig_tasks)(( + maybe_signature(task, app=app) for task in orig_tasks + )) return _upgrade( - d, group(d['kwargs']['tasks'], app=app, **d['options']), + d, group(rebuilt_tasks, app=app, **d['options']), ) def __init__(self, *tasks, **options): diff --git a/t/integration/test_canvas.py b/t/integration/test_canvas.py index d36229371a..a65abbda1c 100644 --- a/t/integration/test_canvas.py +++ b/t/integration/test_canvas.py @@ -1050,7 +1050,6 @@ def test_rebuild_nested_chain_chord(self, manager): ) sig.delay().get(timeout=TIMEOUT) - @pytest.mark.xfail(reason="#6341") def test_rebuild_nested_group_chain(self, manager): sig = chain( tasks.return_nested_signature_group_chain.s(), @@ -1058,7 +1057,6 @@ def test_rebuild_nested_group_chain(self, manager): ) sig.delay().get(timeout=TIMEOUT) - @pytest.mark.xfail(reason="#6341") def test_rebuild_nested_group_group(self, manager): sig = chain( tasks.return_nested_signature_group_group.s(), @@ -1066,7 +1064,6 @@ def test_rebuild_nested_group_group(self, manager): ) sig.delay().get(timeout=TIMEOUT) - @pytest.mark.xfail(reason="#6341") def test_rebuild_nested_group_chord(self, manager): try: manager.app.backend.ensure_chords_allowed() diff --git a/t/unit/tasks/test_canvas.py b/t/unit/tasks/test_canvas.py index 50a3a7a598..23d593b32d 100644 --- a/t/unit/tasks/test_canvas.py +++ b/t/unit/tasks/test_canvas.py @@ -633,7 +633,6 @@ def test_from_dict(self): x['args'] = None assert group.from_dict(dict(x)) - @pytest.mark.xfail(reason="#6341") def test_from_dict_deep_deserialize(self): original_group = group([self.add.s(1, 2)] * 42) serialized_group = json.loads(json.dumps(original_group)) @@ -641,7 +640,6 @@ def test_from_dict_deep_deserialize(self): for ds_task in deserialized_group.tasks: assert isinstance(ds_task, Signature) - @pytest.mark.xfail(reason="#6341") def test_from_dict_deeper_deserialize(self): inner_group = group([self.add.s(1, 2)] * 42) outer_group = group([inner_group] * 42) @@ -986,7 +984,6 @@ def test_from_dict_deep_deserialize(self): assert isinstance(task, Signature) assert isinstance(deserialized_chord.body, Signature) - @pytest.mark.xfail(reason="#6341") def test_from_dict_deep_deserialize_group(self): header = body = group([self.add.s(1, 2)]* 42) original_chord = chord(header=header, body=body) @@ -1001,7 +998,6 @@ def test_from_dict_deep_deserialize_group(self): for task in deserialized_chord.body.tasks: assert isinstance(task, Signature) - @pytest.mark.xfail(reason="#6341") def test_from_dict_deeper_deserialize_group(self): inner_group = group([self.add.s(1, 2)] * 42) header = body = group([inner_group] * 42)