From 473fcf095f2d0df34e4ec2b673b93eccd1f0e1f3 2013-01-13 22:19:42 From: Owen Healy Date: 2013-01-13 22:19:42 Subject: [PATCH] Allow the %run magic with '-b' to specify a file. The syntax would be: %run -d -b file2.py:30 file1.py to break at line 30 of file2.py when running file1.py. The old syntax %run -d -b 20 file1.py still works the way it used to. Suggested by user gozzilli on StackOverflow (http://stackoverflow.com/questions/14305203/ipython-set-a-breakpoint-in-imported-file/). --- diff --git a/IPython/core/magics/execution.py b/IPython/core/magics/execution.py index cd974a1..9a11cab 100644 --- a/IPython/core/magics/execution.py +++ b/IPython/core/magics/execution.py @@ -414,6 +414,10 @@ python-profiler package from non-free.""") the first breakpoint must be set on a line which actually does something (not a comment or docstring) for it to stop execution. + Or you can specify a breakpoint in a different file:: + + %run -d -b myotherfile.py:20 myscript + When the pdb debugger starts, you will see a (Pdb) prompt. You must first enter 'c' (without quotes) to start execution up to the first breakpoint. @@ -551,11 +555,11 @@ python-profiler package from non-free.""") bdb.Breakpoint.bpbynumber = [None] # Set an initial breakpoint to stop execution maxtries = 10 - bp = int(opts.get('b', [1])[0]) - checkline = deb.checkline(filename, bp) + bp_file, bp_line = parse_breakpoint(opts.get('b', [1])[0], filename) + checkline = deb.checkline(bp_file, bp_line) if not checkline: - for bp in range(bp + 1, bp + maxtries + 1): - if deb.checkline(filename, bp): + for bp in range(bp_line + 1, bp_line + maxtries + 1): + if deb.checkline(bp_file, bp): break else: msg = ("\nI failed to find a valid line to set " @@ -566,7 +570,7 @@ python-profiler package from non-free.""") error(msg) return # if we find a good linenumber, set the breakpoint - deb.do_break('%s:%s' % (filename, bp)) + deb.do_break('%s:%s' % (bp_file, bp_line)) # Mimic Pdb._runscript(...) deb._wait_for_mainpyfile = True @@ -578,7 +582,7 @@ python-profiler package from non-free.""") ns = {'execfile': py3compat.execfile, 'prog_ns': prog_ns} try: #save filename so it can be used by methods on the deb object - deb._exec_filename = filename + deb._exec_filename = bp_file deb.run('execfile("%s", prog_ns)' % filename, ns) except: @@ -1079,3 +1083,11 @@ python-profiler package from non-free.""") self.shell.run_cell(cell) if args.output: self.shell.user_ns[args.output] = io + +def parse_breakpoint(text, current_file): + '''Returns (file, line) for file:line and (current_file, line) for line''' + colon = text.find(':') + if colon == -1: + return current_file, int(text) + else: + return text[:colon], int(text[colon+1:])