@@ -293,10 +293,31 @@ def pdb(self, parameter_s=''):
293
293
self .shell .call_pdb = new_pdb
294
294
print 'Automatic pdb calling has been turned' ,on_off (new_pdb )
295
295
296
- @line_magic
297
- def debug (self , parameter_s = '' ):
298
- """Activate the interactive debugger in post-mortem mode.
296
+ @skip_doctest
297
+ @magic_arguments .magic_arguments ()
298
+ @magic_arguments .argument ('--breakpoint' , '-b' , metavar = 'FILE:LINE' ,
299
+ help = """
300
+ Set break point at LINE in FILE.
301
+ """
302
+ )
303
+ @magic_arguments .argument ('statement' , nargs = '*' ,
304
+ help = """
305
+ Code to run in debugger.
306
+ You can omit this in cell magic mode.
307
+ """
308
+ )
309
+ @line_cell_magic
310
+ def debug (self , line = '' , cell = None ):
311
+ """Activate the interactive debugger.
312
+
313
+ This magic command support two ways of activating debugger.
314
+ One is to activate debugger before executing code. This way, you
315
+ can set a break point, to step through the code from the point.
316
+ You can use this mode by giving statements to execute and optionally
317
+ a breakpoint.
299
318
319
+ The other one is to activate debugger in post-mortem mode. You can
320
+ activate this mode simply running %debug without any argument.
300
321
If an exception has just occurred, this lets you inspect its stack
301
322
frames interactively. Note that this will always work only on the last
302
323
traceback that occurred, so you must call this quickly after an
@@ -306,8 +327,27 @@ def debug(self, parameter_s=''):
306
327
If you want IPython to automatically do this on every exception, see
307
328
the %pdb magic for more details.
308
329
"""
330
+ args = magic_arguments .parse_argstring (self .debug , line )
331
+
332
+ if not (args .breakpoint or args .statement or cell ):
333
+ self ._debug_post_mortem ()
334
+ else :
335
+ code = "\n " .join (args .statement )
336
+ if cell :
337
+ code += "\n " + cell
338
+ self ._debug_exec (code , args .breakpoint )
339
+
340
+ def _debug_post_mortem (self ):
309
341
self .shell .debugger (force = True )
310
342
343
+ def _debug_exec (self , code , breakpoint ):
344
+ if breakpoint :
345
+ (filename , bp_line ) = breakpoint .split (':' , 1 )
346
+ bp_line = int (bp_line )
347
+ else :
348
+ (filename , bp_line ) = (None , None )
349
+ self ._run_with_debugger (code , self .shell .user_ns , filename , bp_line )
350
+
311
351
@line_magic
312
352
def tb (self , s ):
313
353
"""Print the last traceback with the currently active exception mode.
@@ -563,8 +603,10 @@ def run(self, parameter_s='', runner=None,
563
603
stats = self ._run_with_profiler (code , opts , code_ns )
564
604
else :
565
605
if 'd' in opts :
606
+ bp_file , bp_line = parse_breakpoint (
607
+ opts .get ('b' , ['1' ])[0 ], filename )
566
608
self ._run_with_debugger (
567
- code , code_ns , opts . get ( 'b' , [ '1' ])[ 0 ], filename )
609
+ code , code_ns , filename , bp_line , bp_file )
568
610
else :
569
611
if 'm' in opts :
570
612
def run ():
@@ -628,7 +670,8 @@ def run():
628
670
629
671
return stats
630
672
631
- def _run_with_debugger (self , code , code_ns , break_point , filename ):
673
+ def _run_with_debugger (self , code , code_ns , filename = None ,
674
+ bp_line = None , bp_file = None ):
632
675
"""
633
676
Run `code` in debugger with a break point.
634
677
@@ -638,19 +681,18 @@ def _run_with_debugger(self, code, code_ns, break_point, filename):
638
681
Code to execute.
639
682
code_ns : dict
640
683
A namespace in which `code` is executed.
641
- break_point : str
642
- Line number in the file specified by `filename` argument
643
- or a string in the format ``file:line``. In the latter
644
- case, `filename` is ignored.
645
- See also :func:`.parse_breakpoint`.
646
684
filename : str
685
+ `code` is ran as if it is in `filename`.
686
+ bp_line : int, optional
687
+ Line number of the break point.
688
+ bp_file : str, optional
647
689
Path to the file in which break point is specified.
690
+ `filename` is used if not given.
648
691
649
692
Raises
650
693
------
651
694
UsageError
652
- If no meaningful break point is given by `break_point` and
653
- `filename`.
695
+ If the break point given by `bp_line` is not valid.
654
696
655
697
"""
656
698
deb = debugger .Pdb (self .shell .colors )
@@ -659,33 +701,36 @@ def _run_with_debugger(self, code, code_ns, break_point, filename):
659
701
bdb .Breakpoint .next = 1
660
702
bdb .Breakpoint .bplist = {}
661
703
bdb .Breakpoint .bpbynumber = [None ]
662
- # Set an initial breakpoint to stop execution
663
- maxtries = 10
664
- bp_file , bp_line = parse_breakpoint (break_point , filename )
665
- checkline = deb .checkline (bp_file , bp_line )
666
- if not checkline :
667
- for bp in range (bp_line + 1 , bp_line + maxtries + 1 ):
668
- if deb .checkline (bp_file , bp ):
669
- break
670
- else :
671
- msg = ("\n I failed to find a valid line to set "
672
- "a breakpoint\n "
673
- "after trying up to line: %s.\n "
674
- "Please set a valid breakpoint manually "
675
- "with the -b option." % bp )
676
- raise UsageError (msg )
677
- # if we find a good linenumber, set the breakpoint
678
- deb .do_break ('%s:%s' % (bp_file , bp_line ))
679
-
680
- # Mimic Pdb._runscript(...)
681
- deb ._wait_for_mainpyfile = True
682
- deb .mainpyfile = deb .canonic (filename )
704
+ if bp_line is not None :
705
+ # Set an initial breakpoint to stop execution
706
+ maxtries = 10
707
+ bp_file = bp_file or filename
708
+ checkline = deb .checkline (bp_file , bp_line )
709
+ if not checkline :
710
+ for bp in range (bp_line + 1 , bp_line + maxtries + 1 ):
711
+ if deb .checkline (bp_file , bp ):
712
+ break
713
+ else :
714
+ msg = ("\n I failed to find a valid line to set "
715
+ "a breakpoint\n "
716
+ "after trying up to line: %s.\n "
717
+ "Please set a valid breakpoint manually "
718
+ "with the -b option." % bp )
719
+ raise UsageError (msg )
720
+ # if we find a good linenumber, set the breakpoint
721
+ deb .do_break ('%s:%s' % (bp_file , bp_line ))
722
+
723
+ if filename :
724
+ # Mimic Pdb._runscript(...)
725
+ deb ._wait_for_mainpyfile = True
726
+ deb .mainpyfile = deb .canonic (filename )
683
727
684
728
# Start file run
685
729
print "NOTE: Enter 'c' at the %s prompt to continue execution." % deb .prompt
686
730
try :
687
- #save filename so it can be used by methods on the deb object
688
- deb ._exec_filename = filename
731
+ if filename :
732
+ # save filename so it can be used by methods on the deb object
733
+ deb ._exec_filename = filename
689
734
deb .run (code , code_ns )
690
735
691
736
except :
0 commit comments