Search code examples
pythonpython-3.xexceptionsubprocesspopen

Python 3.3+: How to suppress exceptions in subprocess.Popen()?


I have a class with some functions that basically do output checks on data, the functions of this class are called using a subprocess. Now if the output check fails the subprocess has a sys.exit call with a different code depending on which check it failed.

In the main code I have this:

try:
    exitCode = 0
    #import module for current test
    teststr = os.path.splitext(test)[0]
    os.chdir(fs.scriptFolder)
    test = __import__(teststr)
    #delete old output folder and create a new one
    if  os.path.isdir(fs.outputFolder):
        rmtree(fs.outputFolder)
    os.mkdir(fs.outputFolder)
    # run the test passed into the function as a new subprocess
    os.chdir(fs.pythonFolder)
    myEnv=os.environ.copy()
    myEnv["x"] = "ON"
    testSubprocess = Popen(['python', test.testInfo.network + '.py', teststr], env=myEnv)
    testSubprocess.wait()
    result = addFields(test)
    # poke the data into the postgresql database if the network ran successfully 
    if testSubprocess.returncode == 0:
        uploadToPerfDatabase(result)     
    elif testSubprocess.returncode == 1:
        raise Exception("Incorrect total number of rows on output, expected: " + str(test.testInfo.outputValidationProps['TotalRowCount']))
        exitCode = 1
    elif testSubprocess.returncode == 2:
        raise Exception("Incorrect number of columns on output, expected: " + str(test.testInfo.outputValidationProps['ColumnCount']))
        exitCode = 1
except Exception as e:
    log.out(teststr + " failed", True)
    log.out(str(e))
    log.out(traceback.format_exc())
    exitCode = 1 
return exitCode

Now the output from this shows all traceback and python exceptions for the sys.exit calls in the subprocess. Im actually logging all errors so I dont want anything being displayed in the command prompt unless ive printed it manually. I'm not quite sure how to go about this.


Solution

  • You can specify stderr to write to os.devnull with the subprocess.DEVNULL flag:

    p = Popen(['python', '-c', 'print(1/0)'], stderr=subprocess.DEVNULL)

    subprocess.DEVNULL Special value that can be used as the stdin, stdout or stderr argument to Popen and indicates that the special file os.devnull will be used.

    New in version 3.3. docs