{"id":171,"date":"2015-06-11T16:45:24","date_gmt":"2015-06-11T08:45:24","guid":{"rendered":"http:\/\/vinta.ws\/code\/?p=171"},"modified":"2026-03-17T01:20:46","modified_gmt":"2026-03-16T17:20:46","slug":"ipdb-interactive-python-debugger-with-ipython","status":"publish","type":"post","link":"https:\/\/vinta.ws\/code\/ipdb-interactive-python-debugger-with-ipython.html","title":{"rendered":"ipdb: The interactive Python debugger with IPython"},"content":{"rendered":"<p>ipdb is an interactive Python Debugger with IPython integration, which features tab completion and syntax highlighting, etc. In layman's terms, ipdb is a better pdb.<\/p>\n<p>ref:<br \/>\n<a href=\"https:\/\/github.com\/gotcha\/ipdb\">https:\/\/github.com\/gotcha\/ipdb<\/a><\/p>\n<h2>Usage<\/h2>\n<pre class=\"line-numbers\"><code class=\"language-bash\">$ pip install -U ipdb<\/code><\/pre>\n<p>ref:<br \/>\n<a href=\"https:\/\/pypi.python.org\/pypi\/ipdb\">https:\/\/pypi.python.org\/pypi\/ipdb<\/a><\/p>\n<p>Add a breakpoint to any place you want to inspect, then run your code.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-py\">import ipdb; ipdb.set_trace()<\/code><\/pre>\n<p>If you use Sublime Text 3, try Python Breakpoints.<br \/>\n<a href=\"https:\/\/github.com\/obormot\/PythonBreakpoints\">https:\/\/github.com\/obormot\/PythonBreakpoints<\/a><\/p>\n<h3>Useful Commands<\/h3>\n<p>Oldest frame is the frame in the stack where your program started; it is the oldest in time; the Newest frame, the other end of the stack, is where Python is executing code and is the current frame of execution.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-py\"># help: Print the list of all commands\nh\n\n# help: Print help about the certain command\nh break\n\n# print: Print the value of the expression\np some_obj\npp some_obj\n\n# Print detailed information about the object\npinfo some_obj\npinfo2 some_obj\n\n# args: Print arguments with their values of the current function\na\n\n# list: List 11 lines of source code around the current line\nl\n\n# list: List 11 lines of source code around line 123\nl 123\n\n# longlist: List all source code for the current function or frame\nll\n\n# jump: Jump to line 123, skip the execution of anything between\nj 123\n\n# args: List all arguments of the current function\na\n\n# step: Execute code line by line, it may jump to another frame when a function call is encountered\ns\n\n# next: Execute code line by line, it doesn't enter functions called from the statement being executed\nn\n\n# return: Continue execution until the current function returns.\nr\n\n# continue: Continue execution, only stop when a breakpoint is encountered\nc\n\n# break: List all breakpoints\nb\n\n# break: Set a breakpoint at line 123\nb 123\n\n# break: Set a breakpoint at line 123 of file.py\nb path\/to\/file.py:123\n\n# break: Set a breakpoint on some_func that will be triggered if some_arg == 0\nb some_func, some_arg == 0\n\n# clear: Clear all breakpoints\nclear\n\n# where: Print a stack trace\nw\n\n# up: Move the current frame one level up in the stack trace\nu\n\n# down: Move the current frame one level down in the stack trace\nd\n\n# quit: Quit debugging\nq\n\n# use ! to run Python code that may conflict with pdb's built-in commands\n!r = 123\n!r = 123; c = 455<\/code><\/pre>\n<p>ref:<br \/>\n<a href=\"https:\/\/docs.python.org\/2\/library\/pdb.html#debugger-commands\">https:\/\/docs.python.org\/2\/library\/pdb.html#debugger-commands<\/a><br \/>\n<a href=\"https:\/\/docs.python.org\/3\/library\/pdb.html#debugger-commands\">https:\/\/docs.python.org\/3\/library\/pdb.html#debugger-commands<\/a><br \/>\n<a href=\"https:\/\/pymotw.com\/2\/pdb\/\">https:\/\/pymotw.com\/2\/pdb\/<\/a><br \/>\n<a href=\"https:\/\/pymotw.com\/3\/pdb\/\">https:\/\/pymotw.com\/3\/pdb\/<\/a><br \/>\n<a href=\"https:\/\/medium.com\/instamojo-matters\/become-a-pdb-power-user-e3fc4e2774b2\">https:\/\/medium.com\/instamojo-matters\/become-a-pdb-power-user-e3fc4e2774b2<\/a><\/p>\n<h3>post_mortem<\/h3>\n<p>Debugging a failure after a program terminates is called post-mortem debugging.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-py\">&gt;&gt;&gt; do_shit(a)\nTraceback (most recent call last):\n  File \"&lt;stdin&gt;\", line 1, in &lt;module&gt;\n  File \"pdb_post_mortem.py\", line 13, in go\n    for i in range(self.num_loops):\nAttributeError: 'MyObj' object has no attribute 'num_loops'\n&gt;&gt;&gt; import ipdb; ipdb.pm()\n&gt;&gt;&gt; w<\/code><\/pre>\n<h3>trace<\/h3>\n<p>Tracing a program as it runs. In this case, it will enter ipdb when <code>sys.path<\/code> changes.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-py\">import sys\n\n# this function will execute on every line!!!\ndef trace_sys_path(frame, event, arg):\n    if sys.path[0].endswith('\/lib'):\n        ipdb.set_trace()\n    return trace_sys_path\n\nsys.settrace(trace_sys_path)<\/code><\/pre>\n<p>ref:<br \/>\n<a href=\"https:\/\/youtu.be\/5XvAVgcbmdY?t=22m51s\">https:\/\/youtu.be\/5XvAVgcbmdY?t=22m51s<\/a><\/p>\n<h2>Use IPython magic functions in ipdb<\/h2>\n<p>Because ipdb is not a full IPython shell \u2014 it provides the same Python Debugger interface as pdb \u2014 ipdb lacks many features of IPython, for instance, magic functions. You could use the following code to enter a real IPython environment for debugging.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-py\">from IPython import embed; embed()<\/code><\/pre>\n<p>Instead of <code>import ipdb; ipdb.set_trace()<\/code>.<\/p>\n<p>ref:<br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/16184487\/use-ipython-magic-functions-in-ipdb-shell\">http:\/\/stackoverflow.com\/questions\/16184487\/use-ipython-magic-functions-in-ipdb-shell<\/a><br \/>\n<a href=\"https:\/\/github.com\/gotcha\/ipdb\/issues\/33\">https:\/\/github.com\/gotcha\/ipdb\/issues\/33<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>ipdb is an interactive Python Debugger with IPython integration, which features tab completion and syntax highlighting, etc. In layman's terms, ipdb is a better pdb.<\/p>\n","protected":false},"author":1,"featured_media":277,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[29,2],"class_list":["post-171","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-about-python","tag-debug","tag-python"],"_links":{"self":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/posts\/171","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/comments?post=171"}],"version-history":[{"count":0,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/posts\/171\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/media\/277"}],"wp:attachment":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/media?parent=171"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/categories?post=171"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/tags?post=171"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}