Skip to content

Commit 113bffb

Browse files
committed
Revise subdirs_without_files() and subdirs_without_wheels() based on initial review.
It might even work this time!
1 parent 9f693f5 commit 113bffb

File tree

1 file changed

+28
-52
lines changed

1 file changed

+28
-52
lines changed

src/pip/_internal/utils/filesystem.py

Lines changed: 28 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -168,66 +168,42 @@ def copy_directory_permissions(directory: str, target_file: BinaryIO) -> None:
168168
def subdirs_without_files(path: str) -> Generator[Path]:
169169
"""Yields every subdirectory of +path+ that has no files under it."""
170170

171-
def inner(path: Path, parents: list[Path]) -> Generator[Path]:
172-
path_obj = Path(path)
171+
path = Path(path)
173172

174-
if not path_obj.exists():
175-
return
173+
directories = []
174+
non_empty = set()
176175

177-
subdirs = []
178-
for item in path_obj.iterdir():
179-
if item.is_dir():
180-
subdirs.append(item)
181-
else:
182-
# If we find a file, we want to preserve the whole subtree,
183-
# so bail immediately.
184-
return
185-
186-
# If we get to this point, we didn't find a file yet.
187-
188-
if parents is None:
189-
parents = []
190-
else:
191-
parents += [path_obj]
192-
193-
if subdirs:
194-
for subdir in subdirs:
195-
yield from inner(subdir, parents)
196-
else:
197-
yield from parents
176+
for root, _, filenames in path.resolve().walk():
177+
if filenames:
178+
# This directory contains a file, so mark it and all of its
179+
# parent directories as non-empty.
180+
# The last item in root.parents is ".", so we ignore it.
181+
non_empty.update(root.parents[:-1])
182+
non_empty.add(root)
183+
directories.append(root)
198184

199-
yield from sorted(set(inner(Path(path), [])), reverse=True)
185+
for d in sorted(directories, reverse=True):
186+
if d not in non_empty:
187+
yield d
200188

201189

202190
def subdirs_without_wheels(path: str) -> Generator[Path]:
203191
"""Yields every subdirectory of +path+ that has no .whl files under it."""
204192

205-
def inner(path: str | Path, parents: list[Path]) -> Generator[Path]:
206-
path_obj = Path(path)
193+
path = Path(path)
207194

208-
if not path_obj.exists():
209-
return
195+
directories = []
196+
has_wheels = set()
210197

211-
subdirs = []
212-
for item in path_obj.iterdir():
213-
if item.is_dir():
214-
subdirs.append(item)
215-
elif item.name.endswith(".whl"):
216-
# If we found a wheel, we want to preserve this whole subtree,
217-
# so we bail immediately and don't return any results.
218-
return
219-
220-
# If we get to this point, we didn't find a wheel yet.
221-
222-
if parents is None:
223-
parents = []
224-
else:
225-
parents += [path_obj]
226-
227-
if subdirs:
228-
for subdir in subdirs:
229-
yield from inner(subdir, parents)
230-
else:
231-
yield from parents
198+
for root, _, filenames in path.resolve().walk():
199+
if any(x.endswith('.whl') for x in filenames):
200+
# This directory contains a wheel file, so mark it and all of its
201+
# parent directories as has-wheel.
202+
# The last item in root.parents is ".", so we ignore it.
203+
has_wheels.update(root.parents[:-1])
204+
has_wheels.add(root)
205+
directories.append(root)
232206

233-
yield from sorted(set(inner(path, [])), reverse=True)
207+
for d in sorted(directories, reverse=True):
208+
if d not in has_wheels:
209+
yield d

0 commit comments

Comments
 (0)