duffsterlp
duffsterlp

Reputation: 377

Suppress Python printout

I'm embedding Python in a C++ application (using the Python C API) and I want Python exceptions that are thrown to be handled by an exception handler mechanism that is already setup in C++. This exception handler mechanism will print out the exception itself, so I don't want the embedded Python interpreter to print it to screen. Can I setup the embedded Python interpreter to suppress console output in some way?

Upvotes: 1

Views: 993

Answers (2)

Colin O'Coal
Colin O'Coal

Reputation: 1427

You can plug a Stub-Streamhandler to both the standard out and standard error channels in python.

Here a sample (inclusive revoicing both channels):

import sys
import cStringIO

print("Silencing stdout and stderr")
_stdout = sys.stdout
_stderr = sys.stderr
sys.stdout = cStringIO.StringIO()
sys.stderr = cStringIO.StringIO()

print("This should not be printed out")

sys.stdout = _stdout
sys.stderr = _stderr

print("Revoiced stdout and stderr")

Running this sample should results in following output:

Silencing stdout and stderr
Revoiced stdout and stderr

[UPDATED]

And here the memory-saving variant with sending to devnull:

import os, sys
with open(os.devnull, 'w') as devnull:
    sys.stdout = devnull
    sys.stderr = devnull
    # ... here your code

Upvotes: 4

Sven
Sven

Reputation: 720

How did you execute the code? If an exception is not catched and printed by python directly (someone has installed an handler in python directly) it will be set to the exception handling and then the exception can be examined using C (see section Exception Handling in the reference manual).

If you call the python script from C-code, the calling function will return NULL or -1 (exception has occured) and now you can use the above stated API to read the exception (for e.g. PyErr_Occurred(),... ).

But if the things are done by the python code itself (if someone installed a hook or something inside its code and prints it directly), you have no change to catch things easily. Maybe you can add a hook by yourself, calling your code. This can be done via sys.excepthook(type, value, traceback) and one solution would be to find the position and remove it from the code or have a look at other methods to circumvent it.

This site is very informative about it: Python API/include files

Edit: For redirecting stdout or stderr you can use the C-Api function:

FILE* sto = fopen("out.txt", "w+");
FILE* ste = fopen("outErr.txt", "w+");
PySys_SetObject("stdout", PyFile_FromFile(sto, "out.txt","wb", fclose)); 
PySys_SetObject("stderr", PyFile_FromFile(ste, "outErr.txt","wb", fclose)); 

before calling any other python code. PyFile_FromFile maybe also replaced by something else, I think, but I have not used this so far.

Upvotes: 0

Related Questions