Преглед изворни кода

Fixes #4106 - change GroupResult:as_tuple() to include parent (#4205)

* include parent in GroupResult:to_tuple()

* unit test for #4106

* check for list/tuple before unpacking id, parent

* flake8 issues

* wrong method call in unit test

* assert results equal in test_GroupResult_with_parent

* GroupResult.__eq__ checks parents, del redundant parent=None

* added test for GroupResult _eq_

* GroupResult_as_tuple unit test
pachewise пре 7 година
родитељ
комит
48de89df0c
2 измењених фајлова са 57 додато и 8 уклоњено
  1. 16 8
      celery/result.py
  2. 41 0
      t/unit/tasks/test_result.py

+ 16 - 8
celery/result.py

@@ -815,6 +815,7 @@ class GroupResult(ResultSet):
     Arguments:
         id (str): The id of the group.
         results (Sequence[AsyncResult]): List of result instances.
+        parent (ResultBase): Parent result of this group.
     """
 
     #: The UUID of the group.
@@ -823,8 +824,9 @@ class GroupResult(ResultSet):
     #: List/iterator of results in the group
     results = None
 
-    def __init__(self, id=None, results=None, **kwargs):
+    def __init__(self, id=None, results=None, parent=None, **kwargs):
         self.id = id
+        self.parent = parent
         ResultSet.__init__(self, results, **kwargs)
 
     def save(self, backend=None):
@@ -853,7 +855,11 @@ class GroupResult(ResultSet):
 
     def __eq__(self, other):
         if isinstance(other, GroupResult):
-            return other.id == self.id and other.results == self.results
+            return (
+                other.id == self.id and
+                other.results == self.results and
+                other.parent == self.parent
+            )
         return NotImplemented
 
     def __ne__(self, other):
@@ -865,7 +871,7 @@ class GroupResult(ResultSet):
                                          ', '.join(r.id for r in self.results))
 
     def as_tuple(self):
-        return self.id, [r.as_tuple() for r in self.results]
+        return (self.id, self.parent), [r.as_tuple() for r in self.results]
 
     @property
     def children(self):
@@ -969,13 +975,15 @@ def result_from_tuple(r, app=None):
     Result = app.AsyncResult
     if not isinstance(r, ResultBase):
         res, nodes = r
-        if nodes:
-            return app.GroupResult(
-                res, [result_from_tuple(child, app) for child in nodes],
-            )
-        # previously didn't include parent
         id, parent = res if isinstance(res, (list, tuple)) else (res, None)
         if parent:
             parent = result_from_tuple(parent, app)
+
+        if nodes:
+            return app.GroupResult(
+                id, [result_from_tuple(child, app) for child in nodes],
+                parent=parent,
+            )
+
         return Result(id, parent=parent)
     return r

+ 41 - 0
t/unit/tasks/test_result.py

@@ -595,6 +595,21 @@ class test_GroupResult:
     def test_eq_other(self):
         assert self.ts != 1
 
+    def test_eq_with_parent(self):
+        # GroupResult instances with different .parent are not equal
+        grp_res = self.app.GroupResult(
+            uuid(), [self.app.AsyncResult(uuid()) for _ in range(10)],
+            parent=self.app.AsyncResult(uuid())
+        )
+        grp_res_2 = self.app.GroupResult(grp_res.id, grp_res.results)
+        assert grp_res != grp_res_2
+
+        grp_res_2.parent = self.app.AsyncResult(uuid())
+        assert grp_res != grp_res_2
+
+        grp_res_2.parent = grp_res.parent
+        assert grp_res == grp_res_2
+
     @pytest.mark.usefixtures('depends_on_current_app')
     def test_pickleable(self):
         assert pickle.loads(pickle.dumps(self.ts))
@@ -892,3 +907,29 @@ class test_tuples:
         )
         assert x, result_from_tuple(x.as_tuple() == self.app)
         assert x, result_from_tuple(x == self.app)
+
+    def test_GroupResult_with_parent(self):
+        parent = self.app.AsyncResult(uuid())
+        result = self.app.GroupResult(
+            uuid(), [self.app.AsyncResult(uuid()) for _ in range(10)],
+            parent
+        )
+        second_result = result_from_tuple(result.as_tuple(), self.app)
+        assert second_result == result
+        assert second_result.parent == parent
+
+    def test_GroupResult_as_tuple(self):
+        parent = self.app.AsyncResult(uuid())
+        result = self.app.GroupResult(
+            'group-result-1',
+            [self.app.AsyncResult('async-result-{}'.format(i))
+             for i in range(2)],
+            parent
+        )
+        (result_id, parent_id), group_results = result.as_tuple()
+        assert result_id == result.id
+        assert parent_id == parent.id
+        assert isinstance(group_results, list)
+        expected_grp_res = [(('async-result-{}'.format(i), None), None)
+                            for i in range(2)]
+        assert group_results == expected_grp_res