Skip to main content

⛏️sproc: subprocesseses for subhumanses ⛏

Run a command in a subprocess and yield lines of text from stdout and stderr independently.

Useful for handling long-running processes that write to both stdout and stderr.

Simple Example

import sproc

CMD = 'my-unix-command "My Cool File.txt" No-file.txt'

sp = sproc.Sub(CMD)
for is_stdout, line in sp:
    if is_stdout:
         print(' ', line)
    else:
         print('!', line)

if sp.returncode:
    print('Error code', sp.returncode)

# Return two lists of text lines and a returncode
out_lines, err_lines, returncode = sproc.run(CMD)

# Call callback functions with lines of text read from stdout and stderr
returncode = sproc.call(CMD, save_results, print_errors)

# Log stdout and stderr, with prefixes
returncode = sproc.log(CMD)

Lifecycle and current limitations

One Sub instance supports one active invocation. is_running reports whether that invocation is still active, and reader_error exposes the first reader I/O or UTF-8 decoding error. Existing callbacks and return values are unchanged; callback exceptions retain their existing thread behavior.

call_in_thread and its compatibility alias call_async currently wait for the subprocess before returning, despite their names. Output ordering between stdout and stderr is unspecified.

Nonblocking output stream

start() is the preferred nonblocking API. It starts the process immediately and yields tuple-compatible OutputEvent values while it runs. is_stdout identifies stdout rather than success, and text is the output value. wait(timeout) returns None when the timeout expires without terminating the process. Consume the events before close(), which waits for normal completion and reader shutdown.

stream = sproc.start(CMD)
for event in stream:
    print('out' if event.is_stdout else 'err', event.text, end='')
returncode = stream.close()

The events remain unpackable for callers that prefer is_stdout, text = event.

Compatibility timeline

call_in_thread() and call_async() remain supported compatibility APIs with no planned removal version. This release emits no warning for either. A future minor release may add a migration warning after users have had time to adopt ProcessStream.

Command semantics

For compatibility, a string command with shell=False uses POSIX shlex splitting, including on Windows. A sequence command with shell=False is passed directly to Popen. With shell=True, a string is passed to the platform shell unchanged; callers must use the quoting rules of that shell. Sequence commands with shell=True retain their legacy POSIX shlex joining.

Use sequence commands when portability matters. Sproc does not promise that a POSIX-quoted string works in cmd.exe or PowerShell.

Liveness controls

ProcessStream.wait(timeout) returns None when the timeout expires and does not terminate the process. terminate() and kill() are idempotent operations on the direct child only; they never claim to stop shell children or other descendants.

For a bounded output queue, pass both a size and overflow='raise'. Sproc continues draining the child after the limit so that the child can finish, then iteration raises OutputQueueFullError after yielding the output that fit.

stream = sproc.start(CMD, max_queue_size=100, overflow='raise')

A child that gives stdout or stderr to a long-lived descendant can delay stream EOF after the direct child exits. Keep descendant output separate, for example by redirecting it to subprocess.DEVNULL; Sproc does not guess which process tree to terminate.

Text, binary, and chunked output

ProcessStream decodes UTF-8 strictly by default. Set encoding and errors to choose a text codec and decoding policy. Set encoding=None for binary events: one stream yields either str values or bytes values, never both.

text = sproc.start(CMD, encoding='latin-1')
binary = sproc.start(CMD, encoding=None)

Line mode is the default. For incremental output chunks, set by_lines=False and provide a positive chunk_size; each chunk has at most that many bytes before text decoding. The old helpers retain their EOF-sized chunk behavior.

chunks = sproc.start(CMD, by_lines=False, chunk_size=4096)

API Documentation

Metadata

Release files for sproc 3.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sproc 3.0.2
File Size Uploaded
sproc-3.0.2.tar.gz 44.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sproc 3.0.2
File Interpreter ABI Platform
sproc-3.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 52.7 kB

Release files / sproc-3.0.2.tar.gz

Download URL sproc-3.0.2.tar.gz
Size 44.0 kB
Tags Source
SHA-256 checksum
How to use checksums
23bd0e0890227462ee929ef0f4bf9a90e309691f1ce42f7ca062301bd8e770f4
BLAKE2b-256 checksum
How to use checksums
8aa6529adffa6e978039e6b3f7d85e746c176b1bced0e4cc5920320c5d4877ac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / sproc-3.0.2-py3-none-any.whl

Download URL sproc-3.0.2-py3-none-any.whl
Size 8.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e2ab0777b0fcd5413c3e31a24d9791312f3990e1236da7a37651c6671e11efc9
BLAKE2b-256 checksum
How to use checksums
87284066c4cd4235609be936f3535892963358c674cd03249db96bcaf36f8d7d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

3.0.4

2 release files

This release

3.0.2 This release

2 release files

2.6.0

2 release files

2.5.0

2 release files

2.4.1

2 release files

2.4.0

2 release files

2.3.1

2 release files

2.3.0

2 release files

2.2.0

2 release files

2.1.0

2 release files

2.0.5

2 release files

2.0.4

2 release files

2.0.3

2 release files

2.0.2

2 release files

2.0.1

2 release files

2.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page