[Tutor] logging to cmd.exe

Albert-Jan Roskam sjeik_appie at hotmail.com
Tue Sep 26 07:26:40 EDT 2017


 From: Tutor <tutor-bounces+sjeik_appie=hotmail.com at python.org> on behalf of Peter Otten <__peter__ at web.de>
 Sent: Monday, September 25, 2017 2:59 PM
 To: tutor at python.org
 Subject: Re: [Tutor] logging to cmd.exe
     
 Albert-Jan Roskam wrote:

 > Hi,
 > 
 > 
 > With Python 3.5 under Windows I am using the logging module to log
 > messages to stdout (and to a file), but this occasionally causes logging
 > errors because some characters cannot be represented in the codepage used
 > by cmd.exe (cp850, aka OEM codepage, I think). What is the best way to
 > prevent this from happening? The program runs fine, but the error is
 > distracting. I know I can use s.encode(sys.stdout.encoding, 'replace') and
 > log that, but this is ugly and tedious to do when there are many log
 > messages. I also don't understand why %r (instead of %s) still causes an
 > error. I thought that the character representation uses only ascii
 > characters?!

 Not in Python 3. You can enforce ascii with "%a":

 >>> euro = '\u20ac'
 >>> print("%r" % euro)
 '€'
 >>> print("%a" % euro)
 '\u20ac'



 ========> aaahh, I did not know about %a. Thank you! 


 Or you can set an error handler with PYTHONIOENCODING (I have to use 
 something that is not utf-8-encodable for the demo):

 $ python3 -c 'print("\udc85")'
 Traceback (most recent call last):
   File "<string>", line 1, in <module>
 UnicodeEncodeError: 'utf-8' codec can't encode character '\udc85' in 
 position 0: surrogates not allowed

 $ PYTHONIOENCODING=:backslashreplace python3 -c 'print("\udc85")'
 \udc85


 ========> Nice to know about this variable, though I prefer not to change the environment because other will need to do the same. 
 For others who would like to read more: https://docs.python.org/3/using/cmdline.html


 Or you follow the convention and log to stderr:

 $ python3 -c 'import sys; print("\udc85", file=sys.stderr)'
 \udc85
 $ $ python3 -c 'import logging; logging.basicConfig(); 
 logging.getLogger().warn("\udc85")' > to_prove_it_s_not_stdout
 WARNING:root:\udc85


 ========> That's perhaps the best choice. But will messages with logging level warning and lower also be logged to stderr?



More information about the Tutor mailing list