Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forward warnings during backend calls to the subprocess logger #12090

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/pip/_internal/distributions/sdist.py
Expand Up @@ -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__)

Expand Down Expand Up @@ -87,15 +90,15 @@ 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
with backend.subprocess_runner(runner):
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"
)
Expand Down
7 changes: 5 additions & 2 deletions src/pip/_internal/operations/build/metadata.py
Expand Up @@ -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


Expand All @@ -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.
Expand Down
7 changes: 5 additions & 2 deletions src/pip/_internal/operations/build/metadata_editable.py
Expand Up @@ -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


Expand All @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions src/pip/_internal/operations/build/metadata_legacy.py
Expand Up @@ -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__)
Expand Down Expand Up @@ -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(
Expand Down
4 changes: 2 additions & 2 deletions src/pip/_internal/operations/install/editable_legacy.py
Expand Up @@ -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__)

Expand Down Expand Up @@ -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",
Expand Down
7 changes: 5 additions & 2 deletions src/pip/_internal/req/req_install.py
Expand Up @@ -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
Expand Down Expand Up @@ -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"
)
Expand Down
27 changes: 27 additions & 0 deletions 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
Expand Down Expand Up @@ -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
4 changes: 2 additions & 2 deletions src/pip/_internal/wheel_builder.py
Expand Up @@ -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
Expand Down Expand Up @@ -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
)
Expand Down