mirror of https://github.com/pypa/pip
Make in-tree-build the default
Add an out-of-tree-build feature flag to ease the transition.
This commit is contained in:
parent
605d68ead3
commit
040cc391ba
|
@ -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`:
|
||||
|
|
|
@ -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.
|
|
@ -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."),
|
||||
)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue