Search code examples
pythonsubprocesspopen

What is the output type of Subprocess.communicate?


I was going through official documentation of Popen.communicate().

p = subprocess.Popen('echo hello',stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True,universal_newlines=True)
r,e = p.communicate()

I want to know at which case it will return string output and which case it will return in bytes.(with example would be great)

In the above case r type is string.

Popen.communicate(input=None, timeout=None)
Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate and set the returncode attribute. The optional input argument should be data to be sent to the child process, or None, if no data should be sent to the child. If streams were opened in text mode, input must be a string. Otherwise, it must be bytes.

communicate() returns a tuple (stdout_data, stderr_data). The data will be strings if streams were opened in text mode; otherwise, bytes.

Solution

  • It depends on the text mode used as per the docs

    If encoding or errors are specified, or text (also known as universal_newlines) is true, the file objects stdin, stdout and stderr will be opened in text mode using the encoding and errors specified in the call or the defaults for io.TextIOWrapper... If text mode is not used, stdin, stdout and stderr will be opened as binary streams. No encoding or line ending conversion is performed.

    For future use-cases on well typed libraries, you can use typing.reveal_type with static analyzers such as mypy. This makes it quite easy to determine values in your code.

    Example, test.py

    from subprocess import Popen
    from typing import reveal_type
    
    p1 = Popen("blah", text=False)
    reveal_type(p1.communicate())
    
    
    p2 = Popen("blah", text=True)
    reveal_type(p2.communicate())
    
    > mypy test.py
    test.py:5: note: Revealed type is "Tuple[builtins.bytes, builtins.bytes]"
    test.py:9: note: Revealed type is "Tuple[builtins.str, builtins.str]"
    Success: no issues found in 1 source file
    

    You can see here, when text=False the values are bytes, when text=True the values are strings.