Skip to content

Commit 127a324

Browse files
committed
Windows fix
1 parent 8f25fbf commit 127a324

File tree

1 file changed

+33
-16
lines changed

1 file changed

+33
-16
lines changed

wcmatch/_wcmatch.py

+33-16
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,30 @@
1212
# Right half can return an empty set if not supported
1313
SUPPORT_DIR_FD = {os.open, os.stat} <= os.supports_dir_fd and os.scandir in os.supports_fd
1414

15-
1615
RE_WIN_MOUNT = (
17-
re.compile(r'\\|[a-z]:(?:\\|$)', re.I),
18-
re.compile(br'\\|[a-z]:(?:\\|$)', re.I)
16+
re.compile(r'\\|/|[a-z]:(?:\\|/|$)', re.I),
17+
re.compile(br'\\|/|[a-z]:(?:\\|/|$)', re.I)
1918
)
2019
RE_MOUNT = (
2120
re.compile(r'/'),
2221
re.compile(br'/')
2322
)
23+
RE_WIN_SPLIT = (
24+
re.compile(r'\\|/'),
25+
re.compile(br'\\|/')
26+
)
27+
RE_SPLIT = (
28+
re.compile(r'/'),
29+
re.compile(br'/')
30+
)
31+
RE_WIN_STRIP = (
32+
r'\\/',
33+
br'\\/'
34+
)
35+
RE_STRIP = (
36+
r'/',
37+
br'/'
38+
)
2439

2540

2641
class _Match(Generic[AnyStr]):
@@ -49,8 +64,7 @@ def _fs_match(
4964
self,
5065
pattern: Pattern[AnyStr],
5166
filename: AnyStr,
52-
is_dir: bool,
53-
sep: AnyStr,
67+
is_win: bool,
5468
follow: bool,
5569
symlinks: dict[tuple[int | None, AnyStr], bool],
5670
root: AnyStr,
@@ -65,15 +79,16 @@ def _fs_match(
6579
We only check for the symlink if we know we are looking at a directory.
6680
And we only call `lstat` if we can't find it in the cache.
6781
68-
We know it's a directory if:
82+
We know we need to check the directory if:
6983
70-
1. If the base is a directory, all parts are directories.
71-
2. If we are not the last part of the `globstar`, the part is a directory.
72-
3. If the base is a file, but the part is not at the end, it is a directory.
84+
1. If the match has not reached the end of the path and directory is in `globstar` match.
85+
2. Or the match is at the end of the path and the directory is not the last part of `globstar` match.
7386
7487
"""
7588

7689
matched = False
90+
split = (RE_WIN_SPLIT if is_win else RE_SPLIT)[self.ptype] # type: Any
91+
strip = (RE_WIN_STRIP if is_win else RE_STRIP)[self.ptype] # type: Any
7792

7893
end = len(filename) - 1
7994
base = None
@@ -87,7 +102,7 @@ def _fs_match(
87102
for i, star in enumerate(m.groups(), 1):
88103
if star:
89104
at_end = m.end(i) == end
90-
parts = star.strip(sep).split(sep)
105+
parts = split.split(star.strip(strip))
91106
if base is None:
92107
base = os.path.join(root, filename[:m.start(i)])
93108
last_part = len(parts)
@@ -125,13 +140,15 @@ def _match_real(
125140
) -> bool:
126141
"""Match real filename includes and excludes."""
127142

128-
temp = '\\' if util.platform() == "windows" else '/'
143+
is_win = util.platform() == "windows"
144+
129145
if isinstance(self.filename, bytes):
130-
sep = os.fsencode(temp)
146+
sep = b'/'
147+
is_dir = (RE_WIN_SPLIT if is_win else RE_SPLIT)[1].match(self.filename[-1:]) is not None
131148
else:
132-
sep = temp
149+
sep = '/'
150+
is_dir = (RE_WIN_SPLIT if is_win else RE_SPLIT)[0].match(self.filename[-1:]) is not None
133151

134-
is_dir = self.filename.endswith(sep)
135152
try:
136153
if dir_fd is None:
137154
is_file_dir = os.path.isdir(os.path.join(root, self.filename))
@@ -153,14 +170,14 @@ def _match_real(
153170

154171
matched = False
155172
for pattern in self.include:
156-
if self._fs_match(pattern, filename, is_dir, sep, self.follow, symlinks, root, dir_fd):
173+
if self._fs_match(pattern, filename, is_win, self.follow, symlinks, root, dir_fd):
157174
matched = True
158175
break
159176

160177
if matched:
161178
if self.exclude:
162179
for pattern in self.exclude:
163-
if self._fs_match(pattern, filename, is_dir, sep, True, symlinks, root, dir_fd):
180+
if self._fs_match(pattern, filename, is_win, True, symlinks, root, dir_fd):
164181
matched = False
165182
break
166183

0 commit comments

Comments
 (0)