or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/pypi-subprocess32

A backport of the Python 3 subprocess module for use on Python 2 with enhanced reliability and thread-safety.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/subprocess32@3.5.x

To install, run

npx @tessl/cli install tessl/pypi-subprocess32@3.5.0

index.mddocs/

subprocess32

A backport of the Python 3 subprocess module for use on Python 2 with enhanced reliability and thread-safety. Provides the full Python 3.2 subprocess functionality plus timeout support from Python 3.3 and the run() API from Python 3.5. Includes a C extension module for reliable process handling in multi-threaded environments.

Package Information

  • Package Name: subprocess32
  • Language: Python
  • Installation: pip install subprocess32
  • Python Version: Python 2.6, 2.7 (backport of Python 3 features)
  • License: Python Software Foundation License

Core Imports

import subprocess32 as subprocess

Alternative import pattern for cross-platform compatibility:

import os
import sys

if os.name == 'posix' and sys.version_info[0] < 3:
    import subprocess32 as subprocess
else:
    import subprocess

Basic Usage

import subprocess32 as subprocess

# Simple command execution
result = subprocess.call(['ls', '-l'])

# Command with error checking
try:
    subprocess.check_call(['ls', '/nonexistent'])
except subprocess.CalledProcessError as e:
    print("Command failed with return code {}".format(e.returncode))

# Capture output
output = subprocess.check_output(['echo', 'Hello World'])
print(output.strip())

# Modern run() API (Python 3.5 style - available in subprocess32)
result = subprocess.run(['echo', 'Hello'], 
                       stdout=subprocess.PIPE, 
                       stderr=subprocess.PIPE)
print("Output: {}".format(result.stdout))
print("Return code: {}".format(result.returncode))

# Advanced process control with Popen
process = subprocess.Popen(['cat'], 
                          stdin=subprocess.PIPE, 
                          stdout=subprocess.PIPE, 
                          stderr=subprocess.PIPE)
stdout, stderr = process.communicate(input=b'Hello subprocess32')
print(stdout.decode())

API Compatibility Notes

subprocess32 provides the complete Python 3.2 subprocess API plus several newer features:

  • Core API (always available): Popen, call, check_call, check_output, CalledProcessError, PIPE, STDOUT
  • Timeout support (from Python 3.3): Available in all functions via timeout parameter, raises TimeoutExpired
  • run() API (from Python 3.5): run() function and CompletedProcess class
  • Additional constants: DEVNULL constant for discarding output
  • Windows constants: Available only on Windows platforms

Capabilities

High-Level Functions

Simple functions for common process execution patterns, offering progressively more control and error handling.

def call(*popenargs, **kwargs):
    """
    Run command with arguments. Wait for command to complete, then return the return code.
    
    Parameters:
    - *popenargs: Command and arguments as sequence or string
    - timeout: Maximum time to wait in seconds (raises TimeoutExpired if exceeded)
    - **kwargs: Additional arguments passed to Popen constructor
    
    Returns:
    int: Process return code (0 for success, non-zero for failure)
    """

def check_call(*popenargs, **kwargs):
    """
    Run command with arguments. Wait for command to complete. 
    If return code is zero, return normally. Otherwise raise CalledProcessError.
    
    Parameters:
    - *popenargs: Command and arguments as sequence or string
    - timeout: Maximum time to wait in seconds (raises TimeoutExpired if exceeded)
    - **kwargs: Additional arguments passed to Popen constructor
    
    Returns:
    None (raises CalledProcessError on non-zero exit)
    
    Raises:
    CalledProcessError: If command returns non-zero exit code
    TimeoutExpired: If timeout is exceeded
    """

def check_output(*popenargs, **kwargs):
    """
    Run command with arguments and return its output.
    If return code is zero, return stdout. Otherwise raise CalledProcessError.
    
    Parameters:
    - *popenargs: Command and arguments as sequence or string
    - timeout: Maximum time to wait in seconds (raises TimeoutExpired if exceeded)
    - **kwargs: Additional arguments passed to Popen constructor (stdout will be overridden)
    
    Note: The stdout argument is not allowed as it is used internally.
    
    Returns:
    bytes: Command's stdout output as byte string
    
    Raises:
    CalledProcessError: If command returns non-zero exit code
    TimeoutExpired: If timeout is exceeded
    """

def run(*popenargs, **kwargs):
    """
    Run command with arguments and return a CompletedProcess instance.
    Modern high-level interface for subprocess execution.
    
    Parameters:
    - *popenargs: Command and arguments as sequence or string
    - input: String or bytes to send to subprocess stdin (cannot be used with stdin argument)
    - timeout: Maximum time to wait in seconds (raises TimeoutExpired if exceeded)
    - check: If True, raise CalledProcessError on non-zero exit code
    - **kwargs: Additional arguments passed to Popen constructor
    
    Note: If input is provided, stdin argument cannot be used as it will be set to PIPE internally.
    
    Returns:
    CompletedProcess: Object containing args, returncode, stdout, stderr
    
    Raises:
    CalledProcessError: If check=True and command returns non-zero exit code
    TimeoutExpired: If timeout is exceeded
    """

Process Control Class

Advanced process creation and management with full control over streams, environment, and execution.

class Popen(object):
    """
    Execute a child program in a new process with flexible stream handling.
    
    Parameters:
    - args: Command and arguments as sequence or string
    - bufsize: Buffer size for subprocess streams (0=unbuffered, 1=line buffered, >1=buffer size)
    - executable: Replacement program to execute instead of args[0]
    - stdin: Standard input specification (None, PIPE, DEVNULL, file descriptor, or file object)
    - stdout: Standard output specification (None, PIPE, DEVNULL, STDOUT, file descriptor, or file object)
    - stderr: Standard error specification (None, PIPE, DEVNULL, STDOUT, file descriptor, or file object)
    - preexec_fn: Function to call in child process before exec (POSIX only)
    - close_fds: Whether to close file descriptors before exec (default True on POSIX)
    - shell: Whether to execute through shell (allows shell features but security risk)
    - cwd: Working directory for child process
    - env: Environment variables for child process (dict or None for inherit)
    - universal_newlines: Whether to open streams in text mode with universal newlines
    - startupinfo: Windows-specific startup information (Windows only)
    - creationflags: Windows-specific process creation flags (Windows only)
    - restore_signals: Whether to restore signals to default handlers before exec (POSIX only, default True)
    - start_new_session: Whether to start subprocess in new session (POSIX only, default False)
    - pass_fds: Sequence of file descriptors to keep open between parent and child (POSIX only)
    
    Attributes:
    - stdin: Standard input stream (if stdin=PIPE)
    - stdout: Standard output stream (if stdout=PIPE)  
    - stderr: Standard error stream (if stderr=PIPE)
    - pid: Process ID of child process
    - returncode: Return code of process (None if not terminated)
    """
    
    def __init__(self, args, bufsize=0, executable=None, stdin=None, stdout=None, 
                 stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, 
                 env=None, universal_newlines=False, startupinfo=None, creationflags=0,
                 restore_signals=True, start_new_session=False, pass_fds=()):
        pass
    
    def poll(self):
        """
        Check if child process has terminated.
        
        Returns:
        int or None: Return code if terminated, None if still running
        """
    
    def wait(self, timeout=None):
        """
        Wait for child process to terminate.
        
        Parameters:
        - timeout: Maximum time to wait in seconds (None for no timeout)
        
        Returns:
        int: Process return code
        
        Raises:
        TimeoutExpired: If timeout is exceeded
        """
    
    def communicate(self, input=None, timeout=None):
        """
        Interact with process: send data to stdin, read data from stdout/stderr.
        
        Parameters:
        - input: Data to send to stdin (bytes or string if universal_newlines=True)
        - timeout: Maximum time to wait in seconds (None for no timeout)
        
        Returns:
        tuple: (stdout_data, stderr_data) as bytes or strings
        
        Raises:
        TimeoutExpired: If timeout is exceeded
        """
    
    def send_signal(self, sig):
        """
        Send signal to the process.
        
        Parameters:
        - sig: Signal number to send
        """
    
    def terminate(self):
        """
        Terminate the process with SIGTERM (graceful shutdown).
        """
    
    def kill(self):
        """
        Kill the process with SIGKILL (immediate termination).
        """
    
    def __enter__(self):
        """Context manager entry."""
        return self
    
    def __exit__(self, type, value, traceback):
        """Context manager exit with automatic cleanup."""
        pass

Result Data Class

Container for process execution results returned by the run() function.

class CompletedProcess(object):
    """
    A process that has finished running, returned by run().
    
    Attributes:
    - args: The list or str args passed to run()
    - returncode: The exit code of the process (negative for signals)
    - stdout: The standard output (None if not captured)
    - stderr: The standard error (None if not captured)
    """
    
    def __init__(self, args, returncode, stdout=None, stderr=None):
        pass
    
    def check_returncode(self):
        """
        Raise CalledProcessError if the exit code is non-zero.
        
        Raises:
        CalledProcessError: If returncode is non-zero
        """

Exception Classes

Comprehensive error handling for process execution failures and timeouts.

class SubprocessError(Exception):
    """
    Base class for subprocess-related exceptions.
    """

class CalledProcessError(SubprocessError):
    """
    Raised when a process run with check_call() or check_output() returns non-zero exit status.
    
    Attributes:
    - cmd: Command that was executed
    - returncode: Non-zero exit status that caused the error
    - output: Output from stdout (if captured) - alias for stdout
    - stderr: Output from stderr (if captured)
    - stdout: Output from stdout (if captured) - alias for output
    """
    
    def __init__(self, returncode, cmd, output=None, stderr=None):
        pass

class TimeoutExpired(SubprocessError):
    """
    Raised when the timeout expires while waiting for a child process.
    
    Attributes:
    - cmd: Command that was executed
    - timeout: Timeout value in seconds that was exceeded
    - output: Output from stdout (if captured) - alias for stdout
    - stderr: Output from stderr (if captured)
    - stdout: Output from stdout (if captured) - alias for output
    """
    
    def __init__(self, cmd, timeout, output=None, stderr=None):
        pass

Constants and Special Values

Special values for controlling subprocess stream handling and behavior.

# Stream redirection constants (always available)
PIPE = -1      # Create a pipe to the subprocess
STDOUT = -2    # Redirect stderr to stdout  
DEVNULL = -3   # Redirect to os.devnull (discard output)

Windows-Specific Constants

The following constants are only available when running on Windows platforms:

# Windows-specific constants (Windows only)
CREATE_NEW_CONSOLE = 16           # Create new console window
CREATE_NEW_PROCESS_GROUP = 512    # Create new process group
STD_INPUT_HANDLE = -10            # Standard input handle
STD_OUTPUT_HANDLE = -11           # Standard output handle
STD_ERROR_HANDLE = -12            # Standard error handle
SW_HIDE = 0                       # Hide window
STARTF_USESTDHANDLES = 256        # Use provided standard handles
STARTF_USESHOWWINDOW = 1          # Use provided window show state

Utility Functions

Helper functions for command-line processing and compatibility.

def list2cmdline(seq):
    """
    Translate a sequence of arguments into a command line string using 
    the same rules as the MS C runtime.
    
    Parameters:
    - seq: Sequence of command line arguments
    
    Returns:
    str: Command line string with proper quoting and escaping
    """

Advanced Usage Examples

Timeout Handling

import subprocess32 as subprocess

try:
    # Command with timeout
    result = subprocess.run(['sleep', '10'], timeout=5)
except subprocess.TimeoutExpired as e:
    print("Command '{}' timed out after {} seconds".format(e.cmd, e.timeout))

# Timeout with Popen
process = subprocess.Popen(['long_running_command'])
try:
    stdout, stderr = process.communicate(timeout=30)
except subprocess.TimeoutExpired:
    process.kill()
    stdout, stderr = process.communicate()
    print("Process was killed due to timeout")

Error Handling

import subprocess32 as subprocess

try:
    result = subprocess.run(['false'], check=True)
except subprocess.CalledProcessError as e:
    print("Command failed with return code {}".format(e.returncode))
    if e.stdout:
        print("stdout: {}".format(e.stdout))
    if e.stderr:
        print("stderr: {}".format(e.stderr))

Advanced Process Control

import subprocess32 as subprocess

# Complex process with custom environment
env = os.environ.copy()
env['CUSTOM_VAR'] = 'value'

with subprocess.Popen(['command'], 
                     stdin=subprocess.PIPE,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE,
                     env=env,
                     cwd='/tmp') as process:
    
    stdout, stderr = process.communicate(input=b'input data')
    if process.returncode != 0:
        print("Process failed: {}".format(stderr.decode()))
    else:
        print("Process succeeded: {}".format(stdout.decode()))

Thread Safety

subprocess32 includes a C extension module that provides thread-safe process creation, addressing critical concurrency issues in Python 2's original subprocess module. This makes it safe to use in multi-threaded applications where the standard library subprocess module would be unreliable.

Migration from Python 2 subprocess

subprocess32 is designed as a drop-in replacement:

# Before
import subprocess

# After  
import subprocess32 as subprocess

All existing code using the subprocess module should work unchanged with subprocess32, while gaining the benefits of Python 3's improvements and thread-safety enhancements.