Skip to content

Commit 81f1054

Browse files
authored
Merge pull request #7873 from hroncok/no_copy_self
Prevent infinite recursion with pip wheel with $TMPDIR in $PWD
2 parents 6c97645 + eb070d2 commit 81f1054

File tree

5 files changed

+41
-5
lines changed

5 files changed

+41
-5
lines changed

news/7872.bugfix

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Prevent an infinite recursion with ``pip wheel`` when ``$TMPDIR`` is within the source directory.

src/pip/_internal/operations/prepare.py

+17-5
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,25 @@ def _copy2_ignoring_special_files(src, dest):
156156

157157
def _copy_source_tree(source, target):
158158
# type: (str, str) -> None
159+
target_abspath = os.path.abspath(target)
160+
target_basename = os.path.basename(target_abspath)
161+
target_dirname = os.path.dirname(target_abspath)
162+
159163
def ignore(d, names):
160164
# type: (str, List[str]) -> List[str]
161-
# Pulling in those directories can potentially be very slow,
162-
# exclude the following directories if they appear in the top
163-
# level dir (and only it).
164-
# See discussion at https://github.com/pypa/pip/pull/6770
165-
return ['.tox', '.nox'] if d == source else []
165+
skipped = [] # type: List[str]
166+
if d == source:
167+
# Pulling in those directories can potentially be very slow,
168+
# exclude the following directories if they appear in the top
169+
# level dir (and only it).
170+
# See discussion at https://github.com/pypa/pip/pull/6770
171+
skipped += ['.tox', '.nox']
172+
if os.path.abspath(d) == target_dirname:
173+
# Prevent an infinite recursion if the target is in source.
174+
# This can happen when TMPDIR is set to ${PWD}/...
175+
# and we copy PWD to TMPDIR.
176+
skipped += [target_basename]
177+
return skipped
166178

167179
kwargs = dict(ignore=ignore, symlinks=True) # type: CopytreeKwargs
168180

tests/data/src/extension/extension.c

Whitespace-only changes.

tests/data/src/extension/setup.py

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from setuptools import Extension, setup
2+
3+
module = Extension('extension', sources=['extension.c'])
4+
setup(name='extension', version='0.0.1', ext_modules = [module])

tests/functional/test_wheel.py

+19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""'pip wheel' tests"""
22
import os
33
import re
4+
import sys
45
from os.path import exists
56

67
import pytest
@@ -289,6 +290,24 @@ def test_pip_wheel_with_user_set_in_config(script, data, common_wheels):
289290
assert "Successfully built withpyproject" in result.stdout, result.stdout
290291

291292

293+
@pytest.mark.skipif(sys.platform.startswith('win'),
294+
reason='The empty extension module does not work on Win')
295+
def test_pip_wheel_ext_module_with_tmpdir_inside(script, data, common_wheels):
296+
tmpdir = data.src / 'extension/tmp'
297+
tmpdir.mkdir()
298+
script.environ['TMPDIR'] = str(tmpdir)
299+
300+
# To avoid a test dependency on a C compiler, we set the env vars to "noop"
301+
# The .c source is empty anyway
302+
script.environ['CC'] = script.environ['LDSHARED'] = str('true')
303+
304+
result = script.pip(
305+
'wheel', data.src / 'extension',
306+
'--no-index', '-f', common_wheels
307+
)
308+
assert "Successfully built extension" in result.stdout, result.stdout
309+
310+
292311
@pytest.mark.network
293312
def test_pep517_wheels_are_not_confused_with_other_files(script, tmpdir, data):
294313
"""Check correct wheels are copied. (#6196)

0 commit comments

Comments
 (0)