##// END OF EJS Templates
Small Debugger fix seen only when using the code outside a running ipython instance
jdh2358 -
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,520 +1,520 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 http://www.python.org/2.2.3/license.html
16 http://www.python.org/2.2.3/license.html
17
17
18 $Id: Debugger.py 2203 2007-04-04 05:08:36Z fperez $"""
18 $Id: Debugger.py 2261 2007-04-20 17:50:00Z jdh2358 $"""
19
19
20 #*****************************************************************************
20 #*****************************************************************************
21 #
21 #
22 # Since this file is essentially a modified copy of the pdb module which is
22 # Since this file is essentially a modified copy of the pdb module which is
23 # part of the standard Python distribution, I assume that the proper procedure
23 # part of the standard Python distribution, I assume that the proper procedure
24 # is to maintain its copyright as belonging to the Python Software Foundation
24 # is to maintain its copyright as belonging to the Python Software Foundation
25 # (in addition to my own, for all new code).
25 # (in addition to my own, for all new code).
26 #
26 #
27 # Copyright (C) 2001 Python Software Foundation, www.python.org
27 # Copyright (C) 2001 Python Software Foundation, www.python.org
28 # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu>
28 # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu>
29 #
29 #
30 # Distributed under the terms of the BSD License. The full license is in
30 # Distributed under the terms of the BSD License. The full license is in
31 # the file COPYING, distributed as part of this software.
31 # the file COPYING, distributed as part of this software.
32 #
32 #
33 #*****************************************************************************
33 #*****************************************************************************
34
34
35 from IPython import Release
35 from IPython import Release
36 __author__ = '%s <%s>' % Release.authors['Fernando']
36 __author__ = '%s <%s>' % Release.authors['Fernando']
37 __license__ = 'Python'
37 __license__ = 'Python'
38
38
39 import bdb
39 import bdb
40 import cmd
40 import cmd
41 import linecache
41 import linecache
42 import os
42 import os
43 import sys
43 import sys
44
44
45 from IPython import PyColorize, ColorANSI, ipapi
45 from IPython import PyColorize, ColorANSI, ipapi
46 from IPython.genutils import Term
46 from IPython.genutils import Term
47 from IPython.excolors import ExceptionColors
47 from IPython.excolors import ExceptionColors
48
48
49 # See if we can use pydb.
49 # See if we can use pydb.
50 has_pydb = False
50 has_pydb = False
51 prompt = 'ipdb> '
51 prompt = 'ipdb> '
52 try:
52 try:
53 import pydb
53 import pydb
54 if hasattr(pydb.pydb, "runl") and pydb.version>'1.17':
54 if hasattr(pydb.pydb, "runl") and pydb.version>'1.17':
55 # Version 1.17 is broken, and that's what ships with Ubuntu Edgy, so we
55 # Version 1.17 is broken, and that's what ships with Ubuntu Edgy, so we
56 # better protetct against it.
56 # better protetct against it.
57 has_pydb = True
57 has_pydb = True
58 from pydb import Pdb as OldPdb
58 from pydb import Pdb as OldPdb
59 except ImportError:
59 except ImportError:
60 pass
60 pass
61
61
62 if has_pydb:
62 if has_pydb:
63 from pydb import Pdb as OldPdb
63 from pydb import Pdb as OldPdb
64 prompt = 'ipydb> '
64 prompt = 'ipydb> '
65 else:
65 else:
66 from pdb import Pdb as OldPdb
66 from pdb import Pdb as OldPdb
67
67
68 # Allow the set_trace code to operate outside of an ipython instance, even if
68 # Allow the set_trace code to operate outside of an ipython instance, even if
69 # it does so with some limitations. The rest of this support is implemented in
69 # it does so with some limitations. The rest of this support is implemented in
70 # the Tracer constructor.
70 # the Tracer constructor.
71 def BdbQuit_excepthook(et,ev,tb):
71 def BdbQuit_excepthook(et,ev,tb):
72 if et==bdb.BdbQuit:
72 if et==bdb.BdbQuit:
73 print 'Exiting Debugger.'
73 print 'Exiting Debugger.'
74 else:
74 else:
75 ehook.excepthook_ori(et,ev,tb)
75 BdbQuit_excepthook.excepthook_ori(et,ev,tb)
76
76
77 def BdbQuit_IPython_excepthook(self,et,ev,tb):
77 def BdbQuit_IPython_excepthook(self,et,ev,tb):
78 print 'Exiting Debugger.'
78 print 'Exiting Debugger.'
79
79
80 class Tracer(object):
80 class Tracer(object):
81 """Class for local debugging, similar to pdb.set_trace.
81 """Class for local debugging, similar to pdb.set_trace.
82
82
83 Instances of this class, when called, behave like pdb.set_trace, but
83 Instances of this class, when called, behave like pdb.set_trace, but
84 providing IPython's enhanced capabilities.
84 providing IPython's enhanced capabilities.
85
85
86 This is implemented as a class which must be initialized in your own code
86 This is implemented as a class which must be initialized in your own code
87 and not as a standalone function because we need to detect at runtime
87 and not as a standalone function because we need to detect at runtime
88 whether IPython is already active or not. That detection is done in the
88 whether IPython is already active or not. That detection is done in the
89 constructor, ensuring that this code plays nicely with a running IPython,
89 constructor, ensuring that this code plays nicely with a running IPython,
90 while functioning acceptably (though with limitations) if outside of it.
90 while functioning acceptably (though with limitations) if outside of it.
91 """
91 """
92
92
93 def __init__(self,colors=None):
93 def __init__(self,colors=None):
94 """Create a local debugger instance.
94 """Create a local debugger instance.
95
95
96 :Parameters:
96 :Parameters:
97
97
98 - `colors` (None): a string containing the name of the color scheme to
98 - `colors` (None): a string containing the name of the color scheme to
99 use, it must be one of IPython's valid color schemes. If not given, the
99 use, it must be one of IPython's valid color schemes. If not given, the
100 function will default to the current IPython scheme when running inside
100 function will default to the current IPython scheme when running inside
101 IPython, and to 'NoColor' otherwise.
101 IPython, and to 'NoColor' otherwise.
102
102
103 Usage example:
103 Usage example:
104
104
105 from IPython.Debugger import Tracer; debug_here = Tracer()
105 from IPython.Debugger import Tracer; debug_here = Tracer()
106
106
107 ... later in your code
107 ... later in your code
108 debug_here() # -> will open up the debugger at that point.
108 debug_here() # -> will open up the debugger at that point.
109
109
110 Once the debugger activates, you can use all of its regular commands to
110 Once the debugger activates, you can use all of its regular commands to
111 step through code, set breakpoints, etc. See the pdb documentation
111 step through code, set breakpoints, etc. See the pdb documentation
112 from the Python standard library for usage details.
112 from the Python standard library for usage details.
113 """
113 """
114
114
115 global __IPYTHON__
115 global __IPYTHON__
116 try:
116 try:
117 __IPYTHON__
117 __IPYTHON__
118 except NameError:
118 except NameError:
119 # Outside of ipython, we set our own exception hook manually
119 # Outside of ipython, we set our own exception hook manually
120 __IPYTHON__ = ipapi.get(True,False)
120 __IPYTHON__ = ipapi.get(True,False)
121 BdbQuit_excepthook.excepthook_ori = sys.excepthook
121 BdbQuit_excepthook.excepthook_ori = sys.excepthook
122 sys.excepthook = BdbQuit_excepthook
122 sys.excepthook = BdbQuit_excepthook
123 def_colors = 'NoColor'
123 def_colors = 'NoColor'
124 try:
124 try:
125 # Limited tab completion support
125 # Limited tab completion support
126 import rlcompleter,readline
126 import rlcompleter,readline
127 readline.parse_and_bind('tab: complete')
127 readline.parse_and_bind('tab: complete')
128 except ImportError:
128 except ImportError:
129 pass
129 pass
130 else:
130 else:
131 # In ipython, we use its custom exception handler mechanism
131 # In ipython, we use its custom exception handler mechanism
132 ip = ipapi.get()
132 ip = ipapi.get()
133 def_colors = ip.options.colors
133 def_colors = ip.options.colors
134 ip.set_custom_exc((bdb.BdbQuit,),BdbQuit_IPython_excepthook)
134 ip.set_custom_exc((bdb.BdbQuit,),BdbQuit_IPython_excepthook)
135
135
136 if colors is None:
136 if colors is None:
137 colors = def_colors
137 colors = def_colors
138 self.debugger = Pdb(colors)
138 self.debugger = Pdb(colors)
139
139
140 def __call__(self):
140 def __call__(self):
141 """Starts an interactive debugger at the point where called.
141 """Starts an interactive debugger at the point where called.
142
142
143 This is similar to the pdb.set_trace() function from the std lib, but
143 This is similar to the pdb.set_trace() function from the std lib, but
144 using IPython's enhanced debugger."""
144 using IPython's enhanced debugger."""
145
145
146 self.debugger.set_trace(sys._getframe().f_back)
146 self.debugger.set_trace(sys._getframe().f_back)
147
147
148 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
148 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
149 """Make new_fn have old_fn's doc string. This is particularly useful
149 """Make new_fn have old_fn's doc string. This is particularly useful
150 for the do_... commands that hook into the help system.
150 for the do_... commands that hook into the help system.
151 Adapted from from a comp.lang.python posting
151 Adapted from from a comp.lang.python posting
152 by Duncan Booth."""
152 by Duncan Booth."""
153 def wrapper(*args, **kw):
153 def wrapper(*args, **kw):
154 return new_fn(*args, **kw)
154 return new_fn(*args, **kw)
155 if old_fn.__doc__:
155 if old_fn.__doc__:
156 wrapper.__doc__ = old_fn.__doc__ + additional_text
156 wrapper.__doc__ = old_fn.__doc__ + additional_text
157 return wrapper
157 return wrapper
158
158
159 def _file_lines(fname):
159 def _file_lines(fname):
160 """Return the contents of a named file as a list of lines.
160 """Return the contents of a named file as a list of lines.
161
161
162 This function never raises an IOError exception: if the file can't be
162 This function never raises an IOError exception: if the file can't be
163 read, it simply returns an empty list."""
163 read, it simply returns an empty list."""
164
164
165 try:
165 try:
166 outfile = open(fname)
166 outfile = open(fname)
167 except IOError:
167 except IOError:
168 return []
168 return []
169 else:
169 else:
170 out = outfile.readlines()
170 out = outfile.readlines()
171 outfile.close()
171 outfile.close()
172 return out
172 return out
173
173
174 class Pdb(OldPdb):
174 class Pdb(OldPdb):
175 """Modified Pdb class, does not load readline."""
175 """Modified Pdb class, does not load readline."""
176
176
177 if sys.version[:3] >= '2.5' or has_pydb:
177 if sys.version[:3] >= '2.5' or has_pydb:
178 def __init__(self,color_scheme='NoColor',completekey=None,
178 def __init__(self,color_scheme='NoColor',completekey=None,
179 stdin=None, stdout=None):
179 stdin=None, stdout=None):
180
180
181 # Parent constructor:
181 # Parent constructor:
182 if has_pydb and completekey is None:
182 if has_pydb and completekey is None:
183 OldPdb.__init__(self,stdin=stdin,stdout=Term.cout)
183 OldPdb.__init__(self,stdin=stdin,stdout=Term.cout)
184 else:
184 else:
185 OldPdb.__init__(self,completekey,stdin,stdout)
185 OldPdb.__init__(self,completekey,stdin,stdout)
186
186
187 self.prompt = prompt # The default prompt is '(Pdb)'
187 self.prompt = prompt # The default prompt is '(Pdb)'
188
188
189 # IPython changes...
189 # IPython changes...
190 self.is_pydb = has_pydb
190 self.is_pydb = has_pydb
191
191
192 if self.is_pydb:
192 if self.is_pydb:
193
193
194 # iplib.py's ipalias seems to want pdb's checkline
194 # iplib.py's ipalias seems to want pdb's checkline
195 # which located in pydb.fn
195 # which located in pydb.fn
196 import pydb.fns
196 import pydb.fns
197 self.checkline = lambda filename, lineno: \
197 self.checkline = lambda filename, lineno: \
198 pydb.fns.checkline(self, filename, lineno)
198 pydb.fns.checkline(self, filename, lineno)
199
199
200 self.curframe = None
200 self.curframe = None
201 self.do_restart = self.new_do_restart
201 self.do_restart = self.new_do_restart
202
202
203 self.old_all_completions = __IPYTHON__.Completer.all_completions
203 self.old_all_completions = __IPYTHON__.Completer.all_completions
204 __IPYTHON__.Completer.all_completions=self.all_completions
204 __IPYTHON__.Completer.all_completions=self.all_completions
205
205
206 self.do_list = decorate_fn_with_doc(self.list_command_pydb,
206 self.do_list = decorate_fn_with_doc(self.list_command_pydb,
207 OldPdb.do_list)
207 OldPdb.do_list)
208 self.do_l = self.do_list
208 self.do_l = self.do_list
209 self.do_frame = decorate_fn_with_doc(self.new_do_frame,
209 self.do_frame = decorate_fn_with_doc(self.new_do_frame,
210 OldPdb.do_frame)
210 OldPdb.do_frame)
211
211
212 self.aliases = {}
212 self.aliases = {}
213
213
214 # Create color table: we copy the default one from the traceback
214 # Create color table: we copy the default one from the traceback
215 # module and add a few attributes needed for debugging
215 # module and add a few attributes needed for debugging
216 self.color_scheme_table = ExceptionColors.copy()
216 self.color_scheme_table = ExceptionColors.copy()
217
217
218 # shorthands
218 # shorthands
219 C = ColorANSI.TermColors
219 C = ColorANSI.TermColors
220 cst = self.color_scheme_table
220 cst = self.color_scheme_table
221
221
222 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
222 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
223 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
223 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
224
224
225 cst['Linux'].colors.breakpoint_enabled = C.LightRed
225 cst['Linux'].colors.breakpoint_enabled = C.LightRed
226 cst['Linux'].colors.breakpoint_disabled = C.Red
226 cst['Linux'].colors.breakpoint_disabled = C.Red
227
227
228 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
228 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
229 cst['LightBG'].colors.breakpoint_disabled = C.Red
229 cst['LightBG'].colors.breakpoint_disabled = C.Red
230
230
231 self.set_colors(color_scheme)
231 self.set_colors(color_scheme)
232
232
233 # Add a python parser so we can syntax highlight source while
233 # Add a python parser so we can syntax highlight source while
234 # debugging.
234 # debugging.
235 self.parser = PyColorize.Parser()
235 self.parser = PyColorize.Parser()
236
236
237
237
238 else:
238 else:
239 # Ugly hack: for Python 2.3-2.4, we can't call the parent constructor,
239 # Ugly hack: for Python 2.3-2.4, we can't call the parent constructor,
240 # because it binds readline and breaks tab-completion. This means we
240 # because it binds readline and breaks tab-completion. This means we
241 # have to COPY the constructor here.
241 # have to COPY the constructor here.
242 def __init__(self,color_scheme='NoColor'):
242 def __init__(self,color_scheme='NoColor'):
243 bdb.Bdb.__init__(self)
243 bdb.Bdb.__init__(self)
244 cmd.Cmd.__init__(self,completekey=None) # don't load readline
244 cmd.Cmd.__init__(self,completekey=None) # don't load readline
245 self.prompt = 'ipdb> ' # The default prompt is '(Pdb)'
245 self.prompt = 'ipdb> ' # The default prompt is '(Pdb)'
246 self.aliases = {}
246 self.aliases = {}
247
247
248 # These two lines are part of the py2.4 constructor, let's put them
248 # These two lines are part of the py2.4 constructor, let's put them
249 # unconditionally here as they won't cause any problems in 2.3.
249 # unconditionally here as they won't cause any problems in 2.3.
250 self.mainpyfile = ''
250 self.mainpyfile = ''
251 self._wait_for_mainpyfile = 0
251 self._wait_for_mainpyfile = 0
252
252
253 # Read $HOME/.pdbrc and ./.pdbrc
253 # Read $HOME/.pdbrc and ./.pdbrc
254 try:
254 try:
255 self.rcLines = _file_lines(os.path.join(os.environ['HOME'],
255 self.rcLines = _file_lines(os.path.join(os.environ['HOME'],
256 ".pdbrc"))
256 ".pdbrc"))
257 except KeyError:
257 except KeyError:
258 self.rcLines = []
258 self.rcLines = []
259 self.rcLines.extend(_file_lines(".pdbrc"))
259 self.rcLines.extend(_file_lines(".pdbrc"))
260
260
261 # Create color table: we copy the default one from the traceback
261 # Create color table: we copy the default one from the traceback
262 # module and add a few attributes needed for debugging
262 # module and add a few attributes needed for debugging
263 ExceptionColors.set_active_scheme(color_scheme)
263 ExceptionColors.set_active_scheme(color_scheme)
264 self.color_scheme_table = ExceptionColors.copy()
264 self.color_scheme_table = ExceptionColors.copy()
265
265
266 # shorthands
266 # shorthands
267 C = ColorANSI.TermColors
267 C = ColorANSI.TermColors
268 cst = self.color_scheme_table
268 cst = self.color_scheme_table
269
269
270 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
270 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
271 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
271 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
272
272
273 cst['Linux'].colors.breakpoint_enabled = C.LightRed
273 cst['Linux'].colors.breakpoint_enabled = C.LightRed
274 cst['Linux'].colors.breakpoint_disabled = C.Red
274 cst['Linux'].colors.breakpoint_disabled = C.Red
275
275
276 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
276 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
277 cst['LightBG'].colors.breakpoint_disabled = C.Red
277 cst['LightBG'].colors.breakpoint_disabled = C.Red
278
278
279 self.set_colors(color_scheme)
279 self.set_colors(color_scheme)
280
280
281 # Add a python parser so we can syntax highlight source while
281 # Add a python parser so we can syntax highlight source while
282 # debugging.
282 # debugging.
283 self.parser = PyColorize.Parser()
283 self.parser = PyColorize.Parser()
284
284
285 def set_colors(self, scheme):
285 def set_colors(self, scheme):
286 """Shorthand access to the color table scheme selector method."""
286 """Shorthand access to the color table scheme selector method."""
287 self.color_scheme_table.set_active_scheme(scheme)
287 self.color_scheme_table.set_active_scheme(scheme)
288
288
289 def interaction(self, frame, traceback):
289 def interaction(self, frame, traceback):
290 __IPYTHON__.set_completer_frame(frame)
290 __IPYTHON__.set_completer_frame(frame)
291 OldPdb.interaction(self, frame, traceback)
291 OldPdb.interaction(self, frame, traceback)
292
292
293 def new_do_up(self, arg):
293 def new_do_up(self, arg):
294 OldPdb.do_up(self, arg)
294 OldPdb.do_up(self, arg)
295 __IPYTHON__.set_completer_frame(self.curframe)
295 __IPYTHON__.set_completer_frame(self.curframe)
296 do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up)
296 do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up)
297
297
298 def new_do_down(self, arg):
298 def new_do_down(self, arg):
299 OldPdb.do_down(self, arg)
299 OldPdb.do_down(self, arg)
300 __IPYTHON__.set_completer_frame(self.curframe)
300 __IPYTHON__.set_completer_frame(self.curframe)
301
301
302 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)
303
303
304 def new_do_frame(self, arg):
304 def new_do_frame(self, arg):
305 OldPdb.do_frame(self, arg)
305 OldPdb.do_frame(self, arg)
306 __IPYTHON__.set_completer_frame(self.curframe)
306 __IPYTHON__.set_completer_frame(self.curframe)
307
307
308 def new_do_quit(self, arg):
308 def new_do_quit(self, arg):
309
309
310 if hasattr(self, 'old_all_completions'):
310 if hasattr(self, 'old_all_completions'):
311 __IPYTHON__.Completer.all_completions=self.old_all_completions
311 __IPYTHON__.Completer.all_completions=self.old_all_completions
312
312
313
313
314 return OldPdb.do_quit(self, arg)
314 return OldPdb.do_quit(self, arg)
315
315
316 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
316 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
317
317
318 def new_do_restart(self, arg):
318 def new_do_restart(self, arg):
319 """Restart command. In the context of ipython this is exactly the same
319 """Restart command. In the context of ipython this is exactly the same
320 thing as 'quit'."""
320 thing as 'quit'."""
321 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
321 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
322 return self.do_quit(arg)
322 return self.do_quit(arg)
323
323
324 def postloop(self):
324 def postloop(self):
325 __IPYTHON__.set_completer_frame(None)
325 __IPYTHON__.set_completer_frame(None)
326
326
327 def print_stack_trace(self):
327 def print_stack_trace(self):
328 try:
328 try:
329 for frame_lineno in self.stack:
329 for frame_lineno in self.stack:
330 self.print_stack_entry(frame_lineno, context = 5)
330 self.print_stack_entry(frame_lineno, context = 5)
331 except KeyboardInterrupt:
331 except KeyboardInterrupt:
332 pass
332 pass
333
333
334 def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ',
334 def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ',
335 context = 3):
335 context = 3):
336 #frame, lineno = frame_lineno
336 #frame, lineno = frame_lineno
337 print >>Term.cout, self.format_stack_entry(frame_lineno, '', context)
337 print >>Term.cout, self.format_stack_entry(frame_lineno, '', context)
338
338
339 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
339 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
340 import linecache, repr
340 import linecache, repr
341
341
342 ret = []
342 ret = []
343
343
344 Colors = self.color_scheme_table.active_colors
344 Colors = self.color_scheme_table.active_colors
345 ColorsNormal = Colors.Normal
345 ColorsNormal = Colors.Normal
346 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
346 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
347 tpl_call = '%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
347 tpl_call = '%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
348 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
348 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
349 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
349 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
350 ColorsNormal)
350 ColorsNormal)
351
351
352 frame, lineno = frame_lineno
352 frame, lineno = frame_lineno
353
353
354 return_value = ''
354 return_value = ''
355 if '__return__' in frame.f_locals:
355 if '__return__' in frame.f_locals:
356 rv = frame.f_locals['__return__']
356 rv = frame.f_locals['__return__']
357 #return_value += '->'
357 #return_value += '->'
358 return_value += repr.repr(rv) + '\n'
358 return_value += repr.repr(rv) + '\n'
359 ret.append(return_value)
359 ret.append(return_value)
360
360
361 #s = filename + '(' + `lineno` + ')'
361 #s = filename + '(' + `lineno` + ')'
362 filename = self.canonic(frame.f_code.co_filename)
362 filename = self.canonic(frame.f_code.co_filename)
363 link = tpl_link % filename
363 link = tpl_link % filename
364
364
365 if frame.f_code.co_name:
365 if frame.f_code.co_name:
366 func = frame.f_code.co_name
366 func = frame.f_code.co_name
367 else:
367 else:
368 func = "<lambda>"
368 func = "<lambda>"
369
369
370 call = ''
370 call = ''
371 if func != '?':
371 if func != '?':
372 if '__args__' in frame.f_locals:
372 if '__args__' in frame.f_locals:
373 args = repr.repr(frame.f_locals['__args__'])
373 args = repr.repr(frame.f_locals['__args__'])
374 else:
374 else:
375 args = '()'
375 args = '()'
376 call = tpl_call % (func, args)
376 call = tpl_call % (func, args)
377
377
378 # The level info should be generated in the same format pdb uses, to
378 # The level info should be generated in the same format pdb uses, to
379 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
379 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
380 if frame is self.curframe:
380 if frame is self.curframe:
381 ret.append('> ')
381 ret.append('> ')
382 else:
382 else:
383 ret.append(' ')
383 ret.append(' ')
384 ret.append('%s(%s)%s\n' % (link,lineno,call))
384 ret.append('%s(%s)%s\n' % (link,lineno,call))
385
385
386 start = lineno - 1 - context//2
386 start = lineno - 1 - context//2
387 lines = linecache.getlines(filename)
387 lines = linecache.getlines(filename)
388 start = max(start, 0)
388 start = max(start, 0)
389 start = min(start, len(lines) - context)
389 start = min(start, len(lines) - context)
390 lines = lines[start : start + context]
390 lines = lines[start : start + context]
391
391
392 for i,line in enumerate(lines):
392 for i,line in enumerate(lines):
393 show_arrow = (start + 1 + i == lineno)
393 show_arrow = (start + 1 + i == lineno)
394 linetpl = (frame is self.curframe or show_arrow) \
394 linetpl = (frame is self.curframe or show_arrow) \
395 and tpl_line_em \
395 and tpl_line_em \
396 or tpl_line
396 or tpl_line
397 ret.append(self.__format_line(linetpl, filename,
397 ret.append(self.__format_line(linetpl, filename,
398 start + 1 + i, line,
398 start + 1 + i, line,
399 arrow = show_arrow) )
399 arrow = show_arrow) )
400
400
401 return ''.join(ret)
401 return ''.join(ret)
402
402
403 def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
403 def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
404 bp_mark = ""
404 bp_mark = ""
405 bp_mark_color = ""
405 bp_mark_color = ""
406
406
407 scheme = self.color_scheme_table.active_scheme_name
407 scheme = self.color_scheme_table.active_scheme_name
408 new_line, err = self.parser.format2(line, 'str', scheme)
408 new_line, err = self.parser.format2(line, 'str', scheme)
409 if not err: line = new_line
409 if not err: line = new_line
410
410
411 bp = None
411 bp = None
412 if lineno in self.get_file_breaks(filename):
412 if lineno in self.get_file_breaks(filename):
413 bps = self.get_breaks(filename, lineno)
413 bps = self.get_breaks(filename, lineno)
414 bp = bps[-1]
414 bp = bps[-1]
415
415
416 if bp:
416 if bp:
417 Colors = self.color_scheme_table.active_colors
417 Colors = self.color_scheme_table.active_colors
418 bp_mark = str(bp.number)
418 bp_mark = str(bp.number)
419 bp_mark_color = Colors.breakpoint_enabled
419 bp_mark_color = Colors.breakpoint_enabled
420 if not bp.enabled:
420 if not bp.enabled:
421 bp_mark_color = Colors.breakpoint_disabled
421 bp_mark_color = Colors.breakpoint_disabled
422
422
423 numbers_width = 7
423 numbers_width = 7
424 if arrow:
424 if arrow:
425 # This is the line with the error
425 # This is the line with the error
426 pad = numbers_width - len(str(lineno)) - len(bp_mark)
426 pad = numbers_width - len(str(lineno)) - len(bp_mark)
427 if pad >= 3:
427 if pad >= 3:
428 marker = '-'*(pad-3) + '-> '
428 marker = '-'*(pad-3) + '-> '
429 elif pad == 2:
429 elif pad == 2:
430 marker = '> '
430 marker = '> '
431 elif pad == 1:
431 elif pad == 1:
432 marker = '>'
432 marker = '>'
433 else:
433 else:
434 marker = ''
434 marker = ''
435 num = '%s%s' % (marker, str(lineno))
435 num = '%s%s' % (marker, str(lineno))
436 line = tpl_line % (bp_mark_color + bp_mark, num, line)
436 line = tpl_line % (bp_mark_color + bp_mark, num, line)
437 else:
437 else:
438 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
438 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
439 line = tpl_line % (bp_mark_color + bp_mark, num, line)
439 line = tpl_line % (bp_mark_color + bp_mark, num, line)
440
440
441 return line
441 return line
442
442
443 def list_command_pydb(self, arg):
443 def list_command_pydb(self, arg):
444 """List command to use if we have a newer pydb installed"""
444 """List command to use if we have a newer pydb installed"""
445 filename, first, last = OldPdb.parse_list_cmd(self, arg)
445 filename, first, last = OldPdb.parse_list_cmd(self, arg)
446 if filename is not None:
446 if filename is not None:
447 self.print_list_lines(filename, first, last)
447 self.print_list_lines(filename, first, last)
448
448
449 def print_list_lines(self, filename, first, last):
449 def print_list_lines(self, filename, first, last):
450 """The printing (as opposed to the parsing part of a 'list'
450 """The printing (as opposed to the parsing part of a 'list'
451 command."""
451 command."""
452 try:
452 try:
453 Colors = self.color_scheme_table.active_colors
453 Colors = self.color_scheme_table.active_colors
454 ColorsNormal = Colors.Normal
454 ColorsNormal = Colors.Normal
455 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
455 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
456 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
456 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
457 src = []
457 src = []
458 for lineno in range(first, last+1):
458 for lineno in range(first, last+1):
459 line = linecache.getline(filename, lineno)
459 line = linecache.getline(filename, lineno)
460 if not line:
460 if not line:
461 break
461 break
462
462
463 if lineno == self.curframe.f_lineno:
463 if lineno == self.curframe.f_lineno:
464 line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
464 line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
465 else:
465 else:
466 line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
466 line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
467
467
468 src.append(line)
468 src.append(line)
469 self.lineno = lineno
469 self.lineno = lineno
470
470
471 print >>Term.cout, ''.join(src)
471 print >>Term.cout, ''.join(src)
472
472
473 except KeyboardInterrupt:
473 except KeyboardInterrupt:
474 pass
474 pass
475
475
476 def do_list(self, arg):
476 def do_list(self, arg):
477 self.lastcmd = 'list'
477 self.lastcmd = 'list'
478 last = None
478 last = None
479 if arg:
479 if arg:
480 try:
480 try:
481 x = eval(arg, {}, {})
481 x = eval(arg, {}, {})
482 if type(x) == type(()):
482 if type(x) == type(()):
483 first, last = x
483 first, last = x
484 first = int(first)
484 first = int(first)
485 last = int(last)
485 last = int(last)
486 if last < first:
486 if last < first:
487 # Assume it's a count
487 # Assume it's a count
488 last = first + last
488 last = first + last
489 else:
489 else:
490 first = max(1, int(x) - 5)
490 first = max(1, int(x) - 5)
491 except:
491 except:
492 print '*** Error in argument:', `arg`
492 print '*** Error in argument:', `arg`
493 return
493 return
494 elif self.lineno is None:
494 elif self.lineno is None:
495 first = max(1, self.curframe.f_lineno - 5)
495 first = max(1, self.curframe.f_lineno - 5)
496 else:
496 else:
497 first = self.lineno + 1
497 first = self.lineno + 1
498 if last is None:
498 if last is None:
499 last = first + 10
499 last = first + 10
500 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
500 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
501
501
502 do_l = do_list
502 do_l = do_list
503
503
504 def do_pdef(self, arg):
504 def do_pdef(self, arg):
505 """The debugger interface to magic_pdef"""
505 """The debugger interface to magic_pdef"""
506 namespaces = [('Locals', self.curframe.f_locals),
506 namespaces = [('Locals', self.curframe.f_locals),
507 ('Globals', self.curframe.f_globals)]
507 ('Globals', self.curframe.f_globals)]
508 __IPYTHON__.magic_pdef(arg, namespaces=namespaces)
508 __IPYTHON__.magic_pdef(arg, namespaces=namespaces)
509
509
510 def do_pdoc(self, arg):
510 def do_pdoc(self, arg):
511 """The debugger interface to magic_pdoc"""
511 """The debugger interface to magic_pdoc"""
512 namespaces = [('Locals', self.curframe.f_locals),
512 namespaces = [('Locals', self.curframe.f_locals),
513 ('Globals', self.curframe.f_globals)]
513 ('Globals', self.curframe.f_globals)]
514 __IPYTHON__.magic_pdoc(arg, namespaces=namespaces)
514 __IPYTHON__.magic_pdoc(arg, namespaces=namespaces)
515
515
516 def do_pinfo(self, arg):
516 def do_pinfo(self, arg):
517 """The debugger equivalant of ?obj"""
517 """The debugger equivalant of ?obj"""
518 namespaces = [('Locals', self.curframe.f_locals),
518 namespaces = [('Locals', self.curframe.f_locals),
519 ('Globals', self.curframe.f_globals)]
519 ('Globals', self.curframe.f_globals)]
520 __IPYTHON__.magic_pinfo("pinfo %s" % arg, namespaces=namespaces)
520 __IPYTHON__.magic_pinfo("pinfo %s" % arg, namespaces=namespaces)
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now