From 0528f9c6b6d1cf676b5135654b4f2404953c74e8 Mon Sep 17 00:00:00 2001
From: Arnaud Fontaine <arnaud.fontaine@nexedi.com>
Date: Tue, 6 Sep 2016 21:19:05 +0900
Subject: [PATCH] Delivery: Fix maximum recursion depth in
 getRootCausalityValueList().

Pattern: SIT_1 => RSPL => SIT_1.

Also, this reduces the complexity by not checking objects twice.
---
 product/ERP5/Document/Delivery.py | 35 ++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 14 deletions(-)

diff --git a/product/ERP5/Document/Delivery.py b/product/ERP5/Document/Delivery.py
index c021de72d0..4540ab46d2 100644
--- a/product/ERP5/Document/Delivery.py
+++ b/product/ERP5/Document/Delivery.py
@@ -710,21 +710,28 @@ class Delivery(XMLObject, ImmobilisationDelivery, SimulableMixin,
         This method will look at the causality and check if the
         causality has already a causality
       """
-      causality_value_list = self.getCausalityValueList()
-      if causality_value_list:
-        initial_list = []
-        for causality in causality_value_list:
-          # The causality may be something which has not this method
-          # (e.g. item)
-          try:
-            getRootCausalityValueList = causality.getRootCausalityValueList
-          except AttributeError:
-            continue
-          assert causality != self
-          initial_list += [x for x in getRootCausalityValueList()
+      seen_set = set()
+      def recursive(self):
+        if self in seen_set:
+          return []
+
+        seen_set.add(self)
+        causality_value_list = self.getCausalityValueList()
+        if causality_value_list:
+          initial_list = []
+          for causality in causality_value_list:
+            # The causality may be something which has not this method
+            # (e.g. item)
+            if getattr(causality, 'getRootCausalityValueList', None) is None:
+                continue
+
+            assert causality != self
+            initial_list += [x for x in recursive(causality)
                              if x not in initial_list]
-        return initial_list
-      return [self]
+          return initial_list
+        return [self]
+
+      return recursive(self)
 
     # XXX Temp hack, should be removed has soon as the structure of
     # the order/delivery builder will be reviewed. It might
-- 
2.30.9