##// END OF EJS Templates
Remove try/except import for Py2 compat
Matthias Bussonnier -
Show More
@@ -1,642 +1,639 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Pdb debugger class.
3 Pdb debugger class.
4
4
5 Modified from the standard pdb.Pdb class to avoid including readline, so that
5 Modified from the standard pdb.Pdb class to avoid including readline, so that
6 the command line completion of other programs which include this isn't
6 the command line completion of other programs which include this isn't
7 damaged.
7 damaged.
8
8
9 In the future, this class will be expanded with improvements over the standard
9 In the future, this class will be expanded with improvements over the standard
10 pdb.
10 pdb.
11
11
12 The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor
12 The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor
13 changes. Licensing should therefore be under the standard Python terms. For
13 changes. Licensing should therefore be under the standard Python terms. For
14 details on the PSF (Python Software Foundation) standard license, see:
14 details on the PSF (Python Software Foundation) standard license, see:
15
15
16 https://docs.python.org/2/license.html
16 https://docs.python.org/2/license.html
17 """
17 """
18
18
19 #*****************************************************************************
19 #*****************************************************************************
20 #
20 #
21 # This file is licensed under the PSF license.
21 # This file is licensed under the PSF license.
22 #
22 #
23 # Copyright (C) 2001 Python Software Foundation, www.python.org
23 # Copyright (C) 2001 Python Software Foundation, www.python.org
24 # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu>
24 # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu>
25 #
25 #
26 #
26 #
27 #*****************************************************************************
27 #*****************************************************************************
28
28
29 import bdb
29 import bdb
30 import functools
30 import functools
31 import inspect
31 import inspect
32 import linecache
32 import linecache
33 import sys
33 import sys
34 import warnings
34 import warnings
35 import re
35 import re
36
36
37 from IPython import get_ipython
37 from IPython import get_ipython
38 from IPython.utils import PyColorize
38 from IPython.utils import PyColorize
39 from IPython.utils import coloransi, py3compat
39 from IPython.utils import coloransi, py3compat
40 from IPython.core.excolors import exception_colors
40 from IPython.core.excolors import exception_colors
41 from IPython.testing.skipdoctest import skip_doctest
41 from IPython.testing.skipdoctest import skip_doctest
42
42
43
43
44 prompt = 'ipdb> '
44 prompt = 'ipdb> '
45
45
46 #We have to check this directly from sys.argv, config struct not yet available
46 #We have to check this directly from sys.argv, config struct not yet available
47 from pdb import Pdb as OldPdb
47 from pdb import Pdb as OldPdb
48
48
49 # Allow the set_trace code to operate outside of an ipython instance, even if
49 # Allow the set_trace code to operate outside of an ipython instance, even if
50 # it does so with some limitations. The rest of this support is implemented in
50 # it does so with some limitations. The rest of this support is implemented in
51 # the Tracer constructor.
51 # the Tracer constructor.
52
52
53 def make_arrow(pad):
53 def make_arrow(pad):
54 """generate the leading arrow in front of traceback or debugger"""
54 """generate the leading arrow in front of traceback or debugger"""
55 if pad >= 2:
55 if pad >= 2:
56 return '-'*(pad-2) + '> '
56 return '-'*(pad-2) + '> '
57 elif pad == 1:
57 elif pad == 1:
58 return '>'
58 return '>'
59 return ''
59 return ''
60
60
61
61
62 def BdbQuit_excepthook(et, ev, tb, excepthook=None):
62 def BdbQuit_excepthook(et, ev, tb, excepthook=None):
63 """Exception hook which handles `BdbQuit` exceptions.
63 """Exception hook which handles `BdbQuit` exceptions.
64
64
65 All other exceptions are processed using the `excepthook`
65 All other exceptions are processed using the `excepthook`
66 parameter.
66 parameter.
67 """
67 """
68 warnings.warn("`BdbQuit_excepthook` is deprecated since version 5.1",
68 warnings.warn("`BdbQuit_excepthook` is deprecated since version 5.1",
69 DeprecationWarning, stacklevel=2)
69 DeprecationWarning, stacklevel=2)
70 if et==bdb.BdbQuit:
70 if et==bdb.BdbQuit:
71 print('Exiting Debugger.')
71 print('Exiting Debugger.')
72 elif excepthook is not None:
72 elif excepthook is not None:
73 excepthook(et, ev, tb)
73 excepthook(et, ev, tb)
74 else:
74 else:
75 # Backwards compatibility. Raise deprecation warning?
75 # Backwards compatibility. Raise deprecation warning?
76 BdbQuit_excepthook.excepthook_ori(et,ev,tb)
76 BdbQuit_excepthook.excepthook_ori(et,ev,tb)
77
77
78
78
79 def BdbQuit_IPython_excepthook(self,et,ev,tb,tb_offset=None):
79 def BdbQuit_IPython_excepthook(self,et,ev,tb,tb_offset=None):
80 warnings.warn(
80 warnings.warn(
81 "`BdbQuit_IPython_excepthook` is deprecated since version 5.1",
81 "`BdbQuit_IPython_excepthook` is deprecated since version 5.1",
82 DeprecationWarning, stacklevel=2)
82 DeprecationWarning, stacklevel=2)
83 print('Exiting Debugger.')
83 print('Exiting Debugger.')
84
84
85
85
86 class Tracer(object):
86 class Tracer(object):
87 """
87 """
88 DEPRECATED
88 DEPRECATED
89
89
90 Class for local debugging, similar to pdb.set_trace.
90 Class for local debugging, similar to pdb.set_trace.
91
91
92 Instances of this class, when called, behave like pdb.set_trace, but
92 Instances of this class, when called, behave like pdb.set_trace, but
93 providing IPython's enhanced capabilities.
93 providing IPython's enhanced capabilities.
94
94
95 This is implemented as a class which must be initialized in your own code
95 This is implemented as a class which must be initialized in your own code
96 and not as a standalone function because we need to detect at runtime
96 and not as a standalone function because we need to detect at runtime
97 whether IPython is already active or not. That detection is done in the
97 whether IPython is already active or not. That detection is done in the
98 constructor, ensuring that this code plays nicely with a running IPython,
98 constructor, ensuring that this code plays nicely with a running IPython,
99 while functioning acceptably (though with limitations) if outside of it.
99 while functioning acceptably (though with limitations) if outside of it.
100 """
100 """
101
101
102 @skip_doctest
102 @skip_doctest
103 def __init__(self, colors=None):
103 def __init__(self, colors=None):
104 """
104 """
105 DEPRECATED
105 DEPRECATED
106
106
107 Create a local debugger instance.
107 Create a local debugger instance.
108
108
109 Parameters
109 Parameters
110 ----------
110 ----------
111
111
112 colors : str, optional
112 colors : str, optional
113 The name of the color scheme to use, it must be one of IPython's
113 The name of the color scheme to use, it must be one of IPython's
114 valid color schemes. If not given, the function will default to
114 valid color schemes. If not given, the function will default to
115 the current IPython scheme when running inside IPython, and to
115 the current IPython scheme when running inside IPython, and to
116 'NoColor' otherwise.
116 'NoColor' otherwise.
117
117
118 Examples
118 Examples
119 --------
119 --------
120 ::
120 ::
121
121
122 from IPython.core.debugger import Tracer; debug_here = Tracer()
122 from IPython.core.debugger import Tracer; debug_here = Tracer()
123
123
124 Later in your code::
124 Later in your code::
125
125
126 debug_here() # -> will open up the debugger at that point.
126 debug_here() # -> will open up the debugger at that point.
127
127
128 Once the debugger activates, you can use all of its regular commands to
128 Once the debugger activates, you can use all of its regular commands to
129 step through code, set breakpoints, etc. See the pdb documentation
129 step through code, set breakpoints, etc. See the pdb documentation
130 from the Python standard library for usage details.
130 from the Python standard library for usage details.
131 """
131 """
132 warnings.warn("`Tracer` is deprecated since version 5.1, directly use "
132 warnings.warn("`Tracer` is deprecated since version 5.1, directly use "
133 "`IPython.core.debugger.Pdb.set_trace()`",
133 "`IPython.core.debugger.Pdb.set_trace()`",
134 DeprecationWarning, stacklevel=2)
134 DeprecationWarning, stacklevel=2)
135
135
136 ip = get_ipython()
136 ip = get_ipython()
137 if ip is None:
137 if ip is None:
138 # Outside of ipython, we set our own exception hook manually
138 # Outside of ipython, we set our own exception hook manually
139 sys.excepthook = functools.partial(BdbQuit_excepthook,
139 sys.excepthook = functools.partial(BdbQuit_excepthook,
140 excepthook=sys.excepthook)
140 excepthook=sys.excepthook)
141 def_colors = 'NoColor'
141 def_colors = 'NoColor'
142 else:
142 else:
143 # In ipython, we use its custom exception handler mechanism
143 # In ipython, we use its custom exception handler mechanism
144 def_colors = ip.colors
144 def_colors = ip.colors
145 ip.set_custom_exc((bdb.BdbQuit,), BdbQuit_IPython_excepthook)
145 ip.set_custom_exc((bdb.BdbQuit,), BdbQuit_IPython_excepthook)
146
146
147 if colors is None:
147 if colors is None:
148 colors = def_colors
148 colors = def_colors
149
149
150 # The stdlib debugger internally uses a modified repr from the `repr`
150 # The stdlib debugger internally uses a modified repr from the `repr`
151 # module, that limits the length of printed strings to a hardcoded
151 # module, that limits the length of printed strings to a hardcoded
152 # limit of 30 characters. That much trimming is too aggressive, let's
152 # limit of 30 characters. That much trimming is too aggressive, let's
153 # at least raise that limit to 80 chars, which should be enough for
153 # at least raise that limit to 80 chars, which should be enough for
154 # most interactive uses.
154 # most interactive uses.
155 try:
155 try:
156 try:
156 from reprlib import aRepr
157 from reprlib import aRepr # Py 3
158 except ImportError:
159 from repr import aRepr # Py 2
160 aRepr.maxstring = 80
157 aRepr.maxstring = 80
161 except:
158 except:
162 # This is only a user-facing convenience, so any error we encounter
159 # This is only a user-facing convenience, so any error we encounter
163 # here can be warned about but can be otherwise ignored. These
160 # here can be warned about but can be otherwise ignored. These
164 # printouts will tell us about problems if this API changes
161 # printouts will tell us about problems if this API changes
165 import traceback
162 import traceback
166 traceback.print_exc()
163 traceback.print_exc()
167
164
168 self.debugger = Pdb(colors)
165 self.debugger = Pdb(colors)
169
166
170 def __call__(self):
167 def __call__(self):
171 """Starts an interactive debugger at the point where called.
168 """Starts an interactive debugger at the point where called.
172
169
173 This is similar to the pdb.set_trace() function from the std lib, but
170 This is similar to the pdb.set_trace() function from the std lib, but
174 using IPython's enhanced debugger."""
171 using IPython's enhanced debugger."""
175
172
176 self.debugger.set_trace(sys._getframe().f_back)
173 self.debugger.set_trace(sys._getframe().f_back)
177
174
178
175
179 RGX_EXTRA_INDENT = re.compile(r'(?<=\n)\s+')
176 RGX_EXTRA_INDENT = re.compile(r'(?<=\n)\s+')
180
177
181
178
182 def strip_indentation(multiline_string):
179 def strip_indentation(multiline_string):
183 return RGX_EXTRA_INDENT.sub('', multiline_string)
180 return RGX_EXTRA_INDENT.sub('', multiline_string)
184
181
185
182
186 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
183 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
187 """Make new_fn have old_fn's doc string. This is particularly useful
184 """Make new_fn have old_fn's doc string. This is particularly useful
188 for the ``do_...`` commands that hook into the help system.
185 for the ``do_...`` commands that hook into the help system.
189 Adapted from from a comp.lang.python posting
186 Adapted from from a comp.lang.python posting
190 by Duncan Booth."""
187 by Duncan Booth."""
191 def wrapper(*args, **kw):
188 def wrapper(*args, **kw):
192 return new_fn(*args, **kw)
189 return new_fn(*args, **kw)
193 if old_fn.__doc__:
190 if old_fn.__doc__:
194 wrapper.__doc__ = strip_indentation(old_fn.__doc__) + additional_text
191 wrapper.__doc__ = strip_indentation(old_fn.__doc__) + additional_text
195 return wrapper
192 return wrapper
196
193
197
194
198 class Pdb(OldPdb):
195 class Pdb(OldPdb):
199 """Modified Pdb class, does not load readline.
196 """Modified Pdb class, does not load readline.
200
197
201 for a standalone version that uses prompt_toolkit, see
198 for a standalone version that uses prompt_toolkit, see
202 `IPython.terminal.debugger.TerminalPdb` and
199 `IPython.terminal.debugger.TerminalPdb` and
203 `IPython.terminal.debugger.set_trace()`
200 `IPython.terminal.debugger.set_trace()`
204 """
201 """
205
202
206 def __init__(self, color_scheme=None, completekey=None,
203 def __init__(self, color_scheme=None, completekey=None,
207 stdin=None, stdout=None, context=5, **kwargs):
204 stdin=None, stdout=None, context=5, **kwargs):
208 """Create a new IPython debugger.
205 """Create a new IPython debugger.
209
206
210 :param color_scheme: Deprecated, do not use.
207 :param color_scheme: Deprecated, do not use.
211 :param completekey: Passed to pdb.Pdb.
208 :param completekey: Passed to pdb.Pdb.
212 :param stdin: Passed to pdb.Pdb.
209 :param stdin: Passed to pdb.Pdb.
213 :param stdout: Passed to pdb.Pdb.
210 :param stdout: Passed to pdb.Pdb.
214 :param context: Number of lines of source code context to show when
211 :param context: Number of lines of source code context to show when
215 displaying stacktrace information.
212 displaying stacktrace information.
216 :param kwargs: Passed to pdb.Pdb.
213 :param kwargs: Passed to pdb.Pdb.
217 The possibilities are python version dependent, see the python
214 The possibilities are python version dependent, see the python
218 docs for more info.
215 docs for more info.
219 """
216 """
220
217
221 # Parent constructor:
218 # Parent constructor:
222 try:
219 try:
223 self.context = int(context)
220 self.context = int(context)
224 if self.context <= 0:
221 if self.context <= 0:
225 raise ValueError("Context must be a positive integer")
222 raise ValueError("Context must be a positive integer")
226 except (TypeError, ValueError):
223 except (TypeError, ValueError):
227 raise ValueError("Context must be a positive integer")
224 raise ValueError("Context must be a positive integer")
228
225
229 # `kwargs` ensures full compatibility with stdlib's `pdb.Pdb`.
226 # `kwargs` ensures full compatibility with stdlib's `pdb.Pdb`.
230 OldPdb.__init__(self, completekey, stdin, stdout, **kwargs)
227 OldPdb.__init__(self, completekey, stdin, stdout, **kwargs)
231
228
232 # IPython changes...
229 # IPython changes...
233 self.shell = get_ipython()
230 self.shell = get_ipython()
234
231
235 if self.shell is None:
232 if self.shell is None:
236 save_main = sys.modules['__main__']
233 save_main = sys.modules['__main__']
237 # No IPython instance running, we must create one
234 # No IPython instance running, we must create one
238 from IPython.terminal.interactiveshell import \
235 from IPython.terminal.interactiveshell import \
239 TerminalInteractiveShell
236 TerminalInteractiveShell
240 self.shell = TerminalInteractiveShell.instance()
237 self.shell = TerminalInteractiveShell.instance()
241 # needed by any code which calls __import__("__main__") after
238 # needed by any code which calls __import__("__main__") after
242 # the debugger was entered. See also #9941.
239 # the debugger was entered. See also #9941.
243 sys.modules['__main__'] = save_main
240 sys.modules['__main__'] = save_main
244
241
245 if color_scheme is not None:
242 if color_scheme is not None:
246 warnings.warn(
243 warnings.warn(
247 "The `color_scheme` argument is deprecated since version 5.1",
244 "The `color_scheme` argument is deprecated since version 5.1",
248 DeprecationWarning, stacklevel=2)
245 DeprecationWarning, stacklevel=2)
249 else:
246 else:
250 color_scheme = self.shell.colors
247 color_scheme = self.shell.colors
251
248
252 self.aliases = {}
249 self.aliases = {}
253
250
254 # Create color table: we copy the default one from the traceback
251 # Create color table: we copy the default one from the traceback
255 # module and add a few attributes needed for debugging
252 # module and add a few attributes needed for debugging
256 self.color_scheme_table = exception_colors()
253 self.color_scheme_table = exception_colors()
257
254
258 # shorthands
255 # shorthands
259 C = coloransi.TermColors
256 C = coloransi.TermColors
260 cst = self.color_scheme_table
257 cst = self.color_scheme_table
261
258
262 cst['NoColor'].colors.prompt = C.NoColor
259 cst['NoColor'].colors.prompt = C.NoColor
263 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
260 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
264 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
261 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
265
262
266 cst['Linux'].colors.prompt = C.Green
263 cst['Linux'].colors.prompt = C.Green
267 cst['Linux'].colors.breakpoint_enabled = C.LightRed
264 cst['Linux'].colors.breakpoint_enabled = C.LightRed
268 cst['Linux'].colors.breakpoint_disabled = C.Red
265 cst['Linux'].colors.breakpoint_disabled = C.Red
269
266
270 cst['LightBG'].colors.prompt = C.Blue
267 cst['LightBG'].colors.prompt = C.Blue
271 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
268 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
272 cst['LightBG'].colors.breakpoint_disabled = C.Red
269 cst['LightBG'].colors.breakpoint_disabled = C.Red
273
270
274 cst['Neutral'].colors.prompt = C.Blue
271 cst['Neutral'].colors.prompt = C.Blue
275 cst['Neutral'].colors.breakpoint_enabled = C.LightRed
272 cst['Neutral'].colors.breakpoint_enabled = C.LightRed
276 cst['Neutral'].colors.breakpoint_disabled = C.Red
273 cst['Neutral'].colors.breakpoint_disabled = C.Red
277
274
278
275
279 # Add a python parser so we can syntax highlight source while
276 # Add a python parser so we can syntax highlight source while
280 # debugging.
277 # debugging.
281 self.parser = PyColorize.Parser(style=color_scheme)
278 self.parser = PyColorize.Parser(style=color_scheme)
282 self.set_colors(color_scheme)
279 self.set_colors(color_scheme)
283
280
284 # Set the prompt - the default prompt is '(Pdb)'
281 # Set the prompt - the default prompt is '(Pdb)'
285 self.prompt = prompt
282 self.prompt = prompt
286
283
287 def set_colors(self, scheme):
284 def set_colors(self, scheme):
288 """Shorthand access to the color table scheme selector method."""
285 """Shorthand access to the color table scheme selector method."""
289 self.color_scheme_table.set_active_scheme(scheme)
286 self.color_scheme_table.set_active_scheme(scheme)
290 self.parser.style = scheme
287 self.parser.style = scheme
291
288
292 def interaction(self, frame, traceback):
289 def interaction(self, frame, traceback):
293 try:
290 try:
294 OldPdb.interaction(self, frame, traceback)
291 OldPdb.interaction(self, frame, traceback)
295 except KeyboardInterrupt:
292 except KeyboardInterrupt:
296 self.stdout.write('\n' + self.shell.get_exception_only())
293 self.stdout.write('\n' + self.shell.get_exception_only())
297
294
298 def new_do_up(self, arg):
295 def new_do_up(self, arg):
299 OldPdb.do_up(self, arg)
296 OldPdb.do_up(self, arg)
300 do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up)
297 do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up)
301
298
302 def new_do_down(self, arg):
299 def new_do_down(self, arg):
303 OldPdb.do_down(self, arg)
300 OldPdb.do_down(self, arg)
304
301
305 do_d = do_down = decorate_fn_with_doc(new_do_down, OldPdb.do_down)
302 do_d = do_down = decorate_fn_with_doc(new_do_down, OldPdb.do_down)
306
303
307 def new_do_frame(self, arg):
304 def new_do_frame(self, arg):
308 OldPdb.do_frame(self, arg)
305 OldPdb.do_frame(self, arg)
309
306
310 def new_do_quit(self, arg):
307 def new_do_quit(self, arg):
311
308
312 if hasattr(self, 'old_all_completions'):
309 if hasattr(self, 'old_all_completions'):
313 self.shell.Completer.all_completions=self.old_all_completions
310 self.shell.Completer.all_completions=self.old_all_completions
314
311
315 return OldPdb.do_quit(self, arg)
312 return OldPdb.do_quit(self, arg)
316
313
317 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
314 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
318
315
319 def new_do_restart(self, arg):
316 def new_do_restart(self, arg):
320 """Restart command. In the context of ipython this is exactly the same
317 """Restart command. In the context of ipython this is exactly the same
321 thing as 'quit'."""
318 thing as 'quit'."""
322 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
319 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
323 return self.do_quit(arg)
320 return self.do_quit(arg)
324
321
325 def print_stack_trace(self, context=None):
322 def print_stack_trace(self, context=None):
326 if context is None:
323 if context is None:
327 context = self.context
324 context = self.context
328 try:
325 try:
329 context=int(context)
326 context=int(context)
330 if context <= 0:
327 if context <= 0:
331 raise ValueError("Context must be a positive integer")
328 raise ValueError("Context must be a positive integer")
332 except (TypeError, ValueError):
329 except (TypeError, ValueError):
333 raise ValueError("Context must be a positive integer")
330 raise ValueError("Context must be a positive integer")
334 try:
331 try:
335 for frame_lineno in self.stack:
332 for frame_lineno in self.stack:
336 self.print_stack_entry(frame_lineno, context=context)
333 self.print_stack_entry(frame_lineno, context=context)
337 except KeyboardInterrupt:
334 except KeyboardInterrupt:
338 pass
335 pass
339
336
340 def print_stack_entry(self, frame_lineno, prompt_prefix='\n-> ',
337 def print_stack_entry(self, frame_lineno, prompt_prefix='\n-> ',
341 context=None):
338 context=None):
342 if context is None:
339 if context is None:
343 context = self.context
340 context = self.context
344 try:
341 try:
345 context=int(context)
342 context=int(context)
346 if context <= 0:
343 if context <= 0:
347 raise ValueError("Context must be a positive integer")
344 raise ValueError("Context must be a positive integer")
348 except (TypeError, ValueError):
345 except (TypeError, ValueError):
349 raise ValueError("Context must be a positive integer")
346 raise ValueError("Context must be a positive integer")
350 print(self.format_stack_entry(frame_lineno, '', context), file=self.stdout)
347 print(self.format_stack_entry(frame_lineno, '', context), file=self.stdout)
351
348
352 # vds: >>
349 # vds: >>
353 frame, lineno = frame_lineno
350 frame, lineno = frame_lineno
354 filename = frame.f_code.co_filename
351 filename = frame.f_code.co_filename
355 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
352 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
356 # vds: <<
353 # vds: <<
357
354
358 def format_stack_entry(self, frame_lineno, lprefix=': ', context=None):
355 def format_stack_entry(self, frame_lineno, lprefix=': ', context=None):
359 if context is None:
356 if context is None:
360 context = self.context
357 context = self.context
361 try:
358 try:
362 context=int(context)
359 context=int(context)
363 if context <= 0:
360 if context <= 0:
364 print("Context must be a positive integer", file=self.stdout)
361 print("Context must be a positive integer", file=self.stdout)
365 except (TypeError, ValueError):
362 except (TypeError, ValueError):
366 print("Context must be a positive integer", file=self.stdout)
363 print("Context must be a positive integer", file=self.stdout)
367 try:
364 try:
368 import reprlib # Py 3
365 import reprlib # Py 3
369 except ImportError:
366 except ImportError:
370 import repr as reprlib # Py 2
367 import repr as reprlib # Py 2
371
368
372 ret = []
369 ret = []
373
370
374 Colors = self.color_scheme_table.active_colors
371 Colors = self.color_scheme_table.active_colors
375 ColorsNormal = Colors.Normal
372 ColorsNormal = Colors.Normal
376 tpl_link = u'%s%%s%s' % (Colors.filenameEm, ColorsNormal)
373 tpl_link = u'%s%%s%s' % (Colors.filenameEm, ColorsNormal)
377 tpl_call = u'%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
374 tpl_call = u'%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
378 tpl_line = u'%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
375 tpl_line = u'%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
379 tpl_line_em = u'%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
376 tpl_line_em = u'%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
380 ColorsNormal)
377 ColorsNormal)
381
378
382 frame, lineno = frame_lineno
379 frame, lineno = frame_lineno
383
380
384 return_value = ''
381 return_value = ''
385 if '__return__' in frame.f_locals:
382 if '__return__' in frame.f_locals:
386 rv = frame.f_locals['__return__']
383 rv = frame.f_locals['__return__']
387 #return_value += '->'
384 #return_value += '->'
388 return_value += reprlib.repr(rv) + '\n'
385 return_value += reprlib.repr(rv) + '\n'
389 ret.append(return_value)
386 ret.append(return_value)
390
387
391 #s = filename + '(' + `lineno` + ')'
388 #s = filename + '(' + `lineno` + ')'
392 filename = self.canonic(frame.f_code.co_filename)
389 filename = self.canonic(frame.f_code.co_filename)
393 link = tpl_link % py3compat.cast_unicode(filename)
390 link = tpl_link % py3compat.cast_unicode(filename)
394
391
395 if frame.f_code.co_name:
392 if frame.f_code.co_name:
396 func = frame.f_code.co_name
393 func = frame.f_code.co_name
397 else:
394 else:
398 func = "<lambda>"
395 func = "<lambda>"
399
396
400 call = ''
397 call = ''
401 if func != '?':
398 if func != '?':
402 if '__args__' in frame.f_locals:
399 if '__args__' in frame.f_locals:
403 args = reprlib.repr(frame.f_locals['__args__'])
400 args = reprlib.repr(frame.f_locals['__args__'])
404 else:
401 else:
405 args = '()'
402 args = '()'
406 call = tpl_call % (func, args)
403 call = tpl_call % (func, args)
407
404
408 # The level info should be generated in the same format pdb uses, to
405 # The level info should be generated in the same format pdb uses, to
409 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
406 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
410 if frame is self.curframe:
407 if frame is self.curframe:
411 ret.append('> ')
408 ret.append('> ')
412 else:
409 else:
413 ret.append(' ')
410 ret.append(' ')
414 ret.append(u'%s(%s)%s\n' % (link,lineno,call))
411 ret.append(u'%s(%s)%s\n' % (link,lineno,call))
415
412
416 start = lineno - 1 - context//2
413 start = lineno - 1 - context//2
417 lines = linecache.getlines(filename)
414 lines = linecache.getlines(filename)
418 start = min(start, len(lines) - context)
415 start = min(start, len(lines) - context)
419 start = max(start, 0)
416 start = max(start, 0)
420 lines = lines[start : start + context]
417 lines = lines[start : start + context]
421
418
422 for i,line in enumerate(lines):
419 for i,line in enumerate(lines):
423 show_arrow = (start + 1 + i == lineno)
420 show_arrow = (start + 1 + i == lineno)
424 linetpl = (frame is self.curframe or show_arrow) \
421 linetpl = (frame is self.curframe or show_arrow) \
425 and tpl_line_em \
422 and tpl_line_em \
426 or tpl_line
423 or tpl_line
427 ret.append(self.__format_line(linetpl, filename,
424 ret.append(self.__format_line(linetpl, filename,
428 start + 1 + i, line,
425 start + 1 + i, line,
429 arrow = show_arrow) )
426 arrow = show_arrow) )
430 return ''.join(ret)
427 return ''.join(ret)
431
428
432 def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
429 def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
433 bp_mark = ""
430 bp_mark = ""
434 bp_mark_color = ""
431 bp_mark_color = ""
435
432
436 new_line, err = self.parser.format2(line, 'str')
433 new_line, err = self.parser.format2(line, 'str')
437 if not err:
434 if not err:
438 line = new_line
435 line = new_line
439
436
440 bp = None
437 bp = None
441 if lineno in self.get_file_breaks(filename):
438 if lineno in self.get_file_breaks(filename):
442 bps = self.get_breaks(filename, lineno)
439 bps = self.get_breaks(filename, lineno)
443 bp = bps[-1]
440 bp = bps[-1]
444
441
445 if bp:
442 if bp:
446 Colors = self.color_scheme_table.active_colors
443 Colors = self.color_scheme_table.active_colors
447 bp_mark = str(bp.number)
444 bp_mark = str(bp.number)
448 bp_mark_color = Colors.breakpoint_enabled
445 bp_mark_color = Colors.breakpoint_enabled
449 if not bp.enabled:
446 if not bp.enabled:
450 bp_mark_color = Colors.breakpoint_disabled
447 bp_mark_color = Colors.breakpoint_disabled
451
448
452 numbers_width = 7
449 numbers_width = 7
453 if arrow:
450 if arrow:
454 # This is the line with the error
451 # This is the line with the error
455 pad = numbers_width - len(str(lineno)) - len(bp_mark)
452 pad = numbers_width - len(str(lineno)) - len(bp_mark)
456 num = '%s%s' % (make_arrow(pad), str(lineno))
453 num = '%s%s' % (make_arrow(pad), str(lineno))
457 else:
454 else:
458 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
455 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
459
456
460 return tpl_line % (bp_mark_color + bp_mark, num, line)
457 return tpl_line % (bp_mark_color + bp_mark, num, line)
461
458
462
459
463 def print_list_lines(self, filename, first, last):
460 def print_list_lines(self, filename, first, last):
464 """The printing (as opposed to the parsing part of a 'list'
461 """The printing (as opposed to the parsing part of a 'list'
465 command."""
462 command."""
466 try:
463 try:
467 Colors = self.color_scheme_table.active_colors
464 Colors = self.color_scheme_table.active_colors
468 ColorsNormal = Colors.Normal
465 ColorsNormal = Colors.Normal
469 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
466 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
470 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
467 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
471 src = []
468 src = []
472 if filename == "<string>" and hasattr(self, "_exec_filename"):
469 if filename == "<string>" and hasattr(self, "_exec_filename"):
473 filename = self._exec_filename
470 filename = self._exec_filename
474
471
475 for lineno in range(first, last+1):
472 for lineno in range(first, last+1):
476 line = linecache.getline(filename, lineno)
473 line = linecache.getline(filename, lineno)
477 if not line:
474 if not line:
478 break
475 break
479
476
480 if lineno == self.curframe.f_lineno:
477 if lineno == self.curframe.f_lineno:
481 line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
478 line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
482 else:
479 else:
483 line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
480 line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
484
481
485 src.append(line)
482 src.append(line)
486 self.lineno = lineno
483 self.lineno = lineno
487
484
488 print(''.join(src), file=self.stdout)
485 print(''.join(src), file=self.stdout)
489
486
490 except KeyboardInterrupt:
487 except KeyboardInterrupt:
491 pass
488 pass
492
489
493 def do_list(self, arg):
490 def do_list(self, arg):
494 """Print lines of code from the current stack frame
491 """Print lines of code from the current stack frame
495 """
492 """
496 self.lastcmd = 'list'
493 self.lastcmd = 'list'
497 last = None
494 last = None
498 if arg:
495 if arg:
499 try:
496 try:
500 x = eval(arg, {}, {})
497 x = eval(arg, {}, {})
501 if type(x) == type(()):
498 if type(x) == type(()):
502 first, last = x
499 first, last = x
503 first = int(first)
500 first = int(first)
504 last = int(last)
501 last = int(last)
505 if last < first:
502 if last < first:
506 # Assume it's a count
503 # Assume it's a count
507 last = first + last
504 last = first + last
508 else:
505 else:
509 first = max(1, int(x) - 5)
506 first = max(1, int(x) - 5)
510 except:
507 except:
511 print('*** Error in argument:', repr(arg), file=self.stdout)
508 print('*** Error in argument:', repr(arg), file=self.stdout)
512 return
509 return
513 elif self.lineno is None:
510 elif self.lineno is None:
514 first = max(1, self.curframe.f_lineno - 5)
511 first = max(1, self.curframe.f_lineno - 5)
515 else:
512 else:
516 first = self.lineno + 1
513 first = self.lineno + 1
517 if last is None:
514 if last is None:
518 last = first + 10
515 last = first + 10
519 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
516 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
520
517
521 # vds: >>
518 # vds: >>
522 lineno = first
519 lineno = first
523 filename = self.curframe.f_code.co_filename
520 filename = self.curframe.f_code.co_filename
524 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
521 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
525 # vds: <<
522 # vds: <<
526
523
527 do_l = do_list
524 do_l = do_list
528
525
529 def getsourcelines(self, obj):
526 def getsourcelines(self, obj):
530 lines, lineno = inspect.findsource(obj)
527 lines, lineno = inspect.findsource(obj)
531 if inspect.isframe(obj) and obj.f_globals is obj.f_locals:
528 if inspect.isframe(obj) and obj.f_globals is obj.f_locals:
532 # must be a module frame: do not try to cut a block out of it
529 # must be a module frame: do not try to cut a block out of it
533 return lines, 1
530 return lines, 1
534 elif inspect.ismodule(obj):
531 elif inspect.ismodule(obj):
535 return lines, 1
532 return lines, 1
536 return inspect.getblock(lines[lineno:]), lineno+1
533 return inspect.getblock(lines[lineno:]), lineno+1
537
534
538 def do_longlist(self, arg):
535 def do_longlist(self, arg):
539 """Print lines of code from the current stack frame.
536 """Print lines of code from the current stack frame.
540
537
541 Shows more lines than 'list' does.
538 Shows more lines than 'list' does.
542 """
539 """
543 self.lastcmd = 'longlist'
540 self.lastcmd = 'longlist'
544 try:
541 try:
545 lines, lineno = self.getsourcelines(self.curframe)
542 lines, lineno = self.getsourcelines(self.curframe)
546 except OSError as err:
543 except OSError as err:
547 self.error(err)
544 self.error(err)
548 return
545 return
549 last = lineno + len(lines)
546 last = lineno + len(lines)
550 self.print_list_lines(self.curframe.f_code.co_filename, lineno, last)
547 self.print_list_lines(self.curframe.f_code.co_filename, lineno, last)
551 do_ll = do_longlist
548 do_ll = do_longlist
552
549
553 def do_debug(self, arg):
550 def do_debug(self, arg):
554 """debug code
551 """debug code
555 Enter a recursive debugger that steps through the code
552 Enter a recursive debugger that steps through the code
556 argument (which is an arbitrary expression or statement to be
553 argument (which is an arbitrary expression or statement to be
557 executed in the current environment).
554 executed in the current environment).
558 """
555 """
559 sys.settrace(None)
556 sys.settrace(None)
560 globals = self.curframe.f_globals
557 globals = self.curframe.f_globals
561 locals = self.curframe_locals
558 locals = self.curframe_locals
562 p = self.__class__(completekey=self.completekey,
559 p = self.__class__(completekey=self.completekey,
563 stdin=self.stdin, stdout=self.stdout)
560 stdin=self.stdin, stdout=self.stdout)
564 p.use_rawinput = self.use_rawinput
561 p.use_rawinput = self.use_rawinput
565 p.prompt = "(%s) " % self.prompt.strip()
562 p.prompt = "(%s) " % self.prompt.strip()
566 self.message("ENTERING RECURSIVE DEBUGGER")
563 self.message("ENTERING RECURSIVE DEBUGGER")
567 sys.call_tracing(p.run, (arg, globals, locals))
564 sys.call_tracing(p.run, (arg, globals, locals))
568 self.message("LEAVING RECURSIVE DEBUGGER")
565 self.message("LEAVING RECURSIVE DEBUGGER")
569 sys.settrace(self.trace_dispatch)
566 sys.settrace(self.trace_dispatch)
570 self.lastcmd = p.lastcmd
567 self.lastcmd = p.lastcmd
571
568
572 def do_pdef(self, arg):
569 def do_pdef(self, arg):
573 """Print the call signature for any callable object.
570 """Print the call signature for any callable object.
574
571
575 The debugger interface to %pdef"""
572 The debugger interface to %pdef"""
576 namespaces = [('Locals', self.curframe.f_locals),
573 namespaces = [('Locals', self.curframe.f_locals),
577 ('Globals', self.curframe.f_globals)]
574 ('Globals', self.curframe.f_globals)]
578 self.shell.find_line_magic('pdef')(arg, namespaces=namespaces)
575 self.shell.find_line_magic('pdef')(arg, namespaces=namespaces)
579
576
580 def do_pdoc(self, arg):
577 def do_pdoc(self, arg):
581 """Print the docstring for an object.
578 """Print the docstring for an object.
582
579
583 The debugger interface to %pdoc."""
580 The debugger interface to %pdoc."""
584 namespaces = [('Locals', self.curframe.f_locals),
581 namespaces = [('Locals', self.curframe.f_locals),
585 ('Globals', self.curframe.f_globals)]
582 ('Globals', self.curframe.f_globals)]
586 self.shell.find_line_magic('pdoc')(arg, namespaces=namespaces)
583 self.shell.find_line_magic('pdoc')(arg, namespaces=namespaces)
587
584
588 def do_pfile(self, arg):
585 def do_pfile(self, arg):
589 """Print (or run through pager) the file where an object is defined.
586 """Print (or run through pager) the file where an object is defined.
590
587
591 The debugger interface to %pfile.
588 The debugger interface to %pfile.
592 """
589 """
593 namespaces = [('Locals', self.curframe.f_locals),
590 namespaces = [('Locals', self.curframe.f_locals),
594 ('Globals', self.curframe.f_globals)]
591 ('Globals', self.curframe.f_globals)]
595 self.shell.find_line_magic('pfile')(arg, namespaces=namespaces)
592 self.shell.find_line_magic('pfile')(arg, namespaces=namespaces)
596
593
597 def do_pinfo(self, arg):
594 def do_pinfo(self, arg):
598 """Provide detailed information about an object.
595 """Provide detailed information about an object.
599
596
600 The debugger interface to %pinfo, i.e., obj?."""
597 The debugger interface to %pinfo, i.e., obj?."""
601 namespaces = [('Locals', self.curframe.f_locals),
598 namespaces = [('Locals', self.curframe.f_locals),
602 ('Globals', self.curframe.f_globals)]
599 ('Globals', self.curframe.f_globals)]
603 self.shell.find_line_magic('pinfo')(arg, namespaces=namespaces)
600 self.shell.find_line_magic('pinfo')(arg, namespaces=namespaces)
604
601
605 def do_pinfo2(self, arg):
602 def do_pinfo2(self, arg):
606 """Provide extra detailed information about an object.
603 """Provide extra detailed information about an object.
607
604
608 The debugger interface to %pinfo2, i.e., obj??."""
605 The debugger interface to %pinfo2, i.e., obj??."""
609 namespaces = [('Locals', self.curframe.f_locals),
606 namespaces = [('Locals', self.curframe.f_locals),
610 ('Globals', self.curframe.f_globals)]
607 ('Globals', self.curframe.f_globals)]
611 self.shell.find_line_magic('pinfo2')(arg, namespaces=namespaces)
608 self.shell.find_line_magic('pinfo2')(arg, namespaces=namespaces)
612
609
613 def do_psource(self, arg):
610 def do_psource(self, arg):
614 """Print (or run through pager) the source code for an object."""
611 """Print (or run through pager) the source code for an object."""
615 namespaces = [('Locals', self.curframe.f_locals),
612 namespaces = [('Locals', self.curframe.f_locals),
616 ('Globals', self.curframe.f_globals)]
613 ('Globals', self.curframe.f_globals)]
617 self.shell.find_line_magic('psource')(arg, namespaces=namespaces)
614 self.shell.find_line_magic('psource')(arg, namespaces=namespaces)
618
615
619 def do_where(self, arg):
616 def do_where(self, arg):
620 """w(here)
617 """w(here)
621 Print a stack trace, with the most recent frame at the bottom.
618 Print a stack trace, with the most recent frame at the bottom.
622 An arrow indicates the "current frame", which determines the
619 An arrow indicates the "current frame", which determines the
623 context of most commands. 'bt' is an alias for this command.
620 context of most commands. 'bt' is an alias for this command.
624
621
625 Take a number as argument as an (optional) number of context line to
622 Take a number as argument as an (optional) number of context line to
626 print"""
623 print"""
627 if arg:
624 if arg:
628 context = int(arg)
625 context = int(arg)
629 self.print_stack_trace(context)
626 self.print_stack_trace(context)
630 else:
627 else:
631 self.print_stack_trace()
628 self.print_stack_trace()
632
629
633 do_w = do_where
630 do_w = do_where
634
631
635
632
636 def set_trace(frame=None):
633 def set_trace(frame=None):
637 """
634 """
638 Start debugging from `frame`.
635 Start debugging from `frame`.
639
636
640 If frame is not specified, debugging starts from caller's frame.
637 If frame is not specified, debugging starts from caller's frame.
641 """
638 """
642 Pdb().set_trace(frame or sys._getframe().f_back)
639 Pdb().set_trace(frame or sys._getframe().f_back)
General Comments 0
You need to be logged in to leave comments. Login now