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 bigger? I'd think it would be configurable, but haven't开发者_如何学C been able to find it.
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 l
s reveal further lines below your breakpoint).
You can get more context by doing:
ipdb.set_trace(context=21)
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.
easy way to do this - 2022
- figure out where you're loading ipdb from
import ipdb
print(ipdb.__file__)
- open
__main__.py
from that folder - search for
except (configparser.NoSectionError, configparser.NoOptionError):
- below it is 3. Change that to your desired value
Why this is better than the proper way:
- I don't need to learn a new configuration language
- I don't need to create a new configfile
- I don't need to debug why my configfile isn't being picked up
- you never get tricked by file scoping/permissions/visibility since you are sure which ipdb module is being loaded (i.e. it covers virtualenvs too)
- I don't have to talk to upstream and try to convince them to adopt this default.
There are several ways to configure it without changing any code.
If you want to have a persistent setting in your shell, you can use IPDB_CONTEXT_SIZE
variable. Add the following to your .bashrc
/.zshrc
/etc.:
export IPDB_CONTEXT_SIZE=10
Thanks to N1ngu for pointing this out.
Keep in mind though, that this is implemented in ipdb
itself, not in IPython
, so while it will work when used with ipdb.set_trace()
, it doesn't apply to the %debug
magic.
Starting with IPython 7.21 you can also use context
command in ipdb to change the number of backtrace lines shown:
import ipdb; ipdb.set_trace()
...
ipdb> context 10
ipdb> bt
You can put the following line in ~/.ipdb
to make ipdb set it automatically:
context = 10
Apart from that, there's also the old context=
argument in set_trace()
, which makes it possible to set it at the time of running the debugger:
import ipdb; ipdb.set_trace(context=10)
# or, if you've set PYTHONBREAKPOINT=ipdb.set_trace in your environment
breakpoint(context=10)
Edit: it was implemented: https://stackoverflow.com/a/66474153/895245
As a quick complement to this other answer 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
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
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.
Following the @erock618 way, in more recent ipdb versions you can use:
debugger_cls = ipdb.__main__._get_debugger_cls()
精彩评论