diff --git a/src/pyproject_hooks/_impl.py b/src/pyproject_hooks/_impl.py index 14484fa..e11b6db 100644 --- a/src/pyproject_hooks/_impl.py +++ b/src/pyproject_hooks/_impl.py @@ -3,6 +3,7 @@ import sys import tempfile from contextlib import contextmanager +from itertools import chain from os.path import abspath from os.path import join as pjoin from subprocess import STDOUT, check_call, check_output @@ -380,6 +381,15 @@ def build_sdist( }, ) + def _get_warnopts(self) -> Iterator[str]: + """ + Reconstruct Python's warn options that are active for the current process, + so that it can be forwarded to a subprocess. + """ + # `sys.warnoptions` is documented/mentioned in + # https://docs.python.org/3.13/library/warnings.html#describing-warning-filters + return chain.from_iterable(("-W", opt) for opt in sys.warnoptions) + def _call_hook(self, hook_name: str, kwargs: Mapping[str, Any]) -> Any: extra_environ = {"_PYPROJECT_HOOKS_BUILD_BACKEND": self.build_backend} @@ -394,8 +404,9 @@ def _call_hook(self, hook_name: str, kwargs: Mapping[str, Any]) -> Any: # Run the hook in a subprocess with _in_proc_script_path() as script: python = self.python_executable + opts = self._get_warnopts() self._subprocess_runner( - [python, abspath(str(script)), hook_name, td], + [python, *opts, abspath(str(script)), hook_name, td], cwd=self.source_dir, extra_environ=extra_environ, ) diff --git a/tests/test_call_hooks.py b/tests/test_call_hooks.py index 1fae0b8..662e95a 100644 --- a/tests/test_call_hooks.py +++ b/tests/test_call_hooks.py @@ -4,6 +4,7 @@ import zipfile from os.path import abspath, dirname from os.path import join as pjoin +from subprocess import CalledProcessError from unittest.mock import Mock import pytest @@ -233,3 +234,25 @@ def test_warnings(): with modified_env({"PYTHONPATH": BUILDSYS_PKGS}): with pytest.warns(BuildBackendWarning, match="this is my example warning"): hooks.get_requires_for_build_wheel({}) + + +def test_forward_warnopts(monkeypatch, recwarn): + hooks = get_hooks("pkg-with-warnings") + + monkeypatch.setattr( + BuildBackendHookCaller, "_get_warnopts", lambda _: ["-W", "ignore"] + ) + with modified_env({"PYTHONPATH": BUILDSYS_PKGS}): + hooks.get_requires_for_build_wheel({}) + assert len(recwarn) == 0 # All subprocess warnings were ignored. + + monkeypatch.setattr( + BuildBackendHookCaller, "_get_warnopts", lambda _: ["-W", "error"] + ) + with modified_env({"PYTHONPATH": BUILDSYS_PKGS}): + with pytest.raises(CalledProcessError): + # The `match` argument does not work against the exception in the + # subprocess, but we have a sanity check in place: the same call + # worked above when the warnings were ignored, so we known this is + # caused by the new warnings filter. + hooks.get_requires_for_build_wheel({})