What do you mean by this? The print statement in 2.x does *not* bypass
sys.stdout. It may use other methods besides write (writeln perhaps)
but you can *definitely* override sys.stdout to capture the output
from print statements.
Suppose you want to implement a "tee" variant in Python: print output
should go to stdout and also to some file (with timestamp added, just to
be fancy). First attempt:
py> import sys
py> import time
py>
py> class tee(file):
.... def write(self, data):
.... file.write(self, '%s: %r\n' % (time.ctime(), data))
.... sys.__stdout__.write(data)
....
py> sys.stdout = tee('test.txt', 'w')
py> print "Hello world"
py> print "Bye"
py> ^Z
D:\TEMP>type test.txt
Hello world
Bye
Note:
- no output to stdout inside the interpreter
- no timestamp in the file
This modified version works fine:
py> class tee():
.... def __init__(self, filename, mode):
.... self.file = open(filename, mode)
.... def write(self, data):
.... self.file.write('%s: %r\n' % (time.ctime(), data))
.... sys.__stdout__.write(data)
What happened? When sys.stdout is an instance of some class inheriting
from file (that is, isinstance(sys.stdout, file) is true) then the print
statement ignores sys.stdout.write() completely -- instead it calls
directly some C stdio functions (fwrite).
The only way to influence 'print' is *not* to inherit from file in the
first place.
It's an optimization, sure. I guess it is there before inheriting from
builtin types was allowed (in such scenario, it's a perfectly valid
optimization). Now, perhaps the test for 'file' should be more strict,
only taking the C shortcut when using an actual file instance, not a
subclass of it. This would allow the example above to work correctly.