Skip to content

Commit

Permalink
Merge pull request #11871 from sbidoul/always-use-pep517-when-wheel-a…
Browse files Browse the repository at this point in the history
…bsent-sbi

Always use pep 517 when the 'wheel' package is absent
  • Loading branch information
sbidoul authored Mar 27, 2023
2 parents b0a2841 + e4d291c commit 123e8a4
Show file tree
Hide file tree
Showing 29 changed files with 69 additions and 230 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 @@
When the ``wheel`` package is not installed, pip now uses the default build backend
instead of ``setup.py install`` for project without ``pyproject.toml``.
10 changes: 7 additions & 3 deletions src/pip/_internal/cli/cmdoptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -783,10 +783,14 @@ def _handle_no_use_pep517(
"""
raise_option_error(parser, option=option, msg=msg)

# If user doesn't wish to use pep517, we check if setuptools is installed
# If user doesn't wish to use pep517, we check if setuptools and wheel are installed
# and raise error if it is not.
if not importlib.util.find_spec("setuptools"):
msg = "It is not possible to use --no-use-pep517 without setuptools installed."
packages = ("setuptools", "wheel")
if not all(importlib.util.find_spec(package) for package in packages):
msg = (
f"It is not possible to use --no-use-pep517 "
f"without {' and '.join(packages)} installed."
)
raise_option_error(parser, option=option, msg=msg)

# Otherwise, --no-use-pep517 was passed via the command-line.
Expand Down
9 changes: 7 additions & 2 deletions src/pip/_internal/pyproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,17 @@ def load_pyproject_toml(
# we do so if the project has a pyproject.toml file
# or if we cannot import setuptools.

# We fallback to PEP 517 when without setuptools,
# We fallback to PEP 517 when without setuptools or without the wheel package,
# so setuptools can be installed as a default build backend.
# For more info see:
# https://discuss.python.org/t/pip-without-setuptools-could-the-experience-be-improved/11810/9
# https://github.com/pypa/pip/issues/8559
elif use_pep517 is None:
use_pep517 = has_pyproject or not importlib.util.find_spec("setuptools")
use_pep517 = (
has_pyproject
or not importlib.util.find_spec("setuptools")
or not importlib.util.find_spec("wheel")
)

# At this point, we know whether we're going to use PEP 517.
assert use_pep517 is not None
Expand Down
14 changes: 0 additions & 14 deletions src/pip/_internal/utils/deprecation.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,17 +159,3 @@ def emit_deprecation(self, name: str) -> 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="23.1",
issue=8559,
emit_before_install=True,
)
12 changes: 0 additions & 12 deletions src/pip/_internal/utils/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -615,18 +615,6 @@ def hash_file(path: str, blocksize: int = 1 << 20) -> Tuple[Any, int]:
return h, length


def is_wheel_installed() -> bool:
"""
Return whether the wheel package is installed.
"""
try:
import wheel # noqa: F401
except ImportError:
return False

return True


def pairwise(iterable: Iterable[Any]) -> Iterator[Tuple[Any, Any]]:
"""
Return paired elements.
Expand Down
11 changes: 1 addition & 10 deletions src/pip/_internal/wheel_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@
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.misc import ensure_dir, hash_file
from pip._internal.utils.setuptools_build import make_setuptools_clean_args
from pip._internal.utils.subprocess import call_subprocess
from pip._internal.utils.temp_dir import TempDirectory
Expand Down Expand Up @@ -73,14 +72,6 @@ def _should_build(
# we only build PEP 660 editable requirements
return req.supports_pyproject_editable()

if req.use_pep517:
return True

if not is_wheel_installed():
# we don't build legacy requirements if wheel is not installed
req.legacy_install_reason = LegacyInstallReasonMissingWheelPackage
return False

return True


Expand Down
9 changes: 3 additions & 6 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ def virtualenv_template(
tmpdir_factory: pytest.TempPathFactory,
pip_src: Path,
setuptools_install: Path,
wheel_install: Path,
coverage_install: Path,
) -> Iterator[VirtualEnvironment]:

Expand All @@ -442,8 +443,9 @@ def virtualenv_template(
tmpdir = tmpdir_factory.mktemp("virtualenv")
venv = VirtualEnvironment(tmpdir.joinpath("venv_orig"), venv_type=venv_type)

# Install setuptools and pip.
# Install setuptools, wheel and pip.
install_pth_link(venv, "setuptools", setuptools_install)
install_pth_link(venv, "wheel", wheel_install)
pip_editable = tmpdir_factory.mktemp("pip") / "pip"
shutil.copytree(pip_src, pip_editable, symlinks=True)
# noxfile.py is Python 3 only
Expand Down Expand Up @@ -501,11 +503,6 @@ def virtualenv(
yield virtualenv_factory(tmpdir.joinpath("workspace", "venv"))


@pytest.fixture
def with_wheel(virtualenv: VirtualEnvironment, wheel_install: Path) -> None:
install_pth_link(virtualenv, "wheel", wheel_install)


class ScriptFactory(Protocol):
def __call__(
self,
Expand Down
2 changes: 1 addition & 1 deletion tests/data/packages/BrokenEmitsUTF8/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class FakeError(Exception):
pass


if sys.argv[1] == "install":
if sys.argv[1] in ("install", "bdist_wheel"):
if hasattr(sys.stdout, "buffer"):
sys.stdout.buffer.write(
"\nThis package prints out UTF-8 stuff like:\n".encode("utf-8")
Expand Down
2 changes: 0 additions & 2 deletions tests/functional/test_download.py
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,6 @@ def make_wheel_with_python_requires(
return package_dir / "dist" / file_name


@pytest.mark.usefixtures("with_wheel")
def test_download__python_version_used_for_python_requires(
script: PipTestEnvironment, data: TestData
) -> None:
Expand Down Expand Up @@ -700,7 +699,6 @@ def make_args(python_version: str) -> List[str]:
script.pip(*args) # no exception


@pytest.mark.usefixtures("with_wheel")
def test_download_ignore_requires_python_dont_fail_with_wrong_python(
script: PipTestEnvironment,
) -> None:
Expand Down
3 changes: 0 additions & 3 deletions tests/functional/test_freeze.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ def test_exclude_and_normalization(script: PipTestEnvironment, tmpdir: Path) ->
assert "Normalizable_Name" not in result.stdout


@pytest.mark.usefixtures("with_wheel")
def test_freeze_multiple_exclude_with_all(script: PipTestEnvironment) -> None:
result = script.pip("freeze", "--all")
assert "pip==" in result.stdout
Expand Down Expand Up @@ -962,7 +961,6 @@ def test_freeze_path_multiple(
_check_output(result.stdout, expected)


@pytest.mark.usefixtures("with_wheel")
def test_freeze_direct_url_archive(
script: PipTestEnvironment, shared_data: TestData
) -> None:
Expand Down Expand Up @@ -1005,7 +1003,6 @@ def test_freeze_include_work_dir_pkg(script: PipTestEnvironment) -> None:
assert "simple==1.0" in result.stdout


@pytest.mark.usefixtures("with_wheel")
def test_freeze_pep610_editable(script: PipTestEnvironment) -> None:
"""
Test that a package installed with a direct_url.json with editable=true
Expand Down
3 changes: 2 additions & 1 deletion tests/functional/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ def test_inspect_basic(simple_script: PipTestEnvironment) -> None:
result = simple_script.pip("inspect")
report = json.loads(result.stdout)
installed = report["installed"]
assert len(installed) == 4
assert len(installed) == 5
installed_by_name = {i["metadata"]["name"]: i for i in installed}
assert installed_by_name.keys() == {
"pip",
"setuptools",
"wheel",
"coverage",
"simplewheel",
}
Expand Down
Loading

0 comments on commit 123e8a4

Please sign in to comment.