How can I make ipdb show more lines of context while debugging?

前端 未结 6 1876
慢半拍i
慢半拍i 2021-02-01 13:08

By default, during debugging in IPython, ipdb shows one line above and one line below the current position in code.

Is there an easy way to make the area shown a bit b

相关标签:
6条回答
  • 2021-02-01 13:35

    You can type l in ipdb to show a few more lines of the current context

    and you can keep hitting l and it continue revealing more lines from the file

    If you want to show more lines of context around the current line you can type l to get the current line. And then type l curr_line - 10, curr_line + 10. Say I was on line 50 and I wanted to see the surrounding 20 lines. I would type: l 40,60 to see more.

    As noted by @jrieke in a comment, you can also hit ll to get a bigger chunk of context. One nice thing about ll is it will print all the way back from the start of the current method (whereas consecutive ls reveal further lines below your breakpoint).

    0 讨论(0)
  • 2021-02-01 13:35

    OK, I found the place in the IPython source code to do this. In my installation it's at

    .../python2.7/site-packages/ipython-0.10.2-py2.7.egg/IPython/Debugger.py:327:
    

    Change this:

    def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ',
                          context = 3):
    

    to

    def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ',
                          context = 11):
    

    It is awesome!

    For IPython 4.0.1, in debugger.py just add this:

    class Pdb(OldPdb):
      """Modified Pdb class, does not load readline."""
    
      def __init__(self,color_scheme='NoColor',completekey=None,
                   stdin=None, stdout=None, context=None):
          context=20
    
    0 讨论(0)
  • 2021-02-01 13:37

    If you want to stop execution in a running system, as others said, use:

    ipdb.set_trace(context=number_of_lines)
    

    For running some function or an object's method modifying this context lines is a little bit tricky. The only way I found was:

    ipdb.__main__._init_pdb(context=number_of_lines).runcall(callable, *args, **kwargs)
    

    In case it serves someone.

    0 讨论(0)
  • 2021-02-01 13:52

    You can get more context by doing:

    ipdb.set_trace(context=21)
    

    (there's a bug introduced in 0.10.0 that breaks this, but it should be fixed soon)

    Permanent context size

    To permanently set context size, find the installation directory by doing

    python -c 'import ipdb; print(ipdb)'
    

    which will show you a __init__.py file. Open that file and find the line (which may also be found in IPDB's __main__.py:

    def set_trace(frame=None, context=3):
    

    change the 3 to however many context lines you want.

    0 讨论(0)
  • 2021-02-01 13:54

    As a quick complement to https://stackoverflow.com/a/35883288/895245 this is the one liner that you generally want to add to the code you want to debug:

    __import__('ipdb').set_trace(context=21)
    

    You likely want to add a shortcut for that from your editor, e.g. for Vim snipmat I have:

    snippet ipd
        __import__('ipdb').set_trace(context=21)
    

    so I can type just ipd<tab> and it expands to the breakpoint. Then removing it is easy with dd since everything is contained in a single line.

    Feature request for ipdb to increase the default context size: https://github.com/gotcha/ipdb/issues/147

    0 讨论(0)
  • 2021-02-01 13:58

    Here's a patch to permanently set context for your program:

    (works across set_trace and post_mortem)

    def ipdb_patch(context = 11):
        import ipdb
        ipdbmain = ipdb.__main__
        def _init_pdb(context=context, commands=[]):
            try              : p = ipdbmain.debugger_cls(context=context)
            except TypeError : p = ipdbmain.debugger_cls()
            p.rcLines.extend(commands)
            return p
        def set_trace(frame=None, context=context):
            ipdbmain.wrap_sys_excepthook()
            if frame is None : frame = ipdbmain.sys._getframe().f_back
            p = ipdbmain._init_pdb(context).set_trace(frame)
            if p and hasattr(p, 'shell') : p.shell.restore_sys_module_state()
        ipdbmain._init_pdb = _init_pdb
        ipdb.set_trace = set_trace
        return ipdb
    ipdb = ipdb_patch()
    

    to add breakpoint() functionality simply add:

    import sys
    sys.breakpointhook = ipdb.set_trace
    

    With that all the following commands have the right context size:

    ipdb.set_trace()
    breakpoint()
    ipdb.post_mortem()
    ipdb.pm()
    %debug
    

    It does not however work with this:

    In [1]: %run -d file.py
    

    If you know how to adjust that, please feel free to drop in comments

    0 讨论(0)
提交回复
热议问题