Make in-tree-build the default

Add an out-of-tree-build feature flag to ease the transition.
This commit is contained in:
Stéphane Bidoul 2021-09-21 17:13:39 +02:00
parent 605d68ead3
commit 040cc391ba
No known key found for this signature in database
GPG Key ID: BCAB2555446B5B92
8 changed files with 64 additions and 32 deletions

View File

@ -490,18 +490,20 @@ You can install local projects by specifying the project path to pip:
py -m pip install path/to/SomeProject
During regular installation, pip will copy the entire project directory to a
temporary location and install from there. The exception is that pip will
exclude .tox and .nox directories present in the top level of the project from
being copied. This approach is the cause of several performance and correctness
issues, so it is planned that pip 21.3 will change to install directly from the
local project directory. Depending on the build backend used by the project,
this may generate secondary build artifacts in the project directory, such as
the ``.egg-info`` and ``build`` directories in the case of the setuptools
backend.
.. note::
To opt in to the future behavior, specify the ``--use-feature=in-tree-build``
option in pip's command line.
Depending on the build backend used by the project, this may generate
secondary build artifacts in the project directory, such as the
``.egg-info`` and ``build`` directories in the case of the setuptools
backend.
Pip has a legacy behaviour that copies the entire project directory to a
temporary location and installs from there. This approach was the cause of
several performance and correctness issues, so it is now disabled by
default, and it is planned that pip 22.1 will remove it.
To opt in to the legacy behavior, specify the
``--use-deprecated=out-of-tree-build`` option in pip's command line.
.. _`editable-installs`:

3
news/10495.removal.rst Normal file
View File

@ -0,0 +1,3 @@
In-tree builds are now the default. ``--use-feature=in-tree-build`` is now
ignored. ``--use-deprecated=out-of-tree-build`` may be used temporarily to ease
the transition.

View File

@ -961,7 +961,7 @@ use_deprecated_feature: Callable[..., Option] = partial(
metavar="feature",
action="append",
default=[],
choices=["legacy-resolver"],
choices=["legacy-resolver", "out-of-tree-build"],
help=("Enable deprecated functionality, that will be removed in the future."),
)

View File

@ -34,6 +34,7 @@ from pip._internal.req.req_install import InstallRequirement
from pip._internal.req.req_tracker import RequirementTracker
from pip._internal.resolution.base import BaseResolver
from pip._internal.self_outdated_check import pip_self_version_check
from pip._internal.utils.deprecation import deprecated
from pip._internal.utils.temp_dir import (
TempDirectory,
TempDirectoryTypeRegistry,
@ -260,6 +261,20 @@ class RequirementCommand(IndexGroupCommand):
"fast-deps has no effect when used with the legacy resolver."
)
in_tree_build = "out-of-tree-build" not in options.deprecated_features_enabled
if "in-tree-build" in options.features_enabled:
deprecated(
reason="In-tree builds are now the default.",
replacement="to remove the --use-feature=in-tree-build flag",
gone_in="22.1",
)
if "out-of-tree-build" in options.deprecated_features_enabled:
deprecated(
reason="Out-of-tree builds are deprecated.",
replacement=None,
gone_in="22.1",
)
return RequirementPreparer(
build_dir=temp_build_dir_path,
src_dir=options.src_dir,
@ -272,7 +287,7 @@ class RequirementCommand(IndexGroupCommand):
require_hashes=options.require_hashes,
use_user_site=use_user_site,
lazy_wheel=lazy_wheel,
in_tree_build="in-tree-build" in options.features_enabled,
in_tree_build=in_tree_build,
)
@classmethod

View File

@ -35,7 +35,6 @@ from pip._internal.network.lazy_wheel import (
from pip._internal.network.session import PipSession
from pip._internal.req.req_install import InstallRequirement
from pip._internal.req.req_tracker import RequirementTracker
from pip._internal.utils.deprecation import deprecated
from pip._internal.utils.filesystem import copy2_fixed
from pip._internal.utils.hashes import Hashes, MissingHashes
from pip._internal.utils.logging import indent_log
@ -197,19 +196,9 @@ def unpack_url(
#
# As further cleanup, _copy_source_tree and accompanying tests can
# be removed.
#
# TODO when use-deprecated=out-of-tree-build is removed
if link.is_existing_dir():
deprecated(
reason=(
"pip copied the source tree into a temporary directory "
"before building it. This is changing so that packages "
"are built in-place "
'within the original source tree ("in-tree build").'
),
replacement=None,
gone_in="21.3",
feature_flag="in-tree-build",
issue=7555,
)
if os.path.isdir(location):
rmtree(location)
_copy_source_tree(link.file_path, location)

View File

@ -36,7 +36,8 @@ def test_entrypoints_work(entrypoint, script):
)
)
script.pip("install", "-vvv", str(fake_pkg))
# expect_temp because pip install will generate fake_pkg.egg-info
script.pip("install", "-vvv", str(fake_pkg), expect_temp=True)
result = script.pip("-V")
result2 = script.run("fake_pip", "-V", allow_stderr_warning=True)
assert result.stdout == result2.stdout

View File

@ -587,7 +587,12 @@ def test_install_from_local_directory_with_symlinks_to_directories(script, data)
Test installing from a local directory containing symlinks to directories.
"""
to_install = data.packages.joinpath("symlinks")
result = script.pip("install", to_install)
result = script.pip(
"install",
"--use-deprecated=out-of-tree-build",
to_install,
allow_stderr_warning=True, # TODO: set to False when removing out-of-tree-build
)
pkg_folder = script.site_packages / "symlinks"
dist_info_folder = script.site_packages / "symlinks-0.1.dev0.dist-info"
result.did_create(pkg_folder)
@ -597,10 +602,10 @@ def test_install_from_local_directory_with_symlinks_to_directories(script, data)
@pytest.mark.usefixtures("with_wheel")
def test_install_from_local_directory_with_in_tree_build(script, data):
"""
Test installing from a local directory with --use-feature=in-tree-build.
Test installing from a local directory with default in tree build.
"""
to_install = data.packages.joinpath("FSPkg")
args = ["install", "--use-feature=in-tree-build", to_install]
args = ["install", to_install]
in_tree_build_dir = to_install / "build"
assert not in_tree_build_dir.exists()
@ -618,6 +623,8 @@ def test_install_from_local_directory_with_socket_file(script, data, tmpdir):
"""
Test installing from a local directory containing a socket file.
"""
# TODO: remove this test when removing out-of-tree-build support,
# it is only meant to test the copy of socket files
dist_info_folder = script.site_packages / "FSPkg-0.1.dev0.dist-info"
package_folder = script.site_packages / "fspkg"
to_copy = data.packages.joinpath("FSPkg")
@ -628,7 +635,13 @@ def test_install_from_local_directory_with_socket_file(script, data, tmpdir):
socket_file_path = os.path.join(to_install, "example")
make_socket_file(socket_file_path)
result = script.pip("install", "--verbose", to_install)
result = script.pip(
"install",
"--use-deprecated=out-of-tree-build",
"--verbose",
to_install,
allow_stderr_warning=True, # because of the out-of-tree deprecation warning
)
result.did_create(package_folder)
result.did_create(dist_info_folder)
assert str(socket_file_path) in result.stderr

View File

@ -12,6 +12,7 @@ from pip._internal.req.constructors import install_req_from_line
from pip._internal.utils.misc import rmtree
from tests.lib import assert_all_changes, create_test_package_with_setup, need_svn
from tests.lib.local_repos import local_checkout, local_repo
from tests.lib.path import Path
@pytest.mark.network
@ -279,7 +280,15 @@ def test_uninstall_console_scripts(script):
result = script.pip("install", pkg_path)
result.did_create(script.bin / "discover" + script.exe)
result2 = script.pip("uninstall", "discover", "-y")
assert_all_changes(result, result2, [script.venv / "build", "cache"])
assert_all_changes(
result,
result2,
[
script.venv / "build",
"cache",
Path("scratch") / "discover" / "discover.egg-info",
],
)
def test_uninstall_console_scripts_uppercase_name(script):