diff --git a/newsfragments/3555.bugfix.rst b/newsfragments/3555.bugfix.rst new file mode 100644 index 0000000000..979ede1d5d --- /dev/null +++ b/newsfragments/3555.bugfix.rst @@ -0,0 +1,2 @@ +`trio.Process` no longer emits an `EncodingWarning` on Linux when Python runs with +``-X warn_default_encoding`` (or ``PYTHONWARNDEFAULTENCODING=1``). diff --git a/src/trio/_subprocess.py b/src/trio/_subprocess.py index d73ba3dc23..710600dcf4 100644 --- a/src/trio/_subprocess.py +++ b/src/trio/_subprocess.py @@ -7,6 +7,7 @@ import warnings from contextlib import ExitStack from functools import partial +from io import FileIO from typing import ( TYPE_CHECKING, Final, @@ -32,7 +33,6 @@ if TYPE_CHECKING: import signal from collections.abc import Awaitable, Callable, Iterable, Mapping, Sequence - from io import TextIOWrapper from typing_extensions import Unpack @@ -173,7 +173,7 @@ def __init__( self._wait_lock: Lock = Lock() - self._pidfd: TextIOWrapper | None = None + self._pidfd: FileIO | None = None if can_try_pidfd_open: try: fd: int = pidfd_open(self._proc.pid, 0) @@ -186,8 +186,7 @@ def __init__( else: # It worked! Wrap the raw fd up in a Python file object to # make sure it'll get closed. - # SIM115: open-file-with-context-handler - self._pidfd = open(fd) # noqa: SIM115 + self._pidfd = FileIO(fd) self.args: StrOrBytesPath | Sequence[StrOrBytesPath] = self._proc.args self.pid: int = self._proc.pid diff --git a/src/trio/_tests/test_subprocess.py b/src/trio/_tests/test_subprocess.py index dbd55f8282..be762c0756 100644 --- a/src/trio/_tests/test_subprocess.py +++ b/src/trio/_tests/test_subprocess.py @@ -157,6 +157,26 @@ async def test_basic_no_pidfd(background_process: BackgroundProcessType) -> None ) +async def test_no_encoding_warning() -> None: + # Spawning a process must not open anything in text mode without an + # explicit encoding, which warns under -X warn_default_encoding. + code = "import sys, trio; trio.run(trio.run_process, [sys.executable, '-c', ''])" + result = await run_process( + [ + sys.executable, + "-X", + "warn_default_encoding", + "-W", + "error::EncodingWarning", + "-c", + code, + ], + capture_stderr=True, + check=False, + ) + assert result.returncode == 0, result.stderr.decode() + + @background_process_param async def test_auto_update_returncode( background_process: BackgroundProcessType,