Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/IPython/core/crashhandler.py: 27%

73 statements  

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

1# encoding: utf-8 

2"""sys.excepthook for IPython itself, leaves a detailed report on disk. 

3 

4Authors: 

5 

6* Fernando Perez 

7* Brian E. Granger 

8""" 

9 

10#----------------------------------------------------------------------------- 

11# Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu> 

12# Copyright (C) 2008-2011 The IPython Development Team 

13# 

14# Distributed under the terms of the BSD License. The full license is in 

15# the file COPYING, distributed as part of this software. 

16#----------------------------------------------------------------------------- 

17 

18#----------------------------------------------------------------------------- 

19# Imports 

20#----------------------------------------------------------------------------- 

21 

22import sys 

23import traceback 

24from pprint import pformat 

25from pathlib import Path 

26 

27from IPython.core import ultratb 

28from IPython.core.release import author_email 

29from IPython.utils.sysinfo import sys_info 

30from IPython.utils.py3compat import input 

31 

32from IPython.core.release import __version__ as version 

33 

34from typing import Optional 

35 

36#----------------------------------------------------------------------------- 

37# Code 

38#----------------------------------------------------------------------------- 

39 

40# Template for the user message. 

41_default_message_template = """\ 

42Oops, {app_name} crashed. We do our best to make it stable, but... 

43 

44A crash report was automatically generated with the following information: 

45 - A verbatim copy of the crash traceback. 

46 - A copy of your input history during this session. 

47 - Data on your current {app_name} configuration. 

48 

49It was left in the file named: 

50\t'{crash_report_fname}' 

51If you can email this file to the developers, the information in it will help 

52them in understanding and correcting the problem. 

53 

54You can mail it to: {contact_name} at {contact_email} 

55with the subject '{app_name} Crash Report'. 

56 

57If you want to do it now, the following command will work (under Unix): 

58mail -s '{app_name} Crash Report' {contact_email} < {crash_report_fname} 

59 

60In your email, please also include information about: 

61- The operating system under which the crash happened: Linux, macOS, Windows, 

62 other, and which exact version (for example: Ubuntu 16.04.3, macOS 10.13.2, 

63 Windows 10 Pro), and whether it is 32-bit or 64-bit; 

64- How {app_name} was installed: using pip or conda, from GitHub, as part of 

65 a Docker container, or other, providing more detail if possible; 

66- How to reproduce the crash: what exact sequence of instructions can one 

67 input to get the same crash? Ideally, find a minimal yet complete sequence 

68 of instructions that yields the crash. 

69 

70To ensure accurate tracking of this issue, please file a report about it at: 

71{bug_tracker} 

72""" 

73 

74_lite_message_template = """ 

75If you suspect this is an IPython {version} bug, please report it at: 

76 https://github.com/ipython/ipython/issues 

77or send an email to the mailing list at {email} 

78 

79You can print a more detailed traceback right now with "%tb", or use "%debug" 

80to interactively debug it. 

81 

82Extra-detailed tracebacks for bug-reporting purposes can be enabled via: 

83 {config}Application.verbose_crash=True 

84""" 

85 

86 

87class CrashHandler(object): 

88 """Customizable crash handlers for IPython applications. 

89 

90 Instances of this class provide a :meth:`__call__` method which can be 

91 used as a ``sys.excepthook``. The :meth:`__call__` signature is:: 

92 

93 def __call__(self, etype, evalue, etb) 

94 """ 

95 

96 message_template = _default_message_template 

97 section_sep = '\n\n'+'*'*75+'\n\n' 

98 

99 def __init__( 

100 self, 

101 app, 

102 contact_name: Optional[str] = None, 

103 contact_email: Optional[str] = None, 

104 bug_tracker: Optional[str] = None, 

105 show_crash_traceback: bool = True, 

106 call_pdb: bool = False, 

107 ): 

108 """Create a new crash handler 

109 

110 Parameters 

111 ---------- 

112 app : Application 

113 A running :class:`Application` instance, which will be queried at 

114 crash time for internal information. 

115 contact_name : str 

116 A string with the name of the person to contact. 

117 contact_email : str 

118 A string with the email address of the contact. 

119 bug_tracker : str 

120 A string with the URL for your project's bug tracker. 

121 show_crash_traceback : bool 

122 If false, don't print the crash traceback on stderr, only generate 

123 the on-disk report 

124 call_pdb 

125 Whether to call pdb on crash 

126 

127 Attributes 

128 ---------- 

129 These instances contain some non-argument attributes which allow for 

130 further customization of the crash handler's behavior. Please see the 

131 source for further details. 

132 

133 """ 

134 self.crash_report_fname = "Crash_report_%s.txt" % app.name 

135 self.app = app 

136 self.call_pdb = call_pdb 

137 #self.call_pdb = True # dbg 

138 self.show_crash_traceback = show_crash_traceback 

139 self.info = dict(app_name = app.name, 

140 contact_name = contact_name, 

141 contact_email = contact_email, 

142 bug_tracker = bug_tracker, 

143 crash_report_fname = self.crash_report_fname) 

144 

145 

146 def __call__(self, etype, evalue, etb): 

147 """Handle an exception, call for compatible with sys.excepthook""" 

148 

149 # do not allow the crash handler to be called twice without reinstalling it 

150 # this prevents unlikely errors in the crash handling from entering an 

151 # infinite loop. 

152 sys.excepthook = sys.__excepthook__ 

153 

154 # Report tracebacks shouldn't use color in general (safer for users) 

155 color_scheme = 'NoColor' 

156 

157 # Use this ONLY for developer debugging (keep commented out for release) 

158 #color_scheme = 'Linux' # dbg 

159 try: 

160 rptdir = self.app.ipython_dir 

161 except: 

162 rptdir = Path.cwd() 

163 if rptdir is None or not Path.is_dir(rptdir): 

164 rptdir = Path.cwd() 

165 report_name = rptdir / self.crash_report_fname 

166 # write the report filename into the instance dict so it can get 

167 # properly expanded out in the user message template 

168 self.crash_report_fname = report_name 

169 self.info['crash_report_fname'] = report_name 

170 TBhandler = ultratb.VerboseTB( 

171 color_scheme=color_scheme, 

172 long_header=1, 

173 call_pdb=self.call_pdb, 

174 ) 

175 if self.call_pdb: 

176 TBhandler(etype,evalue,etb) 

177 return 

178 else: 

179 traceback = TBhandler.text(etype,evalue,etb,context=31) 

180 

181 # print traceback to screen 

182 if self.show_crash_traceback: 

183 print(traceback, file=sys.stderr) 

184 

185 # and generate a complete report on disk 

186 try: 

187 report = open(report_name, "w", encoding="utf-8") 

188 except: 

189 print('Could not create crash report on disk.', file=sys.stderr) 

190 return 

191 

192 with report: 

193 # Inform user on stderr of what happened 

194 print('\n'+'*'*70+'\n', file=sys.stderr) 

195 print(self.message_template.format(**self.info), file=sys.stderr) 

196 

197 # Construct report on disk 

198 report.write(self.make_report(traceback)) 

199 

200 input("Hit <Enter> to quit (your terminal may close):") 

201 

202 def make_report(self,traceback): 

203 """Return a string containing a crash report.""" 

204 

205 sec_sep = self.section_sep 

206 

207 report = ['*'*75+'\n\n'+'IPython post-mortem report\n\n'] 

208 rpt_add = report.append 

209 rpt_add(sys_info()) 

210 

211 try: 

212 config = pformat(self.app.config) 

213 rpt_add(sec_sep) 

214 rpt_add('Application name: %s\n\n' % self.app_name) 

215 rpt_add('Current user configuration structure:\n\n') 

216 rpt_add(config) 

217 except: 

218 pass 

219 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback) 

220 

221 return ''.join(report) 

222 

223 

224def crash_handler_lite(etype, evalue, tb): 

225 """a light excepthook, adding a small message to the usual traceback""" 

226 traceback.print_exception(etype, evalue, tb) 

227 

228 from IPython.core.interactiveshell import InteractiveShell 

229 if InteractiveShell.initialized(): 

230 # we are in a Shell environment, give %magic example 

231 config = "%config " 

232 else: 

233 # we are not in a shell, show generic config 

234 config = "c." 

235 print(_lite_message_template.format(email=author_email, config=config, version=version), file=sys.stderr) 

236