diff --git a/stdlib/asyncio/subprocess.pyi b/stdlib/asyncio/subprocess.pyi index 50d75391f36d..6235754cf120 100644 --- a/stdlib/asyncio/subprocess.pyi +++ b/stdlib/asyncio/subprocess.pyi @@ -3,14 +3,14 @@ import sys from _typeshed import StrOrBytesPath from asyncio import events, protocols, streams, transports from collections.abc import Callable, Collection -from typing import IO, Any, Literal +from typing import IO, Any, Literal, overload # Keep asyncio.__all__ updated with any changes to __all__ here __all__ = ("create_subprocess_exec", "create_subprocess_shell") -PIPE: int -STDOUT: int -DEVNULL: int +PIPE = subprocess.PIPE +STDOUT = subprocess.STDOUT +DEVNULL = subprocess.DEVNULL class SubprocessStreamProtocol(streams.FlowControlMixin, protocols.SubprocessProtocol): stdin: streams.StreamWriter | None @@ -19,7 +19,7 @@ class SubprocessStreamProtocol(streams.FlowControlMixin, protocols.SubprocessPro def __init__(self, limit: int, loop: events.AbstractEventLoop) -> None: ... def pipe_data_received(self, fd: int, data: bytes | str) -> None: ... -class Process: +class Process[CommOut: (PIPE, int, IO[Any], None), CommErr: (PIPE, int, IO[Any], None)]: stdin: streams.StreamWriter | None stdout: streams.StreamReader | None stderr: streams.StreamReader | None @@ -33,14 +33,31 @@ class Process: def send_signal(self, signal: int) -> None: ... def terminate(self) -> None: ... def kill(self) -> None: ... - async def communicate(self, input: bytes | bytearray | memoryview | None = None) -> tuple[bytes, bytes]: ... + @overload + async def communicate( + self: Process[PIPE, PIPE], input: bytes | bytearray | memoryview | None = None + ) -> tuple[bytes, bytes]: ... + @overload + async def communicate( + self: Process[PIPE, int | IO[Any] | None], input: bytes | bytearray | memoryview | None = None + ) -> tuple[bytes, None]: ... + @overload + async def communicate( + self: Process[int | IO[Any] | None, PIPE], input: bytes | bytearray | memoryview | None = None + ) -> tuple[None, bytes]: ... + @overload + async def communicate( + self: Process[int | IO[Any] | None, int | IO[Any] | None], input: bytes | bytearray | memoryview | None = None + ) -> tuple[None, None]: ... if sys.version_info >= (3, 11): - async def create_subprocess_shell( + async def create_subprocess_shell[ + Out: (PIPE, int, IO[Any], None), Err: (PIPE, int, IO[Any], None) + ]( cmd: str | bytes, stdin: int | IO[Any] | None = None, - stdout: int | IO[Any] | None = None, - stderr: int | IO[Any] | None = None, + stdout: Out = None, + stderr: Err = None, limit: int = 65536, *, # These parameters are forced to these values by BaseEventLoop.subprocess_shell @@ -67,13 +84,15 @@ if sys.version_info >= (3, 11): umask: int = -1, process_group: int | None = None, pipesize: int = -1, - ) -> Process: ... - async def create_subprocess_exec( + ) -> Process[Out, Err]: ... + async def create_subprocess_exec[ + Out: (PIPE, int, IO[Any], None), Err: (PIPE, int, IO[Any], None) + ]( program: StrOrBytesPath, *args: StrOrBytesPath, stdin: int | IO[Any] | None = None, - stdout: int | IO[Any] | None = None, - stderr: int | IO[Any] | None = None, + stdout: Out = None, + stderr: Err = None, limit: int = 65536, # These parameters are forced to these values by BaseEventLoop.subprocess_exec universal_newlines: Literal[False] = False, @@ -99,14 +118,16 @@ if sys.version_info >= (3, 11): umask: int = -1, process_group: int | None = None, pipesize: int = -1, - ) -> Process: ... + ) -> Process[Out, Err]: ... elif sys.version_info >= (3, 10): - async def create_subprocess_shell( + async def create_subprocess_shell[ + Out: (PIPE, int, IO[Any], None), Err: (PIPE, int, IO[Any], None) + ]( cmd: str | bytes, stdin: int | IO[Any] | None = None, - stdout: int | IO[Any] | None = None, - stderr: int | IO[Any] | None = None, + stdout: Out = None, + stderr: Err = None, limit: int = 65536, *, # These parameters are forced to these values by BaseEventLoop.subprocess_shell @@ -132,13 +153,15 @@ elif sys.version_info >= (3, 10): user: None | str | int = None, umask: int = -1, pipesize: int = -1, - ) -> Process: ... - async def create_subprocess_exec( + ) -> Process[Out, Err]: ... + async def create_subprocess_exec[ + Out: (PIPE, int, IO[Any], None), Err: (PIPE, int, IO[Any], None) + ]( program: StrOrBytesPath, *args: StrOrBytesPath, stdin: int | IO[Any] | None = None, - stdout: int | IO[Any] | None = None, - stderr: int | IO[Any] | None = None, + stdout: Out = None, + stderr: Err = None, limit: int = 65536, # These parameters are forced to these values by BaseEventLoop.subprocess_exec universal_newlines: Literal[False] = False, @@ -163,14 +186,16 @@ elif sys.version_info >= (3, 10): user: None | str | int = None, umask: int = -1, pipesize: int = -1, - ) -> Process: ... + ) -> Process[Out, Err]: ... else: # >= 3.9 - async def create_subprocess_shell( + async def create_subprocess_shell[ + Out: (PIPE, int, IO[Any], None), Err: (PIPE, int, IO[Any], None) + ]( cmd: str | bytes, stdin: int | IO[Any] | None = None, - stdout: int | IO[Any] | None = None, - stderr: int | IO[Any] | None = None, + stdout: Out = None, + stderr: Err = None, loop: events.AbstractEventLoop | None = None, limit: int = 65536, *, @@ -196,13 +221,15 @@ else: # >= 3.9 extra_groups: None | Collection[str | int] = None, user: None | str | int = None, umask: int = -1, - ) -> Process: ... - async def create_subprocess_exec( + ) -> Process[Out, Err]: ... + async def create_subprocess_exec[ + Out: (PIPE, int, IO[Any], None), Err: (PIPE, int, IO[Any], None) + ]( program: StrOrBytesPath, *args: StrOrBytesPath, stdin: int | IO[Any] | None = None, - stdout: int | IO[Any] | None = None, - stderr: int | IO[Any] | None = None, + stdout: Out = None, + stderr: Err = None, loop: events.AbstractEventLoop | None = None, limit: int = 65536, # These parameters are forced to these values by BaseEventLoop.subprocess_exec @@ -227,4 +254,4 @@ else: # >= 3.9 extra_groups: None | Collection[str | int] = None, user: None | str | int = None, umask: int = -1, - ) -> Process: ... + ) -> Process[Out, Err]: ... diff --git a/stdlib/subprocess.pyi b/stdlib/subprocess.pyi index fef35b56945a..bae04ba60ae2 100644 --- a/stdlib/subprocess.pyi +++ b/stdlib/subprocess.pyi @@ -1810,9 +1810,9 @@ else: text: bool | None = None, ) -> Any: ... # morally: -> str | bytes -PIPE: Final[int] -STDOUT: Final[int] -DEVNULL: Final[int] +PIPE: Final[Literal[-1]] +STDOUT: Final[Literal[-2]] +DEVNULL: Final[Literal[-3]] class SubprocessError(Exception): ...