Skip to content

Commit bd03f3d

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

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
@@ -1674,7 +1674,7 @@ def match(self, patterns, name, accept_prefix=False):
16741674
matcher = wildcard.get_matcher(patterns, case_sensitive)
16751675
return matcher(name)
16761676

1677-
def match_glob(self, patterns, name, accept_prefix=False):
1677+
def match_glob(self, patterns, path, accept_prefix=False):
16781678
# type: (Optional[Iterable[Text]], Text, bool) -> bool
16791679
"""Check if a path matches any of a list of glob patterns.
16801680
@@ -1687,26 +1687,27 @@ def match_glob(self, patterns, name, accept_prefix=False):
16871687
Arguments:
16881688
patterns (list, optional): A list of patterns, e.g.
16891689
``['*.py']``, or `None` to match everything.
1690-
name (str): A file or directory name (not a path)
1691-
accept_prefix (bool): If ``True``, the name is
1690+
path (str): A resource path, starting with "/".
1691+
accept_prefix (bool): If ``True``, the path is
16921692
not required to match the wildcards themselves
16931693
but only need to be a prefix of a string that does.
16941694
16951695
Returns:
1696-
bool: `True` if ``name`` matches any of the patterns.
1696+
bool: `True` if ``path`` matches any of the patterns.
16971697
16981698
Raises:
16991699
TypeError: If ``patterns`` is a single string instead of
17001700
a list (or `None`).
1701+
ValueError: If ``path`` is not a string starting with "/".
17011702
17021703
Example:
1703-
>>> my_fs.match_glob(['*.py'], '__init__.py')
1704+
>>> my_fs.match_glob(['*.py'], '/__init__.py')
17041705
True
1705-
>>> my_fs.match_glob(['*.jpg', '*.png'], 'foo.gif')
1706+
>>> my_fs.match_glob(['*.jpg', '*.png'], '/foo.gif')
17061707
False
1707-
>>> my_fs.match_glob(['dir/file.txt'], 'dir/', accept_prefix=True)
1708+
>>> my_fs.match_glob(['dir/file.txt'], '/dir/', accept_prefix=True)
17081709
True
1709-
>>> my_fs.match_glob(['dir/file.txt'], 'dir/gile.txt', accept_prefix=True)
1710+
>>> my_fs.match_glob(['dir/file.txt'], '/dir/gile.txt', accept_prefix=True)
17101711
False
17111712
17121713
Note:
@@ -1716,6 +1717,8 @@ def match_glob(self, patterns, name, accept_prefix=False):
17161717
"""
17171718
if patterns is None:
17181719
return True
1720+
if not path or path[0] != "/":
1721+
raise ValueError("%s needs to be a string starting with /" % path)
17191722
if isinstance(patterns, six.text_type):
17201723
raise TypeError("patterns must be a list or sequence")
17211724
case_sensitive = not typing.cast(
@@ -1724,7 +1727,7 @@ def match_glob(self, patterns, name, accept_prefix=False):
17241727
matcher = glob.get_matcher(
17251728
patterns, case_sensitive, accept_prefix=accept_prefix
17261729
)
1727-
return matcher(name)
1730+
return matcher(path)
17281731

17291732
def tree(self, **kwargs):
17301733
# 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)