Skip to content

Commit

Permalink
Resolver: Implement recursive wildcard **
Browse files Browse the repository at this point in the history
Fixes #4
  • Loading branch information
moi90 committed Jun 30, 2022
1 parent d63289b commit fa4d42a
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 20 deletions.
55 changes: 35 additions & 20 deletions anytree/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import re

from anytree.iterators.preorderiter import PreOrderIter

_MAXCACHE = 20


Expand Down Expand Up @@ -204,26 +206,39 @@ def __start(self, node, path, cmp_):

def __glob(self, node, parts):
assert node is not None
nodes = []
if parts:
name = parts[0]
remainder = parts[1:]
# handle relative
if name == "..":
parent = node.parent
if parent is None:
raise RootResolverError(node)
nodes += self.__glob(parent, remainder)
elif name in ("", "."):
nodes += self.__glob(node, remainder)
else:
matches = self.__find(node, name, remainder)
if not matches and not Resolver.is_wildcard(name):
raise ChildResolverError(node, name, self.pathattr)
nodes += matches
else:
nodes = [node]
return nodes

if not parts:
return [node]

name = parts[0]
remainder = parts[1:]

# handle relative
if name == "..":
parent = node.parent
if parent is None:
raise RootResolverError(node)
return self.__glob(parent, remainder)

if name in ("", "."):
return self.__glob(node, remainder)

# handle recursive
if name == "**":
matches = []
for n in PreOrderIter(node):
try:
matches += self.__glob(n, remainder)
except ChildResolverError:
pass
return matches

print(node, name, remainder)

matches = self.__find(node, name, remainder)
if not matches and not Resolver.is_wildcard(name):
raise ChildResolverError(node, name, self.pathattr)
return matches

def __find(self, node, pat, remainder):
matches = []
Expand Down
3 changes: 3 additions & 0 deletions tests/test_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ def test_glob():
with assert_raises(at.ResolverError, "unknown root node '/z*'. root is '/top'."):
r.glob(sub1, "/z*")

# Recursive matching
eq_(r.glob(top, "**/sub0"), [sub0, sub0sub0, sub0sub1sub0, sub1sub0])


def test_glob_cache():
"""Wildcard Cache."""
Expand Down

0 comments on commit fa4d42a

Please sign in to comment.