diff --git a/src/pip/_internal/distributions/sdist.py b/src/pip/_internal/distributions/sdist.py index 4c25647930c..e5a5a2742d2 100644 --- a/src/pip/_internal/distributions/sdist.py +++ b/src/pip/_internal/distributions/sdist.py @@ -6,7 +6,10 @@ from pip._internal.exceptions import InstallationError from pip._internal.index.package_finder import PackageFinder from pip._internal.metadata import BaseDistribution -from pip._internal.utils.subprocess import runner_with_spinner_message +from pip._internal.utils.subprocess import ( + log_backend_warnings, + runner_with_spinner_message, +) logger = logging.getLogger(__name__) @@ -87,7 +90,7 @@ def _prepare_build_backend(self, finder: PackageFinder) -> None: ) def _get_build_requires_wheel(self) -> Iterable[str]: - with self.req.build_env: + with self.req.build_env, log_backend_warnings(): runner = runner_with_spinner_message("Getting requirements to build wheel") backend = self.req.pep517_backend assert backend is not None @@ -95,7 +98,7 @@ def _get_build_requires_wheel(self) -> Iterable[str]: return backend.get_requires_for_build_wheel() def _get_build_requires_editable(self) -> Iterable[str]: - with self.req.build_env: + with self.req.build_env, log_backend_warnings(): runner = runner_with_spinner_message( "Getting requirements to build editable" ) diff --git a/src/pip/_internal/operations/build/metadata.py b/src/pip/_internal/operations/build/metadata.py index c66ac354deb..49cfade0052 100644 --- a/src/pip/_internal/operations/build/metadata.py +++ b/src/pip/_internal/operations/build/metadata.py @@ -10,7 +10,10 @@ InstallationSubprocessError, MetadataGenerationFailed, ) -from pip._internal.utils.subprocess import runner_with_spinner_message +from pip._internal.utils.subprocess import ( + log_backend_warnings, + runner_with_spinner_message, +) from pip._internal.utils.temp_dir import TempDirectory @@ -25,7 +28,7 @@ def generate_metadata( metadata_dir = metadata_tmpdir.path - with build_env: + with build_env, log_backend_warnings(): # Note that BuildBackendHookCaller implements a fallback for # prepare_metadata_for_build_wheel, so we don't have to # consider the possibility that this hook doesn't exist. diff --git a/src/pip/_internal/operations/build/metadata_editable.py b/src/pip/_internal/operations/build/metadata_editable.py index 27c69f0d1ea..0179034db3b 100644 --- a/src/pip/_internal/operations/build/metadata_editable.py +++ b/src/pip/_internal/operations/build/metadata_editable.py @@ -10,7 +10,10 @@ InstallationSubprocessError, MetadataGenerationFailed, ) -from pip._internal.utils.subprocess import runner_with_spinner_message +from pip._internal.utils.subprocess import ( + log_backend_warnings, + runner_with_spinner_message, +) from pip._internal.utils.temp_dir import TempDirectory @@ -25,7 +28,7 @@ def generate_editable_metadata( metadata_dir = metadata_tmpdir.path - with build_env: + with build_env, log_backend_warnings(): # Note that BuildBackendHookCaller implements a fallback for # prepare_metadata_for_build_wheel/editable, so we don't have to # consider the possibility that this hook doesn't exist. diff --git a/src/pip/_internal/operations/build/metadata_legacy.py b/src/pip/_internal/operations/build/metadata_legacy.py index e60988d643e..12128ccd5b7 100644 --- a/src/pip/_internal/operations/build/metadata_legacy.py +++ b/src/pip/_internal/operations/build/metadata_legacy.py @@ -12,7 +12,7 @@ MetadataGenerationFailed, ) from pip._internal.utils.setuptools_build import make_setuptools_egg_info_args -from pip._internal.utils.subprocess import call_subprocess +from pip._internal.utils.subprocess import call_subprocess, log_backend_warnings from pip._internal.utils.temp_dir import TempDirectory logger = logging.getLogger(__name__) @@ -58,7 +58,7 @@ def generate_metadata( no_user_config=isolated, ) - with build_env: + with build_env, log_backend_warnings(): with open_spinner("Preparing metadata (setup.py)") as spinner: try: call_subprocess( diff --git a/src/pip/_internal/operations/install/editable_legacy.py b/src/pip/_internal/operations/install/editable_legacy.py index bebe24e6d3a..dfd4188f639 100644 --- a/src/pip/_internal/operations/install/editable_legacy.py +++ b/src/pip/_internal/operations/install/editable_legacy.py @@ -6,7 +6,7 @@ from pip._internal.build_env import BuildEnvironment from pip._internal.utils.logging import indent_log from pip._internal.utils.setuptools_build import make_setuptools_develop_args -from pip._internal.utils.subprocess import call_subprocess +from pip._internal.utils.subprocess import call_subprocess, log_backend_warnings logger = logging.getLogger(__name__) @@ -38,7 +38,7 @@ def install_editable( ) with indent_log(): - with build_env: + with build_env, log_backend_warnings(): call_subprocess( args, command_desc="python setup.py develop", diff --git a/src/pip/_internal/req/req_install.py b/src/pip/_internal/req/req_install.py index 1f479713a94..c2be69548e0 100644 --- a/src/pip/_internal/req/req_install.py +++ b/src/pip/_internal/req/req_install.py @@ -53,7 +53,10 @@ redact_auth_from_url, ) from pip._internal.utils.packaging import safe_extra -from pip._internal.utils.subprocess import runner_with_spinner_message +from pip._internal.utils.subprocess import ( + log_backend_warnings, + runner_with_spinner_message, +) from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds from pip._internal.utils.virtualenv import running_under_virtualenv from pip._internal.vcs import vcs @@ -235,7 +238,7 @@ def supports_pyproject_editable(self) -> bool: if not self.use_pep517: return False assert self.pep517_backend - with self.build_env: + with self.build_env, log_backend_warnings(): runner = runner_with_spinner_message( "Checking if build backend supports build_editable" ) diff --git a/src/pip/_internal/utils/subprocess.py b/src/pip/_internal/utils/subprocess.py index 1e8ff50edfb..c3b2de9a5bf 100644 --- a/src/pip/_internal/utils/subprocess.py +++ b/src/pip/_internal/utils/subprocess.py @@ -1,18 +1,24 @@ +import contextlib import logging import os import shlex import subprocess +import warnings from typing import ( TYPE_CHECKING, Any, Callable, + Generator, Iterable, List, Mapping, Optional, + TextIO, + Type, Union, ) +from pip._vendor.pyproject_hooks import BuildBackendWarning from pip._vendor.rich.markup import escape from pip._internal.cli.spinners import SpinnerInterface, open_spinner @@ -258,3 +264,24 @@ def runner( ) return runner + + +@contextlib.contextmanager +def log_backend_warnings() -> Generator[None, None, None]: + def showwarning( + message: Warning | str, + category: Type[Warning], + filename: str, + lineno: int, + file: TextIO | None = None, + line: str | None = None, + ) -> None: + if category == BuildBackendWarning: + subprocess_logger.warning(message) + + try: + original_showwarning = warnings.showwarning + warnings.showwarning = showwarning + yield + finally: + warnings.showwarning = original_showwarning diff --git a/src/pip/_internal/wheel_builder.py b/src/pip/_internal/wheel_builder.py index 60d75dd18ef..f98e0028b46 100644 --- a/src/pip/_internal/wheel_builder.py +++ b/src/pip/_internal/wheel_builder.py @@ -22,7 +22,7 @@ from pip._internal.utils.logging import indent_log 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.subprocess import call_subprocess, log_backend_warnings from pip._internal.utils.temp_dir import TempDirectory from pip._internal.utils.urls import path_to_url from pip._internal.vcs import vcs @@ -190,7 +190,7 @@ def _build_one( return None # Install build deps into temporary directory (PEP 518) - with req.build_env: + with req.build_env, log_backend_warnings(): wheel_path = _build_one_inside_env( req, output_dir, build_options, global_options, editable )