Redirecting FORTRAN (called via F2PY) output in Python
The stdin and stdout fds are being inherited by the C shared library.
from fortran_code import fortran_functionimport osprint "will run fortran function!"# open 2 fdsnull_fds = [os.open(os.devnull, os.O_RDWR) for x in xrange(2)]# save the current file descriptors to a tuplesave = os.dup(1), os.dup(2)# put /dev/null fds on 1 and 2os.dup2(null_fds[0], 1)os.dup2(null_fds[1], 2)# *** run the function ***fortran_function()# restore file descriptors so I can print the resultsos.dup2(save[0], 1)os.dup2(save[1], 2)# close the temporary fdsos.close(null_fds[0])os.close(null_fds[1])print "done!"
Here's a context manager that I recently wrote and found useful, because I was having a similar problem with distutils.ccompiler.CCompiler.has_function
while working on pymssql. I also used the file descriptor approach but I used a context manager. Here's what I came up with:
import contextlib@contextlib.contextmanagerdef stdchannel_redirected(stdchannel, dest_filename): """ A context manager to temporarily redirect stdout or stderr e.g.: with stdchannel_redirected(sys.stderr, os.devnull): if compiler.has_function('clock_gettime', libraries=['rt']): libraries.append('rt') """ try: oldstdchannel = os.dup(stdchannel.fileno()) dest_file = open(dest_filename, 'w') os.dup2(dest_file.fileno(), stdchannel.fileno()) yield finally: if oldstdchannel is not None: os.dup2(oldstdchannel, stdchannel.fileno()) if dest_file is not None: dest_file.close()
The context for why I created this is at this blog post. Similar to yours I think.
I use it like this in a setup.py
:
with stdchannel_redirected(sys.stderr, os.devnull): if compiler.has_function('clock_gettime', libraries=['rt']): libraries.append('rt')