##// END OF EJS Templates
Add support for chained exceptions....
Matthias Bussonnier -
Show More
@@ -1,997 +1,1107 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Pdb debugger class.
3 Pdb debugger class.
4
4
5
5
6 This is an extension to PDB which adds a number of new features.
6 This is an extension to PDB which adds a number of new features.
7 Note that there is also the `IPython.terminal.debugger` class which provides UI
7 Note that there is also the `IPython.terminal.debugger` class which provides UI
8 improvements.
8 improvements.
9
9
10 We also strongly recommend to use this via the `ipdb` package, which provides
10 We also strongly recommend to use this via the `ipdb` package, which provides
11 extra configuration options.
11 extra configuration options.
12
12
13 Among other things, this subclass of PDB:
13 Among other things, this subclass of PDB:
14 - supports many IPython magics like pdef/psource
14 - supports many IPython magics like pdef/psource
15 - hide frames in tracebacks based on `__tracebackhide__`
15 - hide frames in tracebacks based on `__tracebackhide__`
16 - allows to skip frames based on `__debuggerskip__`
16 - allows to skip frames based on `__debuggerskip__`
17
17
18 The skipping and hiding frames are configurable via the `skip_predicates`
18 The skipping and hiding frames are configurable via the `skip_predicates`
19 command.
19 command.
20
20
21 By default, frames from readonly files will be hidden, frames containing
21 By default, frames from readonly files will be hidden, frames containing
22 ``__tracebackhide__=True`` will be hidden.
22 ``__tracebackhide__=True`` will be hidden.
23
23
24 Frames containing ``__debuggerskip__`` will be stepped over, frames who's parent
24 Frames containing ``__debuggerskip__`` will be stepped over, frames who's parent
25 frames value of ``__debuggerskip__`` is ``True`` will be skipped.
25 frames value of ``__debuggerskip__`` is ``True`` will be skipped.
26
26
27 >>> def helpers_helper():
27 >>> def helpers_helper():
28 ... pass
28 ... pass
29 ...
29 ...
30 ... def helper_1():
30 ... def helper_1():
31 ... print("don't step in me")
31 ... print("don't step in me")
32 ... helpers_helpers() # will be stepped over unless breakpoint set.
32 ... helpers_helpers() # will be stepped over unless breakpoint set.
33 ...
33 ...
34 ...
34 ...
35 ... def helper_2():
35 ... def helper_2():
36 ... print("in me neither")
36 ... print("in me neither")
37 ...
37 ...
38
38
39 One can define a decorator that wraps a function between the two helpers:
39 One can define a decorator that wraps a function between the two helpers:
40
40
41 >>> def pdb_skipped_decorator(function):
41 >>> def pdb_skipped_decorator(function):
42 ...
42 ...
43 ...
43 ...
44 ... def wrapped_fn(*args, **kwargs):
44 ... def wrapped_fn(*args, **kwargs):
45 ... __debuggerskip__ = True
45 ... __debuggerskip__ = True
46 ... helper_1()
46 ... helper_1()
47 ... __debuggerskip__ = False
47 ... __debuggerskip__ = False
48 ... result = function(*args, **kwargs)
48 ... result = function(*args, **kwargs)
49 ... __debuggerskip__ = True
49 ... __debuggerskip__ = True
50 ... helper_2()
50 ... helper_2()
51 ... # setting __debuggerskip__ to False again is not necessary
51 ... # setting __debuggerskip__ to False again is not necessary
52 ... return result
52 ... return result
53 ...
53 ...
54 ... return wrapped_fn
54 ... return wrapped_fn
55
55
56 When decorating a function, ipdb will directly step into ``bar()`` by
56 When decorating a function, ipdb will directly step into ``bar()`` by
57 default:
57 default:
58
58
59 >>> @foo_decorator
59 >>> @foo_decorator
60 ... def bar(x, y):
60 ... def bar(x, y):
61 ... return x * y
61 ... return x * y
62
62
63
63
64 You can toggle the behavior with
64 You can toggle the behavior with
65
65
66 ipdb> skip_predicates debuggerskip false
66 ipdb> skip_predicates debuggerskip false
67
67
68 or configure it in your ``.pdbrc``
68 or configure it in your ``.pdbrc``
69
69
70
70
71
71
72 License
72 License
73 -------
73 -------
74
74
75 Modified from the standard pdb.Pdb class to avoid including readline, so that
75 Modified from the standard pdb.Pdb class to avoid including readline, so that
76 the command line completion of other programs which include this isn't
76 the command line completion of other programs which include this isn't
77 damaged.
77 damaged.
78
78
79 In the future, this class will be expanded with improvements over the standard
79 In the future, this class will be expanded with improvements over the standard
80 pdb.
80 pdb.
81
81
82 The original code in this file is mainly lifted out of cmd.py in Python 2.2,
82 The original code in this file is mainly lifted out of cmd.py in Python 2.2,
83 with minor changes. Licensing should therefore be under the standard Python
83 with minor changes. Licensing should therefore be under the standard Python
84 terms. For details on the PSF (Python Software Foundation) standard license,
84 terms. For details on the PSF (Python Software Foundation) standard license,
85 see:
85 see:
86
86
87 https://docs.python.org/2/license.html
87 https://docs.python.org/2/license.html
88
88
89
89
90 All the changes since then are under the same license as IPython.
90 All the changes since then are under the same license as IPython.
91
91
92 """
92 """
93
93
94 #*****************************************************************************
94 #*****************************************************************************
95 #
95 #
96 # This file is licensed under the PSF license.
96 # This file is licensed under the PSF license.
97 #
97 #
98 # Copyright (C) 2001 Python Software Foundation, www.python.org
98 # Copyright (C) 2001 Python Software Foundation, www.python.org
99 # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu>
99 # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu>
100 #
100 #
101 #
101 #
102 #*****************************************************************************
102 #*****************************************************************************
103
103
104 import inspect
104 import inspect
105 import linecache
105 import linecache
106 import sys
106 import sys
107 import re
107 import re
108 import os
108 import os
109
109
110 from IPython import get_ipython
110 from IPython import get_ipython
111 from contextlib import contextmanager
111 from IPython.utils import PyColorize
112 from IPython.utils import PyColorize
112 from IPython.utils import coloransi, py3compat
113 from IPython.utils import coloransi, py3compat
113 from IPython.core.excolors import exception_colors
114 from IPython.core.excolors import exception_colors
114
115
115 # skip module docstests
116 # skip module docstests
116 __skip_doctest__ = True
117 __skip_doctest__ = True
117
118
118 prompt = 'ipdb> '
119 prompt = 'ipdb> '
119
120
120 # We have to check this directly from sys.argv, config struct not yet available
121 # We have to check this directly from sys.argv, config struct not yet available
121 from pdb import Pdb as OldPdb
122 from pdb import Pdb as OldPdb
122
123
123 # Allow the set_trace code to operate outside of an ipython instance, even if
124 # Allow the set_trace code to operate outside of an ipython instance, even if
124 # it does so with some limitations. The rest of this support is implemented in
125 # it does so with some limitations. The rest of this support is implemented in
125 # the Tracer constructor.
126 # the Tracer constructor.
126
127
127 DEBUGGERSKIP = "__debuggerskip__"
128 DEBUGGERSKIP = "__debuggerskip__"
128
129
129
130
131 # this has been implemented in Pdb in Python 3.13 (https://github.com/python/cpython/pull/106676
132 # on lower python versions, we backported the feature.
133 CHAIN_EXCEPTIONS = sys.version_info < (3, 13)
134
135
130 def make_arrow(pad):
136 def make_arrow(pad):
131 """generate the leading arrow in front of traceback or debugger"""
137 """generate the leading arrow in front of traceback or debugger"""
132 if pad >= 2:
138 if pad >= 2:
133 return '-'*(pad-2) + '> '
139 return '-'*(pad-2) + '> '
134 elif pad == 1:
140 elif pad == 1:
135 return '>'
141 return '>'
136 return ''
142 return ''
137
143
138
144
139 def BdbQuit_excepthook(et, ev, tb, excepthook=None):
145 def BdbQuit_excepthook(et, ev, tb, excepthook=None):
140 """Exception hook which handles `BdbQuit` exceptions.
146 """Exception hook which handles `BdbQuit` exceptions.
141
147
142 All other exceptions are processed using the `excepthook`
148 All other exceptions are processed using the `excepthook`
143 parameter.
149 parameter.
144 """
150 """
145 raise ValueError(
151 raise ValueError(
146 "`BdbQuit_excepthook` is deprecated since version 5.1",
152 "`BdbQuit_excepthook` is deprecated since version 5.1",
147 )
153 )
148
154
149
155
150 def BdbQuit_IPython_excepthook(self, et, ev, tb, tb_offset=None):
156 def BdbQuit_IPython_excepthook(self, et, ev, tb, tb_offset=None):
151 raise ValueError(
157 raise ValueError(
152 "`BdbQuit_IPython_excepthook` is deprecated since version 5.1",
158 "`BdbQuit_IPython_excepthook` is deprecated since version 5.1",
153 DeprecationWarning, stacklevel=2)
159 DeprecationWarning, stacklevel=2)
154
160
155
161
156 RGX_EXTRA_INDENT = re.compile(r'(?<=\n)\s+')
162 RGX_EXTRA_INDENT = re.compile(r'(?<=\n)\s+')
157
163
158
164
159 def strip_indentation(multiline_string):
165 def strip_indentation(multiline_string):
160 return RGX_EXTRA_INDENT.sub('', multiline_string)
166 return RGX_EXTRA_INDENT.sub('', multiline_string)
161
167
162
168
163 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
169 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
164 """Make new_fn have old_fn's doc string. This is particularly useful
170 """Make new_fn have old_fn's doc string. This is particularly useful
165 for the ``do_...`` commands that hook into the help system.
171 for the ``do_...`` commands that hook into the help system.
166 Adapted from from a comp.lang.python posting
172 Adapted from from a comp.lang.python posting
167 by Duncan Booth."""
173 by Duncan Booth."""
168 def wrapper(*args, **kw):
174 def wrapper(*args, **kw):
169 return new_fn(*args, **kw)
175 return new_fn(*args, **kw)
170 if old_fn.__doc__:
176 if old_fn.__doc__:
171 wrapper.__doc__ = strip_indentation(old_fn.__doc__) + additional_text
177 wrapper.__doc__ = strip_indentation(old_fn.__doc__) + additional_text
172 return wrapper
178 return wrapper
173
179
174
180
175 class Pdb(OldPdb):
181 class Pdb(OldPdb):
176 """Modified Pdb class, does not load readline.
182 """Modified Pdb class, does not load readline.
177
183
178 for a standalone version that uses prompt_toolkit, see
184 for a standalone version that uses prompt_toolkit, see
179 `IPython.terminal.debugger.TerminalPdb` and
185 `IPython.terminal.debugger.TerminalPdb` and
180 `IPython.terminal.debugger.set_trace()`
186 `IPython.terminal.debugger.set_trace()`
181
187
182
188
183 This debugger can hide and skip frames that are tagged according to some predicates.
189 This debugger can hide and skip frames that are tagged according to some predicates.
184 See the `skip_predicates` commands.
190 See the `skip_predicates` commands.
185
191
186 """
192 """
187
193
194 if CHAIN_EXCEPTIONS:
195 MAX_CHAINED_EXCEPTION_DEPTH = 999
196
188 default_predicates = {
197 default_predicates = {
189 "tbhide": True,
198 "tbhide": True,
190 "readonly": False,
199 "readonly": False,
191 "ipython_internal": True,
200 "ipython_internal": True,
192 "debuggerskip": True,
201 "debuggerskip": True,
193 }
202 }
194
203
195 def __init__(self, completekey=None, stdin=None, stdout=None, context=5, **kwargs):
204 def __init__(self, completekey=None, stdin=None, stdout=None, context=5, **kwargs):
196 """Create a new IPython debugger.
205 """Create a new IPython debugger.
197
206
198 Parameters
207 Parameters
199 ----------
208 ----------
200 completekey : default None
209 completekey : default None
201 Passed to pdb.Pdb.
210 Passed to pdb.Pdb.
202 stdin : default None
211 stdin : default None
203 Passed to pdb.Pdb.
212 Passed to pdb.Pdb.
204 stdout : default None
213 stdout : default None
205 Passed to pdb.Pdb.
214 Passed to pdb.Pdb.
206 context : int
215 context : int
207 Number of lines of source code context to show when
216 Number of lines of source code context to show when
208 displaying stacktrace information.
217 displaying stacktrace information.
209 **kwargs
218 **kwargs
210 Passed to pdb.Pdb.
219 Passed to pdb.Pdb.
211
220
212 Notes
221 Notes
213 -----
222 -----
214 The possibilities are python version dependent, see the python
223 The possibilities are python version dependent, see the python
215 docs for more info.
224 docs for more info.
216 """
225 """
217
226
218 # Parent constructor:
227 # Parent constructor:
219 try:
228 try:
220 self.context = int(context)
229 self.context = int(context)
221 if self.context <= 0:
230 if self.context <= 0:
222 raise ValueError("Context must be a positive integer")
231 raise ValueError("Context must be a positive integer")
223 except (TypeError, ValueError) as e:
232 except (TypeError, ValueError) as e:
224 raise ValueError("Context must be a positive integer") from e
233 raise ValueError("Context must be a positive integer") from e
225
234
226 # `kwargs` ensures full compatibility with stdlib's `pdb.Pdb`.
235 # `kwargs` ensures full compatibility with stdlib's `pdb.Pdb`.
227 OldPdb.__init__(self, completekey, stdin, stdout, **kwargs)
236 OldPdb.__init__(self, completekey, stdin, stdout, **kwargs)
228
237
229 # IPython changes...
238 # IPython changes...
230 self.shell = get_ipython()
239 self.shell = get_ipython()
231
240
232 if self.shell is None:
241 if self.shell is None:
233 save_main = sys.modules['__main__']
242 save_main = sys.modules['__main__']
234 # No IPython instance running, we must create one
243 # No IPython instance running, we must create one
235 from IPython.terminal.interactiveshell import \
244 from IPython.terminal.interactiveshell import \
236 TerminalInteractiveShell
245 TerminalInteractiveShell
237 self.shell = TerminalInteractiveShell.instance()
246 self.shell = TerminalInteractiveShell.instance()
238 # needed by any code which calls __import__("__main__") after
247 # needed by any code which calls __import__("__main__") after
239 # the debugger was entered. See also #9941.
248 # the debugger was entered. See also #9941.
240 sys.modules["__main__"] = save_main
249 sys.modules["__main__"] = save_main
241
250
242
251
243 color_scheme = self.shell.colors
252 color_scheme = self.shell.colors
244
253
245 self.aliases = {}
254 self.aliases = {}
246
255
247 # Create color table: we copy the default one from the traceback
256 # Create color table: we copy the default one from the traceback
248 # module and add a few attributes needed for debugging
257 # module and add a few attributes needed for debugging
249 self.color_scheme_table = exception_colors()
258 self.color_scheme_table = exception_colors()
250
259
251 # shorthands
260 # shorthands
252 C = coloransi.TermColors
261 C = coloransi.TermColors
253 cst = self.color_scheme_table
262 cst = self.color_scheme_table
254
263
255 cst['NoColor'].colors.prompt = C.NoColor
264 cst['NoColor'].colors.prompt = C.NoColor
256 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
265 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
257 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
266 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
258
267
259 cst['Linux'].colors.prompt = C.Green
268 cst['Linux'].colors.prompt = C.Green
260 cst['Linux'].colors.breakpoint_enabled = C.LightRed
269 cst['Linux'].colors.breakpoint_enabled = C.LightRed
261 cst['Linux'].colors.breakpoint_disabled = C.Red
270 cst['Linux'].colors.breakpoint_disabled = C.Red
262
271
263 cst['LightBG'].colors.prompt = C.Blue
272 cst['LightBG'].colors.prompt = C.Blue
264 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
273 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
265 cst['LightBG'].colors.breakpoint_disabled = C.Red
274 cst['LightBG'].colors.breakpoint_disabled = C.Red
266
275
267 cst['Neutral'].colors.prompt = C.Blue
276 cst['Neutral'].colors.prompt = C.Blue
268 cst['Neutral'].colors.breakpoint_enabled = C.LightRed
277 cst['Neutral'].colors.breakpoint_enabled = C.LightRed
269 cst['Neutral'].colors.breakpoint_disabled = C.Red
278 cst['Neutral'].colors.breakpoint_disabled = C.Red
270
279
271 # Add a python parser so we can syntax highlight source while
280 # Add a python parser so we can syntax highlight source while
272 # debugging.
281 # debugging.
273 self.parser = PyColorize.Parser(style=color_scheme)
282 self.parser = PyColorize.Parser(style=color_scheme)
274 self.set_colors(color_scheme)
283 self.set_colors(color_scheme)
275
284
276 # Set the prompt - the default prompt is '(Pdb)'
285 # Set the prompt - the default prompt is '(Pdb)'
277 self.prompt = prompt
286 self.prompt = prompt
278 self.skip_hidden = True
287 self.skip_hidden = True
279 self.report_skipped = True
288 self.report_skipped = True
280
289
281 # list of predicates we use to skip frames
290 # list of predicates we use to skip frames
282 self._predicates = self.default_predicates
291 self._predicates = self.default_predicates
283
292
293 if CHAIN_EXCEPTIONS:
294 self._chained_exceptions = tuple()
295 self._chained_exception_index = 0
296
284 #
297 #
285 def set_colors(self, scheme):
298 def set_colors(self, scheme):
286 """Shorthand access to the color table scheme selector method."""
299 """Shorthand access to the color table scheme selector method."""
287 self.color_scheme_table.set_active_scheme(scheme)
300 self.color_scheme_table.set_active_scheme(scheme)
288 self.parser.style = scheme
301 self.parser.style = scheme
289
302
290 def set_trace(self, frame=None):
303 def set_trace(self, frame=None):
291 if frame is None:
304 if frame is None:
292 frame = sys._getframe().f_back
305 frame = sys._getframe().f_back
293 self.initial_frame = frame
306 self.initial_frame = frame
294 return super().set_trace(frame)
307 return super().set_trace(frame)
295
308
296 def _hidden_predicate(self, frame):
309 def _hidden_predicate(self, frame):
297 """
310 """
298 Given a frame return whether it it should be hidden or not by IPython.
311 Given a frame return whether it it should be hidden or not by IPython.
299 """
312 """
300
313
301 if self._predicates["readonly"]:
314 if self._predicates["readonly"]:
302 fname = frame.f_code.co_filename
315 fname = frame.f_code.co_filename
303 # we need to check for file existence and interactively define
316 # we need to check for file existence and interactively define
304 # function would otherwise appear as RO.
317 # function would otherwise appear as RO.
305 if os.path.isfile(fname) and not os.access(fname, os.W_OK):
318 if os.path.isfile(fname) and not os.access(fname, os.W_OK):
306 return True
319 return True
307
320
308 if self._predicates["tbhide"]:
321 if self._predicates["tbhide"]:
309 if frame in (self.curframe, getattr(self, "initial_frame", None)):
322 if frame in (self.curframe, getattr(self, "initial_frame", None)):
310 return False
323 return False
311 frame_locals = self._get_frame_locals(frame)
324 frame_locals = self._get_frame_locals(frame)
312 if "__tracebackhide__" not in frame_locals:
325 if "__tracebackhide__" not in frame_locals:
313 return False
326 return False
314 return frame_locals["__tracebackhide__"]
327 return frame_locals["__tracebackhide__"]
315 return False
328 return False
316
329
317 def hidden_frames(self, stack):
330 def hidden_frames(self, stack):
318 """
331 """
319 Given an index in the stack return whether it should be skipped.
332 Given an index in the stack return whether it should be skipped.
320
333
321 This is used in up/down and where to skip frames.
334 This is used in up/down and where to skip frames.
322 """
335 """
323 # The f_locals dictionary is updated from the actual frame
336 # The f_locals dictionary is updated from the actual frame
324 # locals whenever the .f_locals accessor is called, so we
337 # locals whenever the .f_locals accessor is called, so we
325 # avoid calling it here to preserve self.curframe_locals.
338 # avoid calling it here to preserve self.curframe_locals.
326 # Furthermore, there is no good reason to hide the current frame.
339 # Furthermore, there is no good reason to hide the current frame.
327 ip_hide = [self._hidden_predicate(s[0]) for s in stack]
340 ip_hide = [self._hidden_predicate(s[0]) for s in stack]
328 ip_start = [i for i, s in enumerate(ip_hide) if s == "__ipython_bottom__"]
341 ip_start = [i for i, s in enumerate(ip_hide) if s == "__ipython_bottom__"]
329 if ip_start and self._predicates["ipython_internal"]:
342 if ip_start and self._predicates["ipython_internal"]:
330 ip_hide = [h if i > ip_start[0] else True for (i, h) in enumerate(ip_hide)]
343 ip_hide = [h if i > ip_start[0] else True for (i, h) in enumerate(ip_hide)]
331 return ip_hide
344 return ip_hide
332
345
333 def interaction(self, frame, traceback):
346 if CHAIN_EXCEPTIONS:
347
348 def _get_tb_and_exceptions(self, tb_or_exc):
349 """
350 Given a tracecack or an exception, return a tuple of chained exceptions
351 and current traceback to inspect.
352 This will deal with selecting the right ``__cause__`` or ``__context__``
353 as well as handling cycles, and return a flattened list of exceptions we
354 can jump to with do_exceptions.
355 """
356 _exceptions = []
357 if isinstance(tb_or_exc, BaseException):
358 traceback, current = tb_or_exc.__traceback__, tb_or_exc
359
360 while current is not None:
361 if current in _exceptions:
362 break
363 _exceptions.append(current)
364 if current.__cause__ is not None:
365 current = current.__cause__
366 elif (
367 current.__context__ is not None
368 and not current.__suppress_context__
369 ):
370 current = current.__context__
371
372 if len(_exceptions) >= self.MAX_CHAINED_EXCEPTION_DEPTH:
373 self.message(
374 f"More than {self.MAX_CHAINED_EXCEPTION_DEPTH}"
375 " chained exceptions found, not all exceptions"
376 "will be browsable with `exceptions`."
377 )
378 break
379 else:
380 traceback = tb_or_exc
381 return tuple(reversed(_exceptions)), traceback
382
383 @contextmanager
384 def _hold_exceptions(self, exceptions):
385 """
386 Context manager to ensure proper cleaning of exceptions references
387 When given a chained exception instead of a traceback,
388 pdb may hold references to many objects which may leak memory.
389 We use this context manager to make sure everything is properly cleaned
390 """
391 try:
392 self._chained_exceptions = exceptions
393 self._chained_exception_index = len(exceptions) - 1
394 yield
395 finally:
396 # we can't put those in forget as otherwise they would
397 # be cleared on exception change
398 self._chained_exceptions = tuple()
399 self._chained_exception_index = 0
400
401 def do_exceptions(self, arg):
402 """exceptions [number]
403 List or change current exception in an exception chain.
404 Without arguments, list all the current exception in the exception
405 chain. Exceptions will be numbered, with the current exception indicated
406 with an arrow.
407 If given an integer as argument, switch to the exception at that index.
408 """
409 if not self._chained_exceptions:
410 self.message(
411 "Did not find chained exceptions. To move between"
412 " exceptions, pdb/post_mortem must be given an exception"
413 " object rather than a traceback."
414 )
415 return
416 if not arg:
417 for ix, exc in enumerate(self._chained_exceptions):
418 prompt = ">" if ix == self._chained_exception_index else " "
419 rep = repr(exc)
420 if len(rep) > 80:
421 rep = rep[:77] + "..."
422 self.message(f"{prompt} {ix:>3} {rep}")
423 else:
424 try:
425 number = int(arg)
426 except ValueError:
427 self.error("Argument must be an integer")
428 return
429 if 0 <= number < len(self._chained_exceptions):
430 self._chained_exception_index = number
431 self.setup(None, self._chained_exceptions[number].__traceback__)
432 self.print_stack_entry(self.stack[self.curindex])
433 else:
434 self.error("No exception with that number")
435
436 def interaction(self, frame, tb_or_exc):
334 try:
437 try:
335 OldPdb.interaction(self, frame, traceback)
438 if CHAIN_EXCEPTIONS:
439 # this context manager is part of interaction in 3.13
440 _chained_exceptions, tb = self._get_tb_and_exceptions(tb_or_exc)
441 with self._hold_exceptions(_chained_exceptions):
442 OldPdb.interaction(self, frame, tb)
443 else:
444 OldPdb.interaction(self, frame, traceback)
445
336 except KeyboardInterrupt:
446 except KeyboardInterrupt:
337 self.stdout.write("\n" + self.shell.get_exception_only())
447 self.stdout.write("\n" + self.shell.get_exception_only())
338
448
339 def precmd(self, line):
449 def precmd(self, line):
340 """Perform useful escapes on the command before it is executed."""
450 """Perform useful escapes on the command before it is executed."""
341
451
342 if line.endswith("??"):
452 if line.endswith("??"):
343 line = "pinfo2 " + line[:-2]
453 line = "pinfo2 " + line[:-2]
344 elif line.endswith("?"):
454 elif line.endswith("?"):
345 line = "pinfo " + line[:-1]
455 line = "pinfo " + line[:-1]
346
456
347 line = super().precmd(line)
457 line = super().precmd(line)
348
458
349 return line
459 return line
350
460
351 def new_do_frame(self, arg):
461 def new_do_frame(self, arg):
352 OldPdb.do_frame(self, arg)
462 OldPdb.do_frame(self, arg)
353
463
354 def new_do_quit(self, arg):
464 def new_do_quit(self, arg):
355
465
356 if hasattr(self, 'old_all_completions'):
466 if hasattr(self, 'old_all_completions'):
357 self.shell.Completer.all_completions = self.old_all_completions
467 self.shell.Completer.all_completions = self.old_all_completions
358
468
359 return OldPdb.do_quit(self, arg)
469 return OldPdb.do_quit(self, arg)
360
470
361 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
471 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
362
472
363 def new_do_restart(self, arg):
473 def new_do_restart(self, arg):
364 """Restart command. In the context of ipython this is exactly the same
474 """Restart command. In the context of ipython this is exactly the same
365 thing as 'quit'."""
475 thing as 'quit'."""
366 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
476 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
367 return self.do_quit(arg)
477 return self.do_quit(arg)
368
478
369 def print_stack_trace(self, context=None):
479 def print_stack_trace(self, context=None):
370 Colors = self.color_scheme_table.active_colors
480 Colors = self.color_scheme_table.active_colors
371 ColorsNormal = Colors.Normal
481 ColorsNormal = Colors.Normal
372 if context is None:
482 if context is None:
373 context = self.context
483 context = self.context
374 try:
484 try:
375 context = int(context)
485 context = int(context)
376 if context <= 0:
486 if context <= 0:
377 raise ValueError("Context must be a positive integer")
487 raise ValueError("Context must be a positive integer")
378 except (TypeError, ValueError) as e:
488 except (TypeError, ValueError) as e:
379 raise ValueError("Context must be a positive integer") from e
489 raise ValueError("Context must be a positive integer") from e
380 try:
490 try:
381 skipped = 0
491 skipped = 0
382 for hidden, frame_lineno in zip(self.hidden_frames(self.stack), self.stack):
492 for hidden, frame_lineno in zip(self.hidden_frames(self.stack), self.stack):
383 if hidden and self.skip_hidden:
493 if hidden and self.skip_hidden:
384 skipped += 1
494 skipped += 1
385 continue
495 continue
386 if skipped:
496 if skipped:
387 print(
497 print(
388 f"{Colors.excName} [... skipping {skipped} hidden frame(s)]{ColorsNormal}\n"
498 f"{Colors.excName} [... skipping {skipped} hidden frame(s)]{ColorsNormal}\n"
389 )
499 )
390 skipped = 0
500 skipped = 0
391 self.print_stack_entry(frame_lineno, context=context)
501 self.print_stack_entry(frame_lineno, context=context)
392 if skipped:
502 if skipped:
393 print(
503 print(
394 f"{Colors.excName} [... skipping {skipped} hidden frame(s)]{ColorsNormal}\n"
504 f"{Colors.excName} [... skipping {skipped} hidden frame(s)]{ColorsNormal}\n"
395 )
505 )
396 except KeyboardInterrupt:
506 except KeyboardInterrupt:
397 pass
507 pass
398
508
399 def print_stack_entry(self, frame_lineno, prompt_prefix='\n-> ',
509 def print_stack_entry(self, frame_lineno, prompt_prefix='\n-> ',
400 context=None):
510 context=None):
401 if context is None:
511 if context is None:
402 context = self.context
512 context = self.context
403 try:
513 try:
404 context = int(context)
514 context = int(context)
405 if context <= 0:
515 if context <= 0:
406 raise ValueError("Context must be a positive integer")
516 raise ValueError("Context must be a positive integer")
407 except (TypeError, ValueError) as e:
517 except (TypeError, ValueError) as e:
408 raise ValueError("Context must be a positive integer") from e
518 raise ValueError("Context must be a positive integer") from e
409 print(self.format_stack_entry(frame_lineno, '', context), file=self.stdout)
519 print(self.format_stack_entry(frame_lineno, '', context), file=self.stdout)
410
520
411 # vds: >>
521 # vds: >>
412 frame, lineno = frame_lineno
522 frame, lineno = frame_lineno
413 filename = frame.f_code.co_filename
523 filename = frame.f_code.co_filename
414 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
524 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
415 # vds: <<
525 # vds: <<
416
526
417 def _get_frame_locals(self, frame):
527 def _get_frame_locals(self, frame):
418 """ "
528 """ "
419 Accessing f_local of current frame reset the namespace, so we want to avoid
529 Accessing f_local of current frame reset the namespace, so we want to avoid
420 that or the following can happen
530 that or the following can happen
421
531
422 ipdb> foo
532 ipdb> foo
423 "old"
533 "old"
424 ipdb> foo = "new"
534 ipdb> foo = "new"
425 ipdb> foo
535 ipdb> foo
426 "new"
536 "new"
427 ipdb> where
537 ipdb> where
428 ipdb> foo
538 ipdb> foo
429 "old"
539 "old"
430
540
431 So if frame is self.current_frame we instead return self.curframe_locals
541 So if frame is self.current_frame we instead return self.curframe_locals
432
542
433 """
543 """
434 if frame is self.curframe:
544 if frame is self.curframe:
435 return self.curframe_locals
545 return self.curframe_locals
436 else:
546 else:
437 return frame.f_locals
547 return frame.f_locals
438
548
439 def format_stack_entry(self, frame_lineno, lprefix=': ', context=None):
549 def format_stack_entry(self, frame_lineno, lprefix=': ', context=None):
440 if context is None:
550 if context is None:
441 context = self.context
551 context = self.context
442 try:
552 try:
443 context = int(context)
553 context = int(context)
444 if context <= 0:
554 if context <= 0:
445 print("Context must be a positive integer", file=self.stdout)
555 print("Context must be a positive integer", file=self.stdout)
446 except (TypeError, ValueError):
556 except (TypeError, ValueError):
447 print("Context must be a positive integer", file=self.stdout)
557 print("Context must be a positive integer", file=self.stdout)
448
558
449 import reprlib
559 import reprlib
450
560
451 ret = []
561 ret = []
452
562
453 Colors = self.color_scheme_table.active_colors
563 Colors = self.color_scheme_table.active_colors
454 ColorsNormal = Colors.Normal
564 ColorsNormal = Colors.Normal
455 tpl_link = "%s%%s%s" % (Colors.filenameEm, ColorsNormal)
565 tpl_link = "%s%%s%s" % (Colors.filenameEm, ColorsNormal)
456 tpl_call = "%s%%s%s%%s%s" % (Colors.vName, Colors.valEm, ColorsNormal)
566 tpl_call = "%s%%s%s%%s%s" % (Colors.vName, Colors.valEm, ColorsNormal)
457 tpl_line = "%%s%s%%s %s%%s" % (Colors.lineno, ColorsNormal)
567 tpl_line = "%%s%s%%s %s%%s" % (Colors.lineno, ColorsNormal)
458 tpl_line_em = "%%s%s%%s %s%%s%s" % (Colors.linenoEm, Colors.line, ColorsNormal)
568 tpl_line_em = "%%s%s%%s %s%%s%s" % (Colors.linenoEm, Colors.line, ColorsNormal)
459
569
460 frame, lineno = frame_lineno
570 frame, lineno = frame_lineno
461
571
462 return_value = ''
572 return_value = ''
463 loc_frame = self._get_frame_locals(frame)
573 loc_frame = self._get_frame_locals(frame)
464 if "__return__" in loc_frame:
574 if "__return__" in loc_frame:
465 rv = loc_frame["__return__"]
575 rv = loc_frame["__return__"]
466 # return_value += '->'
576 # return_value += '->'
467 return_value += reprlib.repr(rv) + "\n"
577 return_value += reprlib.repr(rv) + "\n"
468 ret.append(return_value)
578 ret.append(return_value)
469
579
470 #s = filename + '(' + `lineno` + ')'
580 #s = filename + '(' + `lineno` + ')'
471 filename = self.canonic(frame.f_code.co_filename)
581 filename = self.canonic(frame.f_code.co_filename)
472 link = tpl_link % py3compat.cast_unicode(filename)
582 link = tpl_link % py3compat.cast_unicode(filename)
473
583
474 if frame.f_code.co_name:
584 if frame.f_code.co_name:
475 func = frame.f_code.co_name
585 func = frame.f_code.co_name
476 else:
586 else:
477 func = "<lambda>"
587 func = "<lambda>"
478
588
479 call = ""
589 call = ""
480 if func != "?":
590 if func != "?":
481 if "__args__" in loc_frame:
591 if "__args__" in loc_frame:
482 args = reprlib.repr(loc_frame["__args__"])
592 args = reprlib.repr(loc_frame["__args__"])
483 else:
593 else:
484 args = '()'
594 args = '()'
485 call = tpl_call % (func, args)
595 call = tpl_call % (func, args)
486
596
487 # The level info should be generated in the same format pdb uses, to
597 # The level info should be generated in the same format pdb uses, to
488 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
598 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
489 if frame is self.curframe:
599 if frame is self.curframe:
490 ret.append('> ')
600 ret.append('> ')
491 else:
601 else:
492 ret.append(" ")
602 ret.append(" ")
493 ret.append("%s(%s)%s\n" % (link, lineno, call))
603 ret.append("%s(%s)%s\n" % (link, lineno, call))
494
604
495 start = lineno - 1 - context//2
605 start = lineno - 1 - context//2
496 lines = linecache.getlines(filename)
606 lines = linecache.getlines(filename)
497 start = min(start, len(lines) - context)
607 start = min(start, len(lines) - context)
498 start = max(start, 0)
608 start = max(start, 0)
499 lines = lines[start : start + context]
609 lines = lines[start : start + context]
500
610
501 for i, line in enumerate(lines):
611 for i, line in enumerate(lines):
502 show_arrow = start + 1 + i == lineno
612 show_arrow = start + 1 + i == lineno
503 linetpl = (frame is self.curframe or show_arrow) and tpl_line_em or tpl_line
613 linetpl = (frame is self.curframe or show_arrow) and tpl_line_em or tpl_line
504 ret.append(
614 ret.append(
505 self.__format_line(
615 self.__format_line(
506 linetpl, filename, start + 1 + i, line, arrow=show_arrow
616 linetpl, filename, start + 1 + i, line, arrow=show_arrow
507 )
617 )
508 )
618 )
509 return "".join(ret)
619 return "".join(ret)
510
620
511 def __format_line(self, tpl_line, filename, lineno, line, arrow=False):
621 def __format_line(self, tpl_line, filename, lineno, line, arrow=False):
512 bp_mark = ""
622 bp_mark = ""
513 bp_mark_color = ""
623 bp_mark_color = ""
514
624
515 new_line, err = self.parser.format2(line, 'str')
625 new_line, err = self.parser.format2(line, 'str')
516 if not err:
626 if not err:
517 line = new_line
627 line = new_line
518
628
519 bp = None
629 bp = None
520 if lineno in self.get_file_breaks(filename):
630 if lineno in self.get_file_breaks(filename):
521 bps = self.get_breaks(filename, lineno)
631 bps = self.get_breaks(filename, lineno)
522 bp = bps[-1]
632 bp = bps[-1]
523
633
524 if bp:
634 if bp:
525 Colors = self.color_scheme_table.active_colors
635 Colors = self.color_scheme_table.active_colors
526 bp_mark = str(bp.number)
636 bp_mark = str(bp.number)
527 bp_mark_color = Colors.breakpoint_enabled
637 bp_mark_color = Colors.breakpoint_enabled
528 if not bp.enabled:
638 if not bp.enabled:
529 bp_mark_color = Colors.breakpoint_disabled
639 bp_mark_color = Colors.breakpoint_disabled
530
640
531 numbers_width = 7
641 numbers_width = 7
532 if arrow:
642 if arrow:
533 # This is the line with the error
643 # This is the line with the error
534 pad = numbers_width - len(str(lineno)) - len(bp_mark)
644 pad = numbers_width - len(str(lineno)) - len(bp_mark)
535 num = '%s%s' % (make_arrow(pad), str(lineno))
645 num = '%s%s' % (make_arrow(pad), str(lineno))
536 else:
646 else:
537 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
647 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
538
648
539 return tpl_line % (bp_mark_color + bp_mark, num, line)
649 return tpl_line % (bp_mark_color + bp_mark, num, line)
540
650
541 def print_list_lines(self, filename, first, last):
651 def print_list_lines(self, filename, first, last):
542 """The printing (as opposed to the parsing part of a 'list'
652 """The printing (as opposed to the parsing part of a 'list'
543 command."""
653 command."""
544 try:
654 try:
545 Colors = self.color_scheme_table.active_colors
655 Colors = self.color_scheme_table.active_colors
546 ColorsNormal = Colors.Normal
656 ColorsNormal = Colors.Normal
547 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
657 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
548 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
658 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
549 src = []
659 src = []
550 if filename == "<string>" and hasattr(self, "_exec_filename"):
660 if filename == "<string>" and hasattr(self, "_exec_filename"):
551 filename = self._exec_filename
661 filename = self._exec_filename
552
662
553 for lineno in range(first, last+1):
663 for lineno in range(first, last+1):
554 line = linecache.getline(filename, lineno)
664 line = linecache.getline(filename, lineno)
555 if not line:
665 if not line:
556 break
666 break
557
667
558 if lineno == self.curframe.f_lineno:
668 if lineno == self.curframe.f_lineno:
559 line = self.__format_line(
669 line = self.__format_line(
560 tpl_line_em, filename, lineno, line, arrow=True
670 tpl_line_em, filename, lineno, line, arrow=True
561 )
671 )
562 else:
672 else:
563 line = self.__format_line(
673 line = self.__format_line(
564 tpl_line, filename, lineno, line, arrow=False
674 tpl_line, filename, lineno, line, arrow=False
565 )
675 )
566
676
567 src.append(line)
677 src.append(line)
568 self.lineno = lineno
678 self.lineno = lineno
569
679
570 print(''.join(src), file=self.stdout)
680 print(''.join(src), file=self.stdout)
571
681
572 except KeyboardInterrupt:
682 except KeyboardInterrupt:
573 pass
683 pass
574
684
575 def do_skip_predicates(self, args):
685 def do_skip_predicates(self, args):
576 """
686 """
577 Turn on/off individual predicates as to whether a frame should be hidden/skip.
687 Turn on/off individual predicates as to whether a frame should be hidden/skip.
578
688
579 The global option to skip (or not) hidden frames is set with skip_hidden
689 The global option to skip (or not) hidden frames is set with skip_hidden
580
690
581 To change the value of a predicate
691 To change the value of a predicate
582
692
583 skip_predicates key [true|false]
693 skip_predicates key [true|false]
584
694
585 Call without arguments to see the current values.
695 Call without arguments to see the current values.
586
696
587 To permanently change the value of an option add the corresponding
697 To permanently change the value of an option add the corresponding
588 command to your ``~/.pdbrc`` file. If you are programmatically using the
698 command to your ``~/.pdbrc`` file. If you are programmatically using the
589 Pdb instance you can also change the ``default_predicates`` class
699 Pdb instance you can also change the ``default_predicates`` class
590 attribute.
700 attribute.
591 """
701 """
592 if not args.strip():
702 if not args.strip():
593 print("current predicates:")
703 print("current predicates:")
594 for p, v in self._predicates.items():
704 for p, v in self._predicates.items():
595 print(" ", p, ":", v)
705 print(" ", p, ":", v)
596 return
706 return
597 type_value = args.strip().split(" ")
707 type_value = args.strip().split(" ")
598 if len(type_value) != 2:
708 if len(type_value) != 2:
599 print(
709 print(
600 f"Usage: skip_predicates <type> <value>, with <type> one of {set(self._predicates.keys())}"
710 f"Usage: skip_predicates <type> <value>, with <type> one of {set(self._predicates.keys())}"
601 )
711 )
602 return
712 return
603
713
604 type_, value = type_value
714 type_, value = type_value
605 if type_ not in self._predicates:
715 if type_ not in self._predicates:
606 print(f"{type_!r} not in {set(self._predicates.keys())}")
716 print(f"{type_!r} not in {set(self._predicates.keys())}")
607 return
717 return
608 if value.lower() not in ("true", "yes", "1", "no", "false", "0"):
718 if value.lower() not in ("true", "yes", "1", "no", "false", "0"):
609 print(
719 print(
610 f"{value!r} is invalid - use one of ('true', 'yes', '1', 'no', 'false', '0')"
720 f"{value!r} is invalid - use one of ('true', 'yes', '1', 'no', 'false', '0')"
611 )
721 )
612 return
722 return
613
723
614 self._predicates[type_] = value.lower() in ("true", "yes", "1")
724 self._predicates[type_] = value.lower() in ("true", "yes", "1")
615 if not any(self._predicates.values()):
725 if not any(self._predicates.values()):
616 print(
726 print(
617 "Warning, all predicates set to False, skip_hidden may not have any effects."
727 "Warning, all predicates set to False, skip_hidden may not have any effects."
618 )
728 )
619
729
620 def do_skip_hidden(self, arg):
730 def do_skip_hidden(self, arg):
621 """
731 """
622 Change whether or not we should skip frames with the
732 Change whether or not we should skip frames with the
623 __tracebackhide__ attribute.
733 __tracebackhide__ attribute.
624 """
734 """
625 if not arg.strip():
735 if not arg.strip():
626 print(
736 print(
627 f"skip_hidden = {self.skip_hidden}, use 'yes','no', 'true', or 'false' to change."
737 f"skip_hidden = {self.skip_hidden}, use 'yes','no', 'true', or 'false' to change."
628 )
738 )
629 elif arg.strip().lower() in ("true", "yes"):
739 elif arg.strip().lower() in ("true", "yes"):
630 self.skip_hidden = True
740 self.skip_hidden = True
631 elif arg.strip().lower() in ("false", "no"):
741 elif arg.strip().lower() in ("false", "no"):
632 self.skip_hidden = False
742 self.skip_hidden = False
633 if not any(self._predicates.values()):
743 if not any(self._predicates.values()):
634 print(
744 print(
635 "Warning, all predicates set to False, skip_hidden may not have any effects."
745 "Warning, all predicates set to False, skip_hidden may not have any effects."
636 )
746 )
637
747
638 def do_list(self, arg):
748 def do_list(self, arg):
639 """Print lines of code from the current stack frame
749 """Print lines of code from the current stack frame
640 """
750 """
641 self.lastcmd = 'list'
751 self.lastcmd = 'list'
642 last = None
752 last = None
643 if arg and arg != ".":
753 if arg and arg != ".":
644 try:
754 try:
645 x = eval(arg, {}, {})
755 x = eval(arg, {}, {})
646 if type(x) == type(()):
756 if type(x) == type(()):
647 first, last = x
757 first, last = x
648 first = int(first)
758 first = int(first)
649 last = int(last)
759 last = int(last)
650 if last < first:
760 if last < first:
651 # Assume it's a count
761 # Assume it's a count
652 last = first + last
762 last = first + last
653 else:
763 else:
654 first = max(1, int(x) - 5)
764 first = max(1, int(x) - 5)
655 except:
765 except:
656 print('*** Error in argument:', repr(arg), file=self.stdout)
766 print('*** Error in argument:', repr(arg), file=self.stdout)
657 return
767 return
658 elif self.lineno is None or arg == ".":
768 elif self.lineno is None or arg == ".":
659 first = max(1, self.curframe.f_lineno - 5)
769 first = max(1, self.curframe.f_lineno - 5)
660 else:
770 else:
661 first = self.lineno + 1
771 first = self.lineno + 1
662 if last is None:
772 if last is None:
663 last = first + 10
773 last = first + 10
664 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
774 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
665
775
666 # vds: >>
776 # vds: >>
667 lineno = first
777 lineno = first
668 filename = self.curframe.f_code.co_filename
778 filename = self.curframe.f_code.co_filename
669 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
779 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
670 # vds: <<
780 # vds: <<
671
781
672 do_l = do_list
782 do_l = do_list
673
783
674 def getsourcelines(self, obj):
784 def getsourcelines(self, obj):
675 lines, lineno = inspect.findsource(obj)
785 lines, lineno = inspect.findsource(obj)
676 if inspect.isframe(obj) and obj.f_globals is self._get_frame_locals(obj):
786 if inspect.isframe(obj) and obj.f_globals is self._get_frame_locals(obj):
677 # must be a module frame: do not try to cut a block out of it
787 # must be a module frame: do not try to cut a block out of it
678 return lines, 1
788 return lines, 1
679 elif inspect.ismodule(obj):
789 elif inspect.ismodule(obj):
680 return lines, 1
790 return lines, 1
681 return inspect.getblock(lines[lineno:]), lineno+1
791 return inspect.getblock(lines[lineno:]), lineno+1
682
792
683 def do_longlist(self, arg):
793 def do_longlist(self, arg):
684 """Print lines of code from the current stack frame.
794 """Print lines of code from the current stack frame.
685
795
686 Shows more lines than 'list' does.
796 Shows more lines than 'list' does.
687 """
797 """
688 self.lastcmd = 'longlist'
798 self.lastcmd = 'longlist'
689 try:
799 try:
690 lines, lineno = self.getsourcelines(self.curframe)
800 lines, lineno = self.getsourcelines(self.curframe)
691 except OSError as err:
801 except OSError as err:
692 self.error(err)
802 self.error(err)
693 return
803 return
694 last = lineno + len(lines)
804 last = lineno + len(lines)
695 self.print_list_lines(self.curframe.f_code.co_filename, lineno, last)
805 self.print_list_lines(self.curframe.f_code.co_filename, lineno, last)
696 do_ll = do_longlist
806 do_ll = do_longlist
697
807
698 def do_debug(self, arg):
808 def do_debug(self, arg):
699 """debug code
809 """debug code
700 Enter a recursive debugger that steps through the code
810 Enter a recursive debugger that steps through the code
701 argument (which is an arbitrary expression or statement to be
811 argument (which is an arbitrary expression or statement to be
702 executed in the current environment).
812 executed in the current environment).
703 """
813 """
704 trace_function = sys.gettrace()
814 trace_function = sys.gettrace()
705 sys.settrace(None)
815 sys.settrace(None)
706 globals = self.curframe.f_globals
816 globals = self.curframe.f_globals
707 locals = self.curframe_locals
817 locals = self.curframe_locals
708 p = self.__class__(completekey=self.completekey,
818 p = self.__class__(completekey=self.completekey,
709 stdin=self.stdin, stdout=self.stdout)
819 stdin=self.stdin, stdout=self.stdout)
710 p.use_rawinput = self.use_rawinput
820 p.use_rawinput = self.use_rawinput
711 p.prompt = "(%s) " % self.prompt.strip()
821 p.prompt = "(%s) " % self.prompt.strip()
712 self.message("ENTERING RECURSIVE DEBUGGER")
822 self.message("ENTERING RECURSIVE DEBUGGER")
713 sys.call_tracing(p.run, (arg, globals, locals))
823 sys.call_tracing(p.run, (arg, globals, locals))
714 self.message("LEAVING RECURSIVE DEBUGGER")
824 self.message("LEAVING RECURSIVE DEBUGGER")
715 sys.settrace(trace_function)
825 sys.settrace(trace_function)
716 self.lastcmd = p.lastcmd
826 self.lastcmd = p.lastcmd
717
827
718 def do_pdef(self, arg):
828 def do_pdef(self, arg):
719 """Print the call signature for any callable object.
829 """Print the call signature for any callable object.
720
830
721 The debugger interface to %pdef"""
831 The debugger interface to %pdef"""
722 namespaces = [
832 namespaces = [
723 ("Locals", self.curframe_locals),
833 ("Locals", self.curframe_locals),
724 ("Globals", self.curframe.f_globals),
834 ("Globals", self.curframe.f_globals),
725 ]
835 ]
726 self.shell.find_line_magic("pdef")(arg, namespaces=namespaces)
836 self.shell.find_line_magic("pdef")(arg, namespaces=namespaces)
727
837
728 def do_pdoc(self, arg):
838 def do_pdoc(self, arg):
729 """Print the docstring for an object.
839 """Print the docstring for an object.
730
840
731 The debugger interface to %pdoc."""
841 The debugger interface to %pdoc."""
732 namespaces = [
842 namespaces = [
733 ("Locals", self.curframe_locals),
843 ("Locals", self.curframe_locals),
734 ("Globals", self.curframe.f_globals),
844 ("Globals", self.curframe.f_globals),
735 ]
845 ]
736 self.shell.find_line_magic("pdoc")(arg, namespaces=namespaces)
846 self.shell.find_line_magic("pdoc")(arg, namespaces=namespaces)
737
847
738 def do_pfile(self, arg):
848 def do_pfile(self, arg):
739 """Print (or run through pager) the file where an object is defined.
849 """Print (or run through pager) the file where an object is defined.
740
850
741 The debugger interface to %pfile.
851 The debugger interface to %pfile.
742 """
852 """
743 namespaces = [
853 namespaces = [
744 ("Locals", self.curframe_locals),
854 ("Locals", self.curframe_locals),
745 ("Globals", self.curframe.f_globals),
855 ("Globals", self.curframe.f_globals),
746 ]
856 ]
747 self.shell.find_line_magic("pfile")(arg, namespaces=namespaces)
857 self.shell.find_line_magic("pfile")(arg, namespaces=namespaces)
748
858
749 def do_pinfo(self, arg):
859 def do_pinfo(self, arg):
750 """Provide detailed information about an object.
860 """Provide detailed information about an object.
751
861
752 The debugger interface to %pinfo, i.e., obj?."""
862 The debugger interface to %pinfo, i.e., obj?."""
753 namespaces = [
863 namespaces = [
754 ("Locals", self.curframe_locals),
864 ("Locals", self.curframe_locals),
755 ("Globals", self.curframe.f_globals),
865 ("Globals", self.curframe.f_globals),
756 ]
866 ]
757 self.shell.find_line_magic("pinfo")(arg, namespaces=namespaces)
867 self.shell.find_line_magic("pinfo")(arg, namespaces=namespaces)
758
868
759 def do_pinfo2(self, arg):
869 def do_pinfo2(self, arg):
760 """Provide extra detailed information about an object.
870 """Provide extra detailed information about an object.
761
871
762 The debugger interface to %pinfo2, i.e., obj??."""
872 The debugger interface to %pinfo2, i.e., obj??."""
763 namespaces = [
873 namespaces = [
764 ("Locals", self.curframe_locals),
874 ("Locals", self.curframe_locals),
765 ("Globals", self.curframe.f_globals),
875 ("Globals", self.curframe.f_globals),
766 ]
876 ]
767 self.shell.find_line_magic("pinfo2")(arg, namespaces=namespaces)
877 self.shell.find_line_magic("pinfo2")(arg, namespaces=namespaces)
768
878
769 def do_psource(self, arg):
879 def do_psource(self, arg):
770 """Print (or run through pager) the source code for an object."""
880 """Print (or run through pager) the source code for an object."""
771 namespaces = [
881 namespaces = [
772 ("Locals", self.curframe_locals),
882 ("Locals", self.curframe_locals),
773 ("Globals", self.curframe.f_globals),
883 ("Globals", self.curframe.f_globals),
774 ]
884 ]
775 self.shell.find_line_magic("psource")(arg, namespaces=namespaces)
885 self.shell.find_line_magic("psource")(arg, namespaces=namespaces)
776
886
777 def do_where(self, arg):
887 def do_where(self, arg):
778 """w(here)
888 """w(here)
779 Print a stack trace, with the most recent frame at the bottom.
889 Print a stack trace, with the most recent frame at the bottom.
780 An arrow indicates the "current frame", which determines the
890 An arrow indicates the "current frame", which determines the
781 context of most commands. 'bt' is an alias for this command.
891 context of most commands. 'bt' is an alias for this command.
782
892
783 Take a number as argument as an (optional) number of context line to
893 Take a number as argument as an (optional) number of context line to
784 print"""
894 print"""
785 if arg:
895 if arg:
786 try:
896 try:
787 context = int(arg)
897 context = int(arg)
788 except ValueError as err:
898 except ValueError as err:
789 self.error(err)
899 self.error(err)
790 return
900 return
791 self.print_stack_trace(context)
901 self.print_stack_trace(context)
792 else:
902 else:
793 self.print_stack_trace()
903 self.print_stack_trace()
794
904
795 do_w = do_where
905 do_w = do_where
796
906
797 def break_anywhere(self, frame):
907 def break_anywhere(self, frame):
798 """
908 """
799 _stop_in_decorator_internals is overly restrictive, as we may still want
909 _stop_in_decorator_internals is overly restrictive, as we may still want
800 to trace function calls, so we need to also update break_anywhere so
910 to trace function calls, so we need to also update break_anywhere so
801 that is we don't `stop_here`, because of debugger skip, we may still
911 that is we don't `stop_here`, because of debugger skip, we may still
802 stop at any point inside the function
912 stop at any point inside the function
803
913
804 """
914 """
805
915
806 sup = super().break_anywhere(frame)
916 sup = super().break_anywhere(frame)
807 if sup:
917 if sup:
808 return sup
918 return sup
809 if self._predicates["debuggerskip"]:
919 if self._predicates["debuggerskip"]:
810 if DEBUGGERSKIP in frame.f_code.co_varnames:
920 if DEBUGGERSKIP in frame.f_code.co_varnames:
811 return True
921 return True
812 if frame.f_back and self._get_frame_locals(frame.f_back).get(DEBUGGERSKIP):
922 if frame.f_back and self._get_frame_locals(frame.f_back).get(DEBUGGERSKIP):
813 return True
923 return True
814 return False
924 return False
815
925
816 def _is_in_decorator_internal_and_should_skip(self, frame):
926 def _is_in_decorator_internal_and_should_skip(self, frame):
817 """
927 """
818 Utility to tell us whether we are in a decorator internal and should stop.
928 Utility to tell us whether we are in a decorator internal and should stop.
819
929
820 """
930 """
821
931
822 # if we are disabled don't skip
932 # if we are disabled don't skip
823 if not self._predicates["debuggerskip"]:
933 if not self._predicates["debuggerskip"]:
824 return False
934 return False
825
935
826 # if frame is tagged, skip by default.
936 # if frame is tagged, skip by default.
827 if DEBUGGERSKIP in frame.f_code.co_varnames:
937 if DEBUGGERSKIP in frame.f_code.co_varnames:
828 return True
938 return True
829
939
830 # if one of the parent frame value set to True skip as well.
940 # if one of the parent frame value set to True skip as well.
831
941
832 cframe = frame
942 cframe = frame
833 while getattr(cframe, "f_back", None):
943 while getattr(cframe, "f_back", None):
834 cframe = cframe.f_back
944 cframe = cframe.f_back
835 if self._get_frame_locals(cframe).get(DEBUGGERSKIP):
945 if self._get_frame_locals(cframe).get(DEBUGGERSKIP):
836 return True
946 return True
837
947
838 return False
948 return False
839
949
840 def stop_here(self, frame):
950 def stop_here(self, frame):
841 if self._is_in_decorator_internal_and_should_skip(frame) is True:
951 if self._is_in_decorator_internal_and_should_skip(frame) is True:
842 return False
952 return False
843
953
844 hidden = False
954 hidden = False
845 if self.skip_hidden:
955 if self.skip_hidden:
846 hidden = self._hidden_predicate(frame)
956 hidden = self._hidden_predicate(frame)
847 if hidden:
957 if hidden:
848 if self.report_skipped:
958 if self.report_skipped:
849 Colors = self.color_scheme_table.active_colors
959 Colors = self.color_scheme_table.active_colors
850 ColorsNormal = Colors.Normal
960 ColorsNormal = Colors.Normal
851 print(
961 print(
852 f"{Colors.excName} [... skipped 1 hidden frame]{ColorsNormal}\n"
962 f"{Colors.excName} [... skipped 1 hidden frame]{ColorsNormal}\n"
853 )
963 )
854 return super().stop_here(frame)
964 return super().stop_here(frame)
855
965
856 def do_up(self, arg):
966 def do_up(self, arg):
857 """u(p) [count]
967 """u(p) [count]
858 Move the current frame count (default one) levels up in the
968 Move the current frame count (default one) levels up in the
859 stack trace (to an older frame).
969 stack trace (to an older frame).
860
970
861 Will skip hidden frames.
971 Will skip hidden frames.
862 """
972 """
863 # modified version of upstream that skips
973 # modified version of upstream that skips
864 # frames with __tracebackhide__
974 # frames with __tracebackhide__
865 if self.curindex == 0:
975 if self.curindex == 0:
866 self.error("Oldest frame")
976 self.error("Oldest frame")
867 return
977 return
868 try:
978 try:
869 count = int(arg or 1)
979 count = int(arg or 1)
870 except ValueError:
980 except ValueError:
871 self.error("Invalid frame count (%s)" % arg)
981 self.error("Invalid frame count (%s)" % arg)
872 return
982 return
873 skipped = 0
983 skipped = 0
874 if count < 0:
984 if count < 0:
875 _newframe = 0
985 _newframe = 0
876 else:
986 else:
877 counter = 0
987 counter = 0
878 hidden_frames = self.hidden_frames(self.stack)
988 hidden_frames = self.hidden_frames(self.stack)
879 for i in range(self.curindex - 1, -1, -1):
989 for i in range(self.curindex - 1, -1, -1):
880 if hidden_frames[i] and self.skip_hidden:
990 if hidden_frames[i] and self.skip_hidden:
881 skipped += 1
991 skipped += 1
882 continue
992 continue
883 counter += 1
993 counter += 1
884 if counter >= count:
994 if counter >= count:
885 break
995 break
886 else:
996 else:
887 # if no break occurred.
997 # if no break occurred.
888 self.error(
998 self.error(
889 "all frames above hidden, use `skip_hidden False` to get get into those."
999 "all frames above hidden, use `skip_hidden False` to get get into those."
890 )
1000 )
891 return
1001 return
892
1002
893 Colors = self.color_scheme_table.active_colors
1003 Colors = self.color_scheme_table.active_colors
894 ColorsNormal = Colors.Normal
1004 ColorsNormal = Colors.Normal
895 _newframe = i
1005 _newframe = i
896 self._select_frame(_newframe)
1006 self._select_frame(_newframe)
897 if skipped:
1007 if skipped:
898 print(
1008 print(
899 f"{Colors.excName} [... skipped {skipped} hidden frame(s)]{ColorsNormal}\n"
1009 f"{Colors.excName} [... skipped {skipped} hidden frame(s)]{ColorsNormal}\n"
900 )
1010 )
901
1011
902 def do_down(self, arg):
1012 def do_down(self, arg):
903 """d(own) [count]
1013 """d(own) [count]
904 Move the current frame count (default one) levels down in the
1014 Move the current frame count (default one) levels down in the
905 stack trace (to a newer frame).
1015 stack trace (to a newer frame).
906
1016
907 Will skip hidden frames.
1017 Will skip hidden frames.
908 """
1018 """
909 if self.curindex + 1 == len(self.stack):
1019 if self.curindex + 1 == len(self.stack):
910 self.error("Newest frame")
1020 self.error("Newest frame")
911 return
1021 return
912 try:
1022 try:
913 count = int(arg or 1)
1023 count = int(arg or 1)
914 except ValueError:
1024 except ValueError:
915 self.error("Invalid frame count (%s)" % arg)
1025 self.error("Invalid frame count (%s)" % arg)
916 return
1026 return
917 if count < 0:
1027 if count < 0:
918 _newframe = len(self.stack) - 1
1028 _newframe = len(self.stack) - 1
919 else:
1029 else:
920 counter = 0
1030 counter = 0
921 skipped = 0
1031 skipped = 0
922 hidden_frames = self.hidden_frames(self.stack)
1032 hidden_frames = self.hidden_frames(self.stack)
923 for i in range(self.curindex + 1, len(self.stack)):
1033 for i in range(self.curindex + 1, len(self.stack)):
924 if hidden_frames[i] and self.skip_hidden:
1034 if hidden_frames[i] and self.skip_hidden:
925 skipped += 1
1035 skipped += 1
926 continue
1036 continue
927 counter += 1
1037 counter += 1
928 if counter >= count:
1038 if counter >= count:
929 break
1039 break
930 else:
1040 else:
931 self.error(
1041 self.error(
932 "all frames below hidden, use `skip_hidden False` to get get into those."
1042 "all frames below hidden, use `skip_hidden False` to get get into those."
933 )
1043 )
934 return
1044 return
935
1045
936 Colors = self.color_scheme_table.active_colors
1046 Colors = self.color_scheme_table.active_colors
937 ColorsNormal = Colors.Normal
1047 ColorsNormal = Colors.Normal
938 if skipped:
1048 if skipped:
939 print(
1049 print(
940 f"{Colors.excName} [... skipped {skipped} hidden frame(s)]{ColorsNormal}\n"
1050 f"{Colors.excName} [... skipped {skipped} hidden frame(s)]{ColorsNormal}\n"
941 )
1051 )
942 _newframe = i
1052 _newframe = i
943
1053
944 self._select_frame(_newframe)
1054 self._select_frame(_newframe)
945
1055
946 do_d = do_down
1056 do_d = do_down
947 do_u = do_up
1057 do_u = do_up
948
1058
949 def do_context(self, context):
1059 def do_context(self, context):
950 """context number_of_lines
1060 """context number_of_lines
951 Set the number of lines of source code to show when displaying
1061 Set the number of lines of source code to show when displaying
952 stacktrace information.
1062 stacktrace information.
953 """
1063 """
954 try:
1064 try:
955 new_context = int(context)
1065 new_context = int(context)
956 if new_context <= 0:
1066 if new_context <= 0:
957 raise ValueError()
1067 raise ValueError()
958 self.context = new_context
1068 self.context = new_context
959 except ValueError:
1069 except ValueError:
960 self.error("The 'context' command requires a positive integer argument.")
1070 self.error("The 'context' command requires a positive integer argument.")
961
1071
962
1072
963 class InterruptiblePdb(Pdb):
1073 class InterruptiblePdb(Pdb):
964 """Version of debugger where KeyboardInterrupt exits the debugger altogether."""
1074 """Version of debugger where KeyboardInterrupt exits the debugger altogether."""
965
1075
966 def cmdloop(self, intro=None):
1076 def cmdloop(self, intro=None):
967 """Wrap cmdloop() such that KeyboardInterrupt stops the debugger."""
1077 """Wrap cmdloop() such that KeyboardInterrupt stops the debugger."""
968 try:
1078 try:
969 return OldPdb.cmdloop(self, intro=intro)
1079 return OldPdb.cmdloop(self, intro=intro)
970 except KeyboardInterrupt:
1080 except KeyboardInterrupt:
971 self.stop_here = lambda frame: False
1081 self.stop_here = lambda frame: False
972 self.do_quit("")
1082 self.do_quit("")
973 sys.settrace(None)
1083 sys.settrace(None)
974 self.quitting = False
1084 self.quitting = False
975 raise
1085 raise
976
1086
977 def _cmdloop(self):
1087 def _cmdloop(self):
978 while True:
1088 while True:
979 try:
1089 try:
980 # keyboard interrupts allow for an easy way to cancel
1090 # keyboard interrupts allow for an easy way to cancel
981 # the current command, so allow them during interactive input
1091 # the current command, so allow them during interactive input
982 self.allow_kbdint = True
1092 self.allow_kbdint = True
983 self.cmdloop()
1093 self.cmdloop()
984 self.allow_kbdint = False
1094 self.allow_kbdint = False
985 break
1095 break
986 except KeyboardInterrupt:
1096 except KeyboardInterrupt:
987 self.message('--KeyboardInterrupt--')
1097 self.message('--KeyboardInterrupt--')
988 raise
1098 raise
989
1099
990
1100
991 def set_trace(frame=None):
1101 def set_trace(frame=None):
992 """
1102 """
993 Start debugging from `frame`.
1103 Start debugging from `frame`.
994
1104
995 If frame is not specified, debugging starts from caller's frame.
1105 If frame is not specified, debugging starts from caller's frame.
996 """
1106 """
997 Pdb().set_trace(frame or sys._getframe().f_back)
1107 Pdb().set_trace(frame or sys._getframe().f_back)
@@ -1,1519 +1,1525 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Verbose and colourful traceback formatting.
3 Verbose and colourful traceback formatting.
4
4
5 **ColorTB**
5 **ColorTB**
6
6
7 I've always found it a bit hard to visually parse tracebacks in Python. The
7 I've always found it a bit hard to visually parse tracebacks in Python. The
8 ColorTB class is a solution to that problem. It colors the different parts of a
8 ColorTB class is a solution to that problem. It colors the different parts of a
9 traceback in a manner similar to what you would expect from a syntax-highlighting
9 traceback in a manner similar to what you would expect from a syntax-highlighting
10 text editor.
10 text editor.
11
11
12 Installation instructions for ColorTB::
12 Installation instructions for ColorTB::
13
13
14 import sys,ultratb
14 import sys,ultratb
15 sys.excepthook = ultratb.ColorTB()
15 sys.excepthook = ultratb.ColorTB()
16
16
17 **VerboseTB**
17 **VerboseTB**
18
18
19 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
19 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
20 of useful info when a traceback occurs. Ping originally had it spit out HTML
20 of useful info when a traceback occurs. Ping originally had it spit out HTML
21 and intended it for CGI programmers, but why should they have all the fun? I
21 and intended it for CGI programmers, but why should they have all the fun? I
22 altered it to spit out colored text to the terminal. It's a bit overwhelming,
22 altered it to spit out colored text to the terminal. It's a bit overwhelming,
23 but kind of neat, and maybe useful for long-running programs that you believe
23 but kind of neat, and maybe useful for long-running programs that you believe
24 are bug-free. If a crash *does* occur in that type of program you want details.
24 are bug-free. If a crash *does* occur in that type of program you want details.
25 Give it a shot--you'll love it or you'll hate it.
25 Give it a shot--you'll love it or you'll hate it.
26
26
27 .. note::
27 .. note::
28
28
29 The Verbose mode prints the variables currently visible where the exception
29 The Verbose mode prints the variables currently visible where the exception
30 happened (shortening their strings if too long). This can potentially be
30 happened (shortening their strings if too long). This can potentially be
31 very slow, if you happen to have a huge data structure whose string
31 very slow, if you happen to have a huge data structure whose string
32 representation is complex to compute. Your computer may appear to freeze for
32 representation is complex to compute. Your computer may appear to freeze for
33 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
33 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
34 with Ctrl-C (maybe hitting it more than once).
34 with Ctrl-C (maybe hitting it more than once).
35
35
36 If you encounter this kind of situation often, you may want to use the
36 If you encounter this kind of situation often, you may want to use the
37 Verbose_novars mode instead of the regular Verbose, which avoids formatting
37 Verbose_novars mode instead of the regular Verbose, which avoids formatting
38 variables (but otherwise includes the information and context given by
38 variables (but otherwise includes the information and context given by
39 Verbose).
39 Verbose).
40
40
41 .. note::
41 .. note::
42
42
43 The verbose mode print all variables in the stack, which means it can
43 The verbose mode print all variables in the stack, which means it can
44 potentially leak sensitive information like access keys, or unencrypted
44 potentially leak sensitive information like access keys, or unencrypted
45 password.
45 password.
46
46
47 Installation instructions for VerboseTB::
47 Installation instructions for VerboseTB::
48
48
49 import sys,ultratb
49 import sys,ultratb
50 sys.excepthook = ultratb.VerboseTB()
50 sys.excepthook = ultratb.VerboseTB()
51
51
52 Note: Much of the code in this module was lifted verbatim from the standard
52 Note: Much of the code in this module was lifted verbatim from the standard
53 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
53 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
54
54
55 Color schemes
55 Color schemes
56 -------------
56 -------------
57
57
58 The colors are defined in the class TBTools through the use of the
58 The colors are defined in the class TBTools through the use of the
59 ColorSchemeTable class. Currently the following exist:
59 ColorSchemeTable class. Currently the following exist:
60
60
61 - NoColor: allows all of this module to be used in any terminal (the color
61 - NoColor: allows all of this module to be used in any terminal (the color
62 escapes are just dummy blank strings).
62 escapes are just dummy blank strings).
63
63
64 - Linux: is meant to look good in a terminal like the Linux console (black
64 - Linux: is meant to look good in a terminal like the Linux console (black
65 or very dark background).
65 or very dark background).
66
66
67 - LightBG: similar to Linux but swaps dark/light colors to be more readable
67 - LightBG: similar to Linux but swaps dark/light colors to be more readable
68 in light background terminals.
68 in light background terminals.
69
69
70 - Neutral: a neutral color scheme that should be readable on both light and
70 - Neutral: a neutral color scheme that should be readable on both light and
71 dark background
71 dark background
72
72
73 You can implement other color schemes easily, the syntax is fairly
73 You can implement other color schemes easily, the syntax is fairly
74 self-explanatory. Please send back new schemes you develop to the author for
74 self-explanatory. Please send back new schemes you develop to the author for
75 possible inclusion in future releases.
75 possible inclusion in future releases.
76
76
77 Inheritance diagram:
77 Inheritance diagram:
78
78
79 .. inheritance-diagram:: IPython.core.ultratb
79 .. inheritance-diagram:: IPython.core.ultratb
80 :parts: 3
80 :parts: 3
81 """
81 """
82
82
83 #*****************************************************************************
83 #*****************************************************************************
84 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
84 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
85 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
85 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
86 #
86 #
87 # Distributed under the terms of the BSD License. The full license is in
87 # Distributed under the terms of the BSD License. The full license is in
88 # the file COPYING, distributed as part of this software.
88 # the file COPYING, distributed as part of this software.
89 #*****************************************************************************
89 #*****************************************************************************
90
90
91
91
92 from collections.abc import Sequence
92 from collections.abc import Sequence
93 import functools
93 import functools
94 import inspect
94 import inspect
95 import linecache
95 import linecache
96 import pydoc
96 import pydoc
97 import sys
97 import sys
98 import time
98 import time
99 import traceback
99 import traceback
100 import types
100 import types
101 from types import TracebackType
101 from types import TracebackType
102 from typing import Any, List, Optional, Tuple
102 from typing import Any, List, Optional, Tuple
103
103
104 import stack_data
104 import stack_data
105 from pygments.formatters.terminal256 import Terminal256Formatter
105 from pygments.formatters.terminal256 import Terminal256Formatter
106 from pygments.styles import get_style_by_name
106 from pygments.styles import get_style_by_name
107
107
108 import IPython.utils.colorable as colorable
108 import IPython.utils.colorable as colorable
109 # IPython's own modules
109 # IPython's own modules
110 from IPython import get_ipython
110 from IPython import get_ipython
111 from IPython.core import debugger
111 from IPython.core import debugger
112 from IPython.core.display_trap import DisplayTrap
112 from IPython.core.display_trap import DisplayTrap
113 from IPython.core.excolors import exception_colors
113 from IPython.core.excolors import exception_colors
114 from IPython.utils import PyColorize
114 from IPython.utils import PyColorize
115 from IPython.utils import path as util_path
115 from IPython.utils import path as util_path
116 from IPython.utils import py3compat
116 from IPython.utils import py3compat
117 from IPython.utils.terminal import get_terminal_size
117 from IPython.utils.terminal import get_terminal_size
118
118
119 # Globals
119 # Globals
120 # amount of space to put line numbers before verbose tracebacks
120 # amount of space to put line numbers before verbose tracebacks
121 INDENT_SIZE = 8
121 INDENT_SIZE = 8
122
122
123 # Default color scheme. This is used, for example, by the traceback
123 # Default color scheme. This is used, for example, by the traceback
124 # formatter. When running in an actual IPython instance, the user's rc.colors
124 # formatter. When running in an actual IPython instance, the user's rc.colors
125 # value is used, but having a module global makes this functionality available
125 # value is used, but having a module global makes this functionality available
126 # to users of ultratb who are NOT running inside ipython.
126 # to users of ultratb who are NOT running inside ipython.
127 DEFAULT_SCHEME = 'NoColor'
127 DEFAULT_SCHEME = 'NoColor'
128 FAST_THRESHOLD = 10_000
128 FAST_THRESHOLD = 10_000
129
129
130 # ---------------------------------------------------------------------------
130 # ---------------------------------------------------------------------------
131 # Code begins
131 # Code begins
132
132
133 # Helper function -- largely belongs to VerboseTB, but we need the same
133 # Helper function -- largely belongs to VerboseTB, but we need the same
134 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
134 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
135 # can be recognized properly by ipython.el's py-traceback-line-re
135 # can be recognized properly by ipython.el's py-traceback-line-re
136 # (SyntaxErrors have to be treated specially because they have no traceback)
136 # (SyntaxErrors have to be treated specially because they have no traceback)
137
137
138
138
139 @functools.lru_cache()
139 @functools.lru_cache()
140 def count_lines_in_py_file(filename: str) -> int:
140 def count_lines_in_py_file(filename: str) -> int:
141 """
141 """
142 Given a filename, returns the number of lines in the file
142 Given a filename, returns the number of lines in the file
143 if it ends with the extension ".py". Otherwise, returns 0.
143 if it ends with the extension ".py". Otherwise, returns 0.
144 """
144 """
145 if not filename.endswith(".py"):
145 if not filename.endswith(".py"):
146 return 0
146 return 0
147 else:
147 else:
148 try:
148 try:
149 with open(filename, "r") as file:
149 with open(filename, "r") as file:
150 s = sum(1 for line in file)
150 s = sum(1 for line in file)
151 except UnicodeError:
151 except UnicodeError:
152 return 0
152 return 0
153 return s
153 return s
154
154
155 """
155 """
156 Given a frame object, returns the total number of lines in the file
156 Given a frame object, returns the total number of lines in the file
157 if the filename ends with the extension ".py". Otherwise, returns 0.
157 if the filename ends with the extension ".py". Otherwise, returns 0.
158 """
158 """
159
159
160
160
161 def get_line_number_of_frame(frame: types.FrameType) -> int:
161 def get_line_number_of_frame(frame: types.FrameType) -> int:
162 """
162 """
163 Given a frame object, returns the total number of lines in the file
163 Given a frame object, returns the total number of lines in the file
164 containing the frame's code object, or the number of lines in the
164 containing the frame's code object, or the number of lines in the
165 frame's source code if the file is not available.
165 frame's source code if the file is not available.
166
166
167 Parameters
167 Parameters
168 ----------
168 ----------
169 frame : FrameType
169 frame : FrameType
170 The frame object whose line number is to be determined.
170 The frame object whose line number is to be determined.
171
171
172 Returns
172 Returns
173 -------
173 -------
174 int
174 int
175 The total number of lines in the file containing the frame's
175 The total number of lines in the file containing the frame's
176 code object, or the number of lines in the frame's source code
176 code object, or the number of lines in the frame's source code
177 if the file is not available.
177 if the file is not available.
178 """
178 """
179 filename = frame.f_code.co_filename
179 filename = frame.f_code.co_filename
180 if filename is None:
180 if filename is None:
181 print("No file....")
181 print("No file....")
182 lines, first = inspect.getsourcelines(frame)
182 lines, first = inspect.getsourcelines(frame)
183 return first + len(lines)
183 return first + len(lines)
184 return count_lines_in_py_file(filename)
184 return count_lines_in_py_file(filename)
185
185
186
186
187 def _safe_string(value, what, func=str):
187 def _safe_string(value, what, func=str):
188 # Copied from cpython/Lib/traceback.py
188 # Copied from cpython/Lib/traceback.py
189 try:
189 try:
190 return func(value)
190 return func(value)
191 except:
191 except:
192 return f"<{what} {func.__name__}() failed>"
192 return f"<{what} {func.__name__}() failed>"
193
193
194
194
195 def _format_traceback_lines(lines, Colors, has_colors: bool, lvals):
195 def _format_traceback_lines(lines, Colors, has_colors: bool, lvals):
196 """
196 """
197 Format tracebacks lines with pointing arrow, leading numbers...
197 Format tracebacks lines with pointing arrow, leading numbers...
198
198
199 Parameters
199 Parameters
200 ----------
200 ----------
201 lines : list[Line]
201 lines : list[Line]
202 Colors
202 Colors
203 ColorScheme used.
203 ColorScheme used.
204 lvals : str
204 lvals : str
205 Values of local variables, already colored, to inject just after the error line.
205 Values of local variables, already colored, to inject just after the error line.
206 """
206 """
207 numbers_width = INDENT_SIZE - 1
207 numbers_width = INDENT_SIZE - 1
208 res = []
208 res = []
209
209
210 for stack_line in lines:
210 for stack_line in lines:
211 if stack_line is stack_data.LINE_GAP:
211 if stack_line is stack_data.LINE_GAP:
212 res.append('%s (...)%s\n' % (Colors.linenoEm, Colors.Normal))
212 res.append('%s (...)%s\n' % (Colors.linenoEm, Colors.Normal))
213 continue
213 continue
214
214
215 line = stack_line.render(pygmented=has_colors).rstrip('\n') + '\n'
215 line = stack_line.render(pygmented=has_colors).rstrip('\n') + '\n'
216 lineno = stack_line.lineno
216 lineno = stack_line.lineno
217 if stack_line.is_current:
217 if stack_line.is_current:
218 # This is the line with the error
218 # This is the line with the error
219 pad = numbers_width - len(str(lineno))
219 pad = numbers_width - len(str(lineno))
220 num = '%s%s' % (debugger.make_arrow(pad), str(lineno))
220 num = '%s%s' % (debugger.make_arrow(pad), str(lineno))
221 start_color = Colors.linenoEm
221 start_color = Colors.linenoEm
222 else:
222 else:
223 num = '%*s' % (numbers_width, lineno)
223 num = '%*s' % (numbers_width, lineno)
224 start_color = Colors.lineno
224 start_color = Colors.lineno
225
225
226 line = '%s%s%s %s' % (start_color, num, Colors.Normal, line)
226 line = '%s%s%s %s' % (start_color, num, Colors.Normal, line)
227
227
228 res.append(line)
228 res.append(line)
229 if lvals and stack_line.is_current:
229 if lvals and stack_line.is_current:
230 res.append(lvals + '\n')
230 res.append(lvals + '\n')
231 return res
231 return res
232
232
233 def _simple_format_traceback_lines(lnum, index, lines, Colors, lvals, _line_format):
233 def _simple_format_traceback_lines(lnum, index, lines, Colors, lvals, _line_format):
234 """
234 """
235 Format tracebacks lines with pointing arrow, leading numbers...
235 Format tracebacks lines with pointing arrow, leading numbers...
236
236
237 Parameters
237 Parameters
238 ==========
238 ==========
239
239
240 lnum: int
240 lnum: int
241 number of the target line of code.
241 number of the target line of code.
242 index: int
242 index: int
243 which line in the list should be highlighted.
243 which line in the list should be highlighted.
244 lines: list[string]
244 lines: list[string]
245 Colors:
245 Colors:
246 ColorScheme used.
246 ColorScheme used.
247 lvals: bytes
247 lvals: bytes
248 Values of local variables, already colored, to inject just after the error line.
248 Values of local variables, already colored, to inject just after the error line.
249 _line_format: f (str) -> (str, bool)
249 _line_format: f (str) -> (str, bool)
250 return (colorized version of str, failure to do so)
250 return (colorized version of str, failure to do so)
251 """
251 """
252 numbers_width = INDENT_SIZE - 1
252 numbers_width = INDENT_SIZE - 1
253 res = []
253 res = []
254 for i, line in enumerate(lines, lnum - index):
254 for i, line in enumerate(lines, lnum - index):
255 # assert isinstance(line, str)
255 # assert isinstance(line, str)
256 line = py3compat.cast_unicode(line)
256 line = py3compat.cast_unicode(line)
257
257
258 new_line, err = _line_format(line, "str")
258 new_line, err = _line_format(line, "str")
259 if not err:
259 if not err:
260 line = new_line
260 line = new_line
261
261
262 if i == lnum:
262 if i == lnum:
263 # This is the line with the error
263 # This is the line with the error
264 pad = numbers_width - len(str(i))
264 pad = numbers_width - len(str(i))
265 num = "%s%s" % (debugger.make_arrow(pad), str(lnum))
265 num = "%s%s" % (debugger.make_arrow(pad), str(lnum))
266 line = "%s%s%s %s%s" % (
266 line = "%s%s%s %s%s" % (
267 Colors.linenoEm,
267 Colors.linenoEm,
268 num,
268 num,
269 Colors.line,
269 Colors.line,
270 line,
270 line,
271 Colors.Normal,
271 Colors.Normal,
272 )
272 )
273 else:
273 else:
274 num = "%*s" % (numbers_width, i)
274 num = "%*s" % (numbers_width, i)
275 line = "%s%s%s %s" % (Colors.lineno, num, Colors.Normal, line)
275 line = "%s%s%s %s" % (Colors.lineno, num, Colors.Normal, line)
276
276
277 res.append(line)
277 res.append(line)
278 if lvals and i == lnum:
278 if lvals and i == lnum:
279 res.append(lvals + "\n")
279 res.append(lvals + "\n")
280 return res
280 return res
281
281
282
282
283 def _format_filename(file, ColorFilename, ColorNormal, *, lineno=None):
283 def _format_filename(file, ColorFilename, ColorNormal, *, lineno=None):
284 """
284 """
285 Format filename lines with custom formatting from caching compiler or `File *.py` by default
285 Format filename lines with custom formatting from caching compiler or `File *.py` by default
286
286
287 Parameters
287 Parameters
288 ----------
288 ----------
289 file : str
289 file : str
290 ColorFilename
290 ColorFilename
291 ColorScheme's filename coloring to be used.
291 ColorScheme's filename coloring to be used.
292 ColorNormal
292 ColorNormal
293 ColorScheme's normal coloring to be used.
293 ColorScheme's normal coloring to be used.
294 """
294 """
295 ipinst = get_ipython()
295 ipinst = get_ipython()
296 if (
296 if (
297 ipinst is not None
297 ipinst is not None
298 and (data := ipinst.compile.format_code_name(file)) is not None
298 and (data := ipinst.compile.format_code_name(file)) is not None
299 ):
299 ):
300 label, name = data
300 label, name = data
301 if lineno is None:
301 if lineno is None:
302 tpl_link = f"{{label}} {ColorFilename}{{name}}{ColorNormal}"
302 tpl_link = f"{{label}} {ColorFilename}{{name}}{ColorNormal}"
303 else:
303 else:
304 tpl_link = (
304 tpl_link = (
305 f"{{label}} {ColorFilename}{{name}}, line {{lineno}}{ColorNormal}"
305 f"{{label}} {ColorFilename}{{name}}, line {{lineno}}{ColorNormal}"
306 )
306 )
307 else:
307 else:
308 label = "File"
308 label = "File"
309 name = util_path.compress_user(
309 name = util_path.compress_user(
310 py3compat.cast_unicode(file, util_path.fs_encoding)
310 py3compat.cast_unicode(file, util_path.fs_encoding)
311 )
311 )
312 if lineno is None:
312 if lineno is None:
313 tpl_link = f"{{label}} {ColorFilename}{{name}}{ColorNormal}"
313 tpl_link = f"{{label}} {ColorFilename}{{name}}{ColorNormal}"
314 else:
314 else:
315 # can we make this the more friendly ", line {{lineno}}", or do we need to preserve the formatting with the colon?
315 # can we make this the more friendly ", line {{lineno}}", or do we need to preserve the formatting with the colon?
316 tpl_link = f"{{label}} {ColorFilename}{{name}}:{{lineno}}{ColorNormal}"
316 tpl_link = f"{{label}} {ColorFilename}{{name}}:{{lineno}}{ColorNormal}"
317
317
318 return tpl_link.format(label=label, name=name, lineno=lineno)
318 return tpl_link.format(label=label, name=name, lineno=lineno)
319
319
320 #---------------------------------------------------------------------------
320 #---------------------------------------------------------------------------
321 # Module classes
321 # Module classes
322 class TBTools(colorable.Colorable):
322 class TBTools(colorable.Colorable):
323 """Basic tools used by all traceback printer classes."""
323 """Basic tools used by all traceback printer classes."""
324
324
325 # Number of frames to skip when reporting tracebacks
325 # Number of frames to skip when reporting tracebacks
326 tb_offset = 0
326 tb_offset = 0
327
327
328 def __init__(
328 def __init__(
329 self,
329 self,
330 color_scheme="NoColor",
330 color_scheme="NoColor",
331 call_pdb=False,
331 call_pdb=False,
332 ostream=None,
332 ostream=None,
333 parent=None,
333 parent=None,
334 config=None,
334 config=None,
335 *,
335 *,
336 debugger_cls=None,
336 debugger_cls=None,
337 ):
337 ):
338 # Whether to call the interactive pdb debugger after printing
338 # Whether to call the interactive pdb debugger after printing
339 # tracebacks or not
339 # tracebacks or not
340 super(TBTools, self).__init__(parent=parent, config=config)
340 super(TBTools, self).__init__(parent=parent, config=config)
341 self.call_pdb = call_pdb
341 self.call_pdb = call_pdb
342
342
343 # Output stream to write to. Note that we store the original value in
343 # Output stream to write to. Note that we store the original value in
344 # a private attribute and then make the public ostream a property, so
344 # a private attribute and then make the public ostream a property, so
345 # that we can delay accessing sys.stdout until runtime. The way
345 # that we can delay accessing sys.stdout until runtime. The way
346 # things are written now, the sys.stdout object is dynamically managed
346 # things are written now, the sys.stdout object is dynamically managed
347 # so a reference to it should NEVER be stored statically. This
347 # so a reference to it should NEVER be stored statically. This
348 # property approach confines this detail to a single location, and all
348 # property approach confines this detail to a single location, and all
349 # subclasses can simply access self.ostream for writing.
349 # subclasses can simply access self.ostream for writing.
350 self._ostream = ostream
350 self._ostream = ostream
351
351
352 # Create color table
352 # Create color table
353 self.color_scheme_table = exception_colors()
353 self.color_scheme_table = exception_colors()
354
354
355 self.set_colors(color_scheme)
355 self.set_colors(color_scheme)
356 self.old_scheme = color_scheme # save initial value for toggles
356 self.old_scheme = color_scheme # save initial value for toggles
357 self.debugger_cls = debugger_cls or debugger.Pdb
357 self.debugger_cls = debugger_cls or debugger.Pdb
358
358
359 if call_pdb:
359 if call_pdb:
360 self.pdb = self.debugger_cls()
360 self.pdb = self.debugger_cls()
361 else:
361 else:
362 self.pdb = None
362 self.pdb = None
363
363
364 def _get_ostream(self):
364 def _get_ostream(self):
365 """Output stream that exceptions are written to.
365 """Output stream that exceptions are written to.
366
366
367 Valid values are:
367 Valid values are:
368
368
369 - None: the default, which means that IPython will dynamically resolve
369 - None: the default, which means that IPython will dynamically resolve
370 to sys.stdout. This ensures compatibility with most tools, including
370 to sys.stdout. This ensures compatibility with most tools, including
371 Windows (where plain stdout doesn't recognize ANSI escapes).
371 Windows (where plain stdout doesn't recognize ANSI escapes).
372
372
373 - Any object with 'write' and 'flush' attributes.
373 - Any object with 'write' and 'flush' attributes.
374 """
374 """
375 return sys.stdout if self._ostream is None else self._ostream
375 return sys.stdout if self._ostream is None else self._ostream
376
376
377 def _set_ostream(self, val):
377 def _set_ostream(self, val):
378 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
378 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
379 self._ostream = val
379 self._ostream = val
380
380
381 ostream = property(_get_ostream, _set_ostream)
381 ostream = property(_get_ostream, _set_ostream)
382
382
383 @staticmethod
383 @staticmethod
384 def _get_chained_exception(exception_value):
384 def _get_chained_exception(exception_value):
385 cause = getattr(exception_value, "__cause__", None)
385 cause = getattr(exception_value, "__cause__", None)
386 if cause:
386 if cause:
387 return cause
387 return cause
388 if getattr(exception_value, "__suppress_context__", False):
388 if getattr(exception_value, "__suppress_context__", False):
389 return None
389 return None
390 return getattr(exception_value, "__context__", None)
390 return getattr(exception_value, "__context__", None)
391
391
392 def get_parts_of_chained_exception(
392 def get_parts_of_chained_exception(
393 self, evalue
393 self, evalue
394 ) -> Optional[Tuple[type, BaseException, TracebackType]]:
394 ) -> Optional[Tuple[type, BaseException, TracebackType]]:
395 chained_evalue = self._get_chained_exception(evalue)
395 chained_evalue = self._get_chained_exception(evalue)
396
396
397 if chained_evalue:
397 if chained_evalue:
398 return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__
398 return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__
399 return None
399 return None
400
400
401 def prepare_chained_exception_message(self, cause) -> List[Any]:
401 def prepare_chained_exception_message(self, cause) -> List[Any]:
402 direct_cause = "\nThe above exception was the direct cause of the following exception:\n"
402 direct_cause = "\nThe above exception was the direct cause of the following exception:\n"
403 exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n"
403 exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n"
404
404
405 if cause:
405 if cause:
406 message = [[direct_cause]]
406 message = [[direct_cause]]
407 else:
407 else:
408 message = [[exception_during_handling]]
408 message = [[exception_during_handling]]
409 return message
409 return message
410
410
411 @property
411 @property
412 def has_colors(self) -> bool:
412 def has_colors(self) -> bool:
413 return self.color_scheme_table.active_scheme_name.lower() != "nocolor"
413 return self.color_scheme_table.active_scheme_name.lower() != "nocolor"
414
414
415 def set_colors(self, *args, **kw):
415 def set_colors(self, *args, **kw):
416 """Shorthand access to the color table scheme selector method."""
416 """Shorthand access to the color table scheme selector method."""
417
417
418 # Set own color table
418 # Set own color table
419 self.color_scheme_table.set_active_scheme(*args, **kw)
419 self.color_scheme_table.set_active_scheme(*args, **kw)
420 # for convenience, set Colors to the active scheme
420 # for convenience, set Colors to the active scheme
421 self.Colors = self.color_scheme_table.active_colors
421 self.Colors = self.color_scheme_table.active_colors
422 # Also set colors of debugger
422 # Also set colors of debugger
423 if hasattr(self, 'pdb') and self.pdb is not None:
423 if hasattr(self, 'pdb') and self.pdb is not None:
424 self.pdb.set_colors(*args, **kw)
424 self.pdb.set_colors(*args, **kw)
425
425
426 def color_toggle(self):
426 def color_toggle(self):
427 """Toggle between the currently active color scheme and NoColor."""
427 """Toggle between the currently active color scheme and NoColor."""
428
428
429 if self.color_scheme_table.active_scheme_name == 'NoColor':
429 if self.color_scheme_table.active_scheme_name == 'NoColor':
430 self.color_scheme_table.set_active_scheme(self.old_scheme)
430 self.color_scheme_table.set_active_scheme(self.old_scheme)
431 self.Colors = self.color_scheme_table.active_colors
431 self.Colors = self.color_scheme_table.active_colors
432 else:
432 else:
433 self.old_scheme = self.color_scheme_table.active_scheme_name
433 self.old_scheme = self.color_scheme_table.active_scheme_name
434 self.color_scheme_table.set_active_scheme('NoColor')
434 self.color_scheme_table.set_active_scheme('NoColor')
435 self.Colors = self.color_scheme_table.active_colors
435 self.Colors = self.color_scheme_table.active_colors
436
436
437 def stb2text(self, stb):
437 def stb2text(self, stb):
438 """Convert a structured traceback (a list) to a string."""
438 """Convert a structured traceback (a list) to a string."""
439 return '\n'.join(stb)
439 return '\n'.join(stb)
440
440
441 def text(self, etype, value, tb, tb_offset: Optional[int] = None, context=5):
441 def text(self, etype, value, tb, tb_offset: Optional[int] = None, context=5):
442 """Return formatted traceback.
442 """Return formatted traceback.
443
443
444 Subclasses may override this if they add extra arguments.
444 Subclasses may override this if they add extra arguments.
445 """
445 """
446 tb_list = self.structured_traceback(etype, value, tb,
446 tb_list = self.structured_traceback(etype, value, tb,
447 tb_offset, context)
447 tb_offset, context)
448 return self.stb2text(tb_list)
448 return self.stb2text(tb_list)
449
449
450 def structured_traceback(
450 def structured_traceback(
451 self,
451 self,
452 etype: type,
452 etype: type,
453 evalue: Optional[BaseException],
453 evalue: Optional[BaseException],
454 etb: Optional[TracebackType] = None,
454 etb: Optional[TracebackType] = None,
455 tb_offset: Optional[int] = None,
455 tb_offset: Optional[int] = None,
456 number_of_lines_of_context: int = 5,
456 number_of_lines_of_context: int = 5,
457 ):
457 ):
458 """Return a list of traceback frames.
458 """Return a list of traceback frames.
459
459
460 Must be implemented by each class.
460 Must be implemented by each class.
461 """
461 """
462 raise NotImplementedError()
462 raise NotImplementedError()
463
463
464
464
465 #---------------------------------------------------------------------------
465 #---------------------------------------------------------------------------
466 class ListTB(TBTools):
466 class ListTB(TBTools):
467 """Print traceback information from a traceback list, with optional color.
467 """Print traceback information from a traceback list, with optional color.
468
468
469 Calling requires 3 arguments: (etype, evalue, elist)
469 Calling requires 3 arguments: (etype, evalue, elist)
470 as would be obtained by::
470 as would be obtained by::
471
471
472 etype, evalue, tb = sys.exc_info()
472 etype, evalue, tb = sys.exc_info()
473 if tb:
473 if tb:
474 elist = traceback.extract_tb(tb)
474 elist = traceback.extract_tb(tb)
475 else:
475 else:
476 elist = None
476 elist = None
477
477
478 It can thus be used by programs which need to process the traceback before
478 It can thus be used by programs which need to process the traceback before
479 printing (such as console replacements based on the code module from the
479 printing (such as console replacements based on the code module from the
480 standard library).
480 standard library).
481
481
482 Because they are meant to be called without a full traceback (only a
482 Because they are meant to be called without a full traceback (only a
483 list), instances of this class can't call the interactive pdb debugger."""
483 list), instances of this class can't call the interactive pdb debugger."""
484
484
485
485
486 def __call__(self, etype, value, elist):
486 def __call__(self, etype, value, elist):
487 self.ostream.flush()
487 self.ostream.flush()
488 self.ostream.write(self.text(etype, value, elist))
488 self.ostream.write(self.text(etype, value, elist))
489 self.ostream.write('\n')
489 self.ostream.write('\n')
490
490
491 def _extract_tb(self, tb):
491 def _extract_tb(self, tb):
492 if tb:
492 if tb:
493 return traceback.extract_tb(tb)
493 return traceback.extract_tb(tb)
494 else:
494 else:
495 return None
495 return None
496
496
497 def structured_traceback(
497 def structured_traceback(
498 self,
498 self,
499 etype: type,
499 etype: type,
500 evalue: Optional[BaseException],
500 evalue: Optional[BaseException],
501 etb: Optional[TracebackType] = None,
501 etb: Optional[TracebackType] = None,
502 tb_offset: Optional[int] = None,
502 tb_offset: Optional[int] = None,
503 context=5,
503 context=5,
504 ):
504 ):
505 """Return a color formatted string with the traceback info.
505 """Return a color formatted string with the traceback info.
506
506
507 Parameters
507 Parameters
508 ----------
508 ----------
509 etype : exception type
509 etype : exception type
510 Type of the exception raised.
510 Type of the exception raised.
511 evalue : object
511 evalue : object
512 Data stored in the exception
512 Data stored in the exception
513 etb : list | TracebackType | None
513 etb : list | TracebackType | None
514 If list: List of frames, see class docstring for details.
514 If list: List of frames, see class docstring for details.
515 If Traceback: Traceback of the exception.
515 If Traceback: Traceback of the exception.
516 tb_offset : int, optional
516 tb_offset : int, optional
517 Number of frames in the traceback to skip. If not given, the
517 Number of frames in the traceback to skip. If not given, the
518 instance evalue is used (set in constructor).
518 instance evalue is used (set in constructor).
519 context : int, optional
519 context : int, optional
520 Number of lines of context information to print.
520 Number of lines of context information to print.
521
521
522 Returns
522 Returns
523 -------
523 -------
524 String with formatted exception.
524 String with formatted exception.
525 """
525 """
526 # This is a workaround to get chained_exc_ids in recursive calls
526 # This is a workaround to get chained_exc_ids in recursive calls
527 # etb should not be a tuple if structured_traceback is not recursive
527 # etb should not be a tuple if structured_traceback is not recursive
528 if isinstance(etb, tuple):
528 if isinstance(etb, tuple):
529 etb, chained_exc_ids = etb
529 etb, chained_exc_ids = etb
530 else:
530 else:
531 chained_exc_ids = set()
531 chained_exc_ids = set()
532
532
533 if isinstance(etb, list):
533 if isinstance(etb, list):
534 elist = etb
534 elist = etb
535 elif etb is not None:
535 elif etb is not None:
536 elist = self._extract_tb(etb)
536 elist = self._extract_tb(etb)
537 else:
537 else:
538 elist = []
538 elist = []
539 tb_offset = self.tb_offset if tb_offset is None else tb_offset
539 tb_offset = self.tb_offset if tb_offset is None else tb_offset
540 assert isinstance(tb_offset, int)
540 assert isinstance(tb_offset, int)
541 Colors = self.Colors
541 Colors = self.Colors
542 out_list = []
542 out_list = []
543 if elist:
543 if elist:
544
544
545 if tb_offset and len(elist) > tb_offset:
545 if tb_offset and len(elist) > tb_offset:
546 elist = elist[tb_offset:]
546 elist = elist[tb_offset:]
547
547
548 out_list.append('Traceback %s(most recent call last)%s:' %
548 out_list.append('Traceback %s(most recent call last)%s:' %
549 (Colors.normalEm, Colors.Normal) + '\n')
549 (Colors.normalEm, Colors.Normal) + '\n')
550 out_list.extend(self._format_list(elist))
550 out_list.extend(self._format_list(elist))
551 # The exception info should be a single entry in the list.
551 # The exception info should be a single entry in the list.
552 lines = ''.join(self._format_exception_only(etype, evalue))
552 lines = ''.join(self._format_exception_only(etype, evalue))
553 out_list.append(lines)
553 out_list.append(lines)
554
554
555 exception = self.get_parts_of_chained_exception(evalue)
555 exception = self.get_parts_of_chained_exception(evalue)
556
556
557 if exception and (id(exception[1]) not in chained_exc_ids):
557 if exception and (id(exception[1]) not in chained_exc_ids):
558 chained_exception_message = (
558 chained_exception_message = (
559 self.prepare_chained_exception_message(evalue.__cause__)[0]
559 self.prepare_chained_exception_message(evalue.__cause__)[0]
560 if evalue is not None
560 if evalue is not None
561 else ""
561 else ""
562 )
562 )
563 etype, evalue, etb = exception
563 etype, evalue, etb = exception
564 # Trace exception to avoid infinite 'cause' loop
564 # Trace exception to avoid infinite 'cause' loop
565 chained_exc_ids.add(id(exception[1]))
565 chained_exc_ids.add(id(exception[1]))
566 chained_exceptions_tb_offset = 0
566 chained_exceptions_tb_offset = 0
567 out_list = (
567 out_list = (
568 self.structured_traceback(
568 self.structured_traceback(
569 etype,
569 etype,
570 evalue,
570 evalue,
571 (etb, chained_exc_ids), # type: ignore
571 (etb, chained_exc_ids), # type: ignore
572 chained_exceptions_tb_offset,
572 chained_exceptions_tb_offset,
573 context,
573 context,
574 )
574 )
575 + chained_exception_message
575 + chained_exception_message
576 + out_list)
576 + out_list)
577
577
578 return out_list
578 return out_list
579
579
580 def _format_list(self, extracted_list):
580 def _format_list(self, extracted_list):
581 """Format a list of traceback entry tuples for printing.
581 """Format a list of traceback entry tuples for printing.
582
582
583 Given a list of tuples as returned by extract_tb() or
583 Given a list of tuples as returned by extract_tb() or
584 extract_stack(), return a list of strings ready for printing.
584 extract_stack(), return a list of strings ready for printing.
585 Each string in the resulting list corresponds to the item with the
585 Each string in the resulting list corresponds to the item with the
586 same index in the argument list. Each string ends in a newline;
586 same index in the argument list. Each string ends in a newline;
587 the strings may contain internal newlines as well, for those items
587 the strings may contain internal newlines as well, for those items
588 whose source text line is not None.
588 whose source text line is not None.
589
589
590 Lifted almost verbatim from traceback.py
590 Lifted almost verbatim from traceback.py
591 """
591 """
592
592
593 Colors = self.Colors
593 Colors = self.Colors
594 output_list = []
594 output_list = []
595 for ind, (filename, lineno, name, line) in enumerate(extracted_list):
595 for ind, (filename, lineno, name, line) in enumerate(extracted_list):
596 normalCol, nameCol, fileCol, lineCol = (
596 normalCol, nameCol, fileCol, lineCol = (
597 # Emphasize the last entry
597 # Emphasize the last entry
598 (Colors.normalEm, Colors.nameEm, Colors.filenameEm, Colors.line)
598 (Colors.normalEm, Colors.nameEm, Colors.filenameEm, Colors.line)
599 if ind == len(extracted_list) - 1
599 if ind == len(extracted_list) - 1
600 else (Colors.Normal, Colors.name, Colors.filename, "")
600 else (Colors.Normal, Colors.name, Colors.filename, "")
601 )
601 )
602
602
603 fns = _format_filename(filename, fileCol, normalCol, lineno=lineno)
603 fns = _format_filename(filename, fileCol, normalCol, lineno=lineno)
604 item = f"{normalCol} {fns}"
604 item = f"{normalCol} {fns}"
605
605
606 if name != "<module>":
606 if name != "<module>":
607 item += f" in {nameCol}{name}{normalCol}\n"
607 item += f" in {nameCol}{name}{normalCol}\n"
608 else:
608 else:
609 item += "\n"
609 item += "\n"
610 if line:
610 if line:
611 item += f"{lineCol} {line.strip()}{normalCol}\n"
611 item += f"{lineCol} {line.strip()}{normalCol}\n"
612 output_list.append(item)
612 output_list.append(item)
613
613
614 return output_list
614 return output_list
615
615
616 def _format_exception_only(self, etype, value):
616 def _format_exception_only(self, etype, value):
617 """Format the exception part of a traceback.
617 """Format the exception part of a traceback.
618
618
619 The arguments are the exception type and value such as given by
619 The arguments are the exception type and value such as given by
620 sys.exc_info()[:2]. The return value is a list of strings, each ending
620 sys.exc_info()[:2]. The return value is a list of strings, each ending
621 in a newline. Normally, the list contains a single string; however,
621 in a newline. Normally, the list contains a single string; however,
622 for SyntaxError exceptions, it contains several lines that (when
622 for SyntaxError exceptions, it contains several lines that (when
623 printed) display detailed information about where the syntax error
623 printed) display detailed information about where the syntax error
624 occurred. The message indicating which exception occurred is the
624 occurred. The message indicating which exception occurred is the
625 always last string in the list.
625 always last string in the list.
626
626
627 Also lifted nearly verbatim from traceback.py
627 Also lifted nearly verbatim from traceback.py
628 """
628 """
629 have_filedata = False
629 have_filedata = False
630 Colors = self.Colors
630 Colors = self.Colors
631 output_list = []
631 output_list = []
632 stype = py3compat.cast_unicode(Colors.excName + etype.__name__ + Colors.Normal)
632 stype = py3compat.cast_unicode(Colors.excName + etype.__name__ + Colors.Normal)
633 if value is None:
633 if value is None:
634 # Not sure if this can still happen in Python 2.6 and above
634 # Not sure if this can still happen in Python 2.6 and above
635 output_list.append(stype + "\n")
635 output_list.append(stype + "\n")
636 else:
636 else:
637 if issubclass(etype, SyntaxError):
637 if issubclass(etype, SyntaxError):
638 have_filedata = True
638 have_filedata = True
639 if not value.filename: value.filename = "<string>"
639 if not value.filename: value.filename = "<string>"
640 if value.lineno:
640 if value.lineno:
641 lineno = value.lineno
641 lineno = value.lineno
642 textline = linecache.getline(value.filename, value.lineno)
642 textline = linecache.getline(value.filename, value.lineno)
643 else:
643 else:
644 lineno = "unknown"
644 lineno = "unknown"
645 textline = ""
645 textline = ""
646 output_list.append(
646 output_list.append(
647 "%s %s%s\n"
647 "%s %s%s\n"
648 % (
648 % (
649 Colors.normalEm,
649 Colors.normalEm,
650 _format_filename(
650 _format_filename(
651 value.filename,
651 value.filename,
652 Colors.filenameEm,
652 Colors.filenameEm,
653 Colors.normalEm,
653 Colors.normalEm,
654 lineno=(None if lineno == "unknown" else lineno),
654 lineno=(None if lineno == "unknown" else lineno),
655 ),
655 ),
656 Colors.Normal,
656 Colors.Normal,
657 )
657 )
658 )
658 )
659 if textline == "":
659 if textline == "":
660 textline = py3compat.cast_unicode(value.text, "utf-8")
660 textline = py3compat.cast_unicode(value.text, "utf-8")
661
661
662 if textline is not None:
662 if textline is not None:
663 i = 0
663 i = 0
664 while i < len(textline) and textline[i].isspace():
664 while i < len(textline) and textline[i].isspace():
665 i += 1
665 i += 1
666 output_list.append(
666 output_list.append(
667 "%s %s%s\n" % (Colors.line, textline.strip(), Colors.Normal)
667 "%s %s%s\n" % (Colors.line, textline.strip(), Colors.Normal)
668 )
668 )
669 if value.offset is not None:
669 if value.offset is not None:
670 s = ' '
670 s = ' '
671 for c in textline[i:value.offset - 1]:
671 for c in textline[i:value.offset - 1]:
672 if c.isspace():
672 if c.isspace():
673 s += c
673 s += c
674 else:
674 else:
675 s += " "
675 s += " "
676 output_list.append(
676 output_list.append(
677 "%s%s^%s\n" % (Colors.caret, s, Colors.Normal)
677 "%s%s^%s\n" % (Colors.caret, s, Colors.Normal)
678 )
678 )
679
679
680 try:
680 try:
681 s = value.msg
681 s = value.msg
682 except Exception:
682 except Exception:
683 s = self._some_str(value)
683 s = self._some_str(value)
684 if s:
684 if s:
685 output_list.append(
685 output_list.append(
686 "%s%s:%s %s\n" % (stype, Colors.excName, Colors.Normal, s)
686 "%s%s:%s %s\n" % (stype, Colors.excName, Colors.Normal, s)
687 )
687 )
688 else:
688 else:
689 output_list.append("%s\n" % stype)
689 output_list.append("%s\n" % stype)
690
690
691 # PEP-678 notes
691 # PEP-678 notes
692 output_list.extend(f"{x}\n" for x in getattr(value, "__notes__", []))
692 output_list.extend(f"{x}\n" for x in getattr(value, "__notes__", []))
693
693
694 # sync with user hooks
694 # sync with user hooks
695 if have_filedata:
695 if have_filedata:
696 ipinst = get_ipython()
696 ipinst = get_ipython()
697 if ipinst is not None:
697 if ipinst is not None:
698 ipinst.hooks.synchronize_with_editor(value.filename, value.lineno, 0)
698 ipinst.hooks.synchronize_with_editor(value.filename, value.lineno, 0)
699
699
700 return output_list
700 return output_list
701
701
702 def get_exception_only(self, etype, value):
702 def get_exception_only(self, etype, value):
703 """Only print the exception type and message, without a traceback.
703 """Only print the exception type and message, without a traceback.
704
704
705 Parameters
705 Parameters
706 ----------
706 ----------
707 etype : exception type
707 etype : exception type
708 value : exception value
708 value : exception value
709 """
709 """
710 return ListTB.structured_traceback(self, etype, value)
710 return ListTB.structured_traceback(self, etype, value)
711
711
712 def show_exception_only(self, etype, evalue):
712 def show_exception_only(self, etype, evalue):
713 """Only print the exception type and message, without a traceback.
713 """Only print the exception type and message, without a traceback.
714
714
715 Parameters
715 Parameters
716 ----------
716 ----------
717 etype : exception type
717 etype : exception type
718 evalue : exception value
718 evalue : exception value
719 """
719 """
720 # This method needs to use __call__ from *this* class, not the one from
720 # This method needs to use __call__ from *this* class, not the one from
721 # a subclass whose signature or behavior may be different
721 # a subclass whose signature or behavior may be different
722 ostream = self.ostream
722 ostream = self.ostream
723 ostream.flush()
723 ostream.flush()
724 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
724 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
725 ostream.flush()
725 ostream.flush()
726
726
727 def _some_str(self, value):
727 def _some_str(self, value):
728 # Lifted from traceback.py
728 # Lifted from traceback.py
729 try:
729 try:
730 return py3compat.cast_unicode(str(value))
730 return py3compat.cast_unicode(str(value))
731 except:
731 except:
732 return u'<unprintable %s object>' % type(value).__name__
732 return u'<unprintable %s object>' % type(value).__name__
733
733
734
734
735 class FrameInfo:
735 class FrameInfo:
736 """
736 """
737 Mirror of stack data's FrameInfo, but so that we can bypass highlighting on
737 Mirror of stack data's FrameInfo, but so that we can bypass highlighting on
738 really long frames.
738 really long frames.
739 """
739 """
740
740
741 description: Optional[str]
741 description: Optional[str]
742 filename: Optional[str]
742 filename: Optional[str]
743 lineno: Tuple[int]
743 lineno: Tuple[int]
744 # number of context lines to use
744 # number of context lines to use
745 context: Optional[int]
745 context: Optional[int]
746
746
747 @classmethod
747 @classmethod
748 def _from_stack_data_FrameInfo(cls, frame_info):
748 def _from_stack_data_FrameInfo(cls, frame_info):
749 return cls(
749 return cls(
750 getattr(frame_info, "description", None),
750 getattr(frame_info, "description", None),
751 getattr(frame_info, "filename", None), # type: ignore[arg-type]
751 getattr(frame_info, "filename", None), # type: ignore[arg-type]
752 getattr(frame_info, "lineno", None), # type: ignore[arg-type]
752 getattr(frame_info, "lineno", None), # type: ignore[arg-type]
753 getattr(frame_info, "frame", None),
753 getattr(frame_info, "frame", None),
754 getattr(frame_info, "code", None),
754 getattr(frame_info, "code", None),
755 sd=frame_info,
755 sd=frame_info,
756 context=None,
756 context=None,
757 )
757 )
758
758
759 def __init__(
759 def __init__(
760 self,
760 self,
761 description: Optional[str],
761 description: Optional[str],
762 filename: str,
762 filename: str,
763 lineno: Tuple[int],
763 lineno: Tuple[int],
764 frame,
764 frame,
765 code,
765 code,
766 *,
766 *,
767 sd=None,
767 sd=None,
768 context=None,
768 context=None,
769 ):
769 ):
770 self.description = description
770 self.description = description
771 self.filename = filename
771 self.filename = filename
772 self.lineno = lineno
772 self.lineno = lineno
773 self.frame = frame
773 self.frame = frame
774 self.code = code
774 self.code = code
775 self._sd = sd
775 self._sd = sd
776 self.context = context
776 self.context = context
777
777
778 # self.lines = []
778 # self.lines = []
779 if sd is None:
779 if sd is None:
780 ix = inspect.getsourcelines(frame)
780 ix = inspect.getsourcelines(frame)
781 self.raw_lines = ix[0]
781 self.raw_lines = ix[0]
782
782
783 @property
783 @property
784 def variables_in_executing_piece(self):
784 def variables_in_executing_piece(self):
785 if self._sd:
785 if self._sd:
786 return self._sd.variables_in_executing_piece
786 return self._sd.variables_in_executing_piece
787 else:
787 else:
788 return []
788 return []
789
789
790 @property
790 @property
791 def lines(self):
791 def lines(self):
792 return self._sd.lines
792 return self._sd.lines
793
793
794 @property
794 @property
795 def executing(self):
795 def executing(self):
796 if self._sd:
796 if self._sd:
797 return self._sd.executing
797 return self._sd.executing
798 else:
798 else:
799 return None
799 return None
800
800
801
801
802 # ----------------------------------------------------------------------------
802 # ----------------------------------------------------------------------------
803 class VerboseTB(TBTools):
803 class VerboseTB(TBTools):
804 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
804 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
805 of HTML. Requires inspect and pydoc. Crazy, man.
805 of HTML. Requires inspect and pydoc. Crazy, man.
806
806
807 Modified version which optionally strips the topmost entries from the
807 Modified version which optionally strips the topmost entries from the
808 traceback, to be used with alternate interpreters (because their own code
808 traceback, to be used with alternate interpreters (because their own code
809 would appear in the traceback)."""
809 would appear in the traceback)."""
810
810
811 _tb_highlight = "bg:ansiyellow"
811 _tb_highlight = "bg:ansiyellow"
812 _tb_highlight_style = "default"
812 _tb_highlight_style = "default"
813
813
814 def __init__(
814 def __init__(
815 self,
815 self,
816 color_scheme: str = "Linux",
816 color_scheme: str = "Linux",
817 call_pdb: bool = False,
817 call_pdb: bool = False,
818 ostream=None,
818 ostream=None,
819 tb_offset: int = 0,
819 tb_offset: int = 0,
820 long_header: bool = False,
820 long_header: bool = False,
821 include_vars: bool = True,
821 include_vars: bool = True,
822 check_cache=None,
822 check_cache=None,
823 debugger_cls=None,
823 debugger_cls=None,
824 parent=None,
824 parent=None,
825 config=None,
825 config=None,
826 ):
826 ):
827 """Specify traceback offset, headers and color scheme.
827 """Specify traceback offset, headers and color scheme.
828
828
829 Define how many frames to drop from the tracebacks. Calling it with
829 Define how many frames to drop from the tracebacks. Calling it with
830 tb_offset=1 allows use of this handler in interpreters which will have
830 tb_offset=1 allows use of this handler in interpreters which will have
831 their own code at the top of the traceback (VerboseTB will first
831 their own code at the top of the traceback (VerboseTB will first
832 remove that frame before printing the traceback info)."""
832 remove that frame before printing the traceback info)."""
833 TBTools.__init__(
833 TBTools.__init__(
834 self,
834 self,
835 color_scheme=color_scheme,
835 color_scheme=color_scheme,
836 call_pdb=call_pdb,
836 call_pdb=call_pdb,
837 ostream=ostream,
837 ostream=ostream,
838 parent=parent,
838 parent=parent,
839 config=config,
839 config=config,
840 debugger_cls=debugger_cls,
840 debugger_cls=debugger_cls,
841 )
841 )
842 self.tb_offset = tb_offset
842 self.tb_offset = tb_offset
843 self.long_header = long_header
843 self.long_header = long_header
844 self.include_vars = include_vars
844 self.include_vars = include_vars
845 # By default we use linecache.checkcache, but the user can provide a
845 # By default we use linecache.checkcache, but the user can provide a
846 # different check_cache implementation. This was formerly used by the
846 # different check_cache implementation. This was formerly used by the
847 # IPython kernel for interactive code, but is no longer necessary.
847 # IPython kernel for interactive code, but is no longer necessary.
848 if check_cache is None:
848 if check_cache is None:
849 check_cache = linecache.checkcache
849 check_cache = linecache.checkcache
850 self.check_cache = check_cache
850 self.check_cache = check_cache
851
851
852 self.skip_hidden = True
852 self.skip_hidden = True
853
853
854 def format_record(self, frame_info: FrameInfo):
854 def format_record(self, frame_info: FrameInfo):
855 """Format a single stack frame"""
855 """Format a single stack frame"""
856 assert isinstance(frame_info, FrameInfo)
856 assert isinstance(frame_info, FrameInfo)
857 Colors = self.Colors # just a shorthand + quicker name lookup
857 Colors = self.Colors # just a shorthand + quicker name lookup
858 ColorsNormal = Colors.Normal # used a lot
858 ColorsNormal = Colors.Normal # used a lot
859
859
860 if isinstance(frame_info._sd, stack_data.RepeatedFrames):
860 if isinstance(frame_info._sd, stack_data.RepeatedFrames):
861 return ' %s[... skipping similar frames: %s]%s\n' % (
861 return ' %s[... skipping similar frames: %s]%s\n' % (
862 Colors.excName, frame_info.description, ColorsNormal)
862 Colors.excName, frame_info.description, ColorsNormal)
863
863
864 indent = " " * INDENT_SIZE
864 indent = " " * INDENT_SIZE
865 em_normal = "%s\n%s%s" % (Colors.valEm, indent, ColorsNormal)
865 em_normal = "%s\n%s%s" % (Colors.valEm, indent, ColorsNormal)
866 tpl_call = f"in {Colors.vName}{{file}}{Colors.valEm}{{scope}}{ColorsNormal}"
866 tpl_call = f"in {Colors.vName}{{file}}{Colors.valEm}{{scope}}{ColorsNormal}"
867 tpl_call_fail = "in %s%%s%s(***failed resolving arguments***)%s" % (
867 tpl_call_fail = "in %s%%s%s(***failed resolving arguments***)%s" % (
868 Colors.vName,
868 Colors.vName,
869 Colors.valEm,
869 Colors.valEm,
870 ColorsNormal,
870 ColorsNormal,
871 )
871 )
872 tpl_name_val = "%%s %s= %%s%s" % (Colors.valEm, ColorsNormal)
872 tpl_name_val = "%%s %s= %%s%s" % (Colors.valEm, ColorsNormal)
873
873
874 link = _format_filename(
874 link = _format_filename(
875 frame_info.filename,
875 frame_info.filename,
876 Colors.filenameEm,
876 Colors.filenameEm,
877 ColorsNormal,
877 ColorsNormal,
878 lineno=frame_info.lineno,
878 lineno=frame_info.lineno,
879 )
879 )
880 args, varargs, varkw, locals_ = inspect.getargvalues(frame_info.frame)
880 args, varargs, varkw, locals_ = inspect.getargvalues(frame_info.frame)
881 if frame_info.executing is not None:
881 if frame_info.executing is not None:
882 func = frame_info.executing.code_qualname()
882 func = frame_info.executing.code_qualname()
883 else:
883 else:
884 func = "?"
884 func = "?"
885 if func == "<module>":
885 if func == "<module>":
886 call = ""
886 call = ""
887 else:
887 else:
888 # Decide whether to include variable details or not
888 # Decide whether to include variable details or not
889 var_repr = eqrepr if self.include_vars else nullrepr
889 var_repr = eqrepr if self.include_vars else nullrepr
890 try:
890 try:
891 scope = inspect.formatargvalues(
891 scope = inspect.formatargvalues(
892 args, varargs, varkw, locals_, formatvalue=var_repr
892 args, varargs, varkw, locals_, formatvalue=var_repr
893 )
893 )
894 call = tpl_call.format(file=func, scope=scope)
894 call = tpl_call.format(file=func, scope=scope)
895 except KeyError:
895 except KeyError:
896 # This happens in situations like errors inside generator
896 # This happens in situations like errors inside generator
897 # expressions, where local variables are listed in the
897 # expressions, where local variables are listed in the
898 # line, but can't be extracted from the frame. I'm not
898 # line, but can't be extracted from the frame. I'm not
899 # 100% sure this isn't actually a bug in inspect itself,
899 # 100% sure this isn't actually a bug in inspect itself,
900 # but since there's no info for us to compute with, the
900 # but since there's no info for us to compute with, the
901 # best we can do is report the failure and move on. Here
901 # best we can do is report the failure and move on. Here
902 # we must *not* call any traceback construction again,
902 # we must *not* call any traceback construction again,
903 # because that would mess up use of %debug later on. So we
903 # because that would mess up use of %debug later on. So we
904 # simply report the failure and move on. The only
904 # simply report the failure and move on. The only
905 # limitation will be that this frame won't have locals
905 # limitation will be that this frame won't have locals
906 # listed in the call signature. Quite subtle problem...
906 # listed in the call signature. Quite subtle problem...
907 # I can't think of a good way to validate this in a unit
907 # I can't think of a good way to validate this in a unit
908 # test, but running a script consisting of:
908 # test, but running a script consisting of:
909 # dict( (k,v.strip()) for (k,v) in range(10) )
909 # dict( (k,v.strip()) for (k,v) in range(10) )
910 # will illustrate the error, if this exception catch is
910 # will illustrate the error, if this exception catch is
911 # disabled.
911 # disabled.
912 call = tpl_call_fail % func
912 call = tpl_call_fail % func
913
913
914 lvals = ''
914 lvals = ''
915 lvals_list = []
915 lvals_list = []
916 if self.include_vars:
916 if self.include_vars:
917 try:
917 try:
918 # we likely want to fix stackdata at some point, but
918 # we likely want to fix stackdata at some point, but
919 # still need a workaround.
919 # still need a workaround.
920 fibp = frame_info.variables_in_executing_piece
920 fibp = frame_info.variables_in_executing_piece
921 for var in fibp:
921 for var in fibp:
922 lvals_list.append(tpl_name_val % (var.name, repr(var.value)))
922 lvals_list.append(tpl_name_val % (var.name, repr(var.value)))
923 except Exception:
923 except Exception:
924 lvals_list.append(
924 lvals_list.append(
925 "Exception trying to inspect frame. No more locals available."
925 "Exception trying to inspect frame. No more locals available."
926 )
926 )
927 if lvals_list:
927 if lvals_list:
928 lvals = '%s%s' % (indent, em_normal.join(lvals_list))
928 lvals = '%s%s' % (indent, em_normal.join(lvals_list))
929
929
930 result = f'{link}{", " if call else ""}{call}\n'
930 result = f'{link}{", " if call else ""}{call}\n'
931 if frame_info._sd is None:
931 if frame_info._sd is None:
932 # fast fallback if file is too long
932 # fast fallback if file is too long
933 tpl_link = "%s%%s%s" % (Colors.filenameEm, ColorsNormal)
933 tpl_link = "%s%%s%s" % (Colors.filenameEm, ColorsNormal)
934 link = tpl_link % util_path.compress_user(frame_info.filename)
934 link = tpl_link % util_path.compress_user(frame_info.filename)
935 level = "%s %s\n" % (link, call)
935 level = "%s %s\n" % (link, call)
936 _line_format = PyColorize.Parser(
936 _line_format = PyColorize.Parser(
937 style=self.color_scheme_table.active_scheme_name, parent=self
937 style=self.color_scheme_table.active_scheme_name, parent=self
938 ).format2
938 ).format2
939 first_line = frame_info.code.co_firstlineno
939 first_line = frame_info.code.co_firstlineno
940 current_line = frame_info.lineno[0]
940 current_line = frame_info.lineno[0]
941 raw_lines = frame_info.raw_lines
941 raw_lines = frame_info.raw_lines
942 index = current_line - first_line
942 index = current_line - first_line
943
943
944 if index >= frame_info.context:
944 if index >= frame_info.context:
945 start = max(index - frame_info.context, 0)
945 start = max(index - frame_info.context, 0)
946 stop = index + frame_info.context
946 stop = index + frame_info.context
947 index = frame_info.context
947 index = frame_info.context
948 else:
948 else:
949 start = 0
949 start = 0
950 stop = index + frame_info.context
950 stop = index + frame_info.context
951 raw_lines = raw_lines[start:stop]
951 raw_lines = raw_lines[start:stop]
952
952
953 return "%s%s" % (
953 return "%s%s" % (
954 level,
954 level,
955 "".join(
955 "".join(
956 _simple_format_traceback_lines(
956 _simple_format_traceback_lines(
957 current_line,
957 current_line,
958 index,
958 index,
959 raw_lines,
959 raw_lines,
960 Colors,
960 Colors,
961 lvals,
961 lvals,
962 _line_format,
962 _line_format,
963 )
963 )
964 ),
964 ),
965 )
965 )
966 # result += "\n".join(frame_info.raw_lines)
966 # result += "\n".join(frame_info.raw_lines)
967 else:
967 else:
968 result += "".join(
968 result += "".join(
969 _format_traceback_lines(
969 _format_traceback_lines(
970 frame_info.lines, Colors, self.has_colors, lvals
970 frame_info.lines, Colors, self.has_colors, lvals
971 )
971 )
972 )
972 )
973 return result
973 return result
974
974
975 def prepare_header(self, etype: str, long_version: bool = False):
975 def prepare_header(self, etype: str, long_version: bool = False):
976 colors = self.Colors # just a shorthand + quicker name lookup
976 colors = self.Colors # just a shorthand + quicker name lookup
977 colorsnormal = colors.Normal # used a lot
977 colorsnormal = colors.Normal # used a lot
978 exc = '%s%s%s' % (colors.excName, etype, colorsnormal)
978 exc = '%s%s%s' % (colors.excName, etype, colorsnormal)
979 width = min(75, get_terminal_size()[0])
979 width = min(75, get_terminal_size()[0])
980 if long_version:
980 if long_version:
981 # Header with the exception type, python version, and date
981 # Header with the exception type, python version, and date
982 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
982 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
983 date = time.ctime(time.time())
983 date = time.ctime(time.time())
984
984
985 head = "%s%s%s\n%s%s%s\n%s" % (
985 head = "%s%s%s\n%s%s%s\n%s" % (
986 colors.topline,
986 colors.topline,
987 "-" * width,
987 "-" * width,
988 colorsnormal,
988 colorsnormal,
989 exc,
989 exc,
990 " " * (width - len(etype) - len(pyver)),
990 " " * (width - len(etype) - len(pyver)),
991 pyver,
991 pyver,
992 date.rjust(width),
992 date.rjust(width),
993 )
993 )
994 head += (
994 head += (
995 "\nA problem occurred executing Python code. Here is the sequence of function"
995 "\nA problem occurred executing Python code. Here is the sequence of function"
996 "\ncalls leading up to the error, with the most recent (innermost) call last."
996 "\ncalls leading up to the error, with the most recent (innermost) call last."
997 )
997 )
998 else:
998 else:
999 # Simplified header
999 # Simplified header
1000 head = "%s%s" % (
1000 head = "%s%s" % (
1001 exc,
1001 exc,
1002 "Traceback (most recent call last)".rjust(width - len(etype)),
1002 "Traceback (most recent call last)".rjust(width - len(etype)),
1003 )
1003 )
1004
1004
1005 return head
1005 return head
1006
1006
1007 def format_exception(self, etype, evalue):
1007 def format_exception(self, etype, evalue):
1008 colors = self.Colors # just a shorthand + quicker name lookup
1008 colors = self.Colors # just a shorthand + quicker name lookup
1009 colorsnormal = colors.Normal # used a lot
1009 colorsnormal = colors.Normal # used a lot
1010 # Get (safely) a string form of the exception info
1010 # Get (safely) a string form of the exception info
1011 try:
1011 try:
1012 etype_str, evalue_str = map(str, (etype, evalue))
1012 etype_str, evalue_str = map(str, (etype, evalue))
1013 except:
1013 except:
1014 # User exception is improperly defined.
1014 # User exception is improperly defined.
1015 etype, evalue = str, sys.exc_info()[:2]
1015 etype, evalue = str, sys.exc_info()[:2]
1016 etype_str, evalue_str = map(str, (etype, evalue))
1016 etype_str, evalue_str = map(str, (etype, evalue))
1017
1017
1018 # PEP-678 notes
1018 # PEP-678 notes
1019 notes = getattr(evalue, "__notes__", [])
1019 notes = getattr(evalue, "__notes__", [])
1020 if not isinstance(notes, Sequence) or isinstance(notes, (str, bytes)):
1020 if not isinstance(notes, Sequence) or isinstance(notes, (str, bytes)):
1021 notes = [_safe_string(notes, "__notes__", func=repr)]
1021 notes = [_safe_string(notes, "__notes__", func=repr)]
1022
1022
1023 # ... and format it
1023 # ... and format it
1024 return [
1024 return [
1025 "{}{}{}: {}".format(
1025 "{}{}{}: {}".format(
1026 colors.excName,
1026 colors.excName,
1027 etype_str,
1027 etype_str,
1028 colorsnormal,
1028 colorsnormal,
1029 py3compat.cast_unicode(evalue_str),
1029 py3compat.cast_unicode(evalue_str),
1030 ),
1030 ),
1031 *(
1031 *(
1032 "{}{}".format(
1032 "{}{}".format(
1033 colorsnormal, _safe_string(py3compat.cast_unicode(n), "note")
1033 colorsnormal, _safe_string(py3compat.cast_unicode(n), "note")
1034 )
1034 )
1035 for n in notes
1035 for n in notes
1036 ),
1036 ),
1037 ]
1037 ]
1038
1038
1039 def format_exception_as_a_whole(
1039 def format_exception_as_a_whole(
1040 self,
1040 self,
1041 etype: type,
1041 etype: type,
1042 evalue: Optional[BaseException],
1042 evalue: Optional[BaseException],
1043 etb: Optional[TracebackType],
1043 etb: Optional[TracebackType],
1044 number_of_lines_of_context,
1044 number_of_lines_of_context,
1045 tb_offset: Optional[int],
1045 tb_offset: Optional[int],
1046 ):
1046 ):
1047 """Formats the header, traceback and exception message for a single exception.
1047 """Formats the header, traceback and exception message for a single exception.
1048
1048
1049 This may be called multiple times by Python 3 exception chaining
1049 This may be called multiple times by Python 3 exception chaining
1050 (PEP 3134).
1050 (PEP 3134).
1051 """
1051 """
1052 # some locals
1052 # some locals
1053 orig_etype = etype
1053 orig_etype = etype
1054 try:
1054 try:
1055 etype = etype.__name__ # type: ignore
1055 etype = etype.__name__ # type: ignore
1056 except AttributeError:
1056 except AttributeError:
1057 pass
1057 pass
1058
1058
1059 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1059 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1060 assert isinstance(tb_offset, int)
1060 assert isinstance(tb_offset, int)
1061 head = self.prepare_header(str(etype), self.long_header)
1061 head = self.prepare_header(str(etype), self.long_header)
1062 records = (
1062 records = (
1063 self.get_records(etb, number_of_lines_of_context, tb_offset) if etb else []
1063 self.get_records(etb, number_of_lines_of_context, tb_offset) if etb else []
1064 )
1064 )
1065
1065
1066 frames = []
1066 frames = []
1067 skipped = 0
1067 skipped = 0
1068 lastrecord = len(records) - 1
1068 lastrecord = len(records) - 1
1069 for i, record in enumerate(records):
1069 for i, record in enumerate(records):
1070 if (
1070 if (
1071 not isinstance(record._sd, stack_data.RepeatedFrames)
1071 not isinstance(record._sd, stack_data.RepeatedFrames)
1072 and self.skip_hidden
1072 and self.skip_hidden
1073 ):
1073 ):
1074 if (
1074 if (
1075 record.frame.f_locals.get("__tracebackhide__", 0)
1075 record.frame.f_locals.get("__tracebackhide__", 0)
1076 and i != lastrecord
1076 and i != lastrecord
1077 ):
1077 ):
1078 skipped += 1
1078 skipped += 1
1079 continue
1079 continue
1080 if skipped:
1080 if skipped:
1081 Colors = self.Colors # just a shorthand + quicker name lookup
1081 Colors = self.Colors # just a shorthand + quicker name lookup
1082 ColorsNormal = Colors.Normal # used a lot
1082 ColorsNormal = Colors.Normal # used a lot
1083 frames.append(
1083 frames.append(
1084 " %s[... skipping hidden %s frame]%s\n"
1084 " %s[... skipping hidden %s frame]%s\n"
1085 % (Colors.excName, skipped, ColorsNormal)
1085 % (Colors.excName, skipped, ColorsNormal)
1086 )
1086 )
1087 skipped = 0
1087 skipped = 0
1088 frames.append(self.format_record(record))
1088 frames.append(self.format_record(record))
1089 if skipped:
1089 if skipped:
1090 Colors = self.Colors # just a shorthand + quicker name lookup
1090 Colors = self.Colors # just a shorthand + quicker name lookup
1091 ColorsNormal = Colors.Normal # used a lot
1091 ColorsNormal = Colors.Normal # used a lot
1092 frames.append(
1092 frames.append(
1093 " %s[... skipping hidden %s frame]%s\n"
1093 " %s[... skipping hidden %s frame]%s\n"
1094 % (Colors.excName, skipped, ColorsNormal)
1094 % (Colors.excName, skipped, ColorsNormal)
1095 )
1095 )
1096
1096
1097 formatted_exception = self.format_exception(etype, evalue)
1097 formatted_exception = self.format_exception(etype, evalue)
1098 if records:
1098 if records:
1099 frame_info = records[-1]
1099 frame_info = records[-1]
1100 ipinst = get_ipython()
1100 ipinst = get_ipython()
1101 if ipinst is not None:
1101 if ipinst is not None:
1102 ipinst.hooks.synchronize_with_editor(frame_info.filename, frame_info.lineno, 0)
1102 ipinst.hooks.synchronize_with_editor(frame_info.filename, frame_info.lineno, 0)
1103
1103
1104 return [[head] + frames + formatted_exception]
1104 return [[head] + frames + formatted_exception]
1105
1105
1106 def get_records(
1106 def get_records(
1107 self, etb: TracebackType, number_of_lines_of_context: int, tb_offset: int
1107 self, etb: TracebackType, number_of_lines_of_context: int, tb_offset: int
1108 ):
1108 ):
1109 assert etb is not None
1109 assert etb is not None
1110 context = number_of_lines_of_context - 1
1110 context = number_of_lines_of_context - 1
1111 after = context // 2
1111 after = context // 2
1112 before = context - after
1112 before = context - after
1113 if self.has_colors:
1113 if self.has_colors:
1114 style = get_style_by_name(self._tb_highlight_style)
1114 style = get_style_by_name(self._tb_highlight_style)
1115 style = stack_data.style_with_executing_node(style, self._tb_highlight)
1115 style = stack_data.style_with_executing_node(style, self._tb_highlight)
1116 formatter = Terminal256Formatter(style=style)
1116 formatter = Terminal256Formatter(style=style)
1117 else:
1117 else:
1118 formatter = None
1118 formatter = None
1119 options = stack_data.Options(
1119 options = stack_data.Options(
1120 before=before,
1120 before=before,
1121 after=after,
1121 after=after,
1122 pygments_formatter=formatter,
1122 pygments_formatter=formatter,
1123 )
1123 )
1124
1124
1125 # Let's estimate the amount of code we will have to parse/highlight.
1125 # Let's estimate the amount of code we will have to parse/highlight.
1126 cf: Optional[TracebackType] = etb
1126 cf: Optional[TracebackType] = etb
1127 max_len = 0
1127 max_len = 0
1128 tbs = []
1128 tbs = []
1129 while cf is not None:
1129 while cf is not None:
1130 try:
1130 try:
1131 mod = inspect.getmodule(cf.tb_frame)
1131 mod = inspect.getmodule(cf.tb_frame)
1132 if mod is not None:
1132 if mod is not None:
1133 mod_name = mod.__name__
1133 mod_name = mod.__name__
1134 root_name, *_ = mod_name.split(".")
1134 root_name, *_ = mod_name.split(".")
1135 if root_name == "IPython":
1135 if root_name == "IPython":
1136 cf = cf.tb_next
1136 cf = cf.tb_next
1137 continue
1137 continue
1138 max_len = get_line_number_of_frame(cf.tb_frame)
1138 max_len = get_line_number_of_frame(cf.tb_frame)
1139
1139
1140 except OSError:
1140 except OSError:
1141 max_len = 0
1141 max_len = 0
1142 max_len = max(max_len, max_len)
1142 max_len = max(max_len, max_len)
1143 tbs.append(cf)
1143 tbs.append(cf)
1144 cf = getattr(cf, "tb_next", None)
1144 cf = getattr(cf, "tb_next", None)
1145
1145
1146 if max_len > FAST_THRESHOLD:
1146 if max_len > FAST_THRESHOLD:
1147 FIs = []
1147 FIs = []
1148 for tb in tbs:
1148 for tb in tbs:
1149 frame = tb.tb_frame # type: ignore
1149 frame = tb.tb_frame # type: ignore
1150 lineno = (frame.f_lineno,)
1150 lineno = (frame.f_lineno,)
1151 code = frame.f_code
1151 code = frame.f_code
1152 filename = code.co_filename
1152 filename = code.co_filename
1153 # TODO: Here we need to use before/after/
1153 # TODO: Here we need to use before/after/
1154 FIs.append(
1154 FIs.append(
1155 FrameInfo(
1155 FrameInfo(
1156 "Raw frame", filename, lineno, frame, code, context=context
1156 "Raw frame", filename, lineno, frame, code, context=context
1157 )
1157 )
1158 )
1158 )
1159 return FIs
1159 return FIs
1160 res = list(stack_data.FrameInfo.stack_data(etb, options=options))[tb_offset:]
1160 res = list(stack_data.FrameInfo.stack_data(etb, options=options))[tb_offset:]
1161 res = [FrameInfo._from_stack_data_FrameInfo(r) for r in res]
1161 res = [FrameInfo._from_stack_data_FrameInfo(r) for r in res]
1162 return res
1162 return res
1163
1163
1164 def structured_traceback(
1164 def structured_traceback(
1165 self,
1165 self,
1166 etype: type,
1166 etype: type,
1167 evalue: Optional[BaseException],
1167 evalue: Optional[BaseException],
1168 etb: Optional[TracebackType] = None,
1168 etb: Optional[TracebackType] = None,
1169 tb_offset: Optional[int] = None,
1169 tb_offset: Optional[int] = None,
1170 number_of_lines_of_context: int = 5,
1170 number_of_lines_of_context: int = 5,
1171 ):
1171 ):
1172 """Return a nice text document describing the traceback."""
1172 """Return a nice text document describing the traceback."""
1173 formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context,
1173 formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context,
1174 tb_offset)
1174 tb_offset)
1175
1175
1176 colors = self.Colors # just a shorthand + quicker name lookup
1176 colors = self.Colors # just a shorthand + quicker name lookup
1177 colorsnormal = colors.Normal # used a lot
1177 colorsnormal = colors.Normal # used a lot
1178 head = '%s%s%s' % (colors.topline, '-' * min(75, get_terminal_size()[0]), colorsnormal)
1178 head = '%s%s%s' % (colors.topline, '-' * min(75, get_terminal_size()[0]), colorsnormal)
1179 structured_traceback_parts = [head]
1179 structured_traceback_parts = [head]
1180 chained_exceptions_tb_offset = 0
1180 chained_exceptions_tb_offset = 0
1181 lines_of_context = 3
1181 lines_of_context = 3
1182 formatted_exceptions = formatted_exception
1182 formatted_exceptions = formatted_exception
1183 exception = self.get_parts_of_chained_exception(evalue)
1183 exception = self.get_parts_of_chained_exception(evalue)
1184 if exception:
1184 if exception:
1185 assert evalue is not None
1185 assert evalue is not None
1186 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1186 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1187 etype, evalue, etb = exception
1187 etype, evalue, etb = exception
1188 else:
1188 else:
1189 evalue = None
1189 evalue = None
1190 chained_exc_ids = set()
1190 chained_exc_ids = set()
1191 while evalue:
1191 while evalue:
1192 formatted_exceptions += self.format_exception_as_a_whole(etype, evalue, etb, lines_of_context,
1192 formatted_exceptions += self.format_exception_as_a_whole(etype, evalue, etb, lines_of_context,
1193 chained_exceptions_tb_offset)
1193 chained_exceptions_tb_offset)
1194 exception = self.get_parts_of_chained_exception(evalue)
1194 exception = self.get_parts_of_chained_exception(evalue)
1195
1195
1196 if exception and not id(exception[1]) in chained_exc_ids:
1196 if exception and not id(exception[1]) in chained_exc_ids:
1197 chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop
1197 chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop
1198 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1198 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1199 etype, evalue, etb = exception
1199 etype, evalue, etb = exception
1200 else:
1200 else:
1201 evalue = None
1201 evalue = None
1202
1202
1203 # we want to see exceptions in a reversed order:
1203 # we want to see exceptions in a reversed order:
1204 # the first exception should be on top
1204 # the first exception should be on top
1205 for formatted_exception in reversed(formatted_exceptions):
1205 for formatted_exception in reversed(formatted_exceptions):
1206 structured_traceback_parts += formatted_exception
1206 structured_traceback_parts += formatted_exception
1207
1207
1208 return structured_traceback_parts
1208 return structured_traceback_parts
1209
1209
1210 def debugger(self, force: bool = False):
1210 def debugger(self, force: bool = False):
1211 """Call up the pdb debugger if desired, always clean up the tb
1211 """Call up the pdb debugger if desired, always clean up the tb
1212 reference.
1212 reference.
1213
1213
1214 Keywords:
1214 Keywords:
1215
1215
1216 - force(False): by default, this routine checks the instance call_pdb
1216 - force(False): by default, this routine checks the instance call_pdb
1217 flag and does not actually invoke the debugger if the flag is false.
1217 flag and does not actually invoke the debugger if the flag is false.
1218 The 'force' option forces the debugger to activate even if the flag
1218 The 'force' option forces the debugger to activate even if the flag
1219 is false.
1219 is false.
1220
1220
1221 If the call_pdb flag is set, the pdb interactive debugger is
1221 If the call_pdb flag is set, the pdb interactive debugger is
1222 invoked. In all cases, the self.tb reference to the current traceback
1222 invoked. In all cases, the self.tb reference to the current traceback
1223 is deleted to prevent lingering references which hamper memory
1223 is deleted to prevent lingering references which hamper memory
1224 management.
1224 management.
1225
1225
1226 Note that each call to pdb() does an 'import readline', so if your app
1226 Note that each call to pdb() does an 'import readline', so if your app
1227 requires a special setup for the readline completers, you'll have to
1227 requires a special setup for the readline completers, you'll have to
1228 fix that by hand after invoking the exception handler."""
1228 fix that by hand after invoking the exception handler."""
1229
1229
1230 if force or self.call_pdb:
1230 if force or self.call_pdb:
1231 if self.pdb is None:
1231 if self.pdb is None:
1232 self.pdb = self.debugger_cls()
1232 self.pdb = self.debugger_cls()
1233 # the system displayhook may have changed, restore the original
1233 # the system displayhook may have changed, restore the original
1234 # for pdb
1234 # for pdb
1235 display_trap = DisplayTrap(hook=sys.__displayhook__)
1235 display_trap = DisplayTrap(hook=sys.__displayhook__)
1236 with display_trap:
1236 with display_trap:
1237 self.pdb.reset()
1237 self.pdb.reset()
1238 # Find the right frame so we don't pop up inside ipython itself
1238 # Find the right frame so we don't pop up inside ipython itself
1239 if hasattr(self, "tb") and self.tb is not None: # type: ignore[has-type]
1239 if hasattr(self, "tb") and self.tb is not None: # type: ignore[has-type]
1240 etb = self.tb # type: ignore[has-type]
1240 etb = self.tb # type: ignore[has-type]
1241 else:
1241 else:
1242 etb = self.tb = sys.last_traceback
1242 etb = self.tb = sys.last_traceback
1243 while self.tb is not None and self.tb.tb_next is not None:
1243 while self.tb is not None and self.tb.tb_next is not None:
1244 assert self.tb.tb_next is not None
1244 assert self.tb.tb_next is not None
1245 self.tb = self.tb.tb_next
1245 self.tb = self.tb.tb_next
1246 if etb and etb.tb_next:
1246 if etb and etb.tb_next:
1247 etb = etb.tb_next
1247 etb = etb.tb_next
1248 self.pdb.botframe = etb.tb_frame
1248 self.pdb.botframe = etb.tb_frame
1249 self.pdb.interaction(None, etb)
1249 # last_value should be deprecated, but last-exc sometimme not set
1250 # please check why later and remove the getattr.
1251 exc = sys.last_value if sys.version_info < (3, 12) else getattr(sys, "last_exc", sys.last_value) # type: ignore[attr-defined]
1252 if exc:
1253 self.pdb.interaction(None, exc)
1254 else:
1255 self.pdb.interaction(None, etb)
1250
1256
1251 if hasattr(self, 'tb'):
1257 if hasattr(self, 'tb'):
1252 del self.tb
1258 del self.tb
1253
1259
1254 def handler(self, info=None):
1260 def handler(self, info=None):
1255 (etype, evalue, etb) = info or sys.exc_info()
1261 (etype, evalue, etb) = info or sys.exc_info()
1256 self.tb = etb
1262 self.tb = etb
1257 ostream = self.ostream
1263 ostream = self.ostream
1258 ostream.flush()
1264 ostream.flush()
1259 ostream.write(self.text(etype, evalue, etb))
1265 ostream.write(self.text(etype, evalue, etb))
1260 ostream.write('\n')
1266 ostream.write('\n')
1261 ostream.flush()
1267 ostream.flush()
1262
1268
1263 # Changed so an instance can just be called as VerboseTB_inst() and print
1269 # Changed so an instance can just be called as VerboseTB_inst() and print
1264 # out the right info on its own.
1270 # out the right info on its own.
1265 def __call__(self, etype=None, evalue=None, etb=None):
1271 def __call__(self, etype=None, evalue=None, etb=None):
1266 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
1272 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
1267 if etb is None:
1273 if etb is None:
1268 self.handler()
1274 self.handler()
1269 else:
1275 else:
1270 self.handler((etype, evalue, etb))
1276 self.handler((etype, evalue, etb))
1271 try:
1277 try:
1272 self.debugger()
1278 self.debugger()
1273 except KeyboardInterrupt:
1279 except KeyboardInterrupt:
1274 print("\nKeyboardInterrupt")
1280 print("\nKeyboardInterrupt")
1275
1281
1276
1282
1277 #----------------------------------------------------------------------------
1283 #----------------------------------------------------------------------------
1278 class FormattedTB(VerboseTB, ListTB):
1284 class FormattedTB(VerboseTB, ListTB):
1279 """Subclass ListTB but allow calling with a traceback.
1285 """Subclass ListTB but allow calling with a traceback.
1280
1286
1281 It can thus be used as a sys.excepthook for Python > 2.1.
1287 It can thus be used as a sys.excepthook for Python > 2.1.
1282
1288
1283 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
1289 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
1284
1290
1285 Allows a tb_offset to be specified. This is useful for situations where
1291 Allows a tb_offset to be specified. This is useful for situations where
1286 one needs to remove a number of topmost frames from the traceback (such as
1292 one needs to remove a number of topmost frames from the traceback (such as
1287 occurs with python programs that themselves execute other python code,
1293 occurs with python programs that themselves execute other python code,
1288 like Python shells). """
1294 like Python shells). """
1289
1295
1290 mode: str
1296 mode: str
1291
1297
1292 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1298 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1293 ostream=None,
1299 ostream=None,
1294 tb_offset=0, long_header=False, include_vars=False,
1300 tb_offset=0, long_header=False, include_vars=False,
1295 check_cache=None, debugger_cls=None,
1301 check_cache=None, debugger_cls=None,
1296 parent=None, config=None):
1302 parent=None, config=None):
1297
1303
1298 # NEVER change the order of this list. Put new modes at the end:
1304 # NEVER change the order of this list. Put new modes at the end:
1299 self.valid_modes = ['Plain', 'Context', 'Verbose', 'Minimal']
1305 self.valid_modes = ['Plain', 'Context', 'Verbose', 'Minimal']
1300 self.verbose_modes = self.valid_modes[1:3]
1306 self.verbose_modes = self.valid_modes[1:3]
1301
1307
1302 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
1308 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
1303 ostream=ostream, tb_offset=tb_offset,
1309 ostream=ostream, tb_offset=tb_offset,
1304 long_header=long_header, include_vars=include_vars,
1310 long_header=long_header, include_vars=include_vars,
1305 check_cache=check_cache, debugger_cls=debugger_cls,
1311 check_cache=check_cache, debugger_cls=debugger_cls,
1306 parent=parent, config=config)
1312 parent=parent, config=config)
1307
1313
1308 # Different types of tracebacks are joined with different separators to
1314 # Different types of tracebacks are joined with different separators to
1309 # form a single string. They are taken from this dict
1315 # form a single string. They are taken from this dict
1310 self._join_chars = dict(Plain='', Context='\n', Verbose='\n',
1316 self._join_chars = dict(Plain='', Context='\n', Verbose='\n',
1311 Minimal='')
1317 Minimal='')
1312 # set_mode also sets the tb_join_char attribute
1318 # set_mode also sets the tb_join_char attribute
1313 self.set_mode(mode)
1319 self.set_mode(mode)
1314
1320
1315 def structured_traceback(self, etype, value, tb, tb_offset=None, number_of_lines_of_context=5):
1321 def structured_traceback(self, etype, value, tb, tb_offset=None, number_of_lines_of_context=5):
1316 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1322 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1317 mode = self.mode
1323 mode = self.mode
1318 if mode in self.verbose_modes:
1324 if mode in self.verbose_modes:
1319 # Verbose modes need a full traceback
1325 # Verbose modes need a full traceback
1320 return VerboseTB.structured_traceback(
1326 return VerboseTB.structured_traceback(
1321 self, etype, value, tb, tb_offset, number_of_lines_of_context
1327 self, etype, value, tb, tb_offset, number_of_lines_of_context
1322 )
1328 )
1323 elif mode == 'Minimal':
1329 elif mode == 'Minimal':
1324 return ListTB.get_exception_only(self, etype, value)
1330 return ListTB.get_exception_only(self, etype, value)
1325 else:
1331 else:
1326 # We must check the source cache because otherwise we can print
1332 # We must check the source cache because otherwise we can print
1327 # out-of-date source code.
1333 # out-of-date source code.
1328 self.check_cache()
1334 self.check_cache()
1329 # Now we can extract and format the exception
1335 # Now we can extract and format the exception
1330 return ListTB.structured_traceback(
1336 return ListTB.structured_traceback(
1331 self, etype, value, tb, tb_offset, number_of_lines_of_context
1337 self, etype, value, tb, tb_offset, number_of_lines_of_context
1332 )
1338 )
1333
1339
1334 def stb2text(self, stb):
1340 def stb2text(self, stb):
1335 """Convert a structured traceback (a list) to a string."""
1341 """Convert a structured traceback (a list) to a string."""
1336 return self.tb_join_char.join(stb)
1342 return self.tb_join_char.join(stb)
1337
1343
1338 def set_mode(self, mode: Optional[str] = None):
1344 def set_mode(self, mode: Optional[str] = None):
1339 """Switch to the desired mode.
1345 """Switch to the desired mode.
1340
1346
1341 If mode is not specified, cycles through the available modes."""
1347 If mode is not specified, cycles through the available modes."""
1342
1348
1343 if not mode:
1349 if not mode:
1344 new_idx = (self.valid_modes.index(self.mode) + 1 ) % \
1350 new_idx = (self.valid_modes.index(self.mode) + 1 ) % \
1345 len(self.valid_modes)
1351 len(self.valid_modes)
1346 self.mode = self.valid_modes[new_idx]
1352 self.mode = self.valid_modes[new_idx]
1347 elif mode not in self.valid_modes:
1353 elif mode not in self.valid_modes:
1348 raise ValueError(
1354 raise ValueError(
1349 "Unrecognized mode in FormattedTB: <" + mode + ">\n"
1355 "Unrecognized mode in FormattedTB: <" + mode + ">\n"
1350 "Valid modes: " + str(self.valid_modes)
1356 "Valid modes: " + str(self.valid_modes)
1351 )
1357 )
1352 else:
1358 else:
1353 assert isinstance(mode, str)
1359 assert isinstance(mode, str)
1354 self.mode = mode
1360 self.mode = mode
1355 # include variable details only in 'Verbose' mode
1361 # include variable details only in 'Verbose' mode
1356 self.include_vars = (self.mode == self.valid_modes[2])
1362 self.include_vars = (self.mode == self.valid_modes[2])
1357 # Set the join character for generating text tracebacks
1363 # Set the join character for generating text tracebacks
1358 self.tb_join_char = self._join_chars[self.mode]
1364 self.tb_join_char = self._join_chars[self.mode]
1359
1365
1360 # some convenient shortcuts
1366 # some convenient shortcuts
1361 def plain(self):
1367 def plain(self):
1362 self.set_mode(self.valid_modes[0])
1368 self.set_mode(self.valid_modes[0])
1363
1369
1364 def context(self):
1370 def context(self):
1365 self.set_mode(self.valid_modes[1])
1371 self.set_mode(self.valid_modes[1])
1366
1372
1367 def verbose(self):
1373 def verbose(self):
1368 self.set_mode(self.valid_modes[2])
1374 self.set_mode(self.valid_modes[2])
1369
1375
1370 def minimal(self):
1376 def minimal(self):
1371 self.set_mode(self.valid_modes[3])
1377 self.set_mode(self.valid_modes[3])
1372
1378
1373
1379
1374 #----------------------------------------------------------------------------
1380 #----------------------------------------------------------------------------
1375 class AutoFormattedTB(FormattedTB):
1381 class AutoFormattedTB(FormattedTB):
1376 """A traceback printer which can be called on the fly.
1382 """A traceback printer which can be called on the fly.
1377
1383
1378 It will find out about exceptions by itself.
1384 It will find out about exceptions by itself.
1379
1385
1380 A brief example::
1386 A brief example::
1381
1387
1382 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1388 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1383 try:
1389 try:
1384 ...
1390 ...
1385 except:
1391 except:
1386 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1392 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1387 """
1393 """
1388
1394
1389 def __call__(self, etype=None, evalue=None, etb=None,
1395 def __call__(self, etype=None, evalue=None, etb=None,
1390 out=None, tb_offset=None):
1396 out=None, tb_offset=None):
1391 """Print out a formatted exception traceback.
1397 """Print out a formatted exception traceback.
1392
1398
1393 Optional arguments:
1399 Optional arguments:
1394 - out: an open file-like object to direct output to.
1400 - out: an open file-like object to direct output to.
1395
1401
1396 - tb_offset: the number of frames to skip over in the stack, on a
1402 - tb_offset: the number of frames to skip over in the stack, on a
1397 per-call basis (this overrides temporarily the instance's tb_offset
1403 per-call basis (this overrides temporarily the instance's tb_offset
1398 given at initialization time."""
1404 given at initialization time."""
1399
1405
1400 if out is None:
1406 if out is None:
1401 out = self.ostream
1407 out = self.ostream
1402 out.flush()
1408 out.flush()
1403 out.write(self.text(etype, evalue, etb, tb_offset))
1409 out.write(self.text(etype, evalue, etb, tb_offset))
1404 out.write('\n')
1410 out.write('\n')
1405 out.flush()
1411 out.flush()
1406 # FIXME: we should remove the auto pdb behavior from here and leave
1412 # FIXME: we should remove the auto pdb behavior from here and leave
1407 # that to the clients.
1413 # that to the clients.
1408 try:
1414 try:
1409 self.debugger()
1415 self.debugger()
1410 except KeyboardInterrupt:
1416 except KeyboardInterrupt:
1411 print("\nKeyboardInterrupt")
1417 print("\nKeyboardInterrupt")
1412
1418
1413 def structured_traceback(
1419 def structured_traceback(
1414 self,
1420 self,
1415 etype: type,
1421 etype: type,
1416 evalue: Optional[BaseException],
1422 evalue: Optional[BaseException],
1417 etb: Optional[TracebackType] = None,
1423 etb: Optional[TracebackType] = None,
1418 tb_offset: Optional[int] = None,
1424 tb_offset: Optional[int] = None,
1419 number_of_lines_of_context: int = 5,
1425 number_of_lines_of_context: int = 5,
1420 ):
1426 ):
1421 # tb: TracebackType or tupleof tb types ?
1427 # tb: TracebackType or tupleof tb types ?
1422 if etype is None:
1428 if etype is None:
1423 etype, evalue, etb = sys.exc_info()
1429 etype, evalue, etb = sys.exc_info()
1424 if isinstance(etb, tuple):
1430 if isinstance(etb, tuple):
1425 # tb is a tuple if this is a chained exception.
1431 # tb is a tuple if this is a chained exception.
1426 self.tb = etb[0]
1432 self.tb = etb[0]
1427 else:
1433 else:
1428 self.tb = etb
1434 self.tb = etb
1429 return FormattedTB.structured_traceback(
1435 return FormattedTB.structured_traceback(
1430 self, etype, evalue, etb, tb_offset, number_of_lines_of_context
1436 self, etype, evalue, etb, tb_offset, number_of_lines_of_context
1431 )
1437 )
1432
1438
1433
1439
1434 #---------------------------------------------------------------------------
1440 #---------------------------------------------------------------------------
1435
1441
1436 # A simple class to preserve Nathan's original functionality.
1442 # A simple class to preserve Nathan's original functionality.
1437 class ColorTB(FormattedTB):
1443 class ColorTB(FormattedTB):
1438 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1444 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1439
1445
1440 def __init__(self, color_scheme='Linux', call_pdb=0, **kwargs):
1446 def __init__(self, color_scheme='Linux', call_pdb=0, **kwargs):
1441 FormattedTB.__init__(self, color_scheme=color_scheme,
1447 FormattedTB.__init__(self, color_scheme=color_scheme,
1442 call_pdb=call_pdb, **kwargs)
1448 call_pdb=call_pdb, **kwargs)
1443
1449
1444
1450
1445 class SyntaxTB(ListTB):
1451 class SyntaxTB(ListTB):
1446 """Extension which holds some state: the last exception value"""
1452 """Extension which holds some state: the last exception value"""
1447
1453
1448 def __init__(self, color_scheme='NoColor', parent=None, config=None):
1454 def __init__(self, color_scheme='NoColor', parent=None, config=None):
1449 ListTB.__init__(self, color_scheme, parent=parent, config=config)
1455 ListTB.__init__(self, color_scheme, parent=parent, config=config)
1450 self.last_syntax_error = None
1456 self.last_syntax_error = None
1451
1457
1452 def __call__(self, etype, value, elist):
1458 def __call__(self, etype, value, elist):
1453 self.last_syntax_error = value
1459 self.last_syntax_error = value
1454
1460
1455 ListTB.__call__(self, etype, value, elist)
1461 ListTB.__call__(self, etype, value, elist)
1456
1462
1457 def structured_traceback(self, etype, value, elist, tb_offset=None,
1463 def structured_traceback(self, etype, value, elist, tb_offset=None,
1458 context=5):
1464 context=5):
1459 # If the source file has been edited, the line in the syntax error can
1465 # If the source file has been edited, the line in the syntax error can
1460 # be wrong (retrieved from an outdated cache). This replaces it with
1466 # be wrong (retrieved from an outdated cache). This replaces it with
1461 # the current value.
1467 # the current value.
1462 if isinstance(value, SyntaxError) \
1468 if isinstance(value, SyntaxError) \
1463 and isinstance(value.filename, str) \
1469 and isinstance(value.filename, str) \
1464 and isinstance(value.lineno, int):
1470 and isinstance(value.lineno, int):
1465 linecache.checkcache(value.filename)
1471 linecache.checkcache(value.filename)
1466 newtext = linecache.getline(value.filename, value.lineno)
1472 newtext = linecache.getline(value.filename, value.lineno)
1467 if newtext:
1473 if newtext:
1468 value.text = newtext
1474 value.text = newtext
1469 self.last_syntax_error = value
1475 self.last_syntax_error = value
1470 return super(SyntaxTB, self).structured_traceback(etype, value, elist,
1476 return super(SyntaxTB, self).structured_traceback(etype, value, elist,
1471 tb_offset=tb_offset, context=context)
1477 tb_offset=tb_offset, context=context)
1472
1478
1473 def clear_err_state(self):
1479 def clear_err_state(self):
1474 """Return the current error state and clear it"""
1480 """Return the current error state and clear it"""
1475 e = self.last_syntax_error
1481 e = self.last_syntax_error
1476 self.last_syntax_error = None
1482 self.last_syntax_error = None
1477 return e
1483 return e
1478
1484
1479 def stb2text(self, stb):
1485 def stb2text(self, stb):
1480 """Convert a structured traceback (a list) to a string."""
1486 """Convert a structured traceback (a list) to a string."""
1481 return ''.join(stb)
1487 return ''.join(stb)
1482
1488
1483
1489
1484 # some internal-use functions
1490 # some internal-use functions
1485 def text_repr(value):
1491 def text_repr(value):
1486 """Hopefully pretty robust repr equivalent."""
1492 """Hopefully pretty robust repr equivalent."""
1487 # this is pretty horrible but should always return *something*
1493 # this is pretty horrible but should always return *something*
1488 try:
1494 try:
1489 return pydoc.text.repr(value) # type: ignore[call-arg]
1495 return pydoc.text.repr(value) # type: ignore[call-arg]
1490 except KeyboardInterrupt:
1496 except KeyboardInterrupt:
1491 raise
1497 raise
1492 except:
1498 except:
1493 try:
1499 try:
1494 return repr(value)
1500 return repr(value)
1495 except KeyboardInterrupt:
1501 except KeyboardInterrupt:
1496 raise
1502 raise
1497 except:
1503 except:
1498 try:
1504 try:
1499 # all still in an except block so we catch
1505 # all still in an except block so we catch
1500 # getattr raising
1506 # getattr raising
1501 name = getattr(value, '__name__', None)
1507 name = getattr(value, '__name__', None)
1502 if name:
1508 if name:
1503 # ick, recursion
1509 # ick, recursion
1504 return text_repr(name)
1510 return text_repr(name)
1505 klass = getattr(value, '__class__', None)
1511 klass = getattr(value, '__class__', None)
1506 if klass:
1512 if klass:
1507 return '%s instance' % text_repr(klass)
1513 return '%s instance' % text_repr(klass)
1508 except KeyboardInterrupt:
1514 except KeyboardInterrupt:
1509 raise
1515 raise
1510 except:
1516 except:
1511 return 'UNRECOVERABLE REPR FAILURE'
1517 return 'UNRECOVERABLE REPR FAILURE'
1512
1518
1513
1519
1514 def eqrepr(value, repr=text_repr):
1520 def eqrepr(value, repr=text_repr):
1515 return '=%s' % repr(value)
1521 return '=%s' % repr(value)
1516
1522
1517
1523
1518 def nullrepr(value, repr=text_repr):
1524 def nullrepr(value, repr=text_repr):
1519 return ''
1525 return ''
@@ -1,80 +1,82 b''
1 """Test embedding of IPython"""
1 """Test embedding of IPython"""
2
2
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2013 The IPython Development Team
4 # Copyright (C) 2013 The IPython Development Team
5 #
5 #
6 # Distributed under the terms of the BSD License. The full license is in
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
7 # the file COPYING, distributed as part of this software.
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9
9
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Imports
11 # Imports
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 import os
14 import os
15 import sys
15 import sys
16 from IPython.testing.decorators import skip_win32
16 from IPython.testing.decorators import skip_win32
17 from IPython.testing import IPYTHON_TESTING_TIMEOUT_SCALE
17 from IPython.testing import IPYTHON_TESTING_TIMEOUT_SCALE
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Tests
20 # Tests
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 @skip_win32
23 @skip_win32
24 def test_debug_magic_passes_through_generators():
24 def test_debug_magic_passes_through_generators():
25 """
25 """
26 This test that we can correctly pass through frames of a generator post-mortem.
26 This test that we can correctly pass through frames of a generator post-mortem.
27 """
27 """
28 import pexpect
28 import pexpect
29 import re
29 import re
30 in_prompt = re.compile(br'In ?\[\d+\]:')
30 in_prompt = re.compile(br'In ?\[\d+\]:')
31 ipdb_prompt = 'ipdb>'
31 ipdb_prompt = 'ipdb>'
32 env = os.environ.copy()
32 env = os.environ.copy()
33 child = pexpect.spawn(sys.executable, ['-m', 'IPython', '--colors=nocolor', '--simple-prompt'],
33 child = pexpect.spawn(sys.executable, ['-m', 'IPython', '--colors=nocolor', '--simple-prompt'],
34 env=env)
34 env=env)
35 child.timeout = 15 * IPYTHON_TESTING_TIMEOUT_SCALE
35 child.timeout = 15 * IPYTHON_TESTING_TIMEOUT_SCALE
36
36
37 child.expect(in_prompt)
37 child.expect(in_prompt)
38
38
39 child.timeout = 2 * IPYTHON_TESTING_TIMEOUT_SCALE
39 child.timeout = 2 * IPYTHON_TESTING_TIMEOUT_SCALE
40
40
41 child.sendline("def f(x):")
41 child.sendline("def f(x):")
42 child.sendline(" raise Exception")
42 child.sendline(" raise Exception")
43 child.sendline("")
43 child.sendline("")
44
44
45 child.expect(in_prompt)
45 child.expect(in_prompt)
46 child.sendline("gen = (f(x) for x in [0])")
46 child.sendline("gen = (f(x) for x in [0])")
47 child.sendline("")
47 child.sendline("")
48
48
49 child.expect(in_prompt)
49 child.expect(in_prompt)
50 child.sendline("for x in gen:")
50 child.sendline("for x in gen:")
51 child.sendline(" pass")
51 child.sendline(" pass")
52 child.sendline("")
52 child.sendline("")
53
53
54 child.timeout = 10 * IPYTHON_TESTING_TIMEOUT_SCALE
54 child.timeout = 10 * IPYTHON_TESTING_TIMEOUT_SCALE
55
55
56 child.expect('Exception:')
56 child.expect('Exception:')
57
57
58 child.expect(in_prompt)
58 child.expect(in_prompt)
59 child.sendline(r'%debug')
59 child.sendline(r'%debug')
60 child.expect('----> 2 raise Exception')
60 child.expect('----> 2 raise Exception')
61
61
62 child.expect(ipdb_prompt)
62 child.expect(ipdb_prompt)
63 child.sendline('u')
63 child.sendline('u')
64 child.expect_exact(r'----> 1 gen = (f(x) for x in [0])')
64 child.expect_exact(r'----> 1 gen = (f(x) for x in [0])')
65
65
66 child.expect(ipdb_prompt)
66 child.expect(ipdb_prompt)
67 child.sendline('u')
67 child.sendline('u')
68 child.expect_exact('----> 1 for x in gen:')
68 child.expect_exact('----> 1 for x in gen:')
69
69
70 child.expect(ipdb_prompt)
70 child.expect(ipdb_prompt)
71 child.sendline('u')
71 child.sendline("u")
72 child.expect_exact('*** Oldest frame')
72 child.expect_exact(
73 "*** all frames above hidden, use `skip_hidden False` to get get into those."
74 )
73
75
74 child.expect(ipdb_prompt)
76 child.expect(ipdb_prompt)
75 child.sendline('exit')
77 child.sendline('exit')
76
78
77 child.expect(in_prompt)
79 child.expect(in_prompt)
78 child.sendline('exit')
80 child.sendline('exit')
79
81
80 child.close()
82 child.close()
@@ -1,1746 +1,1763 b''
1 ============
1 ============
2 8.x Series
2 8.x Series
3 ============
3 ============
4
5 .. _version 8.15:
6
7 IPython 8.15
8 ------------
9
10 Medium release of IPython after a couple of month hiatus, and a bit off-schedule.
11
12 The main change is the addition of the ability to move between chained
13 exceptions when using IPdb, this feature was also contributed to upstream Pdb
14 and is thus native to CPython in Python 3.13+ Though ipdb should support this
15 feature in older version of Python. I invite you to look at the `CPython changes
16 and docs <https://github.com/python/cpython/pull/106676>`_ for more details.
17
18 I also want o thanks the `D.E. Shaw group <https://www.deshaw.com/>`_ for
19 suggesting and funding this feature.
20
4 .. _version 8.14:
21 .. _version 8.14:
5
22
6 IPython 8.14
23 IPython 8.14
7 ------------
24 ------------
8
25
9 Small release of IPython.
26 Small release of IPython.
10
27
11 - :ghpull:`14080` fixes some shortcuts issues.
28 - :ghpull:`14080` fixes some shortcuts issues.
12 - :ghpull:`14056` Add option to ``%autoreload`` to hide errors when reloading code. This will be the default for spyder
29 - :ghpull:`14056` Add option to ``%autoreload`` to hide errors when reloading code. This will be the default for spyder
13 user is my understanding.
30 user is my understanding.
14 - :ghpull:`14039` (and :ghpull:`14040`) to show exception notes in tracebacks.
31 - :ghpull:`14039` (and :ghpull:`14040`) to show exception notes in tracebacks.
15
32
16 - :ghpull:`14076` Add option to EventManager to prevent printing
33 - :ghpull:`14076` Add option to EventManager to prevent printing
17
34
18
35
19 SPEC 0 and SPEC 4
36 SPEC 0 and SPEC 4
20 ~~~~~~~~~~~~~~~~~
37 ~~~~~~~~~~~~~~~~~
21
38
22 You've heard about the NEPs, (NumPy enhancement Proposal), having a NEP for something non-numpy specific was sometime confusing.
39 You've heard about the NEPs, (NumPy enhancement Proposal), having a NEP for something non-numpy specific was sometime confusing.
23 Long live the `SPECs <https://scientific-python.org/specs/>`_.
40 Long live the `SPECs <https://scientific-python.org/specs/>`_.
24
41
25 We are now trying to follow SPEC 0 (aka old NEP 29) for of support of upstream libraries.
42 We are now trying to follow SPEC 0 (aka old NEP 29) for of support of upstream libraries.
26
43
27 We also now try to follow SPEC 4 (test and publish nightly on a centralized nightly repository).
44 We also now try to follow SPEC 4 (test and publish nightly on a centralized nightly repository).
28 We encourage you to do so as well in order to report breakage, and contribute to the SPEC process !
45 We encourage you to do so as well in order to report breakage, and contribute to the SPEC process !
29
46
30
47
31 Python 3.12 compatibility ?
48 Python 3.12 compatibility ?
32 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
49 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
33
50
34 Python 3.12 changed its tokenizer to have better support for f-strings and allow arbitrary expression.
51 Python 3.12 changed its tokenizer to have better support for f-strings and allow arbitrary expression.
35 This is a great new feature and performance improvement in python 3.12.
52 This is a great new feature and performance improvement in python 3.12.
36
53
37 Unfortunately this means the new tokenizer does not support incomplete or invalid Python which will
54 Unfortunately this means the new tokenizer does not support incomplete or invalid Python which will
38 break many features of IPython. Thus compatibility of IPython with Python 3.12 is not guarantied.
55 break many features of IPython. Thus compatibility of IPython with Python 3.12 is not guarantied.
39 It is unclear to which extent IPython is affected, and whether we can/should try to still support magics, shell
56 It is unclear to which extent IPython is affected, and whether we can/should try to still support magics, shell
40 escape (``! ....``), ..., as well as how to do it if we can.
57 escape (``! ....``), ..., as well as how to do it if we can.
41
58
42 In addition even if we there is technical feasibility to do so, it is no clear we have the resources to do it.
59 In addition even if we there is technical feasibility to do so, it is no clear we have the resources to do it.
43 We are thus looking for your help if you can _test_ on Python 3.12 to see to which extent this affects users and which
60 We are thus looking for your help if you can _test_ on Python 3.12 to see to which extent this affects users and which
44 features are critical.
61 features are critical.
45
62
46 We are not going to pin IPython to Python ``<3.12`` as otherwise on install pip would downgrade/resolve to IPython 8.13,
63 We are not going to pin IPython to Python ``<3.12`` as otherwise on install pip would downgrade/resolve to IPython 8.13,
47 so if you plan to update to Python 3.12 after its release, we encourage for extra care.
64 so if you plan to update to Python 3.12 after its release, we encourage for extra care.
48
65
49
66
50 .. _version 8.13.1:
67 .. _version 8.13.1:
51 .. _version 8.13.2:
68 .. _version 8.13.2:
52 .. _version 8.12.3:
69 .. _version 8.12.3:
53
70
54 IPython 8.13.1, 8.13.2 and 8.12.2
71 IPython 8.13.1, 8.13.2 and 8.12.2
55 ---------------------------------
72 ---------------------------------
56
73
57 3 quick in succession patch release of IPython in addition to IPython 8.13.0
74 3 quick in succession patch release of IPython in addition to IPython 8.13.0
58 having been yanked.
75 having been yanked.
59
76
60 IPython 8.13.0 was improperly tagged as still compatible with Python 3.8, and
77 IPython 8.13.0 was improperly tagged as still compatible with Python 3.8, and
61 still had some mention of compatibility with 3.8. IPython 8.13.1 is identical to
78 still had some mention of compatibility with 3.8. IPython 8.13.1 is identical to
62 8.13 but with the exception of being correctly tagged. This release and yank was
79 8.13 but with the exception of being correctly tagged. This release and yank was
63 mostly done to fix CI.
80 mostly done to fix CI.
64
81
65 IPython 8.12.2 and 8.13.2 contain UI fixes, with respect to right arrow not
82 IPython 8.12.2 and 8.13.2 contain UI fixes, with respect to right arrow not
66 working in some case in the terminal, and 8.12.2 contain also a requested
83 working in some case in the terminal, and 8.12.2 contain also a requested
67 backport of :ghpull:`14029` (Allow safe access to the ``__getattribute__``
84 backport of :ghpull:`14029` (Allow safe access to the ``__getattribute__``
68 method of modules) for tab completion.
85 method of modules) for tab completion.
69
86
70 .. _version 8.13:
87 .. _version 8.13:
71
88
72 IPython 8.13
89 IPython 8.13
73 ------------
90 ------------
74
91
75 As usual for the end of the month, minor release of IPython. This release is
92 As usual for the end of the month, minor release of IPython. This release is
76 significant in that it not only has a number of bugfixes, but also drop support
93 significant in that it not only has a number of bugfixes, but also drop support
77 for Python 3.8 as per NEP 29 (:ghpull:`14023`).
94 for Python 3.8 as per NEP 29 (:ghpull:`14023`).
78
95
79 All the critical bugfixes have been backported onto the 8.12.1 release (see
96 All the critical bugfixes have been backported onto the 8.12.1 release (see
80 below). In addition to that went into 8.12.1 you'll find:
97 below). In addition to that went into 8.12.1 you'll find:
81
98
82 - Pretty reprensentation for ``Counter`` has been fixed to match the Python one
99 - Pretty reprensentation for ``Counter`` has been fixed to match the Python one
83 and be in decreasing order. :ghpull:`14032`
100 and be in decreasing order. :ghpull:`14032`
84 - Module completion is better when jedi is disabled :ghpull:`14029`.
101 - Module completion is better when jedi is disabled :ghpull:`14029`.
85 - Improvment of ``%%bash`` magic that would get stuck :ghpull:`14019`
102 - Improvment of ``%%bash`` magic that would get stuck :ghpull:`14019`
86
103
87
104
88 We hope you enjoy this release an will maybe see you at JupyterCon in less than
105 We hope you enjoy this release an will maybe see you at JupyterCon in less than
89 two weeks.
106 two weeks.
90
107
91 As usual you can find the full list of PRs on GitHub under `the 8.13 milestone
108 As usual you can find the full list of PRs on GitHub under `the 8.13 milestone
92 <https://github.com/ipython/ipython/milestone/115?closed=1>`__.
109 <https://github.com/ipython/ipython/milestone/115?closed=1>`__.
93
110
94 Thanks to the D.E. Shaw group for the request and sponsoring the work.
111 Thanks to the D.E. Shaw group for the request and sponsoring the work.
95
112
96
113
97 .. _version 8.12.1:
114 .. _version 8.12.1:
98
115
99 IPython 8.12.1
116 IPython 8.12.1
100 --------------
117 --------------
101
118
102 This is the twin release of IPython 8.13 that contain only critical UI and bug
119 This is the twin release of IPython 8.13 that contain only critical UI and bug
103 fixes. The next minor version of IPython has dropped support for Python 3.8 – as
120 fixes. The next minor version of IPython has dropped support for Python 3.8 – as
104 per Nep 29 and this IPython 8.12.x will now only receive bugfixes.
121 per Nep 29 and this IPython 8.12.x will now only receive bugfixes.
105
122
106
123
107 - :ghpull:`14004` Fix a bug introduced in IPython 8.12 that crash when
124 - :ghpull:`14004` Fix a bug introduced in IPython 8.12 that crash when
108 inspecting some docstrings.
125 inspecting some docstrings.
109 - :ghpull:`14010` Fix fast traceback code that was not working in some case.
126 - :ghpull:`14010` Fix fast traceback code that was not working in some case.
110 - :ghpull:`14014` Fix ``%page`` magic broken in some case.
127 - :ghpull:`14014` Fix ``%page`` magic broken in some case.
111 - :ghpull:`14026`, :ghpull:`14027` Tweak default shortcut with respect to
128 - :ghpull:`14026`, :ghpull:`14027` Tweak default shortcut with respect to
112 autosuggestions.
129 autosuggestions.
113 - :ghpull:`14033` add back the ability to use ``.get()`` on OInfo object for
130 - :ghpull:`14033` add back the ability to use ``.get()`` on OInfo object for
114 backward compatibility with h5py (this will be re-deprecated later, and h5py
131 backward compatibility with h5py (this will be re-deprecated later, and h5py
115 will also get a fix).
132 will also get a fix).
116
133
117 As usual you can find the full list of PRs on GitHub under `the 8.12.1 milestone
134 As usual you can find the full list of PRs on GitHub under `the 8.12.1 milestone
118 <https://github.com/ipython/ipython/milestone/116?closed=1>`__.
135 <https://github.com/ipython/ipython/milestone/116?closed=1>`__.
119
136
120 Thanks to the D.E. Shaw group for the request and sponsoring the work.
137 Thanks to the D.E. Shaw group for the request and sponsoring the work.
121
138
122 .. _version 8.12.0:
139 .. _version 8.12.0:
123
140
124 IPython 8.12
141 IPython 8.12
125 ------------
142 ------------
126
143
127 Hopefully slightly early release for IPython 8.12. Last Thursday of the month,
144 Hopefully slightly early release for IPython 8.12. Last Thursday of the month,
128 even if I guess it's likely already Friday somewhere in the pacific ocean.
145 even if I guess it's likely already Friday somewhere in the pacific ocean.
129
146
130 A number of PRs and bug fixes this month with close to 20 PRs merged !
147 A number of PRs and bug fixes this month with close to 20 PRs merged !
131
148
132
149
133 The IPython repo reached :ghpull:`14000` !! Actually the PR that create those exact release
150 The IPython repo reached :ghpull:`14000` !! Actually the PR that create those exact release
134 note is :ghpull:`14000`. Ok, more issues and PR is not always better, and I'd
151 note is :ghpull:`14000`. Ok, more issues and PR is not always better, and I'd
135 love to have more time to close issues and Pull Requests.
152 love to have more time to close issues and Pull Requests.
136
153
137 Let's note that in less than 2 month JupyterCon is back, in Paris please visit
154 Let's note that in less than 2 month JupyterCon is back, in Paris please visit
138 `jupytercon.com <https://jupytercon.com>`__, and looking forward to see you
155 `jupytercon.com <https://jupytercon.com>`__, and looking forward to see you
139 there.
156 there.
140
157
141 Packagers should take note that ``typing_extension`` is now a mandatory dependency
158 Packagers should take note that ``typing_extension`` is now a mandatory dependency
142 for Python versions ``<3.10``.
159 for Python versions ``<3.10``.
143
160
144
161
145
162
146 Let's note also that according to `NEP29
163 Let's note also that according to `NEP29
147 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`__, It is soon time to
164 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`__, It is soon time to
148 stop support for Python 3.8 that will be release more than 3 and 1/2 years ago::
165 stop support for Python 3.8 that will be release more than 3 and 1/2 years ago::
149
166
150 On Apr 14, 2023 drop support for Python 3.8 (initially released on Oct 14, 2019)
167 On Apr 14, 2023 drop support for Python 3.8 (initially released on Oct 14, 2019)
151
168
152 Thus I am likely to stop advertising support for Python 3.8 in the next
169 Thus I am likely to stop advertising support for Python 3.8 in the next
153 release at the end of April.
170 release at the end of April.
154
171
155
172
156 Here are some miscellaneous updates of interest:
173 Here are some miscellaneous updates of interest:
157
174
158 - :ghpull:`13957` brings updates to the Qt integration, particularly for Qt6.
175 - :ghpull:`13957` brings updates to the Qt integration, particularly for Qt6.
159 - :ghpull:`13960` fixes the %debug magic command to give access to the local
176 - :ghpull:`13960` fixes the %debug magic command to give access to the local
160 scope.
177 scope.
161 - :ghpull:`13964` fixes some crashes with the new fast traceback code. Note that
178 - :ghpull:`13964` fixes some crashes with the new fast traceback code. Note that
162 there are still some issues with the fast traceback code, and I a, likely
179 there are still some issues with the fast traceback code, and I a, likely
163 to fix and tweak behavior.
180 to fix and tweak behavior.
164 - :ghpull:`13973` We are slowly migrating IPython internals to use proper type
181 - :ghpull:`13973` We are slowly migrating IPython internals to use proper type
165 objects/dataclasses instead of dictionaries to allow static typing checks.
182 objects/dataclasses instead of dictionaries to allow static typing checks.
166 These are technically public API and could lead to breakage, so please let us
183 These are technically public API and could lead to breakage, so please let us
167 know if that's the case and I'll mitigate.
184 know if that's the case and I'll mitigate.
168 - :ghpull:`13990`, :ghpull:`13991`, :ghpull:`13994` all improve keybinding and
185 - :ghpull:`13990`, :ghpull:`13991`, :ghpull:`13994` all improve keybinding and
169 shortcut configurability.
186 shortcut configurability.
170
187
171 As usual you can find the full list of PRs on GitHub under `the 8.12 milestone
188 As usual you can find the full list of PRs on GitHub under `the 8.12 milestone
172 <https://github.com/ipython/ipython/milestone/114?closed=1>`__.
189 <https://github.com/ipython/ipython/milestone/114?closed=1>`__.
173
190
174 We want to thank the D.E. Shaw group for requesting and sponsoring the work on
191 We want to thank the D.E. Shaw group for requesting and sponsoring the work on
175 the following big feature. We had productive discussions on how to best expose
192 the following big feature. We had productive discussions on how to best expose
176 this feature
193 this feature
177
194
178 Dynamic documentation dispatch
195 Dynamic documentation dispatch
179 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
196 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
180
197
181 We are experimenting with dynamic documentation dispatch for object attribute.
198 We are experimenting with dynamic documentation dispatch for object attribute.
182 See :ghissue:`13860`. The goal is to allow object to define documentation for
199 See :ghissue:`13860`. The goal is to allow object to define documentation for
183 their attributes, properties, even when those are dynamically defined with
200 their attributes, properties, even when those are dynamically defined with
184 `__getattr__`.
201 `__getattr__`.
185
202
186 In particular when those objects are base types it can be useful to show the
203 In particular when those objects are base types it can be useful to show the
187 documentation
204 documentation
188
205
189
206
190 .. code-block:: ipython
207 .. code-block:: ipython
191
208
192
209
193 In [1]: class User:
210 In [1]: class User:
194 ...:
211 ...:
195 ...: __custom_documentations__ = {
212 ...: __custom_documentations__ = {
196 ...: "first": "The first name of the user.",
213 ...: "first": "The first name of the user.",
197 ...: "last": "The last name of the user.",
214 ...: "last": "The last name of the user.",
198 ...: }
215 ...: }
199 ...:
216 ...:
200 ...: first:str
217 ...: first:str
201 ...: last:str
218 ...: last:str
202 ...:
219 ...:
203 ...: def __init__(self, first, last):
220 ...: def __init__(self, first, last):
204 ...: self.first = first
221 ...: self.first = first
205 ...: self.last = last
222 ...: self.last = last
206 ...:
223 ...:
207 ...: @property
224 ...: @property
208 ...: def full(self):
225 ...: def full(self):
209 ...: """`self.first` and `self.last` joined by a space."""
226 ...: """`self.first` and `self.last` joined by a space."""
210 ...: return self.first + " " + self.last
227 ...: return self.first + " " + self.last
211 ...:
228 ...:
212 ...:
229 ...:
213 ...: user = Person('Jane', 'Doe')
230 ...: user = Person('Jane', 'Doe')
214
231
215 In [2]: user.first?
232 In [2]: user.first?
216 Type: str
233 Type: str
217 String form: Jane
234 String form: Jane
218 Length: 4
235 Length: 4
219 Docstring: the first name of a the person object, a str
236 Docstring: the first name of a the person object, a str
220 Class docstring:
237 Class docstring:
221 ....
238 ....
222
239
223 In [3]: user.last?
240 In [3]: user.last?
224 Type: str
241 Type: str
225 String form: Doe
242 String form: Doe
226 Length: 3
243 Length: 3
227 Docstring: the last name, also a str
244 Docstring: the last name, also a str
228 ...
245 ...
229
246
230
247
231 We can see here the symmetry with IPython looking for the docstring on the
248 We can see here the symmetry with IPython looking for the docstring on the
232 properties:
249 properties:
233
250
234 .. code-block:: ipython
251 .. code-block:: ipython
235
252
236
253
237 In [4]: user.full?
254 In [4]: user.full?
238 HERE
255 HERE
239 Type: property
256 Type: property
240 String form: <property object at 0x102bb15d0>
257 String form: <property object at 0x102bb15d0>
241 Docstring: first and last join by a space
258 Docstring: first and last join by a space
242
259
243
260
244 Note that while in the above example we use a static dictionary, libraries may
261 Note that while in the above example we use a static dictionary, libraries may
245 decide to use a custom object that define ``__getitem__``, we caution against
262 decide to use a custom object that define ``__getitem__``, we caution against
246 using objects that would trigger computation to show documentation, but it is
263 using objects that would trigger computation to show documentation, but it is
247 sometime preferable for highly dynamic code that for example export ans API as
264 sometime preferable for highly dynamic code that for example export ans API as
248 object.
265 object.
249
266
250
267
251
268
252 .. _version 8.11.0:
269 .. _version 8.11.0:
253
270
254 IPython 8.11
271 IPython 8.11
255 ------------
272 ------------
256
273
257 Back on almost regular monthly schedule for IPython with end-of-month
274 Back on almost regular monthly schedule for IPython with end-of-month
258 really-late-Friday release to make sure some bugs are properly fixed.
275 really-late-Friday release to make sure some bugs are properly fixed.
259 Small addition of with a few new features, bugfix and UX improvements.
276 Small addition of with a few new features, bugfix and UX improvements.
260
277
261 This is a non-exhaustive list, but among other you will find:
278 This is a non-exhaustive list, but among other you will find:
262
279
263 Faster Traceback Highlighting
280 Faster Traceback Highlighting
264 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
281 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
265
282
266 Resurrection of pre-IPython-8 traceback highlighting code.
283 Resurrection of pre-IPython-8 traceback highlighting code.
267
284
268 Really long and complicated files were slow to highlight in traceback with
285 Really long and complicated files were slow to highlight in traceback with
269 IPython 8 despite upstream improvement that make many case better. Therefore
286 IPython 8 despite upstream improvement that make many case better. Therefore
270 starting with IPython 8.11 when one of the highlighted file is more than 10 000
287 starting with IPython 8.11 when one of the highlighted file is more than 10 000
271 line long by default, we'll fallback to a faster path that does not have all the
288 line long by default, we'll fallback to a faster path that does not have all the
272 features of highlighting failing AST nodes.
289 features of highlighting failing AST nodes.
273
290
274 This can be configures by setting the value of
291 This can be configures by setting the value of
275 ``IPython.code.ultratb.FAST_THRESHOLD`` to an arbitrary low or large value.
292 ``IPython.code.ultratb.FAST_THRESHOLD`` to an arbitrary low or large value.
276
293
277
294
278 Autoreload verbosity
295 Autoreload verbosity
279 ~~~~~~~~~~~~~~~~~~~~
296 ~~~~~~~~~~~~~~~~~~~~
280
297
281 We introduce more descriptive names for the ``%autoreload`` parameter:
298 We introduce more descriptive names for the ``%autoreload`` parameter:
282
299
283 - ``%autoreload now`` (also ``%autoreload``) - perform autoreload immediately.
300 - ``%autoreload now`` (also ``%autoreload``) - perform autoreload immediately.
284 - ``%autoreload off`` (also ``%autoreload 0``) - turn off autoreload.
301 - ``%autoreload off`` (also ``%autoreload 0``) - turn off autoreload.
285 - ``%autoreload explicit`` (also ``%autoreload 1``) - turn on autoreload only for modules
302 - ``%autoreload explicit`` (also ``%autoreload 1``) - turn on autoreload only for modules
286 whitelisted by ``%aimport`` statements.
303 whitelisted by ``%aimport`` statements.
287 - ``%autoreload all`` (also ``%autoreload 2``) - turn on autoreload for all modules except those
304 - ``%autoreload all`` (also ``%autoreload 2``) - turn on autoreload for all modules except those
288 blacklisted by ``%aimport`` statements.
305 blacklisted by ``%aimport`` statements.
289 - ``%autoreload complete`` (also ``%autoreload 3``) - all the fatures of ``all`` but also adding new
306 - ``%autoreload complete`` (also ``%autoreload 3``) - all the fatures of ``all`` but also adding new
290 objects from the imported modules (see
307 objects from the imported modules (see
291 IPython/extensions/tests/test_autoreload.py::test_autoload_newly_added_objects).
308 IPython/extensions/tests/test_autoreload.py::test_autoload_newly_added_objects).
292
309
293 The original designations (e.g. "2") still work, and these new ones are case-insensitive.
310 The original designations (e.g. "2") still work, and these new ones are case-insensitive.
294
311
295 Additionally, the option ``--print`` or ``-p`` can be added to the line to print the names of
312 Additionally, the option ``--print`` or ``-p`` can be added to the line to print the names of
296 modules being reloaded. Similarly, ``--log`` or ``-l`` will output the names to the logger at INFO
313 modules being reloaded. Similarly, ``--log`` or ``-l`` will output the names to the logger at INFO
297 level. Both can be used simultaneously.
314 level. Both can be used simultaneously.
298
315
299 The parsing logic for ``%aimport`` is now improved such that modules can be whitelisted and
316 The parsing logic for ``%aimport`` is now improved such that modules can be whitelisted and
300 blacklisted in the same line, e.g. it's now possible to call ``%aimport os, -math`` to include
317 blacklisted in the same line, e.g. it's now possible to call ``%aimport os, -math`` to include
301 ``os`` for ``%autoreload explicit`` and exclude ``math`` for modes ``all`` and ``complete``.
318 ``os`` for ``%autoreload explicit`` and exclude ``math`` for modes ``all`` and ``complete``.
302
319
303 Terminal shortcuts customization
320 Terminal shortcuts customization
304 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
321 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
305
322
306 Previously modifying shortcuts was only possible by hooking into startup files
323 Previously modifying shortcuts was only possible by hooking into startup files
307 and practically limited to adding new shortcuts or removing all shortcuts bound
324 and practically limited to adding new shortcuts or removing all shortcuts bound
308 to a specific key. This release enables users to override existing terminal
325 to a specific key. This release enables users to override existing terminal
309 shortcuts, disable them or add new keybindings.
326 shortcuts, disable them or add new keybindings.
310
327
311 For example, to set the :kbd:`right` to accept a single character of auto-suggestion
328 For example, to set the :kbd:`right` to accept a single character of auto-suggestion
312 you could use::
329 you could use::
313
330
314 my_shortcuts = [
331 my_shortcuts = [
315 {
332 {
316 "command": "IPython:auto_suggest.accept_character",
333 "command": "IPython:auto_suggest.accept_character",
317 "new_keys": ["right"]
334 "new_keys": ["right"]
318 }
335 }
319 ]
336 ]
320 %config TerminalInteractiveShell.shortcuts = my_shortcuts
337 %config TerminalInteractiveShell.shortcuts = my_shortcuts
321
338
322 You can learn more in :std:configtrait:`TerminalInteractiveShell.shortcuts`
339 You can learn more in :std:configtrait:`TerminalInteractiveShell.shortcuts`
323 configuration reference.
340 configuration reference.
324
341
325 Miscellaneous
342 Miscellaneous
326 ~~~~~~~~~~~~~
343 ~~~~~~~~~~~~~
327
344
328 - ``%gui`` should now support PySide6. :ghpull:`13864`
345 - ``%gui`` should now support PySide6. :ghpull:`13864`
329 - Cli shortcuts can now be configured :ghpull:`13928`, see above.
346 - Cli shortcuts can now be configured :ghpull:`13928`, see above.
330 (note that there might be an issue with prompt_toolkit 3.0.37 and shortcut configuration).
347 (note that there might be an issue with prompt_toolkit 3.0.37 and shortcut configuration).
331
348
332 - Capture output should now respect ``;`` semicolon to suppress output.
349 - Capture output should now respect ``;`` semicolon to suppress output.
333 :ghpull:`13940`
350 :ghpull:`13940`
334 - Base64 encoded images (in jupyter frontend), will not have trailing newlines.
351 - Base64 encoded images (in jupyter frontend), will not have trailing newlines.
335 :ghpull:`13941`
352 :ghpull:`13941`
336
353
337 As usual you can find the full list of PRs on GitHub under `the 8.11 milestone
354 As usual you can find the full list of PRs on GitHub under `the 8.11 milestone
338 <https://github.com/ipython/ipython/milestone/113?closed=1>`__.
355 <https://github.com/ipython/ipython/milestone/113?closed=1>`__.
339
356
340 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
357 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
341 work on IPython and related libraries.
358 work on IPython and related libraries.
342
359
343 .. _version 8.10.0:
360 .. _version 8.10.0:
344
361
345 IPython 8.10
362 IPython 8.10
346 ------------
363 ------------
347
364
348 Out of schedule release of IPython with minor fixes to patch a potential CVE-2023-24816.
365 Out of schedule release of IPython with minor fixes to patch a potential CVE-2023-24816.
349 This is a really low severity CVE that you most likely are not affected by unless:
366 This is a really low severity CVE that you most likely are not affected by unless:
350
367
351 - You are on windows.
368 - You are on windows.
352 - You have a custom build of Python without ``_ctypes``
369 - You have a custom build of Python without ``_ctypes``
353 - You cd or start IPython or Jupyter in untrusted directory which names may be
370 - You cd or start IPython or Jupyter in untrusted directory which names may be
354 valid shell commands.
371 valid shell commands.
355
372
356 You can read more on `the advisory
373 You can read more on `the advisory
357 <https://github.com/ipython/ipython/security/advisories/GHSA-29gw-9793-fvw7>`__.
374 <https://github.com/ipython/ipython/security/advisories/GHSA-29gw-9793-fvw7>`__.
358
375
359 In addition to fixing this CVE we also fix a couple of outstanding bugs and issues.
376 In addition to fixing this CVE we also fix a couple of outstanding bugs and issues.
360
377
361 As usual you can find the full list of PRs on GitHub under `the 8.10 milestone
378 As usual you can find the full list of PRs on GitHub under `the 8.10 milestone
362 <https://github.com/ipython/ipython/milestone/112?closed=1>`__.
379 <https://github.com/ipython/ipython/milestone/112?closed=1>`__.
363
380
364 In Particular:
381 In Particular:
365
382
366 - bump minimum numpy to `>=1.21` version following NEP29. :ghpull:`13930`
383 - bump minimum numpy to `>=1.21` version following NEP29. :ghpull:`13930`
367 - fix for compatibility with MyPy 1.0. :ghpull:`13933`
384 - fix for compatibility with MyPy 1.0. :ghpull:`13933`
368 - fix nbgrader stalling when IPython's ``showtraceback`` function is
385 - fix nbgrader stalling when IPython's ``showtraceback`` function is
369 monkeypatched. :ghpull:`13934`
386 monkeypatched. :ghpull:`13934`
370
387
371
388
372
389
373 As this release also contains those minimal changes in addition to fixing the
390 As this release also contains those minimal changes in addition to fixing the
374 CVE I decided to bump the minor version anyway.
391 CVE I decided to bump the minor version anyway.
375
392
376 This will not affect the normal release schedule, so IPython 8.11 is due in
393 This will not affect the normal release schedule, so IPython 8.11 is due in
377 about 2 weeks.
394 about 2 weeks.
378
395
379 .. _version 8.9.0:
396 .. _version 8.9.0:
380
397
381 IPython 8.9.0
398 IPython 8.9.0
382 -------------
399 -------------
383
400
384 Second release of IPython in 2023, last Friday of the month, we are back on
401 Second release of IPython in 2023, last Friday of the month, we are back on
385 track. This is a small release with a few bug-fixes, and improvements, mostly
402 track. This is a small release with a few bug-fixes, and improvements, mostly
386 with respect to terminal shortcuts.
403 with respect to terminal shortcuts.
387
404
388
405
389 The biggest improvement for 8.9 is a drastic amelioration of the
406 The biggest improvement for 8.9 is a drastic amelioration of the
390 auto-suggestions sponsored by D.E. Shaw and implemented by the more and more
407 auto-suggestions sponsored by D.E. Shaw and implemented by the more and more
391 active contributor `@krassowski <https://github.com/krassowski>`.
408 active contributor `@krassowski <https://github.com/krassowski>`.
392
409
393 - ``right`` accepts a single character from suggestion
410 - ``right`` accepts a single character from suggestion
394 - ``ctrl+right`` accepts a semantic token (macos default shortcuts take
411 - ``ctrl+right`` accepts a semantic token (macos default shortcuts take
395 precedence and need to be disabled to make this work)
412 precedence and need to be disabled to make this work)
396 - ``backspace`` deletes a character and resumes hinting autosuggestions
413 - ``backspace`` deletes a character and resumes hinting autosuggestions
397 - ``ctrl-left`` accepts suggestion and moves cursor left one character.
414 - ``ctrl-left`` accepts suggestion and moves cursor left one character.
398 - ``backspace`` deletes a character and resumes hinting autosuggestions
415 - ``backspace`` deletes a character and resumes hinting autosuggestions
399 - ``down`` moves to suggestion to later in history when no lines are present below the cursors.
416 - ``down`` moves to suggestion to later in history when no lines are present below the cursors.
400 - ``up`` moves to suggestion from earlier in history when no lines are present above the cursor.
417 - ``up`` moves to suggestion from earlier in history when no lines are present above the cursor.
401
418
402 This is best described by the Gif posted by `@krassowski
419 This is best described by the Gif posted by `@krassowski
403 <https://github.com/krassowski>`, and in the PR itself :ghpull:`13888`.
420 <https://github.com/krassowski>`, and in the PR itself :ghpull:`13888`.
404
421
405 .. image:: ../_images/autosuggest.gif
422 .. image:: ../_images/autosuggest.gif
406
423
407 Please report any feedback in order for us to improve the user experience.
424 Please report any feedback in order for us to improve the user experience.
408 In particular we are also working on making the shortcuts configurable.
425 In particular we are also working on making the shortcuts configurable.
409
426
410 If you are interested in better terminal shortcuts, I also invite you to
427 If you are interested in better terminal shortcuts, I also invite you to
411 participate in issue `13879
428 participate in issue `13879
412 <https://github.com/ipython/ipython/issues/13879>`__.
429 <https://github.com/ipython/ipython/issues/13879>`__.
413
430
414
431
415 As we follow `NEP29
432 As we follow `NEP29
416 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`__, next version of
433 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`__, next version of
417 IPython will officially stop supporting numpy 1.20, and will stop supporting
434 IPython will officially stop supporting numpy 1.20, and will stop supporting
418 Python 3.8 after April release.
435 Python 3.8 after April release.
419
436
420 As usual you can find the full list of PRs on GitHub under `the 8.9 milestone
437 As usual you can find the full list of PRs on GitHub under `the 8.9 milestone
421 <https://github.com/ipython/ipython/milestone/111?closed=1>`__.
438 <https://github.com/ipython/ipython/milestone/111?closed=1>`__.
422
439
423
440
424 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
441 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
425 work on IPython and related libraries.
442 work on IPython and related libraries.
426
443
427 .. _version 8.8.0:
444 .. _version 8.8.0:
428
445
429 IPython 8.8.0
446 IPython 8.8.0
430 -------------
447 -------------
431
448
432 First release of IPython in 2023 as there was no release at the end of
449 First release of IPython in 2023 as there was no release at the end of
433 December.
450 December.
434
451
435 This is an unusually big release (relatively speaking) with more than 15 Pull
452 This is an unusually big release (relatively speaking) with more than 15 Pull
436 Requests merged.
453 Requests merged.
437
454
438 Of particular interest are:
455 Of particular interest are:
439
456
440 - :ghpull:`13852` that replaces the greedy completer and improves
457 - :ghpull:`13852` that replaces the greedy completer and improves
441 completion, in particular for dictionary keys.
458 completion, in particular for dictionary keys.
442 - :ghpull:`13858` that adds ``py.typed`` to ``setup.cfg`` to make sure it is
459 - :ghpull:`13858` that adds ``py.typed`` to ``setup.cfg`` to make sure it is
443 bundled in wheels.
460 bundled in wheels.
444 - :ghpull:`13869` that implements tab completions for IPython options in the
461 - :ghpull:`13869` that implements tab completions for IPython options in the
445 shell when using `argcomplete <https://github.com/kislyuk/argcomplete>`. I
462 shell when using `argcomplete <https://github.com/kislyuk/argcomplete>`. I
446 believe this also needs a recent version of Traitlets.
463 believe this also needs a recent version of Traitlets.
447 - :ghpull:`13865` makes the ``inspector`` class of `InteractiveShell`
464 - :ghpull:`13865` makes the ``inspector`` class of `InteractiveShell`
448 configurable.
465 configurable.
449 - :ghpull:`13880` that removes minor-version entrypoints as the minor version
466 - :ghpull:`13880` that removes minor-version entrypoints as the minor version
450 entry points that would be included in the wheel would be the one of the
467 entry points that would be included in the wheel would be the one of the
451 Python version that was used to build the ``whl`` file.
468 Python version that was used to build the ``whl`` file.
452
469
453 In no particular order, the rest of the changes update the test suite to be
470 In no particular order, the rest of the changes update the test suite to be
454 compatible with Pygments 2.14, various docfixes, testing on more recent python
471 compatible with Pygments 2.14, various docfixes, testing on more recent python
455 versions and various updates.
472 versions and various updates.
456
473
457 As usual you can find the full list of PRs on GitHub under `the 8.8 milestone
474 As usual you can find the full list of PRs on GitHub under `the 8.8 milestone
458 <https://github.com/ipython/ipython/milestone/110>`__.
475 <https://github.com/ipython/ipython/milestone/110>`__.
459
476
460 Many thanks to @krassowski for the many PRs and @jasongrout for reviewing and
477 Many thanks to @krassowski for the many PRs and @jasongrout for reviewing and
461 merging contributions.
478 merging contributions.
462
479
463 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
480 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
464 work on IPython and related libraries.
481 work on IPython and related libraries.
465
482
466 .. _version 8.7.0:
483 .. _version 8.7.0:
467
484
468 IPython 8.7.0
485 IPython 8.7.0
469 -------------
486 -------------
470
487
471
488
472 Small release of IPython with a couple of bug fixes and new features for this
489 Small release of IPython with a couple of bug fixes and new features for this
473 month. Next month is the end of year, it is unclear if there will be a release
490 month. Next month is the end of year, it is unclear if there will be a release
474 close to the new year's eve, or if the next release will be at the end of January.
491 close to the new year's eve, or if the next release will be at the end of January.
475
492
476 Here are a few of the relevant fixes,
493 Here are a few of the relevant fixes,
477 as usual you can find the full list of PRs on GitHub under `the 8.7 milestone
494 as usual you can find the full list of PRs on GitHub under `the 8.7 milestone
478 <https://github.com/ipython/ipython/pulls?q=milestone%3A8.7>`__.
495 <https://github.com/ipython/ipython/pulls?q=milestone%3A8.7>`__.
479
496
480
497
481 - :ghpull:`13834` bump the minimum prompt toolkit to 3.0.11.
498 - :ghpull:`13834` bump the minimum prompt toolkit to 3.0.11.
482 - IPython shipped with the ``py.typed`` marker now, and we are progressively
499 - IPython shipped with the ``py.typed`` marker now, and we are progressively
483 adding more types. :ghpull:`13831`
500 adding more types. :ghpull:`13831`
484 - :ghpull:`13817` add configuration of code blacks formatting.
501 - :ghpull:`13817` add configuration of code blacks formatting.
485
502
486
503
487 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
504 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
488 work on IPython and related libraries.
505 work on IPython and related libraries.
489
506
490
507
491 .. _version 8.6.0:
508 .. _version 8.6.0:
492
509
493 IPython 8.6.0
510 IPython 8.6.0
494 -------------
511 -------------
495
512
496 Back to a more regular release schedule (at least I try), as Friday is
513 Back to a more regular release schedule (at least I try), as Friday is
497 already over by more than 24h hours. This is a slightly bigger release with a
514 already over by more than 24h hours. This is a slightly bigger release with a
498 few new features that contain no less than 25 PRs.
515 few new features that contain no less than 25 PRs.
499
516
500 We'll notably found a couple of non negligible changes:
517 We'll notably found a couple of non negligible changes:
501
518
502 The ``install_ext`` and related functions have been removed after being
519 The ``install_ext`` and related functions have been removed after being
503 deprecated for years. You can use pip to install extensions. ``pip`` did not
520 deprecated for years. You can use pip to install extensions. ``pip`` did not
504 exist when ``install_ext`` was introduced. You can still load local extensions
521 exist when ``install_ext`` was introduced. You can still load local extensions
505 without installing them. Just set your ``sys.path`` for example. :ghpull:`13744`
522 without installing them. Just set your ``sys.path`` for example. :ghpull:`13744`
506
523
507 IPython now has extra entry points that use the major *and minor* version of
524 IPython now has extra entry points that use the major *and minor* version of
508 python. For some of you this means that you can do a quick ``ipython3.10`` to
525 python. For some of you this means that you can do a quick ``ipython3.10`` to
509 launch IPython from the Python 3.10 interpreter, while still using Python 3.11
526 launch IPython from the Python 3.10 interpreter, while still using Python 3.11
510 as your main Python. :ghpull:`13743`
527 as your main Python. :ghpull:`13743`
511
528
512 The completer matcher API has been improved. See :ghpull:`13745`. This should
529 The completer matcher API has been improved. See :ghpull:`13745`. This should
513 improve the type inference and improve dict keys completions in many use case.
530 improve the type inference and improve dict keys completions in many use case.
514 Thanks ``@krassowski`` for all the work, and the D.E. Shaw group for sponsoring
531 Thanks ``@krassowski`` for all the work, and the D.E. Shaw group for sponsoring
515 it.
532 it.
516
533
517 The color of error nodes in tracebacks can now be customized. See
534 The color of error nodes in tracebacks can now be customized. See
518 :ghpull:`13756`. This is a private attribute until someone finds the time to
535 :ghpull:`13756`. This is a private attribute until someone finds the time to
519 properly add a configuration option. Note that with Python 3.11 that also shows
536 properly add a configuration option. Note that with Python 3.11 that also shows
520 the relevant nodes in traceback, it would be good to leverage this information
537 the relevant nodes in traceback, it would be good to leverage this information
521 (plus the "did you mean" info added on attribute errors). But that's likely work
538 (plus the "did you mean" info added on attribute errors). But that's likely work
522 I won't have time to do before long, so contributions welcome.
539 I won't have time to do before long, so contributions welcome.
523
540
524 As we follow NEP 29, we removed support for numpy 1.19 :ghpull:`13760`.
541 As we follow NEP 29, we removed support for numpy 1.19 :ghpull:`13760`.
525
542
526
543
527 The ``open()`` function present in the user namespace by default will now refuse
544 The ``open()`` function present in the user namespace by default will now refuse
528 to open the file descriptors 0,1,2 (stdin, out, err), to avoid crashing IPython.
545 to open the file descriptors 0,1,2 (stdin, out, err), to avoid crashing IPython.
529 This mostly occurs in teaching context when incorrect values get passed around.
546 This mostly occurs in teaching context when incorrect values get passed around.
530
547
531
548
532 The ``?``, ``??``, and corresponding ``pinfo``, ``pinfo2`` magics can now find
549 The ``?``, ``??``, and corresponding ``pinfo``, ``pinfo2`` magics can now find
533 objects inside arrays. That is to say, the following now works::
550 objects inside arrays. That is to say, the following now works::
534
551
535
552
536 >>> def my_func(*arg, **kwargs):pass
553 >>> def my_func(*arg, **kwargs):pass
537 >>> container = [my_func]
554 >>> container = [my_func]
538 >>> container[0]?
555 >>> container[0]?
539
556
540
557
541 If ``container`` define a custom ``getitem``, this __will__ trigger the custom
558 If ``container`` define a custom ``getitem``, this __will__ trigger the custom
542 method. So don't put side effects in your ``getitems``. Thanks to the D.E. Shaw
559 method. So don't put side effects in your ``getitems``. Thanks to the D.E. Shaw
543 group for the request and sponsoring the work.
560 group for the request and sponsoring the work.
544
561
545
562
546 As usual you can find the full list of PRs on GitHub under `the 8.6 milestone
563 As usual you can find the full list of PRs on GitHub under `the 8.6 milestone
547 <https://github.com/ipython/ipython/pulls?q=milestone%3A8.6>`__.
564 <https://github.com/ipython/ipython/pulls?q=milestone%3A8.6>`__.
548
565
549 Thanks to all hacktoberfest contributors, please contribute to
566 Thanks to all hacktoberfest contributors, please contribute to
550 `closember.org <https://closember.org/>`__.
567 `closember.org <https://closember.org/>`__.
551
568
552 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
569 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
553 work on IPython and related libraries.
570 work on IPython and related libraries.
554
571
555 .. _version 8.5.0:
572 .. _version 8.5.0:
556
573
557 IPython 8.5.0
574 IPython 8.5.0
558 -------------
575 -------------
559
576
560 First release since a couple of month due to various reasons and timing preventing
577 First release since a couple of month due to various reasons and timing preventing
561 me for sticking to the usual monthly release the last Friday of each month. This
578 me for sticking to the usual monthly release the last Friday of each month. This
562 is of non negligible size as it has more than two dozen PRs with various fixes
579 is of non negligible size as it has more than two dozen PRs with various fixes
563 an bug fixes.
580 an bug fixes.
564
581
565 Many thanks to everybody who contributed PRs for your patience in review and
582 Many thanks to everybody who contributed PRs for your patience in review and
566 merges.
583 merges.
567
584
568 Here is a non-exhaustive list of changes that have been implemented for IPython
585 Here is a non-exhaustive list of changes that have been implemented for IPython
569 8.5.0. As usual you can find the full list of issues and PRs tagged with `the
586 8.5.0. As usual you can find the full list of issues and PRs tagged with `the
570 8.5 milestone
587 8.5 milestone
571 <https://github.com/ipython/ipython/pulls?q=is%3Aclosed+milestone%3A8.5+>`__.
588 <https://github.com/ipython/ipython/pulls?q=is%3Aclosed+milestone%3A8.5+>`__.
572
589
573 - Added a shortcut for accepting auto suggestion. The End key shortcut for
590 - Added a shortcut for accepting auto suggestion. The End key shortcut for
574 accepting auto-suggestion This binding works in Vi mode too, provided
591 accepting auto-suggestion This binding works in Vi mode too, provided
575 ``TerminalInteractiveShell.emacs_bindings_in_vi_insert_mode`` is set to be
592 ``TerminalInteractiveShell.emacs_bindings_in_vi_insert_mode`` is set to be
576 ``True`` :ghpull:`13566`.
593 ``True`` :ghpull:`13566`.
577
594
578 - No popup in window for latex generation when generating latex (e.g. via
595 - No popup in window for latex generation when generating latex (e.g. via
579 `_latex_repr_`) no popup window is shows under Windows. :ghpull:`13679`
596 `_latex_repr_`) no popup window is shows under Windows. :ghpull:`13679`
580
597
581 - Fixed error raised when attempting to tab-complete an input string with
598 - Fixed error raised when attempting to tab-complete an input string with
582 consecutive periods or forward slashes (such as "file:///var/log/...").
599 consecutive periods or forward slashes (such as "file:///var/log/...").
583 :ghpull:`13675`
600 :ghpull:`13675`
584
601
585 - Relative filenames in Latex rendering :
602 - Relative filenames in Latex rendering :
586 The `latex_to_png_dvipng` command internally generates input and output file
603 The `latex_to_png_dvipng` command internally generates input and output file
587 arguments to `latex` and `dvipis`. These arguments are now generated as
604 arguments to `latex` and `dvipis`. These arguments are now generated as
588 relative files to the current working directory instead of absolute file
605 relative files to the current working directory instead of absolute file
589 paths. This solves a problem where the current working directory contains
606 paths. This solves a problem where the current working directory contains
590 characters that are not handled properly by `latex` and `dvips`. There are
607 characters that are not handled properly by `latex` and `dvips`. There are
591 no changes to the user API. :ghpull:`13680`
608 no changes to the user API. :ghpull:`13680`
592
609
593 - Stripping decorators bug: Fixed bug which meant that ipython code blocks in
610 - Stripping decorators bug: Fixed bug which meant that ipython code blocks in
594 restructured text documents executed with the ipython-sphinx extension
611 restructured text documents executed with the ipython-sphinx extension
595 skipped any lines of code containing python decorators. :ghpull:`13612`
612 skipped any lines of code containing python decorators. :ghpull:`13612`
596
613
597 - Allow some modules with frozen dataclasses to be reloaded. :ghpull:`13732`
614 - Allow some modules with frozen dataclasses to be reloaded. :ghpull:`13732`
598 - Fix paste magic on wayland. :ghpull:`13671`
615 - Fix paste magic on wayland. :ghpull:`13671`
599 - show maxlen in deque's repr. :ghpull:`13648`
616 - show maxlen in deque's repr. :ghpull:`13648`
600
617
601 Restore line numbers for Input
618 Restore line numbers for Input
602 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
619 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
603
620
604 Line number information in tracebacks from input are restored.
621 Line number information in tracebacks from input are restored.
605 Line numbers from input were removed during the transition to v8 enhanced traceback reporting.
622 Line numbers from input were removed during the transition to v8 enhanced traceback reporting.
606
623
607 So, instead of::
624 So, instead of::
608
625
609 ---------------------------------------------------------------------------
626 ---------------------------------------------------------------------------
610 ZeroDivisionError Traceback (most recent call last)
627 ZeroDivisionError Traceback (most recent call last)
611 Input In [3], in <cell line: 1>()
628 Input In [3], in <cell line: 1>()
612 ----> 1 myfunc(2)
629 ----> 1 myfunc(2)
613
630
614 Input In [2], in myfunc(z)
631 Input In [2], in myfunc(z)
615 1 def myfunc(z):
632 1 def myfunc(z):
616 ----> 2 foo.boo(z-1)
633 ----> 2 foo.boo(z-1)
617
634
618 File ~/code/python/ipython/foo.py:3, in boo(x)
635 File ~/code/python/ipython/foo.py:3, in boo(x)
619 2 def boo(x):
636 2 def boo(x):
620 ----> 3 return 1/(1-x)
637 ----> 3 return 1/(1-x)
621
638
622 ZeroDivisionError: division by zero
639 ZeroDivisionError: division by zero
623
640
624 The error traceback now looks like::
641 The error traceback now looks like::
625
642
626 ---------------------------------------------------------------------------
643 ---------------------------------------------------------------------------
627 ZeroDivisionError Traceback (most recent call last)
644 ZeroDivisionError Traceback (most recent call last)
628 Cell In [3], line 1
645 Cell In [3], line 1
629 ----> 1 myfunc(2)
646 ----> 1 myfunc(2)
630
647
631 Cell In [2], line 2, in myfunc(z)
648 Cell In [2], line 2, in myfunc(z)
632 1 def myfunc(z):
649 1 def myfunc(z):
633 ----> 2 foo.boo(z-1)
650 ----> 2 foo.boo(z-1)
634
651
635 File ~/code/python/ipython/foo.py:3, in boo(x)
652 File ~/code/python/ipython/foo.py:3, in boo(x)
636 2 def boo(x):
653 2 def boo(x):
637 ----> 3 return 1/(1-x)
654 ----> 3 return 1/(1-x)
638
655
639 ZeroDivisionError: division by zero
656 ZeroDivisionError: division by zero
640
657
641 or, with xmode=Plain::
658 or, with xmode=Plain::
642
659
643 Traceback (most recent call last):
660 Traceback (most recent call last):
644 Cell In [12], line 1
661 Cell In [12], line 1
645 myfunc(2)
662 myfunc(2)
646 Cell In [6], line 2 in myfunc
663 Cell In [6], line 2 in myfunc
647 foo.boo(z-1)
664 foo.boo(z-1)
648 File ~/code/python/ipython/foo.py:3 in boo
665 File ~/code/python/ipython/foo.py:3 in boo
649 return 1/(1-x)
666 return 1/(1-x)
650 ZeroDivisionError: division by zero
667 ZeroDivisionError: division by zero
651
668
652 :ghpull:`13560`
669 :ghpull:`13560`
653
670
654 New setting to silence warning if working inside a virtual environment
671 New setting to silence warning if working inside a virtual environment
655 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
672 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
656
673
657 Previously, when starting IPython in a virtual environment without IPython installed (so IPython from the global environment is used), the following warning was printed:
674 Previously, when starting IPython in a virtual environment without IPython installed (so IPython from the global environment is used), the following warning was printed:
658
675
659 Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
676 Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
660
677
661 This warning can be permanently silenced by setting ``c.InteractiveShell.warn_venv`` to ``False`` (the default is ``True``).
678 This warning can be permanently silenced by setting ``c.InteractiveShell.warn_venv`` to ``False`` (the default is ``True``).
662
679
663 :ghpull:`13706`
680 :ghpull:`13706`
664
681
665 -------
682 -------
666
683
667 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
684 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
668 work on IPython and related libraries.
685 work on IPython and related libraries.
669
686
670
687
671 .. _version 8.4.0:
688 .. _version 8.4.0:
672
689
673 IPython 8.4.0
690 IPython 8.4.0
674 -------------
691 -------------
675
692
676 As for 7.34, this version contains a single fix: fix uncaught BdbQuit exceptions on ipdb
693 As for 7.34, this version contains a single fix: fix uncaught BdbQuit exceptions on ipdb
677 exit :ghpull:`13668`, and a single typo fix in documentation: :ghpull:`13682`
694 exit :ghpull:`13668`, and a single typo fix in documentation: :ghpull:`13682`
678
695
679 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
696 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
680 work on IPython and related libraries.
697 work on IPython and related libraries.
681
698
682
699
683 .. _version 8.3.0:
700 .. _version 8.3.0:
684
701
685 IPython 8.3.0
702 IPython 8.3.0
686 -------------
703 -------------
687
704
688 - :ghpull:`13625`, using ``?``, ``??``, ``*?`` will not call
705 - :ghpull:`13625`, using ``?``, ``??``, ``*?`` will not call
689 ``set_next_input`` as most frontend allow proper multiline editing and it was
706 ``set_next_input`` as most frontend allow proper multiline editing and it was
690 causing issues for many users of multi-cell frontends. This has been backported to 7.33
707 causing issues for many users of multi-cell frontends. This has been backported to 7.33
691
708
692
709
693 - :ghpull:`13600`, ``pre_run_*``-hooks will now have a ``cell_id`` attribute on
710 - :ghpull:`13600`, ``pre_run_*``-hooks will now have a ``cell_id`` attribute on
694 the info object when frontend provides it. This has been backported to 7.33
711 the info object when frontend provides it. This has been backported to 7.33
695
712
696 - :ghpull:`13624`, fixed :kbd:`End` key being broken after accepting an
713 - :ghpull:`13624`, fixed :kbd:`End` key being broken after accepting an
697 auto-suggestion.
714 auto-suggestion.
698
715
699 - :ghpull:`13657` fixed an issue where history from different sessions would be mixed.
716 - :ghpull:`13657` fixed an issue where history from different sessions would be mixed.
700
717
701 .. _version 8.2.0:
718 .. _version 8.2.0:
702
719
703 IPython 8.2.0
720 IPython 8.2.0
704 -------------
721 -------------
705
722
706 IPython 8.2 mostly bring bugfixes to IPython.
723 IPython 8.2 mostly bring bugfixes to IPython.
707
724
708 - Auto-suggestion can now be elected with the ``end`` key. :ghpull:`13566`
725 - Auto-suggestion can now be elected with the ``end`` key. :ghpull:`13566`
709 - Some traceback issues with ``assert etb is not None`` have been fixed. :ghpull:`13588`
726 - Some traceback issues with ``assert etb is not None`` have been fixed. :ghpull:`13588`
710 - History is now pulled from the sqitel database and not from in-memory.
727 - History is now pulled from the sqitel database and not from in-memory.
711 In particular when using the ``%paste`` magic, the content of the pasted text will
728 In particular when using the ``%paste`` magic, the content of the pasted text will
712 be part of the history and not the verbatim text ``%paste`` anymore. :ghpull:`13592`
729 be part of the history and not the verbatim text ``%paste`` anymore. :ghpull:`13592`
713 - Fix ``Ctrl-\\`` exit cleanup :ghpull:`13603`
730 - Fix ``Ctrl-\\`` exit cleanup :ghpull:`13603`
714 - Fixes to ``ultratb`` ipdb support when used outside of IPython. :ghpull:`13498`
731 - Fixes to ``ultratb`` ipdb support when used outside of IPython. :ghpull:`13498`
715
732
716
733
717 I am still trying to fix and investigate :ghissue:`13598`, which seems to be
734 I am still trying to fix and investigate :ghissue:`13598`, which seems to be
718 random, and would appreciate help if you find a reproducible minimal case. I've
735 random, and would appreciate help if you find a reproducible minimal case. I've
719 tried to make various changes to the codebase to mitigate it, but a proper fix
736 tried to make various changes to the codebase to mitigate it, but a proper fix
720 will be difficult without understanding the cause.
737 will be difficult without understanding the cause.
721
738
722
739
723 All the issues on pull-requests for this release can be found in the `8.2
740 All the issues on pull-requests for this release can be found in the `8.2
724 milestone. <https://github.com/ipython/ipython/milestone/100>`__ . And some
741 milestone. <https://github.com/ipython/ipython/milestone/100>`__ . And some
725 documentation only PR can be found as part of the `7.33 milestone
742 documentation only PR can be found as part of the `7.33 milestone
726 <https://github.com/ipython/ipython/milestone/101>`__ (currently not released).
743 <https://github.com/ipython/ipython/milestone/101>`__ (currently not released).
727
744
728 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
745 Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
729 work on IPython and related libraries.
746 work on IPython and related libraries.
730
747
731 .. _version 8.1.1:
748 .. _version 8.1.1:
732
749
733 IPython 8.1.1
750 IPython 8.1.1
734 -------------
751 -------------
735
752
736 Fix an issue with virtualenv and Python 3.8 introduced in 8.1
753 Fix an issue with virtualenv and Python 3.8 introduced in 8.1
737
754
738 Revert :ghpull:`13537` (fix an issue with symlinks in virtualenv) that raises an
755 Revert :ghpull:`13537` (fix an issue with symlinks in virtualenv) that raises an
739 error in Python 3.8, and fixed in a different way in :ghpull:`13559`.
756 error in Python 3.8, and fixed in a different way in :ghpull:`13559`.
740
757
741 .. _version 8.1:
758 .. _version 8.1:
742
759
743 IPython 8.1.0
760 IPython 8.1.0
744 -------------
761 -------------
745
762
746 IPython 8.1 is the first minor release after 8.0 and fixes a number of bugs and
763 IPython 8.1 is the first minor release after 8.0 and fixes a number of bugs and
747 updates a few behaviors that were problematic with the 8.0 as with many new major
764 updates a few behaviors that were problematic with the 8.0 as with many new major
748 release.
765 release.
749
766
750 Note that beyond the changes listed here, IPython 8.1.0 also contains all the
767 Note that beyond the changes listed here, IPython 8.1.0 also contains all the
751 features listed in :ref:`version 7.32`.
768 features listed in :ref:`version 7.32`.
752
769
753 - Misc and multiple fixes around quotation auto-closing. It is now disabled by
770 - Misc and multiple fixes around quotation auto-closing. It is now disabled by
754 default. Run with ``TerminalInteractiveShell.auto_match=True`` to re-enabled
771 default. Run with ``TerminalInteractiveShell.auto_match=True`` to re-enabled
755 - Require pygments>=2.4.0 :ghpull:`13459`, this was implicit in the code, but
772 - Require pygments>=2.4.0 :ghpull:`13459`, this was implicit in the code, but
756 is now explicit in ``setup.cfg``/``setup.py``
773 is now explicit in ``setup.cfg``/``setup.py``
757 - Docs improvement of ``core.magic_arguments`` examples. :ghpull:`13433`
774 - Docs improvement of ``core.magic_arguments`` examples. :ghpull:`13433`
758 - Multi-line edit executes too early with await. :ghpull:`13424`
775 - Multi-line edit executes too early with await. :ghpull:`13424`
759
776
760 - ``black`` is back as an optional dependency, and autoformatting disabled by
777 - ``black`` is back as an optional dependency, and autoformatting disabled by
761 default until some fixes are implemented (black improperly reformat magics).
778 default until some fixes are implemented (black improperly reformat magics).
762 :ghpull:`13471` Additionally the ability to use ``yapf`` as a code
779 :ghpull:`13471` Additionally the ability to use ``yapf`` as a code
763 reformatter has been added :ghpull:`13528` . You can use
780 reformatter has been added :ghpull:`13528` . You can use
764 ``TerminalInteractiveShell.autoformatter="black"``,
781 ``TerminalInteractiveShell.autoformatter="black"``,
765 ``TerminalInteractiveShell.autoformatter="yapf"`` to re-enable auto formating
782 ``TerminalInteractiveShell.autoformatter="yapf"`` to re-enable auto formating
766 with black, or switch to yapf.
783 with black, or switch to yapf.
767
784
768 - Fix and issue where ``display`` was not defined.
785 - Fix and issue where ``display`` was not defined.
769
786
770 - Auto suggestions are now configurable. Currently only
787 - Auto suggestions are now configurable. Currently only
771 ``AutoSuggestFromHistory`` (default) and ``None``. new provider contribution
788 ``AutoSuggestFromHistory`` (default) and ``None``. new provider contribution
772 welcomed. :ghpull:`13475`
789 welcomed. :ghpull:`13475`
773
790
774 - multiple packaging/testing improvement to simplify downstream packaging
791 - multiple packaging/testing improvement to simplify downstream packaging
775 (xfail with reasons, try to not access network...).
792 (xfail with reasons, try to not access network...).
776
793
777 - Update deprecation. ``InteractiveShell.magic`` internal method has been
794 - Update deprecation. ``InteractiveShell.magic`` internal method has been
778 deprecated for many years but did not emit a warning until now.
795 deprecated for many years but did not emit a warning until now.
779
796
780 - internal ``appended_to_syspath`` context manager has been deprecated.
797 - internal ``appended_to_syspath`` context manager has been deprecated.
781
798
782 - fix an issue with symlinks in virtualenv :ghpull:`13537` (Reverted in 8.1.1)
799 - fix an issue with symlinks in virtualenv :ghpull:`13537` (Reverted in 8.1.1)
783
800
784 - Fix an issue with vim mode, where cursor would not be reset on exit :ghpull:`13472`
801 - Fix an issue with vim mode, where cursor would not be reset on exit :ghpull:`13472`
785
802
786 - ipython directive now remove only known pseudo-decorators :ghpull:`13532`
803 - ipython directive now remove only known pseudo-decorators :ghpull:`13532`
787
804
788 - ``IPython/lib/security`` which used to be used for jupyter notebook has been
805 - ``IPython/lib/security`` which used to be used for jupyter notebook has been
789 removed.
806 removed.
790
807
791 - Fix an issue where ``async with`` would execute on new lines. :ghpull:`13436`
808 - Fix an issue where ``async with`` would execute on new lines. :ghpull:`13436`
792
809
793
810
794 We want to remind users that IPython is part of the Jupyter organisations, and
811 We want to remind users that IPython is part of the Jupyter organisations, and
795 thus governed by a Code of Conduct. Some of the behavior we have seen on GitHub is not acceptable.
812 thus governed by a Code of Conduct. Some of the behavior we have seen on GitHub is not acceptable.
796 Abuse and non-respectful comments on discussion will not be tolerated.
813 Abuse and non-respectful comments on discussion will not be tolerated.
797
814
798 Many thanks to all the contributors to this release, many of the above fixed issues and
815 Many thanks to all the contributors to this release, many of the above fixed issues and
799 new features were done by first time contributors, showing there is still
816 new features were done by first time contributors, showing there is still
800 plenty of easy contribution possible in IPython
817 plenty of easy contribution possible in IPython
801 . You can find all individual contributions
818 . You can find all individual contributions
802 to this milestone `on github <https://github.com/ipython/ipython/milestone/91>`__.
819 to this milestone `on github <https://github.com/ipython/ipython/milestone/91>`__.
803
820
804 Thanks as well to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
821 Thanks as well to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring
805 work on IPython and related libraries. In particular the Lazy autoloading of
822 work on IPython and related libraries. In particular the Lazy autoloading of
806 magics that you will find described in the 7.32 release notes.
823 magics that you will find described in the 7.32 release notes.
807
824
808
825
809 .. _version 8.0.1:
826 .. _version 8.0.1:
810
827
811 IPython 8.0.1 (CVE-2022-21699)
828 IPython 8.0.1 (CVE-2022-21699)
812 ------------------------------
829 ------------------------------
813
830
814 IPython 8.0.1, 7.31.1 and 5.11 are security releases that change some default
831 IPython 8.0.1, 7.31.1 and 5.11 are security releases that change some default
815 values in order to prevent potential Execution with Unnecessary Privileges.
832 values in order to prevent potential Execution with Unnecessary Privileges.
816
833
817 Almost all version of IPython looks for configuration and profiles in current
834 Almost all version of IPython looks for configuration and profiles in current
818 working directory. Since IPython was developed before pip and environments
835 working directory. Since IPython was developed before pip and environments
819 existed it was used a convenient way to load code/packages in a project
836 existed it was used a convenient way to load code/packages in a project
820 dependant way.
837 dependant way.
821
838
822 In 2022, it is not necessary anymore, and can lead to confusing behavior where
839 In 2022, it is not necessary anymore, and can lead to confusing behavior where
823 for example cloning a repository and starting IPython or loading a notebook from
840 for example cloning a repository and starting IPython or loading a notebook from
824 any Jupyter-Compatible interface that has ipython set as a kernel can lead to
841 any Jupyter-Compatible interface that has ipython set as a kernel can lead to
825 code execution.
842 code execution.
826
843
827
844
828 I did not find any standard way for packaged to advertise CVEs they fix, I'm
845 I did not find any standard way for packaged to advertise CVEs they fix, I'm
829 thus trying to add a ``__patched_cves__`` attribute to the IPython module that
846 thus trying to add a ``__patched_cves__`` attribute to the IPython module that
830 list the CVEs that should have been fixed. This attribute is informational only
847 list the CVEs that should have been fixed. This attribute is informational only
831 as if a executable has a flaw, this value can always be changed by an attacker.
848 as if a executable has a flaw, this value can always be changed by an attacker.
832
849
833 .. code::
850 .. code::
834
851
835 In [1]: import IPython
852 In [1]: import IPython
836
853
837 In [2]: IPython.__patched_cves__
854 In [2]: IPython.__patched_cves__
838 Out[2]: {'CVE-2022-21699'}
855 Out[2]: {'CVE-2022-21699'}
839
856
840 In [3]: 'CVE-2022-21699' in IPython.__patched_cves__
857 In [3]: 'CVE-2022-21699' in IPython.__patched_cves__
841 Out[3]: True
858 Out[3]: True
842
859
843 Thus starting with this version:
860 Thus starting with this version:
844
861
845 - The current working directory is not searched anymore for profiles or
862 - The current working directory is not searched anymore for profiles or
846 configurations files.
863 configurations files.
847 - Added a ``__patched_cves__`` attribute (set of strings) to IPython module that contain
864 - Added a ``__patched_cves__`` attribute (set of strings) to IPython module that contain
848 the list of fixed CVE. This is informational only.
865 the list of fixed CVE. This is informational only.
849
866
850 Further details can be read on the `GitHub Advisory <https://github.com/ipython/ipython/security/advisories/GHSA-pq7m-3gw7-gq5x>`__
867 Further details can be read on the `GitHub Advisory <https://github.com/ipython/ipython/security/advisories/GHSA-pq7m-3gw7-gq5x>`__
851
868
852
869
853 .. _version 8.0:
870 .. _version 8.0:
854
871
855 IPython 8.0
872 IPython 8.0
856 -----------
873 -----------
857
874
858 IPython 8.0 is bringing a large number of new features and improvements to both the
875 IPython 8.0 is bringing a large number of new features and improvements to both the
859 user of the terminal and of the kernel via Jupyter. The removal of compatibility
876 user of the terminal and of the kernel via Jupyter. The removal of compatibility
860 with an older version of Python is also the opportunity to do a couple of
877 with an older version of Python is also the opportunity to do a couple of
861 performance improvements in particular with respect to startup time.
878 performance improvements in particular with respect to startup time.
862 The 8.x branch started diverging from its predecessor around IPython 7.12
879 The 8.x branch started diverging from its predecessor around IPython 7.12
863 (January 2020).
880 (January 2020).
864
881
865 This release contains 250+ pull requests, in addition to many of the features
882 This release contains 250+ pull requests, in addition to many of the features
866 and backports that have made it to the 7.x branch. Please see the
883 and backports that have made it to the 7.x branch. Please see the
867 `8.0 milestone <https://github.com/ipython/ipython/milestone/73?closed=1>`__ for the full list of pull requests.
884 `8.0 milestone <https://github.com/ipython/ipython/milestone/73?closed=1>`__ for the full list of pull requests.
868
885
869 Please feel free to send pull requests to update those notes after release,
886 Please feel free to send pull requests to update those notes after release,
870 I have likely forgotten a few things reviewing 250+ PRs.
887 I have likely forgotten a few things reviewing 250+ PRs.
871
888
872 Dependencies changes/downstream packaging
889 Dependencies changes/downstream packaging
873 -----------------------------------------
890 -----------------------------------------
874
891
875 Most of our building steps have been changed to be (mostly) declarative
892 Most of our building steps have been changed to be (mostly) declarative
876 and follow PEP 517. We are trying to completely remove ``setup.py`` (:ghpull:`13238`) and are
893 and follow PEP 517. We are trying to completely remove ``setup.py`` (:ghpull:`13238`) and are
877 looking for help to do so.
894 looking for help to do so.
878
895
879 - minimum supported ``traitlets`` version is now 5+
896 - minimum supported ``traitlets`` version is now 5+
880 - we now require ``stack_data``
897 - we now require ``stack_data``
881 - minimal Python is now 3.8
898 - minimal Python is now 3.8
882 - ``nose`` is not a testing requirement anymore
899 - ``nose`` is not a testing requirement anymore
883 - ``pytest`` replaces nose.
900 - ``pytest`` replaces nose.
884 - ``iptest``/``iptest3`` cli entrypoints do not exist anymore.
901 - ``iptest``/``iptest3`` cli entrypoints do not exist anymore.
885 - the minimum officially ​supported ``numpy`` version has been bumped, but this should
902 - the minimum officially ​supported ``numpy`` version has been bumped, but this should
886 not have much effect on packaging.
903 not have much effect on packaging.
887
904
888
905
889 Deprecation and removal
906 Deprecation and removal
890 -----------------------
907 -----------------------
891
908
892 We removed almost all features, arguments, functions, and modules that were
909 We removed almost all features, arguments, functions, and modules that were
893 marked as deprecated between IPython 1.0 and 5.0. As a reminder, 5.0 was released
910 marked as deprecated between IPython 1.0 and 5.0. As a reminder, 5.0 was released
894 in 2016, and 1.0 in 2013. Last release of the 5 branch was 5.10.0, in May 2020.
911 in 2016, and 1.0 in 2013. Last release of the 5 branch was 5.10.0, in May 2020.
895 The few remaining deprecated features we left have better deprecation warnings
912 The few remaining deprecated features we left have better deprecation warnings
896 or have been turned into explicit errors for better error messages.
913 or have been turned into explicit errors for better error messages.
897
914
898 I will use this occasion to add the following requests to anyone emitting a
915 I will use this occasion to add the following requests to anyone emitting a
899 deprecation warning:
916 deprecation warning:
900
917
901 - Please add at least ``stacklevel=2`` so that the warning is emitted into the
918 - Please add at least ``stacklevel=2`` so that the warning is emitted into the
902 caller context, and not the callee one.
919 caller context, and not the callee one.
903 - Please add **since which version** something is deprecated.
920 - Please add **since which version** something is deprecated.
904
921
905 As a side note, it is much easier to conditionally compare version
922 As a side note, it is much easier to conditionally compare version
906 numbers rather than using ``try/except`` when functionality changes with a version.
923 numbers rather than using ``try/except`` when functionality changes with a version.
907
924
908 I won't list all the removed features here, but modules like ``IPython.kernel``,
925 I won't list all the removed features here, but modules like ``IPython.kernel``,
909 which was just a shim module around ``ipykernel`` for the past 8 years, have been
926 which was just a shim module around ``ipykernel`` for the past 8 years, have been
910 removed, and so many other similar things that pre-date the name **Jupyter**
927 removed, and so many other similar things that pre-date the name **Jupyter**
911 itself.
928 itself.
912
929
913 We no longer need to add ``IPython.extensions`` to the PYTHONPATH because that is being
930 We no longer need to add ``IPython.extensions`` to the PYTHONPATH because that is being
914 handled by ``load_extension``.
931 handled by ``load_extension``.
915
932
916 We are also removing ``Cythonmagic``, ``sympyprinting`` and ``rmagic`` as they are now in
933 We are also removing ``Cythonmagic``, ``sympyprinting`` and ``rmagic`` as they are now in
917 other packages and no longer need to be inside IPython.
934 other packages and no longer need to be inside IPython.
918
935
919
936
920 Documentation
937 Documentation
921 -------------
938 -------------
922
939
923 The majority of our docstrings have now been reformatted and automatically fixed by
940 The majority of our docstrings have now been reformatted and automatically fixed by
924 the experimental `VΓ©lin <https://pypi.org/project/velin/>`_ project to conform
941 the experimental `VΓ©lin <https://pypi.org/project/velin/>`_ project to conform
925 to numpydoc.
942 to numpydoc.
926
943
927 Type annotations
944 Type annotations
928 ----------------
945 ----------------
929
946
930 While IPython itself is highly dynamic and can't be completely typed, many of
947 While IPython itself is highly dynamic and can't be completely typed, many of
931 the functions now have type annotations, and part of the codebase is now checked
948 the functions now have type annotations, and part of the codebase is now checked
932 by mypy.
949 by mypy.
933
950
934
951
935 Featured changes
952 Featured changes
936 ----------------
953 ----------------
937
954
938 Here is a features list of changes in IPython 8.0. This is of course non-exhaustive.
955 Here is a features list of changes in IPython 8.0. This is of course non-exhaustive.
939 Please note as well that many features have been added in the 7.x branch as well
956 Please note as well that many features have been added in the 7.x branch as well
940 (and hence why you want to read the 7.x what's new notes), in particular
957 (and hence why you want to read the 7.x what's new notes), in particular
941 features contributed by QuantStack (with respect to debugger protocol and Xeus
958 features contributed by QuantStack (with respect to debugger protocol and Xeus
942 Python), as well as many debugger features that I was pleased to implement as
959 Python), as well as many debugger features that I was pleased to implement as
943 part of my work at QuanSight and sponsored by DE Shaw.
960 part of my work at QuanSight and sponsored by DE Shaw.
944
961
945 Traceback improvements
962 Traceback improvements
946 ~~~~~~~~~~~~~~~~~~~~~~
963 ~~~~~~~~~~~~~~~~~~~~~~
947
964
948 Previously, error tracebacks for errors happening in code cells were showing a
965 Previously, error tracebacks for errors happening in code cells were showing a
949 hash, the one used for compiling the Python AST::
966 hash, the one used for compiling the Python AST::
950
967
951 In [1]: def foo():
968 In [1]: def foo():
952 ...: return 3 / 0
969 ...: return 3 / 0
953 ...:
970 ...:
954
971
955 In [2]: foo()
972 In [2]: foo()
956 ---------------------------------------------------------------------------
973 ---------------------------------------------------------------------------
957 ZeroDivisionError Traceback (most recent call last)
974 ZeroDivisionError Traceback (most recent call last)
958 <ipython-input-2-c19b6d9633cf> in <module>
975 <ipython-input-2-c19b6d9633cf> in <module>
959 ----> 1 foo()
976 ----> 1 foo()
960
977
961 <ipython-input-1-1595a74c32d5> in foo()
978 <ipython-input-1-1595a74c32d5> in foo()
962 1 def foo():
979 1 def foo():
963 ----> 2 return 3 / 0
980 ----> 2 return 3 / 0
964 3
981 3
965
982
966 ZeroDivisionError: division by zero
983 ZeroDivisionError: division by zero
967
984
968 The error traceback is now correctly formatted, showing the cell number in which the error happened::
985 The error traceback is now correctly formatted, showing the cell number in which the error happened::
969
986
970 In [1]: def foo():
987 In [1]: def foo():
971 ...: return 3 / 0
988 ...: return 3 / 0
972 ...:
989 ...:
973
990
974 Input In [2]: foo()
991 Input In [2]: foo()
975 ---------------------------------------------------------------------------
992 ---------------------------------------------------------------------------
976 ZeroDivisionError Traceback (most recent call last)
993 ZeroDivisionError Traceback (most recent call last)
977 input In [2], in <module>
994 input In [2], in <module>
978 ----> 1 foo()
995 ----> 1 foo()
979
996
980 Input In [1], in foo()
997 Input In [1], in foo()
981 1 def foo():
998 1 def foo():
982 ----> 2 return 3 / 0
999 ----> 2 return 3 / 0
983
1000
984 ZeroDivisionError: division by zero
1001 ZeroDivisionError: division by zero
985
1002
986 The ``stack_data`` package has been integrated, which provides smarter information in the traceback;
1003 The ``stack_data`` package has been integrated, which provides smarter information in the traceback;
987 in particular it will highlight the AST node where an error occurs which can help to quickly narrow down errors.
1004 in particular it will highlight the AST node where an error occurs which can help to quickly narrow down errors.
988
1005
989 For example in the following snippet::
1006 For example in the following snippet::
990
1007
991 def foo(i):
1008 def foo(i):
992 x = [[[0]]]
1009 x = [[[0]]]
993 return x[0][i][0]
1010 return x[0][i][0]
994
1011
995
1012
996 def bar():
1013 def bar():
997 return foo(0) + foo(
1014 return foo(0) + foo(
998 1
1015 1
999 ) + foo(2)
1016 ) + foo(2)
1000
1017
1001
1018
1002 calling ``bar()`` would raise an ``IndexError`` on the return line of ``foo``,
1019 calling ``bar()`` would raise an ``IndexError`` on the return line of ``foo``,
1003 and IPython 8.0 is capable of telling you where the index error occurs::
1020 and IPython 8.0 is capable of telling you where the index error occurs::
1004
1021
1005
1022
1006 IndexError
1023 IndexError
1007 Input In [2], in <module>
1024 Input In [2], in <module>
1008 ----> 1 bar()
1025 ----> 1 bar()
1009 ^^^^^
1026 ^^^^^
1010
1027
1011 Input In [1], in bar()
1028 Input In [1], in bar()
1012 6 def bar():
1029 6 def bar():
1013 ----> 7 return foo(0) + foo(
1030 ----> 7 return foo(0) + foo(
1014 ^^^^
1031 ^^^^
1015 8 1
1032 8 1
1016 ^^^^^^^^
1033 ^^^^^^^^
1017 9 ) + foo(2)
1034 9 ) + foo(2)
1018 ^^^^
1035 ^^^^
1019
1036
1020 Input In [1], in foo(i)
1037 Input In [1], in foo(i)
1021 1 def foo(i):
1038 1 def foo(i):
1022 2 x = [[[0]]]
1039 2 x = [[[0]]]
1023 ----> 3 return x[0][i][0]
1040 ----> 3 return x[0][i][0]
1024 ^^^^^^^
1041 ^^^^^^^
1025
1042
1026 The corresponding locations marked here with ``^`` will show up highlighted in
1043 The corresponding locations marked here with ``^`` will show up highlighted in
1027 the terminal and notebooks.
1044 the terminal and notebooks.
1028
1045
1029 Finally, a colon ``::`` and line number is appended after a filename in
1046 Finally, a colon ``::`` and line number is appended after a filename in
1030 traceback::
1047 traceback::
1031
1048
1032
1049
1033 ZeroDivisionError Traceback (most recent call last)
1050 ZeroDivisionError Traceback (most recent call last)
1034 File ~/error.py:4, in <module>
1051 File ~/error.py:4, in <module>
1035 1 def f():
1052 1 def f():
1036 2 1/0
1053 2 1/0
1037 ----> 4 f()
1054 ----> 4 f()
1038
1055
1039 File ~/error.py:2, in f()
1056 File ~/error.py:2, in f()
1040 1 def f():
1057 1 def f():
1041 ----> 2 1/0
1058 ----> 2 1/0
1042
1059
1043 Many terminals and editors have integrations enabling you to directly jump to the
1060 Many terminals and editors have integrations enabling you to directly jump to the
1044 relevant file/line when this syntax is used, so this small addition may have a high
1061 relevant file/line when this syntax is used, so this small addition may have a high
1045 impact on productivity.
1062 impact on productivity.
1046
1063
1047
1064
1048 Autosuggestions
1065 Autosuggestions
1049 ~~~~~~~~~~~~~~~
1066 ~~~~~~~~~~~~~~~
1050
1067
1051 Autosuggestion is a very useful feature available in `fish <https://fishshell.com/>`__, `zsh <https://en.wikipedia.org/wiki/Z_shell>`__, and `prompt-toolkit <https://python-prompt-toolkit.readthedocs.io/en/master/pages/asking_for_input.html#auto-suggestion>`__.
1068 Autosuggestion is a very useful feature available in `fish <https://fishshell.com/>`__, `zsh <https://en.wikipedia.org/wiki/Z_shell>`__, and `prompt-toolkit <https://python-prompt-toolkit.readthedocs.io/en/master/pages/asking_for_input.html#auto-suggestion>`__.
1052
1069
1053 `Ptpython <https://github.com/prompt-toolkit/ptpython#ptpython>`__ allows users to enable this feature in
1070 `Ptpython <https://github.com/prompt-toolkit/ptpython#ptpython>`__ allows users to enable this feature in
1054 `ptpython/config.py <https://github.com/prompt-toolkit/ptpython/blob/master/examples/ptpython_config/config.py#L90>`__.
1071 `ptpython/config.py <https://github.com/prompt-toolkit/ptpython/blob/master/examples/ptpython_config/config.py#L90>`__.
1055
1072
1056 This feature allows users to accept autosuggestions with ctrl e, ctrl f,
1073 This feature allows users to accept autosuggestions with ctrl e, ctrl f,
1057 or right arrow as described below.
1074 or right arrow as described below.
1058
1075
1059 1. Start ipython
1076 1. Start ipython
1060
1077
1061 .. image:: ../_images/8.0/auto_suggest_1_prompt_no_text.png
1078 .. image:: ../_images/8.0/auto_suggest_1_prompt_no_text.png
1062
1079
1063 2. Run ``print("hello")``
1080 2. Run ``print("hello")``
1064
1081
1065 .. image:: ../_images/8.0/auto_suggest_2_print_hello_suggest.png
1082 .. image:: ../_images/8.0/auto_suggest_2_print_hello_suggest.png
1066
1083
1067 3. start typing ``print`` again to see the autosuggestion
1084 3. start typing ``print`` again to see the autosuggestion
1068
1085
1069 .. image:: ../_images/8.0/auto_suggest_3_print_hello_suggest.png
1086 .. image:: ../_images/8.0/auto_suggest_3_print_hello_suggest.png
1070
1087
1071 4. Press ``ctrl-f``, or ``ctrl-e``, or ``right-arrow`` to accept the suggestion
1088 4. Press ``ctrl-f``, or ``ctrl-e``, or ``right-arrow`` to accept the suggestion
1072
1089
1073 .. image:: ../_images/8.0/auto_suggest_4_print_hello.png
1090 .. image:: ../_images/8.0/auto_suggest_4_print_hello.png
1074
1091
1075 You can also complete word by word:
1092 You can also complete word by word:
1076
1093
1077 1. Run ``def say_hello(): print("hello")``
1094 1. Run ``def say_hello(): print("hello")``
1078
1095
1079 .. image:: ../_images/8.0/auto_suggest_second_prompt.png
1096 .. image:: ../_images/8.0/auto_suggest_second_prompt.png
1080
1097
1081 2. Start typing the first letter if ``def`` to see the autosuggestion
1098 2. Start typing the first letter if ``def`` to see the autosuggestion
1082
1099
1083 .. image:: ../_images/8.0/auto_suggest_d_phantom.png
1100 .. image:: ../_images/8.0/auto_suggest_d_phantom.png
1084
1101
1085 3. Press ``alt-f`` (or ``escape`` followed by ``f``), to accept the first word of the suggestion
1102 3. Press ``alt-f`` (or ``escape`` followed by ``f``), to accept the first word of the suggestion
1086
1103
1087 .. image:: ../_images/8.0/auto_suggest_def_phantom.png
1104 .. image:: ../_images/8.0/auto_suggest_def_phantom.png
1088
1105
1089 Importantly, this feature does not interfere with tab completion:
1106 Importantly, this feature does not interfere with tab completion:
1090
1107
1091 1. After running ``def say_hello(): print("hello")``, press d
1108 1. After running ``def say_hello(): print("hello")``, press d
1092
1109
1093 .. image:: ../_images/8.0/auto_suggest_d_phantom.png
1110 .. image:: ../_images/8.0/auto_suggest_d_phantom.png
1094
1111
1095 2. Press Tab to start tab completion
1112 2. Press Tab to start tab completion
1096
1113
1097 .. image:: ../_images/8.0/auto_suggest_d_completions.png
1114 .. image:: ../_images/8.0/auto_suggest_d_completions.png
1098
1115
1099 3A. Press Tab again to select the first option
1116 3A. Press Tab again to select the first option
1100
1117
1101 .. image:: ../_images/8.0/auto_suggest_def_completions.png
1118 .. image:: ../_images/8.0/auto_suggest_def_completions.png
1102
1119
1103 3B. Press ``alt f`` (``escape``, ``f``) to accept to accept the first word of the suggestion
1120 3B. Press ``alt f`` (``escape``, ``f``) to accept to accept the first word of the suggestion
1104
1121
1105 .. image:: ../_images/8.0/auto_suggest_def_phantom.png
1122 .. image:: ../_images/8.0/auto_suggest_def_phantom.png
1106
1123
1107 3C. Press ``ctrl-f`` or ``ctrl-e`` to accept the entire suggestion
1124 3C. Press ``ctrl-f`` or ``ctrl-e`` to accept the entire suggestion
1108
1125
1109 .. image:: ../_images/8.0/auto_suggest_match_parens.png
1126 .. image:: ../_images/8.0/auto_suggest_match_parens.png
1110
1127
1111
1128
1112 Currently, autosuggestions are only shown in the emacs or vi insert editing modes:
1129 Currently, autosuggestions are only shown in the emacs or vi insert editing modes:
1113
1130
1114 - The ctrl e, ctrl f, and alt f shortcuts work by default in emacs mode.
1131 - The ctrl e, ctrl f, and alt f shortcuts work by default in emacs mode.
1115 - To use these shortcuts in vi insert mode, you will have to create `custom keybindings in your config.py <https://github.com/mskar/setup/commit/2892fcee46f9f80ef7788f0749edc99daccc52f4/>`__.
1132 - To use these shortcuts in vi insert mode, you will have to create `custom keybindings in your config.py <https://github.com/mskar/setup/commit/2892fcee46f9f80ef7788f0749edc99daccc52f4/>`__.
1116
1133
1117
1134
1118 Show pinfo information in ipdb using "?" and "??"
1135 Show pinfo information in ipdb using "?" and "??"
1119 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1136 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1120
1137
1121 In IPDB, it is now possible to show the information about an object using "?"
1138 In IPDB, it is now possible to show the information about an object using "?"
1122 and "??", in much the same way that it can be done when using the IPython prompt::
1139 and "??", in much the same way that it can be done when using the IPython prompt::
1123
1140
1124 ipdb> partial?
1141 ipdb> partial?
1125 Init signature: partial(self, /, *args, **kwargs)
1142 Init signature: partial(self, /, *args, **kwargs)
1126 Docstring:
1143 Docstring:
1127 partial(func, *args, **keywords) - new function with partial application
1144 partial(func, *args, **keywords) - new function with partial application
1128 of the given arguments and keywords.
1145 of the given arguments and keywords.
1129 File: ~/.pyenv/versions/3.8.6/lib/python3.8/functools.py
1146 File: ~/.pyenv/versions/3.8.6/lib/python3.8/functools.py
1130 Type: type
1147 Type: type
1131 Subclasses:
1148 Subclasses:
1132
1149
1133 Previously, ``pinfo`` or ``pinfo2`` command had to be used for this purpose.
1150 Previously, ``pinfo`` or ``pinfo2`` command had to be used for this purpose.
1134
1151
1135
1152
1136 Autoreload 3 feature
1153 Autoreload 3 feature
1137 ~~~~~~~~~~~~~~~~~~~~
1154 ~~~~~~~~~~~~~~~~~~~~
1138
1155
1139 Example: When an IPython session is run with the 'autoreload' extension loaded,
1156 Example: When an IPython session is run with the 'autoreload' extension loaded,
1140 you will now have the option '3' to select, which means the following:
1157 you will now have the option '3' to select, which means the following:
1141
1158
1142 1. replicate all functionality from option 2
1159 1. replicate all functionality from option 2
1143 2. autoload all new funcs/classes/enums/globals from the module when they are added
1160 2. autoload all new funcs/classes/enums/globals from the module when they are added
1144 3. autoload all newly imported funcs/classes/enums/globals from external modules
1161 3. autoload all newly imported funcs/classes/enums/globals from external modules
1145
1162
1146 Try ``%autoreload 3`` in an IPython session after running ``%load_ext autoreload``.
1163 Try ``%autoreload 3`` in an IPython session after running ``%load_ext autoreload``.
1147
1164
1148 For more information please see the following unit test : ``extensions/tests/test_autoreload.py:test_autoload_newly_added_objects``
1165 For more information please see the following unit test : ``extensions/tests/test_autoreload.py:test_autoload_newly_added_objects``
1149
1166
1150 Auto formatting with black in the CLI
1167 Auto formatting with black in the CLI
1151 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1168 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1152
1169
1153 This feature was present in 7.x, but disabled by default.
1170 This feature was present in 7.x, but disabled by default.
1154
1171
1155 In 8.0, input was automatically reformatted with Black when black was installed.
1172 In 8.0, input was automatically reformatted with Black when black was installed.
1156 This feature has been reverted for the time being.
1173 This feature has been reverted for the time being.
1157 You can re-enable it by setting ``TerminalInteractiveShell.autoformatter`` to ``"black"``
1174 You can re-enable it by setting ``TerminalInteractiveShell.autoformatter`` to ``"black"``
1158
1175
1159 History Range Glob feature
1176 History Range Glob feature
1160 ~~~~~~~~~~~~~~~~~~~~~~~~~~
1177 ~~~~~~~~~~~~~~~~~~~~~~~~~~
1161
1178
1162 Previously, when using ``%history``, users could specify either
1179 Previously, when using ``%history``, users could specify either
1163 a range of sessions and lines, for example:
1180 a range of sessions and lines, for example:
1164
1181
1165 .. code-block:: python
1182 .. code-block:: python
1166
1183
1167 ~8/1-~6/5 # see history from the first line of 8 sessions ago,
1184 ~8/1-~6/5 # see history from the first line of 8 sessions ago,
1168 # to the fifth line of 6 sessions ago.``
1185 # to the fifth line of 6 sessions ago.``
1169
1186
1170 Or users could specify a glob pattern:
1187 Or users could specify a glob pattern:
1171
1188
1172 .. code-block:: python
1189 .. code-block:: python
1173
1190
1174 -g <pattern> # glob ALL history for the specified pattern.
1191 -g <pattern> # glob ALL history for the specified pattern.
1175
1192
1176 However users could *not* specify both.
1193 However users could *not* specify both.
1177
1194
1178 If a user *did* specify both a range and a glob pattern,
1195 If a user *did* specify both a range and a glob pattern,
1179 then the glob pattern would be used (globbing *all* history) *and the range would be ignored*.
1196 then the glob pattern would be used (globbing *all* history) *and the range would be ignored*.
1180
1197
1181 With this enhancement, if a user specifies both a range and a glob pattern, then the glob pattern will be applied to the specified range of history.
1198 With this enhancement, if a user specifies both a range and a glob pattern, then the glob pattern will be applied to the specified range of history.
1182
1199
1183 Don't start a multi-line cell with sunken parenthesis
1200 Don't start a multi-line cell with sunken parenthesis
1184 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1201 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1185
1202
1186 From now on, IPython will not ask for the next line of input when given a single
1203 From now on, IPython will not ask for the next line of input when given a single
1187 line with more closing than opening brackets. For example, this means that if
1204 line with more closing than opening brackets. For example, this means that if
1188 you (mis)type ``]]`` instead of ``[]``, a ``SyntaxError`` will show up, instead of
1205 you (mis)type ``]]`` instead of ``[]``, a ``SyntaxError`` will show up, instead of
1189 the ``...:`` prompt continuation.
1206 the ``...:`` prompt continuation.
1190
1207
1191 IPython shell for ipdb interact
1208 IPython shell for ipdb interact
1192 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1209 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1193
1210
1194 The ipdb ``interact`` starts an IPython shell instead of Python's built-in ``code.interact()``.
1211 The ipdb ``interact`` starts an IPython shell instead of Python's built-in ``code.interact()``.
1195
1212
1196 Automatic Vi prompt stripping
1213 Automatic Vi prompt stripping
1197 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1214 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1198
1215
1199 When pasting code into IPython, it will strip the leading prompt characters if
1216 When pasting code into IPython, it will strip the leading prompt characters if
1200 there are any. For example, you can paste the following code into the console -
1217 there are any. For example, you can paste the following code into the console -
1201 it will still work, even though each line is prefixed with prompts (``In``,
1218 it will still work, even though each line is prefixed with prompts (``In``,
1202 ``Out``)::
1219 ``Out``)::
1203
1220
1204 In [1]: 2 * 2 == 4
1221 In [1]: 2 * 2 == 4
1205 Out[1]: True
1222 Out[1]: True
1206
1223
1207 In [2]: print("This still works as pasted")
1224 In [2]: print("This still works as pasted")
1208
1225
1209
1226
1210 Previously, this was not the case for the Vi-mode prompts::
1227 Previously, this was not the case for the Vi-mode prompts::
1211
1228
1212 In [1]: [ins] In [13]: 2 * 2 == 4
1229 In [1]: [ins] In [13]: 2 * 2 == 4
1213 ...: Out[13]: True
1230 ...: Out[13]: True
1214 ...:
1231 ...:
1215 File "<ipython-input-1-727bb88eaf33>", line 1
1232 File "<ipython-input-1-727bb88eaf33>", line 1
1216 [ins] In [13]: 2 * 2 == 4
1233 [ins] In [13]: 2 * 2 == 4
1217 ^
1234 ^
1218 SyntaxError: invalid syntax
1235 SyntaxError: invalid syntax
1219
1236
1220 This is now fixed, and Vi prompt prefixes - ``[ins]`` and ``[nav]`` - are
1237 This is now fixed, and Vi prompt prefixes - ``[ins]`` and ``[nav]`` - are
1221 skipped just as the normal ``In`` would be.
1238 skipped just as the normal ``In`` would be.
1222
1239
1223 IPython shell can be started in the Vi mode using ``ipython --TerminalInteractiveShell.editing_mode=vi``,
1240 IPython shell can be started in the Vi mode using ``ipython --TerminalInteractiveShell.editing_mode=vi``,
1224 You should be able to change mode dynamically with ``%config TerminalInteractiveShell.editing_mode='vi'``
1241 You should be able to change mode dynamically with ``%config TerminalInteractiveShell.editing_mode='vi'``
1225
1242
1226 Empty History Ranges
1243 Empty History Ranges
1227 ~~~~~~~~~~~~~~~~~~~~
1244 ~~~~~~~~~~~~~~~~~~~~
1228
1245
1229 A number of magics that take history ranges can now be used with an empty
1246 A number of magics that take history ranges can now be used with an empty
1230 range. These magics are:
1247 range. These magics are:
1231
1248
1232 * ``%save``
1249 * ``%save``
1233 * ``%load``
1250 * ``%load``
1234 * ``%pastebin``
1251 * ``%pastebin``
1235 * ``%pycat``
1252 * ``%pycat``
1236
1253
1237 Using them this way will make them take the history of the current session up
1254 Using them this way will make them take the history of the current session up
1238 to the point of the magic call (such that the magic itself will not be
1255 to the point of the magic call (such that the magic itself will not be
1239 included).
1256 included).
1240
1257
1241 Therefore it is now possible to save the whole history to a file using
1258 Therefore it is now possible to save the whole history to a file using
1242 ``%save <filename>``, load and edit it using ``%load`` (makes for a nice usage
1259 ``%save <filename>``, load and edit it using ``%load`` (makes for a nice usage
1243 when followed with :kbd:`F2`), send it to `dpaste.org <http://dpast.org>`_ using
1260 when followed with :kbd:`F2`), send it to `dpaste.org <http://dpast.org>`_ using
1244 ``%pastebin``, or view the whole thing syntax-highlighted with a single
1261 ``%pastebin``, or view the whole thing syntax-highlighted with a single
1245 ``%pycat``.
1262 ``%pycat``.
1246
1263
1247
1264
1248 Windows timing implementation: Switch to process_time
1265 Windows timing implementation: Switch to process_time
1249 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1266 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1250 Timing on Windows, for example with ``%%time``, was changed from being based on ``time.perf_counter``
1267 Timing on Windows, for example with ``%%time``, was changed from being based on ``time.perf_counter``
1251 (which counted time even when the process was sleeping) to being based on ``time.process_time`` instead
1268 (which counted time even when the process was sleeping) to being based on ``time.process_time`` instead
1252 (which only counts CPU time). This brings it closer to the behavior on Linux. See :ghpull:`12984`.
1269 (which only counts CPU time). This brings it closer to the behavior on Linux. See :ghpull:`12984`.
1253
1270
1254 Miscellaneous
1271 Miscellaneous
1255 ~~~~~~~~~~~~~
1272 ~~~~~~~~~~~~~
1256 - Non-text formatters are not disabled in the terminal, which should simplify
1273 - Non-text formatters are not disabled in the terminal, which should simplify
1257 writing extensions displaying images or other mimetypes in supporting terminals.
1274 writing extensions displaying images or other mimetypes in supporting terminals.
1258 :ghpull:`12315`
1275 :ghpull:`12315`
1259 - It is now possible to automatically insert matching brackets in Terminal IPython using the
1276 - It is now possible to automatically insert matching brackets in Terminal IPython using the
1260 ``TerminalInteractiveShell.auto_match=True`` option. :ghpull:`12586`
1277 ``TerminalInteractiveShell.auto_match=True`` option. :ghpull:`12586`
1261 - We are thinking of deprecating the current ``%%javascript`` magic in favor of a better replacement. See :ghpull:`13376`.
1278 - We are thinking of deprecating the current ``%%javascript`` magic in favor of a better replacement. See :ghpull:`13376`.
1262 - ``~`` is now expanded when part of a path in most magics :ghpull:`13385`
1279 - ``~`` is now expanded when part of a path in most magics :ghpull:`13385`
1263 - ``%/%%timeit`` magic now adds a comma every thousands to make reading a long number easier :ghpull:`13379`
1280 - ``%/%%timeit`` magic now adds a comma every thousands to make reading a long number easier :ghpull:`13379`
1264 - ``"info"`` messages can now be customised to hide some fields :ghpull:`13343`
1281 - ``"info"`` messages can now be customised to hide some fields :ghpull:`13343`
1265 - ``collections.UserList`` now pretty-prints :ghpull:`13320`
1282 - ``collections.UserList`` now pretty-prints :ghpull:`13320`
1266 - The debugger now has a persistent history, which should make it less
1283 - The debugger now has a persistent history, which should make it less
1267 annoying to retype commands :ghpull:`13246`
1284 annoying to retype commands :ghpull:`13246`
1268 - ``!pip`` ``!conda`` ``!cd`` or ``!ls`` are likely doing the wrong thing. We
1285 - ``!pip`` ``!conda`` ``!cd`` or ``!ls`` are likely doing the wrong thing. We
1269 now warn users if they use one of those commands. :ghpull:`12954`
1286 now warn users if they use one of those commands. :ghpull:`12954`
1270 - Make ``%precision`` work for ``numpy.float64`` type :ghpull:`12902`
1287 - Make ``%precision`` work for ``numpy.float64`` type :ghpull:`12902`
1271
1288
1272 Re-added support for XDG config directories
1289 Re-added support for XDG config directories
1273 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1290 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1274
1291
1275 XDG support through the years comes and goes. There is a tension between having
1292 XDG support through the years comes and goes. There is a tension between having
1276 an identical location for configuration in all platforms versus having simple instructions.
1293 an identical location for configuration in all platforms versus having simple instructions.
1277 After initial failures a couple of years ago, IPython was modified to automatically migrate XDG
1294 After initial failures a couple of years ago, IPython was modified to automatically migrate XDG
1278 config files back into ``~/.ipython``. That migration code has now been removed.
1295 config files back into ``~/.ipython``. That migration code has now been removed.
1279 IPython now checks the XDG locations, so if you _manually_ move your config
1296 IPython now checks the XDG locations, so if you _manually_ move your config
1280 files to your preferred location, IPython will not move them back.
1297 files to your preferred location, IPython will not move them back.
1281
1298
1282
1299
1283 Preparing for Python 3.10
1300 Preparing for Python 3.10
1284 -------------------------
1301 -------------------------
1285
1302
1286 To prepare for Python 3.10, we have started working on removing reliance and
1303 To prepare for Python 3.10, we have started working on removing reliance and
1287 any dependency that is not compatible with Python 3.10. This includes migrating our
1304 any dependency that is not compatible with Python 3.10. This includes migrating our
1288 test suite to pytest and starting to remove nose. This also means that the
1305 test suite to pytest and starting to remove nose. This also means that the
1289 ``iptest`` command is now gone and all testing is via pytest.
1306 ``iptest`` command is now gone and all testing is via pytest.
1290
1307
1291 This was in large part thanks to the NumFOCUS Small Developer grant, which enabled us to
1308 This was in large part thanks to the NumFOCUS Small Developer grant, which enabled us to
1292 allocate \$4000 to hire `Nikita Kniazev (@Kojoley) <https://github.com/Kojoley>`_,
1309 allocate \$4000 to hire `Nikita Kniazev (@Kojoley) <https://github.com/Kojoley>`_,
1293 who did a fantastic job at updating our code base, migrating to pytest, pushing
1310 who did a fantastic job at updating our code base, migrating to pytest, pushing
1294 our coverage, and fixing a large number of bugs. I highly recommend contacting
1311 our coverage, and fixing a large number of bugs. I highly recommend contacting
1295 them if you need help with C++ and Python projects.
1312 them if you need help with C++ and Python projects.
1296
1313
1297 You can find all relevant issues and PRs with `the SDG 2021 tag <https://github.com/ipython/ipython/issues?q=label%3A%22Numfocus+SDG+2021%22+>`__
1314 You can find all relevant issues and PRs with `the SDG 2021 tag <https://github.com/ipython/ipython/issues?q=label%3A%22Numfocus+SDG+2021%22+>`__
1298
1315
1299 Removing support for older Python versions
1316 Removing support for older Python versions
1300 ------------------------------------------
1317 ------------------------------------------
1301
1318
1302
1319
1303 We are removing support for Python up through 3.7, allowing internal code to use the more
1320 We are removing support for Python up through 3.7, allowing internal code to use the more
1304 efficient ``pathlib`` and to make better use of type annotations.
1321 efficient ``pathlib`` and to make better use of type annotations.
1305
1322
1306 .. image:: ../_images/8.0/pathlib_pathlib_everywhere.jpg
1323 .. image:: ../_images/8.0/pathlib_pathlib_everywhere.jpg
1307 :alt: "Meme image of Toy Story with Woody and Buzz, with the text 'pathlib, pathlib everywhere'"
1324 :alt: "Meme image of Toy Story with Woody and Buzz, with the text 'pathlib, pathlib everywhere'"
1308
1325
1309
1326
1310 We had about 34 PRs only to update some logic to update some functions from managing strings to
1327 We had about 34 PRs only to update some logic to update some functions from managing strings to
1311 using Pathlib.
1328 using Pathlib.
1312
1329
1313 The completer has also seen significant updates and now makes use of newer Jedi APIs,
1330 The completer has also seen significant updates and now makes use of newer Jedi APIs,
1314 offering faster and more reliable tab completion.
1331 offering faster and more reliable tab completion.
1315
1332
1316 Misc Statistics
1333 Misc Statistics
1317 ---------------
1334 ---------------
1318
1335
1319 Here are some numbers::
1336 Here are some numbers::
1320
1337
1321 7.x: 296 files, 12561 blank lines, 20282 comments, 35142 line of code.
1338 7.x: 296 files, 12561 blank lines, 20282 comments, 35142 line of code.
1322 8.0: 252 files, 12053 blank lines, 19232 comments, 34505 line of code.
1339 8.0: 252 files, 12053 blank lines, 19232 comments, 34505 line of code.
1323
1340
1324 $ git diff --stat 7.x...master | tail -1
1341 $ git diff --stat 7.x...master | tail -1
1325 340 files changed, 13399 insertions(+), 12421 deletions(-)
1342 340 files changed, 13399 insertions(+), 12421 deletions(-)
1326
1343
1327 We have commits from 162 authors, who contributed 1916 commits in 23 month, excluding merges (to not bias toward
1344 We have commits from 162 authors, who contributed 1916 commits in 23 month, excluding merges (to not bias toward
1328 maintainers pushing buttons).::
1345 maintainers pushing buttons).::
1329
1346
1330 $ git shortlog -s --no-merges 7.x...master | sort -nr
1347 $ git shortlog -s --no-merges 7.x...master | sort -nr
1331 535 Matthias Bussonnier
1348 535 Matthias Bussonnier
1332 86 Nikita Kniazev
1349 86 Nikita Kniazev
1333 69 Blazej Michalik
1350 69 Blazej Michalik
1334 49 Samuel Gaist
1351 49 Samuel Gaist
1335 27 Itamar Turner-Trauring
1352 27 Itamar Turner-Trauring
1336 18 Spas Kalaydzhisyki
1353 18 Spas Kalaydzhisyki
1337 17 Thomas Kluyver
1354 17 Thomas Kluyver
1338 17 Quentin Peter
1355 17 Quentin Peter
1339 17 James Morris
1356 17 James Morris
1340 17 Artur Svistunov
1357 17 Artur Svistunov
1341 15 Bart Skowron
1358 15 Bart Skowron
1342 14 Alex Hall
1359 14 Alex Hall
1343 13 rushabh-v
1360 13 rushabh-v
1344 13 Terry Davis
1361 13 Terry Davis
1345 13 Benjamin Ragan-Kelley
1362 13 Benjamin Ragan-Kelley
1346 8 martinRenou
1363 8 martinRenou
1347 8 farisachugthai
1364 8 farisachugthai
1348 7 dswij
1365 7 dswij
1349 7 Gal B
1366 7 Gal B
1350 7 Corentin Cadiou
1367 7 Corentin Cadiou
1351 6 yuji96
1368 6 yuji96
1352 6 Martin Skarzynski
1369 6 Martin Skarzynski
1353 6 Justin Palmer
1370 6 Justin Palmer
1354 6 Daniel Goldfarb
1371 6 Daniel Goldfarb
1355 6 Ben Greiner
1372 6 Ben Greiner
1356 5 Sammy Al Hashemi
1373 5 Sammy Al Hashemi
1357 5 Paul Ivanov
1374 5 Paul Ivanov
1358 5 Inception95
1375 5 Inception95
1359 5 Eyenpi
1376 5 Eyenpi
1360 5 Douglas Blank
1377 5 Douglas Blank
1361 5 Coco Mishra
1378 5 Coco Mishra
1362 5 Bibo Hao
1379 5 Bibo Hao
1363 5 AndrΓ© A. Gomes
1380 5 AndrΓ© A. Gomes
1364 5 Ahmed Fasih
1381 5 Ahmed Fasih
1365 4 takuya fujiwara
1382 4 takuya fujiwara
1366 4 palewire
1383 4 palewire
1367 4 Thomas A Caswell
1384 4 Thomas A Caswell
1368 4 Talley Lambert
1385 4 Talley Lambert
1369 4 Scott Sanderson
1386 4 Scott Sanderson
1370 4 Ram Rachum
1387 4 Ram Rachum
1371 4 Nick Muoh
1388 4 Nick Muoh
1372 4 Nathan Goldbaum
1389 4 Nathan Goldbaum
1373 4 Mithil Poojary
1390 4 Mithil Poojary
1374 4 Michael T
1391 4 Michael T
1375 4 Jakub Klus
1392 4 Jakub Klus
1376 4 Ian Castleden
1393 4 Ian Castleden
1377 4 Eli Rykoff
1394 4 Eli Rykoff
1378 4 Ashwin Vishnu
1395 4 Ashwin Vishnu
1379 3 谭九鼎
1396 3 谭九鼎
1380 3 sleeping
1397 3 sleeping
1381 3 Sylvain Corlay
1398 3 Sylvain Corlay
1382 3 Peter Corke
1399 3 Peter Corke
1383 3 Paul Bissex
1400 3 Paul Bissex
1384 3 Matthew Feickert
1401 3 Matthew Feickert
1385 3 Fernando Perez
1402 3 Fernando Perez
1386 3 Eric Wieser
1403 3 Eric Wieser
1387 3 Daniel Mietchen
1404 3 Daniel Mietchen
1388 3 Aditya Sathe
1405 3 Aditya Sathe
1389 3 007vedant
1406 3 007vedant
1390 2 rchiodo
1407 2 rchiodo
1391 2 nicolaslazo
1408 2 nicolaslazo
1392 2 luttik
1409 2 luttik
1393 2 gorogoroumaru
1410 2 gorogoroumaru
1394 2 foobarbyte
1411 2 foobarbyte
1395 2 bar-hen
1412 2 bar-hen
1396 2 Theo Ouzhinski
1413 2 Theo Ouzhinski
1397 2 Strawkage
1414 2 Strawkage
1398 2 Samreen Zarroug
1415 2 Samreen Zarroug
1399 2 Pete Blois
1416 2 Pete Blois
1400 2 Meysam Azad
1417 2 Meysam Azad
1401 2 Matthieu Ancellin
1418 2 Matthieu Ancellin
1402 2 Mark Schmitz
1419 2 Mark Schmitz
1403 2 Maor Kleinberger
1420 2 Maor Kleinberger
1404 2 MRCWirtz
1421 2 MRCWirtz
1405 2 Lumir Balhar
1422 2 Lumir Balhar
1406 2 Julien Rabinow
1423 2 Julien Rabinow
1407 2 Juan Luis Cano RodrΓ­guez
1424 2 Juan Luis Cano RodrΓ­guez
1408 2 Joyce Er
1425 2 Joyce Er
1409 2 Jakub
1426 2 Jakub
1410 2 Faris A Chugthai
1427 2 Faris A Chugthai
1411 2 Ethan Madden
1428 2 Ethan Madden
1412 2 Dimitri Papadopoulos
1429 2 Dimitri Papadopoulos
1413 2 Diego Fernandez
1430 2 Diego Fernandez
1414 2 Daniel Shimon
1431 2 Daniel Shimon
1415 2 Coco Bennett
1432 2 Coco Bennett
1416 2 Carlos Cordoba
1433 2 Carlos Cordoba
1417 2 Boyuan Liu
1434 2 Boyuan Liu
1418 2 BaoGiang HoangVu
1435 2 BaoGiang HoangVu
1419 2 Augusto
1436 2 Augusto
1420 2 Arthur Svistunov
1437 2 Arthur Svistunov
1421 2 Arthur Moreira
1438 2 Arthur Moreira
1422 2 Ali Nabipour
1439 2 Ali Nabipour
1423 2 Adam Hackbarth
1440 2 Adam Hackbarth
1424 1 richard
1441 1 richard
1425 1 linar-jether
1442 1 linar-jether
1426 1 lbennett
1443 1 lbennett
1427 1 juacrumar
1444 1 juacrumar
1428 1 gpotter2
1445 1 gpotter2
1429 1 digitalvirtuoso
1446 1 digitalvirtuoso
1430 1 dalthviz
1447 1 dalthviz
1431 1 Yonatan Goldschmidt
1448 1 Yonatan Goldschmidt
1432 1 Tomasz KΕ‚oczko
1449 1 Tomasz KΕ‚oczko
1433 1 Tobias Bengfort
1450 1 Tobias Bengfort
1434 1 Timur Kushukov
1451 1 Timur Kushukov
1435 1 Thomas
1452 1 Thomas
1436 1 Snir Broshi
1453 1 Snir Broshi
1437 1 Shao Yang Hong
1454 1 Shao Yang Hong
1438 1 Sanjana-03
1455 1 Sanjana-03
1439 1 Romulo Filho
1456 1 Romulo Filho
1440 1 Rodolfo Carvalho
1457 1 Rodolfo Carvalho
1441 1 Richard Shadrach
1458 1 Richard Shadrach
1442 1 Reilly Tucker Siemens
1459 1 Reilly Tucker Siemens
1443 1 Rakessh Roshan
1460 1 Rakessh Roshan
1444 1 Piers Titus van der Torren
1461 1 Piers Titus van der Torren
1445 1 PhanatosZou
1462 1 PhanatosZou
1446 1 Pavel Safronov
1463 1 Pavel Safronov
1447 1 Paulo S. Costa
1464 1 Paulo S. Costa
1448 1 Paul McCarthy
1465 1 Paul McCarthy
1449 1 NotWearingPants
1466 1 NotWearingPants
1450 1 Naelson Douglas
1467 1 Naelson Douglas
1451 1 Michael Tiemann
1468 1 Michael Tiemann
1452 1 Matt Wozniski
1469 1 Matt Wozniski
1453 1 Markus Wageringel
1470 1 Markus Wageringel
1454 1 Marcus Wirtz
1471 1 Marcus Wirtz
1455 1 Marcio Mazza
1472 1 Marcio Mazza
1456 1 LumΓ­r 'Frenzy' Balhar
1473 1 LumΓ­r 'Frenzy' Balhar
1457 1 Lightyagami1
1474 1 Lightyagami1
1458 1 Leon Anavi
1475 1 Leon Anavi
1459 1 LeafyLi
1476 1 LeafyLi
1460 1 L0uisJ0shua
1477 1 L0uisJ0shua
1461 1 Kyle Cutler
1478 1 Kyle Cutler
1462 1 Krzysztof Cybulski
1479 1 Krzysztof Cybulski
1463 1 Kevin Kirsche
1480 1 Kevin Kirsche
1464 1 KIU Shueng Chuan
1481 1 KIU Shueng Chuan
1465 1 Jonathan Slenders
1482 1 Jonathan Slenders
1466 1 Jay Qi
1483 1 Jay Qi
1467 1 Jake VanderPlas
1484 1 Jake VanderPlas
1468 1 Iwan Briquemont
1485 1 Iwan Briquemont
1469 1 Hussaina Begum Nandyala
1486 1 Hussaina Begum Nandyala
1470 1 Gordon Ball
1487 1 Gordon Ball
1471 1 Gabriel Simonetto
1488 1 Gabriel Simonetto
1472 1 Frank Tobia
1489 1 Frank Tobia
1473 1 Erik
1490 1 Erik
1474 1 Elliott Sales de Andrade
1491 1 Elliott Sales de Andrade
1475 1 Daniel Hahler
1492 1 Daniel Hahler
1476 1 Dan Green-Leipciger
1493 1 Dan Green-Leipciger
1477 1 Dan Green
1494 1 Dan Green
1478 1 Damian Yurzola
1495 1 Damian Yurzola
1479 1 Coon, Ethan T
1496 1 Coon, Ethan T
1480 1 Carol Willing
1497 1 Carol Willing
1481 1 Brian Lee
1498 1 Brian Lee
1482 1 Brendan Gerrity
1499 1 Brendan Gerrity
1483 1 Blake Griffin
1500 1 Blake Griffin
1484 1 Bastian Ebeling
1501 1 Bastian Ebeling
1485 1 Bartosz Telenczuk
1502 1 Bartosz Telenczuk
1486 1 Ankitsingh6299
1503 1 Ankitsingh6299
1487 1 Andrew Port
1504 1 Andrew Port
1488 1 Andrew J. Hesford
1505 1 Andrew J. Hesford
1489 1 Albert Zhang
1506 1 Albert Zhang
1490 1 Adam Johnson
1507 1 Adam Johnson
1491
1508
1492 This does not, of course, represent non-code contributions, for which we are also grateful.
1509 This does not, of course, represent non-code contributions, for which we are also grateful.
1493
1510
1494
1511
1495 API Changes using Frappuccino
1512 API Changes using Frappuccino
1496 -----------------------------
1513 -----------------------------
1497
1514
1498 This is an experimental exhaustive API difference using `Frappuccino <https://pypi.org/project/frappuccino/>`_
1515 This is an experimental exhaustive API difference using `Frappuccino <https://pypi.org/project/frappuccino/>`_
1499
1516
1500
1517
1501 The following items are new in IPython 8.0 ::
1518 The following items are new in IPython 8.0 ::
1502
1519
1503 + IPython.core.async_helpers.get_asyncio_loop()
1520 + IPython.core.async_helpers.get_asyncio_loop()
1504 + IPython.core.completer.Dict
1521 + IPython.core.completer.Dict
1505 + IPython.core.completer.Pattern
1522 + IPython.core.completer.Pattern
1506 + IPython.core.completer.Sequence
1523 + IPython.core.completer.Sequence
1507 + IPython.core.completer.__skip_doctest__
1524 + IPython.core.completer.__skip_doctest__
1508 + IPython.core.debugger.Pdb.precmd(self, line)
1525 + IPython.core.debugger.Pdb.precmd(self, line)
1509 + IPython.core.debugger.__skip_doctest__
1526 + IPython.core.debugger.__skip_doctest__
1510 + IPython.core.display.__getattr__(name)
1527 + IPython.core.display.__getattr__(name)
1511 + IPython.core.display.warn
1528 + IPython.core.display.warn
1512 + IPython.core.display_functions
1529 + IPython.core.display_functions
1513 + IPython.core.display_functions.DisplayHandle
1530 + IPython.core.display_functions.DisplayHandle
1514 + IPython.core.display_functions.DisplayHandle.display(self, obj, **kwargs)
1531 + IPython.core.display_functions.DisplayHandle.display(self, obj, **kwargs)
1515 + IPython.core.display_functions.DisplayHandle.update(self, obj, **kwargs)
1532 + IPython.core.display_functions.DisplayHandle.update(self, obj, **kwargs)
1516 + IPython.core.display_functions.__all__
1533 + IPython.core.display_functions.__all__
1517 + IPython.core.display_functions.__builtins__
1534 + IPython.core.display_functions.__builtins__
1518 + IPython.core.display_functions.__cached__
1535 + IPython.core.display_functions.__cached__
1519 + IPython.core.display_functions.__doc__
1536 + IPython.core.display_functions.__doc__
1520 + IPython.core.display_functions.__file__
1537 + IPython.core.display_functions.__file__
1521 + IPython.core.display_functions.__loader__
1538 + IPython.core.display_functions.__loader__
1522 + IPython.core.display_functions.__name__
1539 + IPython.core.display_functions.__name__
1523 + IPython.core.display_functions.__package__
1540 + IPython.core.display_functions.__package__
1524 + IPython.core.display_functions.__spec__
1541 + IPython.core.display_functions.__spec__
1525 + IPython.core.display_functions.b2a_hex
1542 + IPython.core.display_functions.b2a_hex
1526 + IPython.core.display_functions.clear_output(wait=False)
1543 + IPython.core.display_functions.clear_output(wait=False)
1527 + IPython.core.display_functions.display(*objs, include='None', exclude='None', metadata='None', transient='None', display_id='None', raw=False, clear=False, **kwargs)
1544 + IPython.core.display_functions.display(*objs, include='None', exclude='None', metadata='None', transient='None', display_id='None', raw=False, clear=False, **kwargs)
1528 + IPython.core.display_functions.publish_display_data(data, metadata='None', source='<deprecated>', *, transient='None', **kwargs)
1545 + IPython.core.display_functions.publish_display_data(data, metadata='None', source='<deprecated>', *, transient='None', **kwargs)
1529 + IPython.core.display_functions.update_display(obj, *, display_id, **kwargs)
1546 + IPython.core.display_functions.update_display(obj, *, display_id, **kwargs)
1530 + IPython.core.extensions.BUILTINS_EXTS
1547 + IPython.core.extensions.BUILTINS_EXTS
1531 + IPython.core.inputtransformer2.has_sunken_brackets(tokens)
1548 + IPython.core.inputtransformer2.has_sunken_brackets(tokens)
1532 + IPython.core.interactiveshell.Callable
1549 + IPython.core.interactiveshell.Callable
1533 + IPython.core.interactiveshell.__annotations__
1550 + IPython.core.interactiveshell.__annotations__
1534 + IPython.core.ultratb.List
1551 + IPython.core.ultratb.List
1535 + IPython.core.ultratb.Tuple
1552 + IPython.core.ultratb.Tuple
1536 + IPython.lib.pretty.CallExpression
1553 + IPython.lib.pretty.CallExpression
1537 + IPython.lib.pretty.CallExpression.factory(name)
1554 + IPython.lib.pretty.CallExpression.factory(name)
1538 + IPython.lib.pretty.RawStringLiteral
1555 + IPython.lib.pretty.RawStringLiteral
1539 + IPython.lib.pretty.RawText
1556 + IPython.lib.pretty.RawText
1540 + IPython.terminal.debugger.TerminalPdb.do_interact(self, arg)
1557 + IPython.terminal.debugger.TerminalPdb.do_interact(self, arg)
1541 + IPython.terminal.embed.Set
1558 + IPython.terminal.embed.Set
1542
1559
1543 The following items have been removed (or moved to superclass)::
1560 The following items have been removed (or moved to superclass)::
1544
1561
1545 - IPython.core.application.BaseIPythonApplication.initialize_subcommand
1562 - IPython.core.application.BaseIPythonApplication.initialize_subcommand
1546 - IPython.core.completer.Sentinel
1563 - IPython.core.completer.Sentinel
1547 - IPython.core.completer.skip_doctest
1564 - IPython.core.completer.skip_doctest
1548 - IPython.core.debugger.Tracer
1565 - IPython.core.debugger.Tracer
1549 - IPython.core.display.DisplayHandle
1566 - IPython.core.display.DisplayHandle
1550 - IPython.core.display.DisplayHandle.display
1567 - IPython.core.display.DisplayHandle.display
1551 - IPython.core.display.DisplayHandle.update
1568 - IPython.core.display.DisplayHandle.update
1552 - IPython.core.display.b2a_hex
1569 - IPython.core.display.b2a_hex
1553 - IPython.core.display.clear_output
1570 - IPython.core.display.clear_output
1554 - IPython.core.display.display
1571 - IPython.core.display.display
1555 - IPython.core.display.publish_display_data
1572 - IPython.core.display.publish_display_data
1556 - IPython.core.display.update_display
1573 - IPython.core.display.update_display
1557 - IPython.core.excolors.Deprec
1574 - IPython.core.excolors.Deprec
1558 - IPython.core.excolors.ExceptionColors
1575 - IPython.core.excolors.ExceptionColors
1559 - IPython.core.history.warn
1576 - IPython.core.history.warn
1560 - IPython.core.hooks.late_startup_hook
1577 - IPython.core.hooks.late_startup_hook
1561 - IPython.core.hooks.pre_run_code_hook
1578 - IPython.core.hooks.pre_run_code_hook
1562 - IPython.core.hooks.shutdown_hook
1579 - IPython.core.hooks.shutdown_hook
1563 - IPython.core.interactiveshell.InteractiveShell.init_deprecation_warnings
1580 - IPython.core.interactiveshell.InteractiveShell.init_deprecation_warnings
1564 - IPython.core.interactiveshell.InteractiveShell.init_readline
1581 - IPython.core.interactiveshell.InteractiveShell.init_readline
1565 - IPython.core.interactiveshell.InteractiveShell.write
1582 - IPython.core.interactiveshell.InteractiveShell.write
1566 - IPython.core.interactiveshell.InteractiveShell.write_err
1583 - IPython.core.interactiveshell.InteractiveShell.write_err
1567 - IPython.core.interactiveshell.get_default_colors
1584 - IPython.core.interactiveshell.get_default_colors
1568 - IPython.core.interactiveshell.removed_co_newlocals
1585 - IPython.core.interactiveshell.removed_co_newlocals
1569 - IPython.core.magics.execution.ExecutionMagics.profile_missing_notice
1586 - IPython.core.magics.execution.ExecutionMagics.profile_missing_notice
1570 - IPython.core.magics.script.PIPE
1587 - IPython.core.magics.script.PIPE
1571 - IPython.core.prefilter.PrefilterManager.init_transformers
1588 - IPython.core.prefilter.PrefilterManager.init_transformers
1572 - IPython.core.release.classifiers
1589 - IPython.core.release.classifiers
1573 - IPython.core.release.description
1590 - IPython.core.release.description
1574 - IPython.core.release.keywords
1591 - IPython.core.release.keywords
1575 - IPython.core.release.long_description
1592 - IPython.core.release.long_description
1576 - IPython.core.release.name
1593 - IPython.core.release.name
1577 - IPython.core.release.platforms
1594 - IPython.core.release.platforms
1578 - IPython.core.release.url
1595 - IPython.core.release.url
1579 - IPython.core.ultratb.VerboseTB.format_records
1596 - IPython.core.ultratb.VerboseTB.format_records
1580 - IPython.core.ultratb.find_recursion
1597 - IPython.core.ultratb.find_recursion
1581 - IPython.core.ultratb.findsource
1598 - IPython.core.ultratb.findsource
1582 - IPython.core.ultratb.fix_frame_records_filenames
1599 - IPython.core.ultratb.fix_frame_records_filenames
1583 - IPython.core.ultratb.inspect_error
1600 - IPython.core.ultratb.inspect_error
1584 - IPython.core.ultratb.is_recursion_error
1601 - IPython.core.ultratb.is_recursion_error
1585 - IPython.core.ultratb.with_patch_inspect
1602 - IPython.core.ultratb.with_patch_inspect
1586 - IPython.external.__all__
1603 - IPython.external.__all__
1587 - IPython.external.__builtins__
1604 - IPython.external.__builtins__
1588 - IPython.external.__cached__
1605 - IPython.external.__cached__
1589 - IPython.external.__doc__
1606 - IPython.external.__doc__
1590 - IPython.external.__file__
1607 - IPython.external.__file__
1591 - IPython.external.__loader__
1608 - IPython.external.__loader__
1592 - IPython.external.__name__
1609 - IPython.external.__name__
1593 - IPython.external.__package__
1610 - IPython.external.__package__
1594 - IPython.external.__path__
1611 - IPython.external.__path__
1595 - IPython.external.__spec__
1612 - IPython.external.__spec__
1596 - IPython.kernel.KernelConnectionInfo
1613 - IPython.kernel.KernelConnectionInfo
1597 - IPython.kernel.__builtins__
1614 - IPython.kernel.__builtins__
1598 - IPython.kernel.__cached__
1615 - IPython.kernel.__cached__
1599 - IPython.kernel.__warningregistry__
1616 - IPython.kernel.__warningregistry__
1600 - IPython.kernel.pkg
1617 - IPython.kernel.pkg
1601 - IPython.kernel.protocol_version
1618 - IPython.kernel.protocol_version
1602 - IPython.kernel.protocol_version_info
1619 - IPython.kernel.protocol_version_info
1603 - IPython.kernel.src
1620 - IPython.kernel.src
1604 - IPython.kernel.version_info
1621 - IPython.kernel.version_info
1605 - IPython.kernel.warn
1622 - IPython.kernel.warn
1606 - IPython.lib.backgroundjobs
1623 - IPython.lib.backgroundjobs
1607 - IPython.lib.backgroundjobs.BackgroundJobBase
1624 - IPython.lib.backgroundjobs.BackgroundJobBase
1608 - IPython.lib.backgroundjobs.BackgroundJobBase.run
1625 - IPython.lib.backgroundjobs.BackgroundJobBase.run
1609 - IPython.lib.backgroundjobs.BackgroundJobBase.traceback
1626 - IPython.lib.backgroundjobs.BackgroundJobBase.traceback
1610 - IPython.lib.backgroundjobs.BackgroundJobExpr
1627 - IPython.lib.backgroundjobs.BackgroundJobExpr
1611 - IPython.lib.backgroundjobs.BackgroundJobExpr.call
1628 - IPython.lib.backgroundjobs.BackgroundJobExpr.call
1612 - IPython.lib.backgroundjobs.BackgroundJobFunc
1629 - IPython.lib.backgroundjobs.BackgroundJobFunc
1613 - IPython.lib.backgroundjobs.BackgroundJobFunc.call
1630 - IPython.lib.backgroundjobs.BackgroundJobFunc.call
1614 - IPython.lib.backgroundjobs.BackgroundJobManager
1631 - IPython.lib.backgroundjobs.BackgroundJobManager
1615 - IPython.lib.backgroundjobs.BackgroundJobManager.flush
1632 - IPython.lib.backgroundjobs.BackgroundJobManager.flush
1616 - IPython.lib.backgroundjobs.BackgroundJobManager.new
1633 - IPython.lib.backgroundjobs.BackgroundJobManager.new
1617 - IPython.lib.backgroundjobs.BackgroundJobManager.remove
1634 - IPython.lib.backgroundjobs.BackgroundJobManager.remove
1618 - IPython.lib.backgroundjobs.BackgroundJobManager.result
1635 - IPython.lib.backgroundjobs.BackgroundJobManager.result
1619 - IPython.lib.backgroundjobs.BackgroundJobManager.status
1636 - IPython.lib.backgroundjobs.BackgroundJobManager.status
1620 - IPython.lib.backgroundjobs.BackgroundJobManager.traceback
1637 - IPython.lib.backgroundjobs.BackgroundJobManager.traceback
1621 - IPython.lib.backgroundjobs.__builtins__
1638 - IPython.lib.backgroundjobs.__builtins__
1622 - IPython.lib.backgroundjobs.__cached__
1639 - IPython.lib.backgroundjobs.__cached__
1623 - IPython.lib.backgroundjobs.__doc__
1640 - IPython.lib.backgroundjobs.__doc__
1624 - IPython.lib.backgroundjobs.__file__
1641 - IPython.lib.backgroundjobs.__file__
1625 - IPython.lib.backgroundjobs.__loader__
1642 - IPython.lib.backgroundjobs.__loader__
1626 - IPython.lib.backgroundjobs.__name__
1643 - IPython.lib.backgroundjobs.__name__
1627 - IPython.lib.backgroundjobs.__package__
1644 - IPython.lib.backgroundjobs.__package__
1628 - IPython.lib.backgroundjobs.__spec__
1645 - IPython.lib.backgroundjobs.__spec__
1629 - IPython.lib.kernel.__builtins__
1646 - IPython.lib.kernel.__builtins__
1630 - IPython.lib.kernel.__cached__
1647 - IPython.lib.kernel.__cached__
1631 - IPython.lib.kernel.__doc__
1648 - IPython.lib.kernel.__doc__
1632 - IPython.lib.kernel.__file__
1649 - IPython.lib.kernel.__file__
1633 - IPython.lib.kernel.__loader__
1650 - IPython.lib.kernel.__loader__
1634 - IPython.lib.kernel.__name__
1651 - IPython.lib.kernel.__name__
1635 - IPython.lib.kernel.__package__
1652 - IPython.lib.kernel.__package__
1636 - IPython.lib.kernel.__spec__
1653 - IPython.lib.kernel.__spec__
1637 - IPython.lib.kernel.__warningregistry__
1654 - IPython.lib.kernel.__warningregistry__
1638 - IPython.paths.fs_encoding
1655 - IPython.paths.fs_encoding
1639 - IPython.terminal.debugger.DEFAULT_BUFFER
1656 - IPython.terminal.debugger.DEFAULT_BUFFER
1640 - IPython.terminal.debugger.cursor_in_leading_ws
1657 - IPython.terminal.debugger.cursor_in_leading_ws
1641 - IPython.terminal.debugger.emacs_insert_mode
1658 - IPython.terminal.debugger.emacs_insert_mode
1642 - IPython.terminal.debugger.has_selection
1659 - IPython.terminal.debugger.has_selection
1643 - IPython.terminal.debugger.vi_insert_mode
1660 - IPython.terminal.debugger.vi_insert_mode
1644 - IPython.terminal.interactiveshell.DISPLAY_BANNER_DEPRECATED
1661 - IPython.terminal.interactiveshell.DISPLAY_BANNER_DEPRECATED
1645 - IPython.terminal.ipapp.TerminalIPythonApp.parse_command_line
1662 - IPython.terminal.ipapp.TerminalIPythonApp.parse_command_line
1646 - IPython.testing.test
1663 - IPython.testing.test
1647 - IPython.utils.contexts.NoOpContext
1664 - IPython.utils.contexts.NoOpContext
1648 - IPython.utils.io.IOStream
1665 - IPython.utils.io.IOStream
1649 - IPython.utils.io.IOStream.close
1666 - IPython.utils.io.IOStream.close
1650 - IPython.utils.io.IOStream.write
1667 - IPython.utils.io.IOStream.write
1651 - IPython.utils.io.IOStream.writelines
1668 - IPython.utils.io.IOStream.writelines
1652 - IPython.utils.io.__warningregistry__
1669 - IPython.utils.io.__warningregistry__
1653 - IPython.utils.io.atomic_writing
1670 - IPython.utils.io.atomic_writing
1654 - IPython.utils.io.stderr
1671 - IPython.utils.io.stderr
1655 - IPython.utils.io.stdin
1672 - IPython.utils.io.stdin
1656 - IPython.utils.io.stdout
1673 - IPython.utils.io.stdout
1657 - IPython.utils.io.unicode_std_stream
1674 - IPython.utils.io.unicode_std_stream
1658 - IPython.utils.path.get_ipython_cache_dir
1675 - IPython.utils.path.get_ipython_cache_dir
1659 - IPython.utils.path.get_ipython_dir
1676 - IPython.utils.path.get_ipython_dir
1660 - IPython.utils.path.get_ipython_module_path
1677 - IPython.utils.path.get_ipython_module_path
1661 - IPython.utils.path.get_ipython_package_dir
1678 - IPython.utils.path.get_ipython_package_dir
1662 - IPython.utils.path.locate_profile
1679 - IPython.utils.path.locate_profile
1663 - IPython.utils.path.unquote_filename
1680 - IPython.utils.path.unquote_filename
1664 - IPython.utils.py3compat.PY2
1681 - IPython.utils.py3compat.PY2
1665 - IPython.utils.py3compat.PY3
1682 - IPython.utils.py3compat.PY3
1666 - IPython.utils.py3compat.buffer_to_bytes
1683 - IPython.utils.py3compat.buffer_to_bytes
1667 - IPython.utils.py3compat.builtin_mod_name
1684 - IPython.utils.py3compat.builtin_mod_name
1668 - IPython.utils.py3compat.cast_bytes
1685 - IPython.utils.py3compat.cast_bytes
1669 - IPython.utils.py3compat.getcwd
1686 - IPython.utils.py3compat.getcwd
1670 - IPython.utils.py3compat.isidentifier
1687 - IPython.utils.py3compat.isidentifier
1671 - IPython.utils.py3compat.u_format
1688 - IPython.utils.py3compat.u_format
1672
1689
1673 The following signatures differ between 7.x and 8.0::
1690 The following signatures differ between 7.x and 8.0::
1674
1691
1675 - IPython.core.completer.IPCompleter.unicode_name_matches(self, text)
1692 - IPython.core.completer.IPCompleter.unicode_name_matches(self, text)
1676 + IPython.core.completer.IPCompleter.unicode_name_matches(text)
1693 + IPython.core.completer.IPCompleter.unicode_name_matches(text)
1677
1694
1678 - IPython.core.completer.match_dict_keys(keys, prefix, delims)
1695 - IPython.core.completer.match_dict_keys(keys, prefix, delims)
1679 + IPython.core.completer.match_dict_keys(keys, prefix, delims, extra_prefix='None')
1696 + IPython.core.completer.match_dict_keys(keys, prefix, delims, extra_prefix='None')
1680
1697
1681 - IPython.core.interactiveshell.InteractiveShell.object_inspect_mime(self, oname, detail_level=0)
1698 - IPython.core.interactiveshell.InteractiveShell.object_inspect_mime(self, oname, detail_level=0)
1682 + IPython.core.interactiveshell.InteractiveShell.object_inspect_mime(self, oname, detail_level=0, omit_sections='()')
1699 + IPython.core.interactiveshell.InteractiveShell.object_inspect_mime(self, oname, detail_level=0, omit_sections='()')
1683
1700
1684 - IPython.core.interactiveshell.InteractiveShell.set_hook(self, name, hook, priority=50, str_key='None', re_key='None', _warn_deprecated=True)
1701 - IPython.core.interactiveshell.InteractiveShell.set_hook(self, name, hook, priority=50, str_key='None', re_key='None', _warn_deprecated=True)
1685 + IPython.core.interactiveshell.InteractiveShell.set_hook(self, name, hook, priority=50, str_key='None', re_key='None')
1702 + IPython.core.interactiveshell.InteractiveShell.set_hook(self, name, hook, priority=50, str_key='None', re_key='None')
1686
1703
1687 - IPython.core.oinspect.Inspector.info(self, obj, oname='', formatter='None', info='None', detail_level=0)
1704 - IPython.core.oinspect.Inspector.info(self, obj, oname='', formatter='None', info='None', detail_level=0)
1688 + IPython.core.oinspect.Inspector.info(self, obj, oname='', info='None', detail_level=0)
1705 + IPython.core.oinspect.Inspector.info(self, obj, oname='', info='None', detail_level=0)
1689
1706
1690 - IPython.core.oinspect.Inspector.pinfo(self, obj, oname='', formatter='None', info='None', detail_level=0, enable_html_pager=True)
1707 - IPython.core.oinspect.Inspector.pinfo(self, obj, oname='', formatter='None', info='None', detail_level=0, enable_html_pager=True)
1691 + IPython.core.oinspect.Inspector.pinfo(self, obj, oname='', formatter='None', info='None', detail_level=0, enable_html_pager=True, omit_sections='()')
1708 + IPython.core.oinspect.Inspector.pinfo(self, obj, oname='', formatter='None', info='None', detail_level=0, enable_html_pager=True, omit_sections='()')
1692
1709
1693 - IPython.core.profiledir.ProfileDir.copy_config_file(self, config_file, path='None', overwrite=False)
1710 - IPython.core.profiledir.ProfileDir.copy_config_file(self, config_file, path='None', overwrite=False)
1694 + IPython.core.profiledir.ProfileDir.copy_config_file(self, config_file, path, overwrite=False)
1711 + IPython.core.profiledir.ProfileDir.copy_config_file(self, config_file, path, overwrite=False)
1695
1712
1696 - IPython.core.ultratb.VerboseTB.format_record(self, frame, file, lnum, func, lines, index)
1713 - IPython.core.ultratb.VerboseTB.format_record(self, frame, file, lnum, func, lines, index)
1697 + IPython.core.ultratb.VerboseTB.format_record(self, frame_info)
1714 + IPython.core.ultratb.VerboseTB.format_record(self, frame_info)
1698
1715
1699 - IPython.terminal.embed.InteractiveShellEmbed.mainloop(self, local_ns='None', module='None', stack_depth=0, display_banner='None', global_ns='None', compile_flags='None')
1716 - IPython.terminal.embed.InteractiveShellEmbed.mainloop(self, local_ns='None', module='None', stack_depth=0, display_banner='None', global_ns='None', compile_flags='None')
1700 + IPython.terminal.embed.InteractiveShellEmbed.mainloop(self, local_ns='None', module='None', stack_depth=0, compile_flags='None')
1717 + IPython.terminal.embed.InteractiveShellEmbed.mainloop(self, local_ns='None', module='None', stack_depth=0, compile_flags='None')
1701
1718
1702 - IPython.terminal.embed.embed(**kwargs)
1719 - IPython.terminal.embed.embed(**kwargs)
1703 + IPython.terminal.embed.embed(*, header='', compile_flags='None', **kwargs)
1720 + IPython.terminal.embed.embed(*, header='', compile_flags='None', **kwargs)
1704
1721
1705 - IPython.terminal.interactiveshell.TerminalInteractiveShell.interact(self, display_banner='<object object at 0xffffff>')
1722 - IPython.terminal.interactiveshell.TerminalInteractiveShell.interact(self, display_banner='<object object at 0xffffff>')
1706 + IPython.terminal.interactiveshell.TerminalInteractiveShell.interact(self)
1723 + IPython.terminal.interactiveshell.TerminalInteractiveShell.interact(self)
1707
1724
1708 - IPython.terminal.interactiveshell.TerminalInteractiveShell.mainloop(self, display_banner='<object object at 0xffffff>')
1725 - IPython.terminal.interactiveshell.TerminalInteractiveShell.mainloop(self, display_banner='<object object at 0xffffff>')
1709 + IPython.terminal.interactiveshell.TerminalInteractiveShell.mainloop(self)
1726 + IPython.terminal.interactiveshell.TerminalInteractiveShell.mainloop(self)
1710
1727
1711 - IPython.utils.path.get_py_filename(name, force_win32='None')
1728 - IPython.utils.path.get_py_filename(name, force_win32='None')
1712 + IPython.utils.path.get_py_filename(name)
1729 + IPython.utils.path.get_py_filename(name)
1713
1730
1714 The following are new attributes (that might be inherited)::
1731 The following are new attributes (that might be inherited)::
1715
1732
1716 + IPython.core.completer.IPCompleter.unicode_names
1733 + IPython.core.completer.IPCompleter.unicode_names
1717 + IPython.core.debugger.InterruptiblePdb.precmd
1734 + IPython.core.debugger.InterruptiblePdb.precmd
1718 + IPython.core.debugger.Pdb.precmd
1735 + IPython.core.debugger.Pdb.precmd
1719 + IPython.core.ultratb.AutoFormattedTB.has_colors
1736 + IPython.core.ultratb.AutoFormattedTB.has_colors
1720 + IPython.core.ultratb.ColorTB.has_colors
1737 + IPython.core.ultratb.ColorTB.has_colors
1721 + IPython.core.ultratb.FormattedTB.has_colors
1738 + IPython.core.ultratb.FormattedTB.has_colors
1722 + IPython.core.ultratb.ListTB.has_colors
1739 + IPython.core.ultratb.ListTB.has_colors
1723 + IPython.core.ultratb.SyntaxTB.has_colors
1740 + IPython.core.ultratb.SyntaxTB.has_colors
1724 + IPython.core.ultratb.TBTools.has_colors
1741 + IPython.core.ultratb.TBTools.has_colors
1725 + IPython.core.ultratb.VerboseTB.has_colors
1742 + IPython.core.ultratb.VerboseTB.has_colors
1726 + IPython.terminal.debugger.TerminalPdb.do_interact
1743 + IPython.terminal.debugger.TerminalPdb.do_interact
1727 + IPython.terminal.debugger.TerminalPdb.precmd
1744 + IPython.terminal.debugger.TerminalPdb.precmd
1728
1745
1729 The following attribute/methods have been removed::
1746 The following attribute/methods have been removed::
1730
1747
1731 - IPython.core.application.BaseIPythonApplication.deprecated_subcommands
1748 - IPython.core.application.BaseIPythonApplication.deprecated_subcommands
1732 - IPython.core.ultratb.AutoFormattedTB.format_records
1749 - IPython.core.ultratb.AutoFormattedTB.format_records
1733 - IPython.core.ultratb.ColorTB.format_records
1750 - IPython.core.ultratb.ColorTB.format_records
1734 - IPython.core.ultratb.FormattedTB.format_records
1751 - IPython.core.ultratb.FormattedTB.format_records
1735 - IPython.terminal.embed.InteractiveShellEmbed.init_deprecation_warnings
1752 - IPython.terminal.embed.InteractiveShellEmbed.init_deprecation_warnings
1736 - IPython.terminal.embed.InteractiveShellEmbed.init_readline
1753 - IPython.terminal.embed.InteractiveShellEmbed.init_readline
1737 - IPython.terminal.embed.InteractiveShellEmbed.write
1754 - IPython.terminal.embed.InteractiveShellEmbed.write
1738 - IPython.terminal.embed.InteractiveShellEmbed.write_err
1755 - IPython.terminal.embed.InteractiveShellEmbed.write_err
1739 - IPython.terminal.interactiveshell.TerminalInteractiveShell.init_deprecation_warnings
1756 - IPython.terminal.interactiveshell.TerminalInteractiveShell.init_deprecation_warnings
1740 - IPython.terminal.interactiveshell.TerminalInteractiveShell.init_readline
1757 - IPython.terminal.interactiveshell.TerminalInteractiveShell.init_readline
1741 - IPython.terminal.interactiveshell.TerminalInteractiveShell.write
1758 - IPython.terminal.interactiveshell.TerminalInteractiveShell.write
1742 - IPython.terminal.interactiveshell.TerminalInteractiveShell.write_err
1759 - IPython.terminal.interactiveshell.TerminalInteractiveShell.write_err
1743 - IPython.terminal.ipapp.LocateIPythonApp.deprecated_subcommands
1760 - IPython.terminal.ipapp.LocateIPythonApp.deprecated_subcommands
1744 - IPython.terminal.ipapp.LocateIPythonApp.initialize_subcommand
1761 - IPython.terminal.ipapp.LocateIPythonApp.initialize_subcommand
1745 - IPython.terminal.ipapp.TerminalIPythonApp.deprecated_subcommands
1762 - IPython.terminal.ipapp.TerminalIPythonApp.deprecated_subcommands
1746 - IPython.terminal.ipapp.TerminalIPythonApp.initialize_subcommand
1763 - IPython.terminal.ipapp.TerminalIPythonApp.initialize_subcommand
General Comments 0
You need to be logged in to leave comments. Login now