Redirecting FORTRAN (called via F2PY) output in Python Redirecting FORTRAN (called via F2PY) output in Python unix unix

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')