Skip to content

Commit a07bfb3

Browse files
authored
Merge pull request #10495 from sbidoul/out-of-tree-build-flag
2 parents 9c474d4 + 040cc39 commit a07bfb3

File tree

8 files changed

+65
-33
lines changed

8 files changed

+65
-33
lines changed

docs/html/cli/pip_install.rst

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -490,18 +490,20 @@ You can install local projects by specifying the project path to pip:
490490
491491
py -m pip install path/to/SomeProject
492492
493-
During regular installation, pip will copy the entire project directory to a
494-
temporary location and install from there. The exception is that pip will
495-
exclude .tox and .nox directories present in the top level of the project from
496-
being copied. This approach is the cause of several performance and correctness
497-
issues, so it is planned that pip 21.3 will change to install directly from the
498-
local project directory. Depending on the build backend used by the project,
499-
this may generate secondary build artifacts in the project directory, such as
500-
the ``.egg-info`` and ``build`` directories in the case of the setuptools
501-
backend.
502-
503-
To opt in to the future behavior, specify the ``--use-feature=in-tree-build``
504-
option in pip's command line.
493+
.. note::
494+
495+
Depending on the build backend used by the project, this may generate
496+
secondary build artifacts in the project directory, such as the
497+
``.egg-info`` and ``build`` directories in the case of the setuptools
498+
backend.
499+
500+
Pip has a legacy behaviour that copies the entire project directory to a
501+
temporary location and installs from there. This approach was the cause of
502+
several performance and correctness issues, so it is now disabled by
503+
default, and it is planned that pip 22.1 will remove it.
504+
505+
To opt in to the legacy behavior, specify the
506+
``--use-deprecated=out-of-tree-build`` option in pip's command line.
505507

506508

507509
.. _`editable-installs`:

news/10495.removal.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
In-tree builds are now the default. ``--use-feature=in-tree-build`` is now
2+
ignored. ``--use-deprecated=out-of-tree-build`` may be used temporarily to ease
3+
the transition.

src/pip/_internal/cli/cmdoptions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ def check_list_path_option(options: Values) -> None:
973973
metavar="feature",
974974
action="append",
975975
default=[],
976-
choices=["legacy-resolver"],
976+
choices=["legacy-resolver", "out-of-tree-build"],
977977
help=("Enable deprecated functionality, that will be removed in the future."),
978978
)
979979

src/pip/_internal/cli/req_command.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from pip._internal.req.req_tracker import RequirementTracker
3535
from pip._internal.resolution.base import BaseResolver
3636
from pip._internal.self_outdated_check import pip_self_version_check
37+
from pip._internal.utils.deprecation import deprecated
3738
from pip._internal.utils.temp_dir import (
3839
TempDirectory,
3940
TempDirectoryTypeRegistry,
@@ -260,6 +261,20 @@ def make_requirement_preparer(
260261
"fast-deps has no effect when used with the legacy resolver."
261262
)
262263

264+
in_tree_build = "out-of-tree-build" not in options.deprecated_features_enabled
265+
if "in-tree-build" in options.features_enabled:
266+
deprecated(
267+
reason="In-tree builds are now the default.",
268+
replacement="to remove the --use-feature=in-tree-build flag",
269+
gone_in="22.1",
270+
)
271+
if "out-of-tree-build" in options.deprecated_features_enabled:
272+
deprecated(
273+
reason="Out-of-tree builds are deprecated.",
274+
replacement=None,
275+
gone_in="22.1",
276+
)
277+
263278
return RequirementPreparer(
264279
build_dir=temp_build_dir_path,
265280
src_dir=options.src_dir,
@@ -272,7 +287,7 @@ def make_requirement_preparer(
272287
require_hashes=options.require_hashes,
273288
use_user_site=use_user_site,
274289
lazy_wheel=lazy_wheel,
275-
in_tree_build="in-tree-build" in options.features_enabled,
290+
in_tree_build=in_tree_build,
276291
)
277292

278293
@classmethod

src/pip/_internal/operations/prepare.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
from pip._internal.network.session import PipSession
3636
from pip._internal.req.req_install import InstallRequirement
3737
from pip._internal.req.req_tracker import RequirementTracker
38-
from pip._internal.utils.deprecation import deprecated
3938
from pip._internal.utils.filesystem import copy2_fixed
4039
from pip._internal.utils.hashes import Hashes, MissingHashes
4140
from pip._internal.utils.logging import indent_log
@@ -197,19 +196,9 @@ def unpack_url(
197196
#
198197
# As further cleanup, _copy_source_tree and accompanying tests can
199198
# be removed.
199+
#
200+
# TODO when use-deprecated=out-of-tree-build is removed
200201
if link.is_existing_dir():
201-
deprecated(
202-
reason=(
203-
"pip copied the source tree into a temporary directory "
204-
"before building it. This is changing so that packages "
205-
"are built in-place "
206-
'within the original source tree ("in-tree build").'
207-
),
208-
replacement=None,
209-
gone_in="21.3",
210-
feature_flag="in-tree-build",
211-
issue=7555,
212-
)
213202
if os.path.isdir(location):
214203
rmtree(location)
215204
_copy_source_tree(link.file_path, location)

tests/functional/test_cli.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ def test_entrypoints_work(entrypoint, script):
3636
)
3737
)
3838

39-
script.pip("install", "-vvv", str(fake_pkg))
39+
# expect_temp because pip install will generate fake_pkg.egg-info
40+
script.pip("install", "-vvv", str(fake_pkg), expect_temp=True)
4041
result = script.pip("-V")
4142
result2 = script.run("fake_pip", "-V", allow_stderr_warning=True)
4243
assert result.stdout == result2.stdout

tests/functional/test_install.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,12 @@ def test_install_from_local_directory_with_symlinks_to_directories(script, data)
587587
Test installing from a local directory containing symlinks to directories.
588588
"""
589589
to_install = data.packages.joinpath("symlinks")
590-
result = script.pip("install", to_install)
590+
result = script.pip(
591+
"install",
592+
"--use-deprecated=out-of-tree-build",
593+
to_install,
594+
allow_stderr_warning=True, # TODO: set to False when removing out-of-tree-build
595+
)
591596
pkg_folder = script.site_packages / "symlinks"
592597
dist_info_folder = script.site_packages / "symlinks-0.1.dev0.dist-info"
593598
result.did_create(pkg_folder)
@@ -597,10 +602,10 @@ def test_install_from_local_directory_with_symlinks_to_directories(script, data)
597602
@pytest.mark.usefixtures("with_wheel")
598603
def test_install_from_local_directory_with_in_tree_build(script, data):
599604
"""
600-
Test installing from a local directory with --use-feature=in-tree-build.
605+
Test installing from a local directory with default in tree build.
601606
"""
602607
to_install = data.packages.joinpath("FSPkg")
603-
args = ["install", "--use-feature=in-tree-build", to_install]
608+
args = ["install", to_install]
604609

605610
in_tree_build_dir = to_install / "build"
606611
assert not in_tree_build_dir.exists()
@@ -618,6 +623,8 @@ def test_install_from_local_directory_with_socket_file(script, data, tmpdir):
618623
"""
619624
Test installing from a local directory containing a socket file.
620625
"""
626+
# TODO: remove this test when removing out-of-tree-build support,
627+
# it is only meant to test the copy of socket files
621628
dist_info_folder = script.site_packages / "FSPkg-0.1.dev0.dist-info"
622629
package_folder = script.site_packages / "fspkg"
623630
to_copy = data.packages.joinpath("FSPkg")
@@ -628,7 +635,13 @@ def test_install_from_local_directory_with_socket_file(script, data, tmpdir):
628635
socket_file_path = os.path.join(to_install, "example")
629636
make_socket_file(socket_file_path)
630637

631-
result = script.pip("install", "--verbose", to_install)
638+
result = script.pip(
639+
"install",
640+
"--use-deprecated=out-of-tree-build",
641+
"--verbose",
642+
to_install,
643+
allow_stderr_warning=True, # because of the out-of-tree deprecation warning
644+
)
632645
result.did_create(package_folder)
633646
result.did_create(dist_info_folder)
634647
assert str(socket_file_path) in result.stderr

tests/functional/test_uninstall.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from pip._internal.utils.misc import rmtree
1313
from tests.lib import assert_all_changes, create_test_package_with_setup, need_svn
1414
from tests.lib.local_repos import local_checkout, local_repo
15+
from tests.lib.path import Path
1516

1617

1718
@pytest.mark.network
@@ -279,7 +280,15 @@ def test_uninstall_console_scripts(script):
279280
result = script.pip("install", pkg_path)
280281
result.did_create(script.bin / "discover" + script.exe)
281282
result2 = script.pip("uninstall", "discover", "-y")
282-
assert_all_changes(result, result2, [script.venv / "build", "cache"])
283+
assert_all_changes(
284+
result,
285+
result2,
286+
[
287+
script.venv / "build",
288+
"cache",
289+
Path("scratch") / "discover" / "discover.egg-info",
290+
],
291+
)
283292

284293

285294
def test_uninstall_console_scripts_uppercase_name(script):

0 commit comments

Comments
 (0)