I am using subprocess.CompletedProcess
as a return type of a function. When running mypy
with --strict
, it complains about Missing type parameters for generic type "CompletedProcess"
. This is a short example for which the problem occurs:
import subprocess
def run_command() -> subprocess.CompletedProcess:
return subprocess.CompletedProcess(args=[], returncode=0, stdout='')
I do not understand how CompletedProcess
is a generic. I checked the reference (https://docs.python.org/3.9/library/subprocess.html#subprocess.CompletedProcess) and can't find any mention.
Randomly adding a generic parameter, for example -> subprocess.CompletedProcess[str]
, removes the error, but obviously that's not the point. I'd like to be able to hint the return type without defining a generic parameter.
I am using python 3.8.5 and mypy 0.761 and 0.910 (both give the same output).
The output (stdout
/stderr
) of a subprocess can be either str
or bytes
, depending on the arguments. The generic parameter to CompletedProcess
is required to indicate the type of this.
import subprocess
def run_some_command() -> 'subprocess.CompletedProcess[str]':
"""Run some subprocess that captures output as ``str``"""
return subprocess.CompletedProcess(args=[], returncode=0, stdout='')
def run_other_command() -> 'subprocess.CompletedProcess[bytes]':
"""Run some subprocess that captures output as ``bytes``"""
return subprocess.CompletedProcess(args=[], returncode=0, stdout=b'')
reveal_type(run_some_command().stdout) # note: Revealed type is 'builtins.str*'
Since only the type hint but not the runtime subprocess.CompletedProcess
type is generic, it must be quoted.
The type declarations for the standard library are part of typeshed
. In specific, CompletedProcess
is currently defined as follows:
class CompletedProcess(Generic[_T]):
# morally: _CMD
args: Any
returncode: int
# These are really both Optional, but requiring checks would be tedious
# and writing all the overloads would be horrific.
stdout: _T
stderr: _T
def __init__(self, args: _CMD, returncode: int, stdout: Optional[_T] = ..., stderr: Optional[_T] = ...) -> None: ...
def check_returncode(self) -> None: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any) -> GenericAlias: ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With