Skip to content

Commit e4c32b9

Browse files
authored
Merge pull request #6770 from omry/master
exclude '.tox', '.nox' from being copied during 'pip install .'
2 parents 13df7bf + 6dd5727 commit e4c32b9

File tree

4 files changed

+61
-3
lines changed

4 files changed

+61
-3
lines changed

docs/html/reference/pip_install.rst

+12-1
Original file line numberDiff line numberDiff line change
@@ -694,10 +694,21 @@ does not satisfy the ``--require-hashes`` demand that every package have a
694694
local hash.
695695

696696

697+
Local project installs
698+
++++++++++++++++++++++
699+
pip supports installing local project in both regular mode and editable mode.
700+
You can install local projects by specifying the project path to pip::
701+
702+
$ pip install path/to/SomeProject
703+
704+
During regular installation, pip will copy the entire project directory to a temporary location and install from there.
705+
The exception is that pip will exclude .tox and .nox directories present in the top level of the project from being copied.
706+
707+
697708
.. _`editable-installs`:
698709

699710
"Editable" Installs
700-
+++++++++++++++++++
711+
~~~~~~~~~~~~~~~~~~~
701712

702713
"Editable" installs are fundamentally `"setuptools develop mode"
703714
<https://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode>`_

news/6770.bugfix

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Skip copying .tox and .nox directories to temporary build directories

src/pip/_internal/download.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -967,12 +967,23 @@ def unpack_file_url(
967967
of the link file inside download_dir.
968968
"""
969969
link_path = url_to_path(link.url_without_fragment)
970-
971970
# If it's a url to a local directory
972971
if is_dir_url(link):
972+
973+
def ignore(d, names):
974+
# Pulling in those directories can potentially be very slow,
975+
# exclude the following directories if they appear in the top
976+
# level dir (and only it).
977+
# See discussion at https://github.com/pypa/pip/pull/6770
978+
return ['.tox', '.nox'] if d == link_path else []
979+
973980
if os.path.isdir(location):
974981
rmtree(location)
975-
shutil.copytree(link_path, location, symlinks=True)
982+
shutil.copytree(link_path,
983+
location,
984+
symlinks=True,
985+
ignore=ignore)
986+
976987
if download_dir:
977988
logger.info('Link is a directory, ignoring download_dir')
978989
return

tests/unit/test_download.py

+35
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,41 @@ def test_unpack_file_url_thats_a_dir(self, tmpdir, data):
431431
assert os.path.isdir(os.path.join(self.build_dir, 'fspkg'))
432432

433433

434+
@pytest.mark.parametrize('exclude_dir', [
435+
'.nox',
436+
'.tox'
437+
])
438+
def test_unpack_file_url_excludes_expected_dirs(tmpdir, exclude_dir):
439+
src_dir = tmpdir / 'src'
440+
dst_dir = tmpdir / 'dst'
441+
src_included_file = src_dir.joinpath('file.txt')
442+
src_excluded_dir = src_dir.joinpath(exclude_dir)
443+
src_excluded_file = src_dir.joinpath(exclude_dir, 'file.txt')
444+
src_included_dir = src_dir.joinpath('subdir', exclude_dir)
445+
446+
# set up source directory
447+
src_excluded_dir.mkdir(parents=True)
448+
src_included_dir.mkdir(parents=True)
449+
src_included_file.touch()
450+
src_excluded_file.touch()
451+
452+
dst_included_file = dst_dir.joinpath('file.txt')
453+
dst_excluded_dir = dst_dir.joinpath(exclude_dir)
454+
dst_excluded_file = dst_dir.joinpath(exclude_dir, 'file.txt')
455+
dst_included_dir = dst_dir.joinpath('subdir', exclude_dir)
456+
457+
src_link = Link(path_to_url(src_dir))
458+
unpack_file_url(
459+
src_link,
460+
dst_dir,
461+
download_dir=None
462+
)
463+
assert not os.path.isdir(dst_excluded_dir)
464+
assert not os.path.isfile(dst_excluded_file)
465+
assert os.path.isfile(dst_included_file)
466+
assert os.path.isdir(dst_included_dir)
467+
468+
434469
class TestSafeFileCache:
435470
"""
436471
The no_perms test are useless on Windows since SafeFileCache uses

0 commit comments

Comments
 (0)