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.4

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.4
File Size Uploaded
sproc-3.0.4.tar.gz 44.1 kB Details

Built distribution (wheel)

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

Total release size: 52.8 kB

Release files / sproc-3.0.4.tar.gz

Download URL sproc-3.0.4.tar.gz
Size 44.1 kB
Tags Source
SHA-256 checksum
How to use checksums
560678fc8300687222df2d0993c929366d64a10fbac192b7a89655a57ae0a5d2
BLAKE2b-256 checksum
How to use checksums
396d0acbc6f62fb423777861911aaa1c3b75f6178a226a5d4aece5cad6451d91
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.4-py3-none-any.whl

Download URL sproc-3.0.4-py3-none-any.whl
Size 8.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5f91366f96de129b98cb0690277d5f2ce4a21a008acf69274901b68ac85fb5fc
BLAKE2b-256 checksum
How to use checksums
e56c5941ccef2a694280f6b75e3c92e2c5fe9b61360bfb0c203224af387c94d4
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

This release

3.0.4 This release

2 release files

3.0.2

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