One of the things I've been impressed by is the subprocess module and, in special, its Popen class. By using this class, it is trivial to spawn subprocesses and perform some IPC with them. Unfortunately, Popen does not provide any way to silence the output of the children. As I see it, it'd be nice if you'd pass an IGNORE flag as the stdout/stderr behavior, much like you can currently set those to PIPE or set stderr to STDOUT.
The following trivial module implements this idea. It extends Popen so that the callers can pass the IGNORE value to the stdout/stderr arguments. (Yes, it is trivial but it is also one of the first Python code I write so... it may contain obviously non-Pythonic, ugly things.) The idea is that this exposes the same interface so that it can be used as a drop-in replacement. OK, OK, it lacks some methods and the constructor does not match the original signature, but this is enough for my current use cases!
import subprocessBy the way, somebody else suggested this same thing a while ago. Don't know why it hasn't been implemented in the mainstream subprocess module.
IGNORE = -3
STDOUT = subprocess.STDOUT
assert IGNORE != STDOUT, "IGNORE constant is invalid"
class Popen(subprocess.Popen):
"""Extension of subprocess.Popen with built-in support
for silencing the output channels of a child process"""
__null = None
def __init__(self, args, stdout = None, stderr = None):
subprocess.Popen.__init__(self, args = args,
stdout = self._channel(stdout),
stderr = self._channel(stderr))
def __del__(self):
self._close_null()
def wait(self):
r = subprocess.Popen.wait(self)
self._close_null()
return r
def _null_instance(self):
if self.__null == None:
self.__null = open("/dev/null", "w")
return self.__null
def _close_null(self):
if self.__null != None:
self.__null.close()
self.__null = None
assert self.__null == None,
"Inconsistent internal state"
def _channel(self, behavior):
if behavior == IGNORE:
return self._null_instance()
else:
return behavior