# HG changeset patch
# User Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
# Date 1368599546 -7200
#      Wed May 15 08:32:26 2013 +0200
# Branch stable
# Node ID 3e6b5f8cc4d22d3f6154101b66e89ccefcd09c30
# Parent  cb978d851ad130fa006afecd63e2a88a2dafbdc9
fix add_type_restriction() implementation with IN() function (closes #138635)

When the variable type is defined by an IN() function, ``add_type_restriction``
removes all types in it that don't match the specified type. Since the list
of types is modified inplace, the iteration must be done on a copy, not on
the list itself.

There was a test for "add_type_restriction + IN()" case but since there
was only 2 types defined in the IN function, the problem was not exposed.

diff --git a/nodes.py b/nodes.py
--- a/nodes.py
+++ b/nodes.py
@@ -229,7 +229,8 @@
                 if etype not in etypes:
                     raise RQLException('%r not in %r' % (etype, etypes))
                 if len(etypes) > 1:
-                    for child in istarget.children:
+                    # iterate a copy of children because it's modified inplace
+                    for child in istarget.children[:]:
                         if child.value != etype:
                             istarget.remove(child)
             else:
diff --git a/test/unittest_nodes.py b/test/unittest_nodes.py
--- a/test/unittest_nodes.py
+++ b/test/unittest_nodes.py
@@ -70,12 +70,12 @@
         self.assertEqual(tree.as_string(), 'Any X WHERE X is Person')
 
     def test_add_new_is_type_restriction_in(self):
-        tree = self.parse('Any X WHERE X is IN(Person, Company)')
+        tree = self.parse('Any X WHERE X is IN(Person, Company, Student)')
         select = tree.children[0]
         x = select.get_selected_variables().next()
-        select.add_type_restriction(x.variable, 'Company')
+        select.add_type_restriction(x.variable, 'Person')
         # implementation is KISS (the IN remains)
-        self.assertEqual(tree.as_string(), 'Any X WHERE X is IN(Company)')
+        self.assertEqual(tree.as_string(), 'Any X WHERE X is IN(Person)')
 
     def test_add_is_in_type_restriction(self):
         tree = self.parse('Any X WHERE X is IN(Person, Company)')