Mozprocess
Mozprocess is a process-handling module developed by Mozilla, providing enhanced features beyond Python's standard `subprocess` module, such as improved child process handling (especially on Windows), flexible timeouts, and custom output handlers. While currently at version 1.4.0, the project's documentation notes it is poorly maintained and advises using Python's `subprocess` for routine needs. The project does not have a strict release cadence and updates are infrequent.
Common errors
-
Process hangs indefinitely, never returns, or consumes excessive resources after a `wait(timeout=...)` call.
cause The `wait()` method's `timeout` parameter only controls how long `wait()` itself will block, not the lifespan of the underlying process. If `wait()` returns `None` (indicating a timeout) or a return code that implies the process is still running, `mozprocess` will not automatically kill it.fixAfter `p.wait(timeout=X)`, check `if p.poll() is None:` or `if p.timedOut:`, and if the process is still active and undesirable, explicitly call `p.kill()` to terminate it. -
Output is not printed to console when custom `processOutputLine` handlers are provided.
cause When you provide a list of callables to the `processOutputLine` argument in `ProcessHandler`, these handlers completely replace the default behavior of printing to `sys.stdout`.fixIf you wish to retain default console output *in addition* to your custom handlers, ensure that `stream=sys.stdout` is explicitly passed to the `ProcessHandler` constructor. Your custom handler can also explicitly print to `sys.stdout` or `sys.stderr`. -
`AttributeError: 'ProcessHandlerMixin' object has no attribute 'output'` or `AttributeError: 'ProcessHandlerMixin' object has no attribute 'stream'`
cause `ProcessHandlerMixin` is a lower-level class that doesn't include the default output handling and storage mechanisms found in `ProcessHandler`. It's designed for more explicit, manual management.fixFor most use cases requiring output capture or streaming, use `ProcessHandler`. If you must use `ProcessHandlerMixin`, you need to implement your own output capturing logic via `processOutputLine` handlers and manage streams explicitly.
Warnings
- deprecated Mozilla documentation explicitly states 'THIS MODULE IS POORLY MAINTAINED' and recommends using Python's `subprocess` module for routine process handling. Mozprocess's features were designed for Python 2 limitations, many of which are no longer relevant in modern Python 3.
- gotcha The `run()` method's `timeout` argument kills the process if the timeout is reached. However, the `wait()` method's `timeout` argument merely causes `wait()` to return after the specified seconds but *does not kill the process*. Failing to explicitly kill the process if `wait()` returns due to a timeout can lead to hanging processes.
- gotcha By default, `ProcessHandler` captures output, sends it to `sys.stdout`, and stores it internally. `ProcessHandlerMixin` (the base class), however, does not. If you provide custom output handlers to `ProcessHandler`, they *replace* the default behavior unless `stream=sys.stdout` is explicitly passed.
Install
-
pip install mozprocess
Imports
- ProcessHandler
from mozprocess import ProcessHandler
- ProcessHandlerMixin
from mozprocess import ProcessHandlerMixin
- run_and_wait
from mozprocess import run_and_wait
Quickstart
import sys
import os
from mozprocess import ProcessHandler
def print_output_line(line):
print(f"Process Output: {line.strip()}")
def on_timeout_handler():
print("Process timed out!")
# Example: Run a simple command and capture output
command = ['python', '-c', 'import time; print("Hello"); time.sleep(1); print("World");']
try:
# Using ProcessHandler to manage the process, capture output, and handle timeouts
p = ProcessHandler(
command,
processOutputLine=[print_output_line],
onTimeout=[on_timeout_handler],
# Set a short timeout to demonstrate the onTimeout handler
# For actual use, adjust or remove this timeout.
timeout=5,
outputTimeout=2 # Kill if no output for 2 seconds
)
print(f"Executing command: {p.commandline}")
p.run()
return_code = p.wait()
print(f"Process finished with return code: {return_code}")
if p.timedOut:
print("Note: Process was killed due to timeout.")
except Exception as e:
print(f"An error occurred: {e}")