# 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)')