just thought I'd add my idea... suited my purposes of being able to run sthg in Eclipse and then run from the (Windows) CLI without getting encoding exceptions with each print statement.
Whatever you do don't make EncodingStdout a subclass of class file: the line "self.encoding = encoding" would then result in the encoding attribute being None!
NB one thing I found out during a day grappling with this stuff is that the encoding exception gets raised BEFORE getting to "print" or "write": it is when the parameterised string (i.e. "mondodod %s blah blah %s" % ( "blip", "blap" )) is constructed by... what??? the "framework"?
class EncodingStdout( object ):
def __init__( self, encoding='utf-8' ):
self.encoding = encoding
def write_ln( self, *args ):
if len( args ) < 2:
sys.__stdout__.write( args[ 0 ] + '\n' )
else:
if not isinstance( args[ 0 ], basestring ):
raise Exception( "first arg was %s, type %s" % ( args[ 0 ], type( args[ 0 ]) ))
# if the default encoding is UTF-8 don't bother with encoding
if sys.getdefaultencoding() != 'utf-8':
encoded_args = [ args[ 0 ] ]
for i in range( 1, len( args )):
# numbers (for example) do not have an attribute "encode"
if hasattr( args[ i ], 'encode' ):
encoded_args.append( args[ i ].encode( self.encoding, 'replace' ) )
else:
encoded_args.append( args[ i ])
args = encoded_args
sys.__stdout__.write( args[ 0 ] % tuple( args[ 1 : ] ) + '\n' )
# write seems to need a flush
sys.__stdout__.flush()
def __getattr__( self, name ):
return sys.__stdout__.__getattribute__( name )
print "=== A mondodod %s %s" % ( "été", "pluviôse, irritée contre la ville entière" )
sys.stdout = EncodingStdout()
sys.stdout.write_ln( "=== B mondodod %s %s", "été", "pluviôse, irritée contre la ville entière" )
# convenience method
def pr( *args ):
sys.stdout.write_ln( *args )
pr( "=== C mondodod %s %s", "été", "pluviôse, irritée contre la ville entière" )