In January 2021 we will introduce a 10 GB quota for project repositories. Higher limits for individual projects will be available on request. Please see https://doku.lrz.de/display/PUBLIC/GitLab for more information.

Commit 27fbcf5e authored by di68kap's avatar di68kap

syntaxtree.Node: added __contains__()-method

parent 266ed28c
......@@ -326,7 +326,25 @@ class Node(collections.abc.Sized):
raise ValueError('Leave nodes have no children that can be indexed!')
else:
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.
Args:
tag_name: tag_name which will be searched among the descendant
nodes
Returns:
bool: True, if at least one descendant node with the given tag
name exists, False otherwise
"""
generator = self[tag_name]
try:
generator.__next__()
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(collections.abc.Sized):
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(collections.abc.Sized):
Args:
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.
Yields:
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
else:
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():
print(flatten_sxpr(matches[0].as_sxpr()))
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__":
......
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