fix add_type_restriction() implementation with IN() function (closes #138635) stable
authorAdrien Di Mascio <Adrien.DiMascio@logilab.fr>
Wed, 15 May 2013 08:32:26 +0200
branchstable
changeset 709 3e6b5f8cc4d2
parent 707 cb978d851ad1
child 710 679566d1203d
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.
nodes.py
test/unittest_nodes.py
--- a/nodes.py	Tue Apr 09 01:16:07 2013 +0200
+++ b/nodes.py	Wed May 15 08:32:26 2013 +0200
@@ -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:
--- a/test/unittest_nodes.py	Tue Apr 09 01:16:07 2013 +0200
+++ b/test/unittest_nodes.py	Wed May 15 08:32:26 2013 +0200
@@ -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)')