Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/trio/_subprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@

def pidfd_open(fd: int, flags: int) -> int: ...

from ._subprocess_platform import ClosableReceiveStream, ClosableSendStream

else:
can_try_pidfd_open = True
try:
Expand Down Expand Up @@ -171,9 +169,9 @@ def __init__(
if self.stdin is not None and self.stdout is not None:
self.stdio = StapledStream(self.stdin, self.stdout)

self._wait_lock: Lock = Lock()
self._wait_lock = Lock()

self._pidfd: FileIO | None = None
self._pidfd = None
if can_try_pidfd_open:
try:
fd: int = pidfd_open(self._proc.pid, 0)
Expand All @@ -188,6 +186,8 @@ def __init__(
# make sure it'll get closed.
self._pidfd = FileIO(fd)

# TODO: remove the following two type hints, required only due to
# https://github.com/microsoft/pyright/issues/11917
self.args: StrOrBytesPath | Sequence[StrOrBytesPath] = self._proc.args
self.pid: int = self._proc.pid

Expand Down Expand Up @@ -381,9 +381,9 @@ async def _open_process(
"shell=True on UNIX systems",
)

trio_stdin: ClosableSendStream | None = None
trio_stdout: ClosableReceiveStream | None = None
trio_stderr: ClosableReceiveStream | None = None
trio_stdin = None

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am surprised mypy strict mode is alright with this (then again I don't think we have that turned on be default)

Seeing this here and knowing this is likely a mypy strict mode thing, I wouldn't be surprised if this is one of my contributions for a future where we do enable strict mode

@A5rocks A5rocks Oct 23, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mypy has a ton of special behavior around None where it will look around at context to figure out the right type hint.

See https://mypy-play.net/?mypy=latest&python=3.12&flags=strict&gist=2c203611ecce92bee7a12ef01ab7d524 for an example. (Also at some point I might switch us to using allow-redefinition, mypy's done a new version of it since I last tried that and probably it's less buggy!)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha. Looks like things have changed from what I remember we had to do previously.

trio_stdout = None
trio_stderr = None
# Close the parent's handle for each child side of a pipe; we want the child to
# have the only copy, so that when it exits we can read EOF on our side. The
# trio ends of pipes will be transferred to the Process object, which will be
Expand Down
18 changes: 18 additions & 0 deletions src/trio/_tests/type_tests/subprocesses.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import os
import sys
from collections.abc import Sequence
from typing import TypeAlias

import trio
from typing_extensions import assert_type

StrOrBytesPath: TypeAlias = str | bytes | os.PathLike[str] | os.PathLike[bytes]


async def test() -> None:
Expand All @@ -21,3 +27,15 @@ async def test() -> None:
# 3.11+:
await trio.run_process("python", process_group=5) # type: ignore
await trio.lowlevel.open_process("python", process_group=5) # type: ignore


def check_processes(proc: trio.Process) -> None:
assert_type(proc.stdin, trio.abc.SendStream | None)
assert_type(proc.stdout, trio.abc.ReceiveStream | None)
assert_type(proc.stderr, trio.abc.ReceiveStream | None)
assert_type(
proc.stdio,
trio.StapledStream[trio.abc.SendStream, trio.abc.ReceiveStream] | None,
)
assert_type(proc.args, StrOrBytesPath | Sequence[StrOrBytesPath])
assert_type(proc.pid, int)
Loading