Skip to content

Commit 89c9b3a

Browse files
webknjazhroncok
andcommitted
Prevent copying tmp dir to itself in build backend
Previously, setting `TMPDIR="$(pwd)/smth-inside"` would cause the in-tree PEP 517 build backend to go into infinite recursion, attempting to copy the project directory into a nested folder. Specifically, this is happening in the Fedora land because macros used in RPM packaging (`pyproject-rpm-macros`) are setting it up like this. Additionally, this is only happening with `pip wheel` and doesn't affect `pyproject-build`, because the latter pre-copies the project directory by itself early, and changes current working directory to it while the former does not. This patch addresses the issue by excluding the temporary directory from traversal when copying the directory tree within the build backend. Co-Authored-By: Miro Hrončok <miro@hroncok.cz>
1 parent ba0797c commit 89c9b3a

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

packaging/pep517_backend/_backend.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import os
88
import typing as t # noqa: WPS111
99
from contextlib import contextmanager, suppress
10+
from functools import partial
1011
from pathlib import Path
1112
from shutil import copytree
1213
from sys import version_info as _python_version_tuple
@@ -192,12 +193,44 @@ def _get_sanitized_long_description(self): # noqa: WPS430
192193
_DistutilsDistributionMetadata.get_long_description = orig_func
193194

194195

196+
def _exclude_dir_path(
197+
excluded_dir_path: Path,
198+
visited_directory: str,
199+
_visited_dir_contents: list[str],
200+
) -> list[str]:
201+
"""Prevent recursive directory traversal."""
202+
# This stops the temporary directory from being copied
203+
# into self recursively forever.
204+
# Ref: https://github.com/aio-libs/yarl/issues/992
205+
visited_directory_subdirs_to_ignore = [
206+
subdir
207+
for subdir in _visited_dir_contents
208+
if excluded_dir_path == Path(visited_directory) / subdir
209+
]
210+
if visited_directory_subdirs_to_ignore:
211+
print(
212+
f'Preventing `{excluded_dir_path !s}` from being '
213+
'copied into itself recursively...',
214+
file=_standard_error_stream,
215+
)
216+
return visited_directory_subdirs_to_ignore
217+
218+
195219
@contextmanager
196220
def _in_temporary_directory(src_dir: Path) -> t.Iterator[None]:
197221
with TemporaryDirectory(prefix='.tmp-ansible-pylibssh-pep517-') as tmp_dir:
222+
tmp_dir_path = Path(tmp_dir)
223+
root_tmp_dir_path = tmp_dir_path.parent
224+
_exclude_tmpdir_parent = partial(_exclude_dir_path, root_tmp_dir_path)
225+
198226
with chdir_cm(tmp_dir):
199-
tmp_src_dir = Path(tmp_dir) / 'src'
200-
copytree(src_dir, tmp_src_dir, symlinks=True)
227+
tmp_src_dir = tmp_dir_path / 'src'
228+
copytree(
229+
src_dir,
230+
tmp_src_dir,
231+
ignore=_exclude_tmpdir_parent,
232+
symlinks=True,
233+
)
201234
os.chdir(tmp_src_dir)
202235
yield
203236

0 commit comments

Comments
 (0)