Skip to content

Commit 0f279c7

Browse files
author
atollk
committed
Fixed glob behavior. Missing path separators (/) at the beginning of a string were causing issues.
1 parent d04aca7 commit 0f279c7

File tree

3 files changed

+21
-11
lines changed

3 files changed

+21
-11
lines changed

fs/base.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,7 +1691,7 @@ def match(self, patterns, name, accept_prefix=False):
16911691
matcher = wildcard.get_matcher(patterns, case_sensitive)
16921692
return matcher(name)
16931693

1694-
def match_glob(self, patterns, name, accept_prefix=False):
1694+
def match_glob(self, patterns, path, accept_prefix=False):
16951695
# type: (Optional[Iterable[Text]], Text, bool) -> bool
16961696
"""Check if a path matches any of a list of glob patterns.
16971697
@@ -1704,26 +1704,27 @@ def match_glob(self, patterns, name, accept_prefix=False):
17041704
Arguments:
17051705
patterns (list, optional): A list of patterns, e.g.
17061706
``['*.py']``, or `None` to match everything.
1707-
name (str): A file or directory name (not a path)
1708-
accept_prefix (bool): If ``True``, the name is
1707+
path (str): A resource path, starting with "/".
1708+
accept_prefix (bool): If ``True``, the path is
17091709
not required to match the wildcards themselves
17101710
but only need to be a prefix of a string that does.
17111711
17121712
Returns:
1713-
bool: `True` if ``name`` matches any of the patterns.
1713+
bool: `True` if ``path`` matches any of the patterns.
17141714
17151715
Raises:
17161716
TypeError: If ``patterns`` is a single string instead of
17171717
a list (or `None`).
1718+
ValueError: If ``path`` is not a string starting with "/".
17181719
17191720
Example:
1720-
>>> my_fs.match_glob(['*.py'], '__init__.py')
1721+
>>> my_fs.match_glob(['*.py'], '/__init__.py')
17211722
True
1722-
>>> my_fs.match_glob(['*.jpg', '*.png'], 'foo.gif')
1723+
>>> my_fs.match_glob(['*.jpg', '*.png'], '/foo.gif')
17231724
False
1724-
>>> my_fs.match_glob(['dir/file.txt'], 'dir/', accept_prefix=True)
1725+
>>> my_fs.match_glob(['dir/file.txt'], '/dir/', accept_prefix=True)
17251726
True
1726-
>>> my_fs.match_glob(['dir/file.txt'], 'dir/gile.txt', accept_prefix=True)
1727+
>>> my_fs.match_glob(['dir/file.txt'], '/dir/gile.txt', accept_prefix=True)
17271728
False
17281729
17291730
Note:
@@ -1733,6 +1734,8 @@ def match_glob(self, patterns, name, accept_prefix=False):
17331734
"""
17341735
if patterns is None:
17351736
return True
1737+
if not path or path[0] != "/":
1738+
raise ValueError("%s needs to be a string starting with /" % path)
17361739
if isinstance(patterns, six.text_type):
17371740
raise TypeError("patterns must be a list or sequence")
17381741
case_sensitive = not typing.cast(
@@ -1741,7 +1744,7 @@ def match_glob(self, patterns, name, accept_prefix=False):
17411744
matcher = glob.get_matcher(
17421745
patterns, case_sensitive, accept_prefix=accept_prefix
17431746
)
1744-
return matcher(name)
1747+
return matcher(path)
17451748

17461749
def tree(self, **kwargs):
17471750
# type: (**Any) -> None

fs/glob.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ def match(pattern, path):
150150
except KeyError:
151151
levels, recursive, re_pattern = _translate_glob(pattern, case_sensitive=True)
152152
_PATTERN_CACHE[(pattern, True)] = (levels, recursive, re_pattern)
153+
if path and path[0] != "/":
154+
path = "/" + path
153155
return bool(re_pattern.match(path))
154156

155157

@@ -170,6 +172,8 @@ def imatch(pattern, path):
170172
except KeyError:
171173
levels, recursive, re_pattern = _translate_glob(pattern, case_sensitive=True)
172174
_PATTERN_CACHE[(pattern, False)] = (levels, recursive, re_pattern)
175+
if path and path[0] != "/":
176+
path = "/" + path
173177
return bool(re_pattern.match(path))
174178

175179

@@ -246,9 +250,11 @@ def get_matcher(patterns, case_sensitive, accept_prefix=False):
246250
new_patterns = []
247251
for pattern in patterns:
248252
split = _split_pattern_by_rec(pattern)
249-
for i in range(len(split)):
250-
new_pattern = "/".join(split[: i + 1])
253+
for i in range(1, len(split)):
254+
new_pattern = "/".join(split[:i])
251255
new_patterns.append(new_pattern)
256+
new_patterns.append(new_pattern + "/")
257+
new_patterns.append(pattern)
252258
patterns = new_patterns
253259

254260
matcher = match_any if case_sensitive else imatch_any

tests/test_glob.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def test_match(self):
2222
tests = [
2323
("*.?y", "/test.py", True),
2424
("*.py", "/test.py", True),
25+
("*.py", "__init__.py", True),
2526
("*.py", "/test.pc", False),
2627
("*.py", "/foo/test.py", False),
2728
("foo/*.py", "/foo/test.py", True),

0 commit comments

Comments
 (0)