{"id":8333,"library":"mozprocess","title":"Mozprocess","description":"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.","status":"maintenance","version":"1.4.0","language":"en","source_language":"en","source_url":"https://github.com/mozilla/mozbase/tree/master/mozprocess","tags":["process management","subprocess","mozilla","testing","automation"],"install":[{"cmd":"pip install mozprocess","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"ProcessHandler","correct":"from mozprocess import ProcessHandler"},{"symbol":"ProcessHandlerMixin","correct":"from mozprocess import ProcessHandlerMixin"},{"symbol":"run_and_wait","correct":"from mozprocess import run_and_wait"}],"quickstart":{"code":"import sys\nimport os\nfrom mozprocess import ProcessHandler\n\ndef print_output_line(line):\n    print(f\"Process Output: {line.strip()}\")\n\ndef on_timeout_handler():\n    print(\"Process timed out!\")\n\n# Example: Run a simple command and capture output\ncommand = ['python', '-c', 'import time; print(\"Hello\"); time.sleep(1); print(\"World\");']\n\ntry:\n    # Using ProcessHandler to manage the process, capture output, and handle timeouts\n    p = ProcessHandler(\n        command,\n        processOutputLine=[print_output_line],\n        onTimeout=[on_timeout_handler],\n        # Set a short timeout to demonstrate the onTimeout handler\n        # For actual use, adjust or remove this timeout.\n        timeout=5, \n        outputTimeout=2 # Kill if no output for 2 seconds\n    )\n    print(f\"Executing command: {p.commandline}\")\n    p.run()\n    return_code = p.wait()\n    print(f\"Process finished with return code: {return_code}\")\n    if p.timedOut:\n        print(\"Note: Process was killed due to timeout.\")\nexcept Exception as e:\n    print(f\"An error occurred: {e}\")\n","lang":"python","description":"This quickstart demonstrates launching a process using `mozprocess.ProcessHandler`, setting up a callback for each line of output, and defining a handler for process timeouts. It runs a simple Python script, capturing its output line by line and reporting its final status."},"warnings":[{"fix":"Prefer `subprocess` for general-purpose process management. Only use `mozprocess` for its specific features like advanced child process tracking, output line handlers, or specific timeout behaviors if strictly necessary for Mozilla-related tools. For simpler needs with timeouts/output handling, `mozprocess.run_and_wait()` is the recommended `mozprocess` interface.","message":"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.","severity":"deprecated","affected_versions":"All versions, especially when used in modern Python 3 environments."},{"fix":"Always check `p.timedOut` after `p.wait()` and explicitly `p.kill()` the process if it timed out and is no longer needed. Ensure `kill_on_timeout` is set correctly for `run()` if you expect automatic killing.","message":"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.","severity":"gotcha","affected_versions":"All versions."},{"fix":"If custom `processOutputLine` handlers are used and you still want output to go to `sys.stdout` (or `sys.stderr`), explicitly pass `stream=sys.stdout` (or `stream=sys.stderr`) to the `ProcessHandler` constructor.","message":"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.","severity":"gotcha","affected_versions":"All versions."}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"After `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.","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.","error":"Process hangs indefinitely, never returns, or consumes excessive resources after a `wait(timeout=...)` call."},{"fix":"If 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`.","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`.","error":"Output is not printed to console when custom `processOutputLine` handlers are provided."},{"fix":"For 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.","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.","error":"`AttributeError: 'ProcessHandlerMixin' object has no attribute 'output'` or `AttributeError: 'ProcessHandlerMixin' object has no attribute 'stream'`"}]}