##// END OF EJS Templates
crashhandler: Cast rptdir to Path (#14578)...
M Bussonnier -
r28963:d7eebae4 merge
parent child Browse files
Show More
@@ -24,14 +24,17 b' import traceback'
24 from pprint import pformat
24 from pprint import pformat
25 from pathlib import Path
25 from pathlib import Path
26
26
27 import builtins as builtin_mod
28
27 from IPython.core import ultratb
29 from IPython.core import ultratb
30 from IPython.core.application import Application
28 from IPython.core.release import author_email
31 from IPython.core.release import author_email
29 from IPython.utils.sysinfo import sys_info
32 from IPython.utils.sysinfo import sys_info
30 from IPython.utils.py3compat import input
31
33
32 from IPython.core.release import __version__ as version
34 from IPython.core.release import __version__ as version
33
35
34 from typing import Optional
36 from typing import Optional, Dict
37 import types
35
38
36 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
37 # Code
40 # Code
@@ -84,7 +87,7 b' Extra-detailed tracebacks for bug-reporting purposes can be enabled via:'
84 """
87 """
85
88
86
89
87 class CrashHandler(object):
90 class CrashHandler:
88 """Customizable crash handlers for IPython applications.
91 """Customizable crash handlers for IPython applications.
89
92
90 Instances of this class provide a :meth:`__call__` method which can be
93 Instances of this class provide a :meth:`__call__` method which can be
@@ -95,10 +98,11 b' class CrashHandler(object):'
95
98
96 message_template = _default_message_template
99 message_template = _default_message_template
97 section_sep = '\n\n'+'*'*75+'\n\n'
100 section_sep = '\n\n'+'*'*75+'\n\n'
101 info: Dict[str, Optional[str]]
98
102
99 def __init__(
103 def __init__(
100 self,
104 self,
101 app,
105 app: Application,
102 contact_name: Optional[str] = None,
106 contact_name: Optional[str] = None,
103 contact_email: Optional[str] = None,
107 contact_email: Optional[str] = None,
104 bug_tracker: Optional[str] = None,
108 bug_tracker: Optional[str] = None,
@@ -142,10 +146,14 b' class CrashHandler(object):'
142 bug_tracker = bug_tracker,
146 bug_tracker = bug_tracker,
143 crash_report_fname = self.crash_report_fname)
147 crash_report_fname = self.crash_report_fname)
144
148
145
149 def __call__(
146 def __call__(self, etype, evalue, etb):
150 self,
151 etype: type[BaseException],
152 evalue: BaseException,
153 etb: types.TracebackType,
154 ) -> None:
147 """Handle an exception, call for compatible with sys.excepthook"""
155 """Handle an exception, call for compatible with sys.excepthook"""
148
156
149 # do not allow the crash handler to be called twice without reinstalling it
157 # 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
158 # this prevents unlikely errors in the crash handling from entering an
151 # infinite loop.
159 # infinite loop.
@@ -155,21 +163,23 b' class CrashHandler(object):'
155 color_scheme = 'NoColor'
163 color_scheme = 'NoColor'
156
164
157 # Use this ONLY for developer debugging (keep commented out for release)
165 # Use this ONLY for developer debugging (keep commented out for release)
158 #color_scheme = 'Linux' # dbg
166 # color_scheme = 'Linux' # dbg
159 try:
167 ipython_dir = getattr(self.app, "ipython_dir", None)
160 rptdir = self.app.ipython_dir
168 if ipython_dir is not None:
161 except:
169 assert isinstance(ipython_dir, str)
170 rptdir = Path(ipython_dir)
171 else:
162 rptdir = Path.cwd()
172 rptdir = Path.cwd()
163 if rptdir is None or not Path.is_dir(rptdir):
173 if not rptdir.is_dir():
164 rptdir = Path.cwd()
174 rptdir = Path.cwd()
165 report_name = rptdir / self.crash_report_fname
175 report_name = rptdir / self.crash_report_fname
166 # write the report filename into the instance dict so it can get
176 # write the report filename into the instance dict so it can get
167 # properly expanded out in the user message template
177 # properly expanded out in the user message template
168 self.crash_report_fname = report_name
178 self.crash_report_fname = str(report_name)
169 self.info['crash_report_fname'] = report_name
179 self.info["crash_report_fname"] = str(report_name)
170 TBhandler = ultratb.VerboseTB(
180 TBhandler = ultratb.VerboseTB(
171 color_scheme=color_scheme,
181 color_scheme=color_scheme,
172 long_header=1,
182 long_header=True,
173 call_pdb=self.call_pdb,
183 call_pdb=self.call_pdb,
174 )
184 )
175 if self.call_pdb:
185 if self.call_pdb:
@@ -195,11 +205,11 b' class CrashHandler(object):'
195 print(self.message_template.format(**self.info), file=sys.stderr)
205 print(self.message_template.format(**self.info), file=sys.stderr)
196
206
197 # Construct report on disk
207 # Construct report on disk
198 report.write(self.make_report(traceback))
208 report.write(self.make_report(str(traceback)))
199
209
200 input("Hit <Enter> to quit (your terminal may close):")
210 builtin_mod.input("Hit <Enter> to quit (your terminal may close):")
201
211
202 def make_report(self,traceback):
212 def make_report(self, traceback: str) -> str:
203 """Return a string containing a crash report."""
213 """Return a string containing a crash report."""
204
214
205 sec_sep = self.section_sep
215 sec_sep = self.section_sep
@@ -211,8 +221,8 b' class CrashHandler(object):'
211 try:
221 try:
212 config = pformat(self.app.config)
222 config = pformat(self.app.config)
213 rpt_add(sec_sep)
223 rpt_add(sec_sep)
214 rpt_add('Application name: %s\n\n' % self.app_name)
224 rpt_add("Application name: %s\n\n" % self.app.name)
215 rpt_add('Current user configuration structure:\n\n')
225 rpt_add("Current user configuration structure:\n\n")
216 rpt_add(config)
226 rpt_add(config)
217 except:
227 except:
218 pass
228 pass
@@ -221,7 +231,9 b' class CrashHandler(object):'
221 return ''.join(report)
231 return ''.join(report)
222
232
223
233
224 def crash_handler_lite(etype, evalue, tb):
234 def crash_handler_lite(
235 etype: type[BaseException], evalue: BaseException, tb: types.TracebackType
236 ) -> None:
225 """a light excepthook, adding a small message to the usual traceback"""
237 """a light excepthook, adding a small message to the usual traceback"""
226 traceback.print_exception(etype, evalue, tb)
238 traceback.print_exception(etype, evalue, tb)
227
239
@@ -99,7 +99,7 b' def get_sys_info() -> dict:'
99 path = Path(__file__, "..").resolve().parent
99 path = Path(__file__, "..").resolve().parent
100 return pkg_info(str(path))
100 return pkg_info(str(path))
101
101
102 def sys_info():
102 def sys_info() -> str:
103 """Return useful information about IPython and the system, as a string.
103 """Return useful information about IPython and the system, as a string.
104
104
105 Examples
105 Examples
@@ -137,17 +137,29 b' exclude = ['
137 'IPython/utils/_process_win32.py',
137 'IPython/utils/_process_win32.py',
138 'IPython/utils/path.py',
138 'IPython/utils/path.py',
139 ]
139 ]
140 disallow_untyped_defs = true
140 # check_untyped_defs = true
141 # disallow_untyped_calls = true
142 # disallow_untyped_decorators = true
141 # ignore_errors = false
143 # ignore_errors = false
142 # ignore_missing_imports = false
144 # ignore_missing_imports = false
143 # disallow_untyped_calls = true
144 disallow_incomplete_defs = true
145 disallow_incomplete_defs = true
145 # check_untyped_defs = true
146 disallow_untyped_defs = true
146 # disallow_untyped_decorators = true
147 warn_redundant_casts = true
147 warn_redundant_casts = true
148
148
149 [[tool.mypy.overrides]]
149 [[tool.mypy.overrides]]
150 module = [
150 module = [
151 "IPython.core.crashhandler",
152 ]
153 check_untyped_defs = true
154 disallow_incomplete_defs = true
155 disallow_untyped_calls = true
156 disallow_untyped_decorators = true
157 disallow_untyped_defs = true
158 ignore_errors = false
159 ignore_missing_imports = false
160
161 [[tool.mypy.overrides]]
162 module = [
151 "IPython.utils.text",
163 "IPython.utils.text",
152 ]
164 ]
153 disallow_untyped_defs = true
165 disallow_untyped_defs = true
@@ -165,6 +177,7 b' disallow_incomplete_defs = false'
165 check_untyped_defs = false
177 check_untyped_defs = false
166 disallow_untyped_decorators = false
178 disallow_untyped_decorators = false
167
179
180
168 # gloabl ignore error
181 # gloabl ignore error
169 [[tool.mypy.overrides]]
182 [[tool.mypy.overrides]]
170 module = [
183 module = [
@@ -177,7 +190,6 b' module = ['
177 "IPython.core.compilerop",
190 "IPython.core.compilerop",
178 "IPython.core.completer",
191 "IPython.core.completer",
179 "IPython.core.completerlib",
192 "IPython.core.completerlib",
180 "IPython.core.crashhandler",
181 "IPython.core.debugger",
193 "IPython.core.debugger",
182 "IPython.core.display",
194 "IPython.core.display",
183 "IPython.core.display_functions",
195 "IPython.core.display_functions",
General Comments 0
You need to be logged in to leave comments. Login now