Skip to content

Commit

Permalink
Merge pull request #11331 from sbidoul/8559-take-2-sbi
Browse files Browse the repository at this point in the history
Deprecate setup.py install fallback when wheel package is absent
  • Loading branch information
sbidoul authored Aug 10, 2022
2 parents 496bf56 + ae802e3 commit ee7bcae
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 20 deletions.
2 changes: 2 additions & 0 deletions news/8559.removal.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Deprecate installation with 'setup.py install' when the 'wheel' package is absent for
source distributions without 'pyproject.toml'.
3 changes: 2 additions & 1 deletion src/pip/_internal/commands/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from pip._internal.req import install_given_reqs
from pip._internal.req.req_install import InstallRequirement
from pip._internal.utils.compat import WINDOWS
from pip._internal.utils.deprecation import LegacyInstallReasonFailedBdistWheel
from pip._internal.utils.distutils_args import parse_distutils_args
from pip._internal.utils.filesystem import test_writable_dir
from pip._internal.utils.logging import getLogger
Expand Down Expand Up @@ -440,7 +441,7 @@ def run(self, options: Values, args: List[str]) -> int:
# those.
for r in build_failures:
if not r.use_pep517:
r.legacy_install_reason = 8368
r.legacy_install_reason = LegacyInstallReasonFailedBdistWheel

to_install = resolver.get_installation_order(requirement_set)

Expand Down
27 changes: 13 additions & 14 deletions src/pip/_internal/req/req_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
from pip._internal.operations.install.wheel import install_wheel
from pip._internal.pyproject import load_pyproject_toml, make_pyproject_path
from pip._internal.req.req_uninstall import UninstallPathSet
from pip._internal.utils.deprecation import deprecated
from pip._internal.utils.deprecation import LegacyInstallReason, deprecated
from pip._internal.utils.direct_url_helpers import (
direct_url_for_editable,
direct_url_from_link,
Expand Down Expand Up @@ -96,7 +96,7 @@ def __init__(
self.constraint = constraint
self.editable = editable
self.permit_editable_wheels = permit_editable_wheels
self.legacy_install_reason: Optional[int] = None
self.legacy_install_reason: Optional[LegacyInstallReason] = None

# source_dir is the local directory where the linked requirement is
# located, or unpacked. In case unpacking is needed, creating and
Expand Down Expand Up @@ -811,6 +811,11 @@ def install(
install_options = list(install_options) + self.install_options

try:
if (
self.legacy_install_reason is not None
and self.legacy_install_reason.emit_before_install
):
self.legacy_install_reason.emit_deprecation(self.name)
success = install_legacy(
install_options=install_options,
global_options=global_options,
Expand All @@ -836,18 +841,12 @@ def install(

self.install_succeeded = success

if success and self.legacy_install_reason == 8368:
deprecated(
reason=(
"{} was installed using the legacy 'setup.py install' "
"method, because a wheel could not be built for it.".format(
self.name
)
),
replacement="to fix the wheel build issue reported above",
gone_in=None,
issue=8368,
)
if (
success
and self.legacy_install_reason is not None
and self.legacy_install_reason.emit_after_success
):
self.legacy_install_reason.emit_deprecation(self.name)


def check_invalid_constraint_type(req: InstallRequirement) -> str:
Expand Down
55 changes: 55 additions & 0 deletions src/pip/_internal/utils/deprecation.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,58 @@ def deprecated(
raise PipDeprecationWarning(message)

warnings.warn(message, category=PipDeprecationWarning, stacklevel=2)


class LegacyInstallReason:
def __init__(
self,
reason: str,
replacement: Optional[str],
gone_in: Optional[str],
feature_flag: Optional[str] = None,
issue: Optional[int] = None,
emit_after_success: bool = False,
emit_before_install: bool = False,
):
self._reason = reason
self._replacement = replacement
self._gone_in = gone_in
self._feature_flag = feature_flag
self._issue = issue
self.emit_after_success = emit_after_success
self.emit_before_install = emit_before_install

def emit_deprecation(self, name: str) -> None:
deprecated(
reason=self._reason.format(name=name),
replacement=self._replacement,
gone_in=self._gone_in,
feature_flag=self._feature_flag,
issue=self._issue,
)


LegacyInstallReasonFailedBdistWheel = LegacyInstallReason(
reason=(
"{name} was installed using the legacy 'setup.py install' "
"method, because a wheel could not be built for it."
),
replacement="to fix the wheel build issue reported above",
gone_in=None,
issue=8368,
emit_after_success=True,
)


LegacyInstallReasonMissingWheelPackage = LegacyInstallReason(
reason=(
"{name} is being installed using the legacy "
"'setup.py install' method, because it does not have a "
"'pyproject.toml' and the 'wheel' package "
"is not installed."
),
replacement="to enable the '--use-pep517' option",
gone_in=None,
issue=8559,
emit_before_install=True,
)
7 changes: 2 additions & 5 deletions src/pip/_internal/wheel_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from pip._internal.operations.build.wheel_editable import build_wheel_editable
from pip._internal.operations.build.wheel_legacy import build_wheel_legacy
from pip._internal.req.req_install import InstallRequirement
from pip._internal.utils.deprecation import LegacyInstallReasonMissingWheelPackage
from pip._internal.utils.logging import indent_log
from pip._internal.utils.misc import ensure_dir, hash_file, is_wheel_installed
from pip._internal.utils.setuptools_build import make_setuptools_clean_args
Expand Down Expand Up @@ -86,11 +87,7 @@ def _should_build(

if not is_wheel_installed():
# we don't build legacy requirements if wheel is not installed
logger.info(
"Using legacy 'setup.py install' for %s, "
"since package 'wheel' is not installed.",
req.name,
)
req.legacy_install_reason = LegacyInstallReasonMissingWheelPackage
return False

return True
Expand Down
30 changes: 30 additions & 0 deletions tests/functional/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from pip._internal.cli.status_codes import ERROR, SUCCESS
from pip._internal.models.index import PyPI, TestPyPI
from pip._internal.utils.deprecation import DEPRECATION_MSG_PREFIX
from pip._internal.utils.misc import rmtree
from tests.conftest import CertFactory
from tests.lib import (
Expand Down Expand Up @@ -2303,3 +2304,32 @@ def test_install_dry_run(script: PipTestEnvironment, data: TestData) -> None:
)
assert "Would install simple-3.0" in result.stdout
assert "Successfully installed" not in result.stdout


def test_install_8559_missing_wheel_package(
script: PipTestEnvironment, shared_data: TestData
) -> None:
result = script.pip(
"install",
"--find-links",
shared_data.find_links,
"simple",
allow_stderr_warning=True,
)
assert DEPRECATION_MSG_PREFIX in result.stderr
assert "'wheel' package is not installed" in result.stderr
assert "using the legacy 'setup.py install' method" in result.stderr


@pytest.mark.usefixtures("with_wheel")
def test_install_8559_wheel_package_present(
script: PipTestEnvironment, shared_data: TestData
) -> None:
result = script.pip(
"install",
"--find-links",
shared_data.find_links,
"simple",
allow_stderr_warning=False,
)
assert DEPRECATION_MSG_PREFIX not in result.stderr
1 change: 1 addition & 0 deletions tests/functional/test_install_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def test_find_links_relative_path(script: PipTestEnvironment, data: TestData) ->
result.did_create(initools_folder)


@pytest.mark.usefixtures("with_wheel")
def test_find_links_no_doctype(script: PipTestEnvironment, data: TestData) -> None:
shutil.copy(data.packages / "simple-1.0.tar.gz", script.scratch_path)
html = script.scratch_path.joinpath("index.html")
Expand Down

0 comments on commit ee7bcae

Please sign in to comment.