I am calling a function in a java library from jython which prints to stdout. I would like to suppress this output from the jython script. I attempt the python idiom replacing sys.stdout with a file like object (StringIO), but this does not capture the output of the java library. I'm guessing sys.stdout does not affect the java program. Is there a standard convention for redirecting or suppressing this output programatically in jython? If not what ways can I accomplish this?
2 Answers
You can use System.setOut, like this:
>>> from java.lang import System >>> from java.io import PrintStream, OutputStream >>> oldOut = System.out >>> class NoOutputStream(OutputStream): ... def write(self, b, off, len): pass ... >>> System.setOut(PrintStream(NoOutputStream())) >>> System.out.println('foo') >>> System.setOut(oldOut) >>> System.out.println('foo') foo Note that this won't affect Python output, because Jython grabs System.out when it starts up so you can reassign sys.stdout as you'd expect.
Comments
I've created a context manager to mimic (Python3's) contextlib's redirect_stdout (gist here):
'''Wouldn't it be nice if sys.stdout knew how to redirect the JVM's stdout? Shooting star. Author: Sean Summers <[email protected]> 2015-09-28 v0.1 Permalink: https://gist.githubusercontent.com/seansummers/bbfe021e83935b3db01d/raw/redirect_java_stdout.py ''' from java import io, lang from contextlib import contextmanager @contextmanager def redirect_stdout(new_target): ''' Context manager for temporarily redirecting sys.stdout to another file or file-like object see contextlib.redirect_stdout documentation for usage ''' # file objects aren't java.io.File objects... if isinstance(new_target, file): new_target.close() new_target = io.PrintStream(new_target.name) old_target, target = lang.System.out, new_target try: lang.System.setOut(target) yield None finally: lang.System.setOut(old_target)