From 7d81c2720d0b5bd68ab62d676b207791af7df8c1 Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Wed, 18 Sep 2024 05:53:22 -0400 Subject: [PATCH] Update open process types (#3076) --- newsfragments/3076.bugfix.rst | 1 + src/trio/_subprocess.py | 30 ++++++++++++++++-------------- src/trio/_tools/gen_exports.py | 2 +- 3 files changed, 18 insertions(+), 15 deletions(-) create mode 100644 newsfragments/3076.bugfix.rst diff --git a/newsfragments/3076.bugfix.rst b/newsfragments/3076.bugfix.rst new file mode 100644 index 0000000000..48aa54127a --- /dev/null +++ b/newsfragments/3076.bugfix.rst @@ -0,0 +1 @@ +Update ``trio.lowlevel.open_process``'s documentation to allow bytes. diff --git a/src/trio/_subprocess.py b/src/trio/_subprocess.py index 90ab9cc16a..263225ffca 100644 --- a/src/trio/_subprocess.py +++ b/src/trio/_subprocess.py @@ -304,7 +304,7 @@ def kill(self) -> None: async def _open_process( - command: list[str] | str, + command: StrOrBytesPath | Sequence[StrOrBytesPath], *, stdin: int | HasFileno | None = None, stdout: int | HasFileno | None = None, @@ -329,13 +329,14 @@ async def _open_process( want. Args: - command (list or str): The command to run. Typically this is a - sequence of strings such as ``['ls', '-l', 'directory with spaces']``, - where the first element names the executable to invoke and the other - elements specify its arguments. With ``shell=True`` in the - ``**options``, or on Windows, ``command`` may alternatively - be a string, which will be parsed following platform-dependent - :ref:`quoting rules `. + command: The command to run. Typically this is a sequence of strings or + bytes such as ``['ls', '-l', 'directory with spaces']``, where the + first element names the executable to invoke and the other elements + specify its arguments. With ``shell=True`` in the ``**options``, or on + Windows, ``command`` can be a string or bytes, which will be parsed + following platform-dependent :ref:`quoting rules + `. In all cases ``command`` can be a path or a + sequence of paths. stdin: Specifies what the child process's standard input stream should connect to: output written by the parent (``subprocess.PIPE``), nothing (``subprocess.DEVNULL``), @@ -369,15 +370,16 @@ async def _open_process( ) if os.name == "posix": - if isinstance(command, str) and not options.get("shell"): + # TODO: how do paths and sequences thereof play with `shell=True`? + if isinstance(command, (str, bytes)) and not options.get("shell"): raise TypeError( - "command must be a sequence (not a string) if shell=False " - "on UNIX systems", + "command must be a sequence (not a string or bytes) if " + "shell=False on UNIX systems", ) - if not isinstance(command, str) and options.get("shell"): + if not isinstance(command, (str, bytes)) and options.get("shell"): raise TypeError( - "command must be a string (not a sequence) if shell=True " - "on UNIX systems", + "command must be a string or bytes (not a sequence) if " + "shell=True on UNIX systems", ) trio_stdin: ClosableSendStream | None = None diff --git a/src/trio/_tools/gen_exports.py b/src/trio/_tools/gen_exports.py index 524a65f90d..91969d6bfe 100755 --- a/src/trio/_tools/gen_exports.py +++ b/src/trio/_tools/gen_exports.py @@ -303,7 +303,7 @@ def process(files: Iterable[File], *, do_test: bool) -> None: print("Generated sources are up to date.") else: for new_path, new_source in new_files.items(): - with open(new_path, "w", encoding="utf-8") as f: + with open(new_path, "w", encoding="utf-8", newline="\n") as f: f.write(new_source) print("Regenerated sources successfully.") if not matches_disk: