[despammed] Re: redirect sys.stdout to C++ ?

Bengt Richter bokr at oz.net
Sat Dec 28 03:52:46 EST 2002


On Sat, 28 Dec 2002 02:52:33 +0100, =?ISO-8859-1?Q?Andr=E9_Jonsson?= <tatsujin at despammed.com> wrote:

>Tatsujin wrote:
>> Gr8!
>> I sorta figured that out for myself... though with a small variation:
>> 
>> import selfmademodule     // a module created by my application
>> class Logger:
>>     def __init__(self, source):
>>         self.source=source
>>     def write(self, data):
>>         selfmademodule.logwrite(self.source, data)
>> 
>> import sys
>> sys.stdout = Logger('stdout')
>> sys.stderr = Logger('stderr')
>> 
>> This is because the final destination of the output is not known from 
>> the python side of things.
>
>I got this working quite well... except for one snag I'm having diffculty in 
>understanding. It seems that only the first "output" has a trailing newline 
>character. This screws up the buffering in my application and I am unable to handle it.
>
>A small example. If I write:
>
>    >>> print '1'
>
>I get these calls back to my application:
>
>    logwrite("1")
>    logwrite("\n")
>
>It seem to split it up into two calls, but this is fine by me as I buffer the data 
>and flushes it on newline.
>
>But if I then, in the same session, again type:
>
>    >>> print '1'
>
>This time all that is called to my application is:
>
>    logwrite("1")
>
>...hm?
>
>My application get these calls solely from the above callback of the over-ridden 
>write() method. I've over-ridden all methods that a file object has, but they never 
>seem to be called by the interactive shell.
>
>Also this is not limited to just the 'print' command, also just forcing an error 
>produces the same effect, the newline character is missing the second attempt.
>
>The strange thing is that the behaviour is diffrent from the first outputs to the 
>following ones. Does anyone know why it is this way?
>
Some time ago I ran into (what I at least thought was) a bug in the use of softspace
in interactive mode. Perhaps your problem is related. See (posted 2002-07-16)

    http://groups.google.com/groups?selm=ah2887%24bpu%240%40216.39.172.122&output=gplain

Type help('print') to read some about softspace. (Note the quotes)

In summary, interactive mode output (echo of what you are typing etc)
does not disappear when you redirect sys.stdout, so there are two outputs going.
The bug is that the softspace logic for the interactive echo is (or was?)
apparently not properly separated.

Ok, I guess I ought to volunteer to re-test that:

Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.

 >>> class X:
 ...     def __init__(self): self.s=[]
 ...     def write(self,x): self.s.append(x)
 ...
 >>> import sys
 >>> oso=sys.stdout
 >>> sox=X() # experimental so
 >>> dir(sox)
 ['__doc__', '__init__', '__module__', 's', 'write']

Oops, in the previous test I did the dir(sox) after the next line. (It's ok
we don't need it).

 >>> sys.stdout = sox
 >>> print 'sox ss=%s'% (sox.softspace,),      <<--[1]
 >>> print 'sox ss=%s'% (sox.softspace,),      <<--[2]
 >>> def foo():
 ...     print 'from foo: sox ss=%s'% (sox.softspace,),  <<--[3]
 ...     print 'from foo: sox ss=%s'% (sox.softspace,),  <<--[4]
 ...
 >>> foo()
 >>> sys.stdout=oso
 >>> sox.s
 ['sox ss=0', '\n', 'sox ss=0', '\n', 'from foo: sox ss=0', ' ', 'from foo: sox ss=1', '\n']
 >>> print ''.join(sox.s)
 sox ss=0
 sox ss=0
 from foo: sox ss=0 from foo: sox ss=1

Note the difference in the output when [1] and [2] are done as interactive lines
which of course are printed to the interactive console with newlines at the end,
vs doing the exact same thing from a function at [3] and [4], where the interactive
newline doesn't come until after foo has been called and the foo call line is being printed.

I think this is still a bug. The statement echo to the console is a different output
than stdout, and therefore the line echo output should not touch sys.stdout.softspace.

But it apparently does. Whatever output file class instance is being used for interactive line echo
should also be used for softspace for _that_ output. E.g., a plain print (w/o trailing comma)
involves two newlines: one as data output, and one as the end of the echo of the print line itself.
It seems like this is not clearly distinguished internally somewhere.

Another way to see it is if you put prints on the same echoed line by using semicolons,
so that the interactive newline can't mess with softspace until the end:

 >>> class X:
 ...     def __init__(self): self.s=[]
 ...     def write(self,x): self.s.append(x)
 ...
 >>> import sys
 >>> oso=sys.stdout
 >>> sox=X()
 >>> sys.stdout = sox
 >>> print None,                          [1]
 >>> print None,                          [2]
 >>> print None,;print None,; print None  [3]
 >>> sys.stdout = oso
 >>> sox.s
 ['None', '\n', 'None', '\n', 'None', ' ', 'None', ' ', 'None', '\n']
  [1a]    [1b]  [2a]    [2b]  [3a]    [3b] [3c]    [3d] [3e]    [3f]

The [1b] and [2b] newlines should have been spaces preceding the next output,
not newlines after the preceding output.

I don't know if this is at the root of your problem, but it reminded me.

Regards,
Bengt Richter



More information about the Python-list mailing list