Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/IPython/core/magics/logging.py: 28%

65 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-20 06:09 +0000

1"""Implementation of magic functions for IPython's own logging. 

2""" 

3#----------------------------------------------------------------------------- 

4# Copyright (c) 2012 The IPython Development Team. 

5# 

6# Distributed under the terms of the Modified BSD License. 

7# 

8# The full license is in the file COPYING.txt, distributed with this software. 

9#----------------------------------------------------------------------------- 

10 

11#----------------------------------------------------------------------------- 

12# Imports 

13#----------------------------------------------------------------------------- 

14 

15# Stdlib 

16import os 

17import sys 

18 

19# Our own packages 

20from IPython.core.magic import Magics, magics_class, line_magic 

21from warnings import warn 

22from traitlets import Bool 

23 

24#----------------------------------------------------------------------------- 

25# Magic implementation classes 

26#----------------------------------------------------------------------------- 

27 

28@magics_class 

29class LoggingMagics(Magics): 

30 """Magics related to all logging machinery.""" 

31 

32 quiet = Bool(False, help= 

33 """ 

34 Suppress output of log state when logging is enabled 

35 """ 

36 ).tag(config=True) 

37 

38 @line_magic 

39 def logstart(self, parameter_s=''): 

40 """Start logging anywhere in a session. 

41 

42 %logstart [-o|-r|-t|-q] [log_name [log_mode]] 

43 

44 If no name is given, it defaults to a file named 'ipython_log.py' in your 

45 current directory, in 'rotate' mode (see below). 

46 

47 '%logstart name' saves to file 'name' in 'backup' mode. It saves your 

48 history up to that point and then continues logging. 

49 

50 %logstart takes a second optional parameter: logging mode. This can be one 

51 of (note that the modes are given unquoted): 

52 

53 append 

54 Keep logging at the end of any existing file. 

55 

56 backup 

57 Rename any existing file to name~ and start name. 

58 

59 global 

60 Append to a single logfile in your home directory. 

61 

62 over 

63 Overwrite any existing log. 

64 

65 rotate 

66 Create rotating logs: name.1~, name.2~, etc. 

67 

68 Options: 

69 

70 -o 

71 log also IPython's output. In this mode, all commands which 

72 generate an Out[NN] prompt are recorded to the logfile, right after 

73 their corresponding input line. The output lines are always 

74 prepended with a '#[Out]# ' marker, so that the log remains valid 

75 Python code. 

76 

77 Since this marker is always the same, filtering only the output from 

78 a log is very easy, using for example a simple awk call:: 

79 

80 awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py 

81 

82 -r 

83 log 'raw' input. Normally, IPython's logs contain the processed 

84 input, so that user lines are logged in their final form, converted 

85 into valid Python. For example, %Exit is logged as 

86 _ip.magic("Exit"). If the -r flag is given, all input is logged 

87 exactly as typed, with no transformations applied. 

88 

89 -t 

90 put timestamps before each input line logged (these are put in 

91 comments). 

92 

93 -q  

94 suppress output of logstate message when logging is invoked 

95 """ 

96 

97 opts,par = self.parse_options(parameter_s,'ortq') 

98 log_output = 'o' in opts 

99 log_raw_input = 'r' in opts 

100 timestamp = 't' in opts 

101 quiet = 'q' in opts 

102 

103 logger = self.shell.logger 

104 

105 # if no args are given, the defaults set in the logger constructor by 

106 # ipython remain valid 

107 if par: 

108 try: 

109 logfname,logmode = par.split() 

110 except: 

111 logfname = par 

112 logmode = 'backup' 

113 else: 

114 logfname = logger.logfname 

115 logmode = logger.logmode 

116 # put logfname into rc struct as if it had been called on the command 

117 # line, so it ends up saved in the log header Save it in case we need 

118 # to restore it... 

119 old_logfile = self.shell.logfile 

120 if logfname: 

121 logfname = os.path.expanduser(logfname) 

122 self.shell.logfile = logfname 

123 

124 loghead = u'# IPython log file\n\n' 

125 try: 

126 logger.logstart(logfname, loghead, logmode, log_output, timestamp, 

127 log_raw_input) 

128 except: 

129 self.shell.logfile = old_logfile 

130 warn("Couldn't start log: %s" % sys.exc_info()[1]) 

131 else: 

132 # log input history up to this point, optionally interleaving 

133 # output if requested 

134 

135 if timestamp: 

136 # disable timestamping for the previous history, since we've 

137 # lost those already (no time machine here). 

138 logger.timestamp = False 

139 

140 if log_raw_input: 

141 input_hist = self.shell.history_manager.input_hist_raw 

142 else: 

143 input_hist = self.shell.history_manager.input_hist_parsed 

144 

145 if log_output: 

146 log_write = logger.log_write 

147 output_hist = self.shell.history_manager.output_hist 

148 for n in range(1,len(input_hist)-1): 

149 log_write(input_hist[n].rstrip() + u'\n') 

150 if n in output_hist: 

151 log_write(repr(output_hist[n]),'output') 

152 else: 

153 logger.log_write(u'\n'.join(input_hist[1:])) 

154 logger.log_write(u'\n') 

155 if timestamp: 

156 # re-enable timestamping 

157 logger.timestamp = True 

158 

159 if not (self.quiet or quiet): 

160 print ('Activating auto-logging. ' 

161 'Current session state plus future input saved.') 

162 logger.logstate() 

163 

164 @line_magic 

165 def logstop(self, parameter_s=''): 

166 """Fully stop logging and close log file. 

167 

168 In order to start logging again, a new %logstart call needs to be made, 

169 possibly (though not necessarily) with a new filename, mode and other 

170 options.""" 

171 self.shell.logger.logstop() 

172 

173 @line_magic 

174 def logoff(self, parameter_s=''): 

175 """Temporarily stop logging. 

176 

177 You must have previously started logging.""" 

178 self.shell.logger.switch_log(0) 

179 

180 @line_magic 

181 def logon(self, parameter_s=''): 

182 """Restart logging. 

183 

184 This function is for restarting logging which you've temporarily 

185 stopped with %logoff. For starting logging for the first time, you 

186 must use the %logstart function, which allows you to specify an 

187 optional log filename.""" 

188 

189 self.shell.logger.switch_log(1) 

190 

191 @line_magic 

192 def logstate(self, parameter_s=''): 

193 """Print the status of the logging system.""" 

194 

195 self.shell.logger.logstate()