Commit 27fbcf5e authored by di68kap's avatar di68kap
Browse files

syntaxtree.Node: added __contains__()-method

parent 266ed28c
......@@ -326,7 +326,25 @@ class Node(
raise ValueError('Leave nodes have no children that can be indexed!')
match_function = lambda node: node.tag_name == index_or_tagname
return self.find(match_function)
return self.find(match_function, False)
def __contains__(self, tag_name: str) -> bool:
Returns true if a descendant with the given tag name exists.
tag_name: tag_name which will be searched among the descendant
bool: True, if at least one descendant node with the given tag
name exists, False otherwise
generator = self[tag_name]
return True
except StopIteration:
return False
@property # this needs to be a (dynamic) property, in case sef.parser gets updated
......@@ -613,7 +631,7 @@ class Node(
return self._tree_repr(' ', opening, closing, density=1)
def find(self, match_function: Callable) -> Iterator['Node']:
def find(self, match_function: Callable, include_root: bool=True) -> Iterator['Node']:
Finds nodes in the tree that fulfill a given criterion.
......@@ -624,15 +642,17 @@ class Node(
match_function (function): A function that takes as Node
object as argument and returns True or False
include_root (bool): If False, only descendant nodes will be
checked for a match.
Node: All nodes of the tree for which
``match_function(node)`` returns True
if match_function(self):
if include_root and match_function(self):
yield self
for child in self.children:
for node in child.find(match_function):
for node in child.find(match_function, True):
yield node
......@@ -172,6 +172,10 @@ class TestNodeFind():
assert str(matches[1]) == 'F', str(matches[1])
assert matches[0] == mock_syntax_tree('(X (c d))')
assert matches[1] == mock_syntax_tree('(X F)')
# check default: root is included in search:
matchf2 = lambda node: match_tag_name(node, 'a')
assert list(tree.find(matchf2))
assert not list(tree.find(matchf2, include_root=False))
def test_getitem(self):
tree = mock_syntax_tree('(a (b X) (X (c d)) (e (X F)))')
......@@ -188,6 +192,13 @@ class TestNodeFind():
assert matches[1] == mock_syntax_tree('(X F)')
def test_contains(self):
tree = mock_syntax_tree('(a (b X) (X (c d)) (e (X F)))')
assert 'a' not in tree
assert 'b' in tree
assert 'X' in tree
assert 'e' in tree
assert 'c' in tree
if __name__ == "__main__":
Supports Markdown
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