<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<TITLE>Message</TITLE>

<META content="MSHTML 6.00.2600.0" name=GENERATOR></HEAD>
<BODY>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN class=078341316-15052003>An 
update and a little enlightment. It appears that modifications made to a 
variable made inside of a finally clause are not retained outside of the clause? 
When I move the flush, seek and read to just below the fn() execution call, the 
stderr text appears in my stderr. Or at least it does on Solaris. On Windows the 
text never actually makes it into the stderr.txt file to begin 
with.</SPAN></FONT></DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN 
class=078341316-15052003></SPAN></FONT> </DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN 
class=078341316-15052003>--Mike</SPAN></FONT></DIV>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
  <DIV></DIV>
  <DIV class=OutlookMessageHeader lang=en-us dir=ltr align=left><FONT 
  face=Tahoma size=2>-----Original Message-----<BR><B>From:</B> Michael Pyle 
  [mailto:mpyle@legato.com] <BR><B>Sent:</B> Thursday, May 15, 2003 8:45 
  AM<BR><B>To:</B> 'python-list@python.org'<BR><B>Subject:</B> Redirecting 
  stderr for extension modules<BR><BR></FONT></DIV>
  <P><FONT size=2>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.</FONT></P>
  <P><FONT size=2>Here's what I have:</FONT> </P>
  <P><FONT size=2>def Redirect( fn, *args, **kwds ):</FONT> <BR><FONT 
  size=2>    """</FONT> <BR><FONT size=2>    
  Redirect( fn, ... ) -> (fn return value, stderr)</FONT> <BR><FONT 
  size=2>    </FONT><BR><FONT size=2>    Captures 
  any text written to stderr from the execution of fn. fn </FONT><BR><FONT 
  size=2>    is expected to be an extension module 
  function.</FONT> <BR><FONT size=2>    """</FONT> <BR><FONT 
  size=2>    fd = os.dup( 2 )</FONT> <BR><FONT 
  size=2>    if fd != -1:</FONT> <BR><FONT 
  size=2>        try:</FONT> <BR><FONT 
  size=2>            file 
  = open( 'stderr.txt', 'w+' )</FONT> <BR><FONT 
  size=2>            
  os.dup2( file.fileno(), 2 )</FONT> <BR><FONT 
  size=2>        except:</FONT> <BR><FONT 
  size=2>            file 
  = None</FONT> <BR><FONT size=2>        
  </FONT><BR><FONT size=2>    stderr = None</FONT> <BR><FONT 
  size=2>    try:</FONT> <BR><FONT 
  size=2>        result = fn( *args, **kwds 
  )</FONT> <BR><FONT size=2>        return 
  result, stderr</FONT> <BR><FONT size=2>    finally:</FONT> 
  <BR><FONT size=2>        if file:</FONT> 
  <BR><FONT 
  size=2>            
  file.flush()</FONT> <BR><FONT 
  size=2>            
  file.seek( 0, 0 )</FONT> <BR><FONT 
  size=2>            
  stderr = file.read()</FONT> <BR><FONT 
  size=2>            
  file.close()</FONT> <BR><FONT 
  size=2>        </FONT><BR><FONT 
  size=2>        if fd != -1:</FONT> 
  <BR><FONT 
  size=2>            
  os.dup2( fd, 2 )</FONT> </P></BLOCKQUOTE></BODY></HTML>