Commit 16840633 by Steven Bird

Merge pull request #292 from heatherleaf/master

Fix to #229
parents afcab733 ae15153f
...@@ -697,13 +697,13 @@ operations: ...@@ -697,13 +697,13 @@ operations:
>>> ptree[0,0].remove(make_ptree('(Q p)')) >>> ptree[0,0].remove(make_ptree('(Q p)'))
Traceback (most recent call last): Traceback (most recent call last):
. . . . . .
ValueError: list.index(x): x not in list ValueError: ParentedTree('Q', ['p']) is not in list
>>> ptree.remove('h'); pcheck(ptree) >>> ptree.remove('h'); pcheck(ptree)
ok! (A (B (C (D )) g)) ok! (A (B (C (D )) g))
>>> ptree.remove('h'); >>> ptree.remove('h');
Traceback (most recent call last): Traceback (most recent call last):
. . . . . .
ValueError: list.index(x): x not in list ValueError: 'h' is not in list
>>> # remove() removes the first subtree that is equal (==) to the >>> # remove() removes the first subtree that is equal (==) to the
>>> # given tree, which may not be the identical tree we give it: >>> # given tree, which may not be the identical tree we give it:
>>> ptree = make_ptree('(A (X x) (Y y) (X x))') >>> ptree = make_ptree('(A (X x) (Y y) (X x))')
...@@ -1012,13 +1012,13 @@ multiple parents.) ...@@ -1012,13 +1012,13 @@ multiple parents.)
>>> mptree[0,0].remove(make_mptree('(Q p)')) >>> mptree[0,0].remove(make_mptree('(Q p)'))
Traceback (most recent call last): Traceback (most recent call last):
. . . . . .
ValueError: list.index(x): x not in list ValueError: MultiParentedTree('Q', ['p']) is not in list
>>> mptree.remove('h'); mpcheck(mptree) >>> mptree.remove('h'); mpcheck(mptree)
ok! (A (B (C (D )) g)) ok! (A (B (C (D )) g))
>>> mptree.remove('h'); >>> mptree.remove('h');
Traceback (most recent call last): Traceback (most recent call last):
. . . . . .
ValueError: list.index(x): x not in list ValueError: 'h' is not in list
>>> # remove() removes the first subtree that is equal (==) to the >>> # remove() removes the first subtree that is equal (==) to the
>>> # given tree, which may not be the identical tree we give it: >>> # given tree, which may not be the identical tree we give it:
>>> mptree = make_mptree('(A (X x) (Y y) (X x))') >>> mptree = make_mptree('(A (X x) (Y y) (X x))')
......
...@@ -813,6 +813,21 @@ class AbstractParentedTree(Tree): ...@@ -813,6 +813,21 @@ class AbstractParentedTree(Tree):
- ``_delparent()`` is called whenever a child is removed. - ``_delparent()`` is called whenever a child is removed.
""" """
def __init__(self, node_or_str, children=None):
super(AbstractParentedTree, self).__init__(node_or_str, children)
# If children is None, the tree is parsed from node_or_str, and
# all parents will be set during parsing.
if children is not None:
# Otherwise we have to set the parent of the children.
# Iterate over self, and *not* children, because children
# might be an iterator.
for i, child in enumerate(self):
if isinstance(child, Tree):
self._setparent(child, i, dry_run=True)
for i, child in enumerate(self):
if isinstance(child, Tree):
self._setparent(child, i)
#//////////////////////////////////////////////////////////// #////////////////////////////////////////////////////////////
# Parent management # Parent management
#//////////////////////////////////////////////////////////// #////////////////////////////////////////////////////////////
...@@ -1023,6 +1038,15 @@ class ParentedTree(AbstractParentedTree): ...@@ -1023,6 +1038,15 @@ class ParentedTree(AbstractParentedTree):
self._parent = None self._parent = None
"""The parent of this Tree, or None if it has no parent.""" """The parent of this Tree, or None if it has no parent."""
super(ParentedTree, self).__init__(node_or_str, children) super(ParentedTree, self).__init__(node_or_str, children)
if children is None:
# If children is None, the tree is parsed from node_or_str.
# After parsing, the parent of the immediate children
# will point to an intermediate tree, not self.
# We fix this by brute force:
for i, child in enumerate(self):
if isinstance(child, Tree):
child._parent = None
self._setparent(child, i)
def _frozen_class(self): return ImmutableParentedTree def _frozen_class(self): return ImmutableParentedTree
...@@ -1133,6 +1157,15 @@ class MultiParentedTree(AbstractParentedTree): ...@@ -1133,6 +1157,15 @@ class MultiParentedTree(AbstractParentedTree):
contain duplicates, even if a parent contains this tree contain duplicates, even if a parent contains this tree
multiple times.""" multiple times."""
super(MultiParentedTree, self).__init__(node_or_str, children) super(MultiParentedTree, self).__init__(node_or_str, children)
if children is None:
# If children is None, the tree is parsed from node_or_str.
# After parsing, the parent(s) of the immediate children
# will point to an intermediate tree, not self.
# We fix this by brute force:
for i, child in enumerate(self):
if isinstance(child, Tree):
child._parents = []
self._setparent(child, i)
def _frozen_class(self): return ImmutableMultiParentedTree def _frozen_class(self): return ImmutableMultiParentedTree
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment