From 0eeff21b64b38a8886a7d8294d390f2d6d6cb4f2 2012-05-30 21:05:01 From: Thomas Kluyver Date: 2012-05-30 21:05:01 Subject: [PATCH] Make logging unicode-aware Closes gh-1777 --- diff --git a/IPython/core/logger.py b/IPython/core/logger.py index 4bc162f..8a42dba 100644 --- a/IPython/core/logger.py +++ b/IPython/core/logger.py @@ -14,9 +14,12 @@ # Python standard modules import glob +import io import os import time +from IPython.utils.py3compat import str_to_unicode + #**************************************************************************** # FIXME: This class isn't a mixin anymore, but it still needs attributes from # ipython and does input cache management. Finish cleanup later... @@ -24,7 +27,7 @@ import time class Logger(object): """A Logfile class with different policies for file creation""" - def __init__(self, home_dir, logfname='Logger.log', loghead='', + def __init__(self, home_dir, logfname='Logger.log', loghead=u'', logmode='over'): # this is the full ipython instance, we need some attributes from it @@ -84,7 +87,7 @@ class Logger(object): logmode = self.logmode if logmode == 'append': - self.logfile = open(self.logfname,'a') + self.logfile = io.open(self.logfname, 'a', encoding='utf-8') elif logmode == 'backup': if isfile(self.logfname): @@ -94,16 +97,16 @@ class Logger(object): if isfile(backup_logname): os.remove(backup_logname) os.rename(self.logfname,backup_logname) - self.logfile = open(self.logfname,'w') + self.logfile = io.open(self.logfname, 'w', encoding='utf-8') elif logmode == 'global': self.logfname = os.path.join(self.home_dir,self.logfname) - self.logfile = open(self.logfname, 'a') + self.logfile = io.open(self.logfname, 'a', encoding='utf-8') elif logmode == 'over': if isfile(self.logfname): os.remove(self.logfname) - self.logfile = open(self.logfname,'w') + self.logfile = io.open(self.logfname,'w', encoding='utf-8') elif logmode == 'rotate': if isfile(self.logfname): @@ -116,7 +119,7 @@ class Logger(object): num = int(ext[1:-1])+1 os.rename(f, root+'.'+`num`.zfill(3)+'~') os.rename(self.logfname, self.logfname+'.001~') - self.logfile = open(self.logfname,'w') + self.logfile = io.open(self.logfname, 'w', encoding='utf-8') if logmode != 'append': self.logfile.write(self.loghead) @@ -190,13 +193,13 @@ which already exists. But you must first start the logging process with write = self.logfile.write if kind=='input': if self.timestamp: - write(time.strftime('# %a, %d %b %Y %H:%M:%S\n', - time.localtime())) + write(str_to_unicode(time.strftime('# %a, %d %b %Y %H:%M:%S\n', + time.localtime()))) write(data) elif kind=='output' and self.log_output: - odata = '\n'.join(['#[Out]# %s' % s + odata = u'\n'.join([u'#[Out]# %s' % s for s in data.splitlines()]) - write('%s\n' % odata) + write(u'%s\n' % odata) self.logfile.flush() def logstop(self): diff --git a/IPython/core/magics/logging.py b/IPython/core/magics/logging.py index 23b5567..b1e7b28 100644 --- a/IPython/core/magics/logging.py +++ b/IPython/core/magics/logging.py @@ -19,6 +19,7 @@ import sys # Our own packages from IPython.core.magic import Magics, magics_class, line_magic from IPython.utils.warn import warn +from IPython.utils.py3compat import str_to_unicode #----------------------------------------------------------------------------- # Magic implementation classes @@ -96,7 +97,7 @@ class LoggingMagics(Magics): logfname = os.path.expanduser(logfname) self.shell.logfile = logfname - loghead = '# IPython log file\n\n' + loghead = u'# IPython log file\n\n' try: logger.logstart(logfname, loghead, logmode, log_output, timestamp, log_raw_input) @@ -121,12 +122,12 @@ class LoggingMagics(Magics): log_write = logger.log_write output_hist = self.shell.history_manager.output_hist for n in range(1,len(input_hist)-1): - log_write(input_hist[n].rstrip() + '\n') + log_write(input_hist[n].rstrip() + u'\n') if n in output_hist: - log_write(repr(output_hist[n]),'output') + log_write(str_to_unicode(repr(output_hist[n])),'output') else: - logger.log_write('\n'.join(input_hist[1:])) - logger.log_write('\n') + logger.log_write(u'\n'.join(input_hist[1:])) + logger.log_write(u'\n') if timestamp: # re-enable timestamping logger.timestamp = True @@ -142,7 +143,7 @@ class LoggingMagics(Magics): In order to start logging again, a new %logstart call needs to be made, possibly (though not necessarily) with a new filename, mode and other options.""" - self.logger.logstop() + self.shell.logger.logstop() @line_magic def logoff(self, parameter_s=''):