Redirecting stderr for extension modules

Michael Pyle mpyle at legato.com
Thu May 15 11:45:05 EDT 2003


I've been trying to find a way to redirect the stderr output of a function
in a C extension module. What I'd like to create is a function that can take
a callable and capture any output to stderr that results from the execution
of that callable. It then returns the result of the execution and the stderr
text as a tuple. It seems like this should be pretty straight forward, but
after a day or so of scratching my head I just can't seem to get it to work.

Here's what I have:

def Redirect( fn, *args, **kwds ):
    """
    Redirect( fn, ... ) -> (fn return value, stderr)
    
    Captures any text written to stderr from the execution of fn. fn 
    is expected to be an extension module function.
    """
    fd = os.dup( 2 )
    if fd != -1:
        try:
            file = open( 'stderr.txt', 'w+' )
            os.dup2( file.fileno(), 2 )
        except:
            file = None
        
    stderr = None
    try:
        result = fn( *args, **kwds )
        return result, stderr
    finally:
        if file:
            file.flush()
            file.seek( 0, 0 )
            stderr = file.read()
            file.close()
        
        if fd != -1:
            os.dup2( fd, 2 )


Here's the result of executing this on an extension function that only
writes some text to stderr (using fprintf) and then returns None:

>>> from util import Redirect
[51293 refs]
>>> from libs import legato
[51295 refs]
>>> Redirect( legato.stderr )
(None, None)
This is not a drill! Yes it is!
[51404 refs]
>>>^Z

The interesting thing is that stderr.txt is empty, which means that my
stderr result is None and yet once I close my redirection file and reset the
stderr file descriptor, the text I wrote out appears. Can someone please
give me a boot to the head and point out where I've gone wrong?

Thanks.

--Mike Pyle
--Legato Systems, Inc.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20030515/59c45ccc/attachment.html>


More information about the Python-list mailing list