Issue 6899: Base.replace breaks tree (original) (raw)
In Base.replace, the method checks that self.parent is not None - however, it (unfortunately), breaks this very property itself if self is new, or self in new.
In particular, some fixers return node from transform if they don't want to do anything. In that case, self.parent gets set to None, even though new (which is self) is still connected to the tree.
This patch a) short-cuts the case that self is new b) arranges to set parent of the new nodes only after clearing parent of self
I updated the patch with a few unit tests:
euclid:trunk minge$ ./python.exe Lib/test/test_lib2to3.py
...
====================================================================== FAIL: test_replace (lib2to3.tests.test_pytree.TestNodes)
Traceback (most recent call last): File "/Users/minge/Research/Languages/python/trunk/Lib/lib2to3/tests/test_pytree.py", line 161, in test_replace self.assertEqual(l2.parent, n1) AssertionError: None != Node(1000, [Leaf(100, 'foo'), Leaf(100, '+'), Leaf(100, 'bar')])
====================================================================== FAIL: test_replace_with_list (lib2to3.tests.test_pytree.TestNodes)
Traceback (most recent call last): File "/Users/minge/Research/Languages/python/trunk/Lib/lib2to3/tests/test_pytree.py", line 179, in test_replace_with_list self.assertEqual(l1.parent, n1) AssertionError: None != Node(1000, [Leaf(100, 'foo'), Leaf(100, '+'), Leaf(100, 'baz'), Leaf(100, ''), Leaf(100, ''), Leaf(100, 'bar')])
Ran 541 tests in 19.328s
FAILED (failures=2)
...
euclid:trunk minge$ patch -p0 < python.patch patching file Lib/lib2to3/pytree.py Hunk #1 succeeded at 132 (offset 2 lines). Hunk #2 succeeded at 151 (offset 2 lines).
euclid:trunk minge$ ./python.exe Lib/test/test_lib2to3.py
...
Ran 541 tests in 19.642s
OK