- New
no_close_queues
parameter to leave stdout/stderr queues open for later usage by parent functions - Updated ofunctions.threading implementation to v2.1.0
- Added python 3.12 and pypy 3.10 to test matrix
- poller/monitor tests now have less rounds in pypy python implementation (takes too long on Github actions)
- Various minor linter fixes
- IO priority was set with process priority values instead of IO priority values
- Failing to set process/IO priority because of insufficient permissions now shows a proper warning message in logs
- priorities are now case insensitive
- New silent parameter disabling all logger calls except of logging.DEBUG levels
- New on_exit parameter that takes a callback function as argument
- valid_exit_codes now accept boolean True which means "all" exit codes
- New priority parameter
- New io_priority parameter
- Fix output capture failure should be an error log instead of debug
- Fix no longer show debug logging for stdout or stderr when empty
- Fix endoding always was set to os default unless explicitly disabled by setting
encoding=False
- command_runner now has a
command_runner_threaded()
function which allows to run in background, but still provide live stdout/stderr stream output via queues/callbacks - Refactor poller mode to allow multiple stdout / stderr stream redirectors
- Passing a queue.Queue() instance to stdout/stderr arguments will fill queue with live stream output
- Passing a function to stdout/stderr arguments will callback said function with live stream output
- Passing a string to stdout/stderr arguments will redirect stream into filename described by string
- Added
split_stream
argument which will make command_runner return (exit_code, stdout, stderr) instead of (exit_code, output) tuple - Added
check_interval
argument which decides how much time we sleep between two checks, defaults to 0.05 seconds. Lowering this improves responsiveness, but increases CPU usage. Default value should be more than reasaonable for most applications - Added
stop_on
argument which takes a function, which is called everycheck_interval
and will interrupt execution if it returns True - Added
process_callback
argument which takes a function(process), which is called upon execution with a subprocess.Popen object as argument for optional external process control - Possibility to disable command_runner stream encoding with
encoding=False
so we get raw output (bytes) - Added more unit tests (stop_on, process_callback, stream callback / queues, to_null_redirections, split_streams)
- Fix unix command provided as list didn't work with
shell=True
- Fixed more Python 2.7 UnicodedecodeErrors on corner case exceptions catches
- Fixed python 2.7 TimeoutException output can fail with UnicodedecodeError
- Fix Python 2.7 does not have subprocess.DEVNULL
- Ensure output is always None if process didn't return any string on stdout/stderr on Python 2.7
- Fix python 2.7 process.communicate() multiple calls endup without output (non blocking process.poll() needs communicate() when using shell=True)
- Removed queue usage in monitor mode (needs lesser threads)
- Optimized performance
- Added new exit code -250 when queue/callbacks are used with monitor method or unknown method has been called
- Optimized tests
- Packaging fixes for Python 2.7 when using
pip install command_runner
- Adds the possibility to redirect stdout/stderr to null with
stdout=False
orstderr=False
arguments
- Add python 3.10 to the test matrix
- Timeout race condition with pypy 3.7 (!) where sometimes exit code wasn't -254
- Try to use signal.SIGTERM (if exists) to kill a process instead of os API that uses PID in order to prevent possible collision when process is already dead and another process with the same PID exists
- Unit tests are more verbose
- Black formatter is now enforced
- Timeout tests are less strict to cope with some platform delays
- Added a new capture method (monitor)
- There are now two distinct methods to capture output
- Spawning a thread to enforce timeouts, and using process.communicate() (monitor method)
- Spawning a thread to readlines from stdout pipe to an output queue, and reading from that output queue while enforcing timeouts (polller method)
- On the fly output (live_output=True) option is now explicit (uses poller method only)
- Returns partial stdout output when timeouts are reached
- Returns partial stdout output when CTRL+C signal is received (only with poller method)
- CRITICAL: Fixed rare annoying but where output wasn't complete
- Use process signals in favor of direct os.kill API to avoid potential race conditions when PID is reused too fast
- Allow full process subtree killing on Windows & Linux, hence not blocking multiple commands like echo "test" && sleep 100 && echo "done"
- Windows does not maintain an explicit process subtree, so we runtime walk processes to establish the child processes to kill. Obviously, orphaned processes cannot be killed that way.-
- Adds a default 16K stdout buffer
- Default command execution timeout is 3600s (1 hour)
- Highly improved tests
- All tests are done for both capture methods
- Timeout tests are more accurate
- Added missing encoding tests
- 2500 rounds of file reading and comparison are added to detect rare queue read misses
- Added threaded pipe reader (poller) in order to enforce timeouts on Windows GUI apps
- Fixed possible encoding issue with Python < 3.4 and powershell containing non unicode output
- More packaging fixes
- Packaging fixes for Python 2.7
- Improve CI tests
- Fixed possible use of
windows_no_window
with Python < 3.7 should not be allowed