Is it possible to go into ipython from code?
Asked Answered
C

13

85

For my debugging needs, pdb is pretty good. However, it would be much cooler (and helpful) if I could go into ipython. Is this thing possible?

Cupped answered 14/7, 2009 at 17:45 Comment(0)
G
117

There is an ipdb project which embeds iPython into the standard pdb, so you can just do:

import ipdb; ipdb.set_trace()

It's installable via the usual pip install ipdb.

ipdb is pretty short, so instead of easy_installing you can also create a file ipdb.py somewhere on your Python path and paste the following into the file:

import sys
from IPython.Debugger import Pdb
from IPython.Shell import IPShell
from IPython import ipapi

shell = IPShell(argv=[''])

def set_trace():
    ip = ipapi.get()
    def_colors = ip.options.colors
    Pdb(def_colors).set_trace(sys._getframe().f_back)
Gwennie answered 14/7, 2009 at 18:18 Comment(6)
Works amazingly well with Django. Well, except the fact that I can't see the text I'm typing, but that's probably easily fixible (since ipdb's only six lines).Fleabane
Actually, the issue there is that Django forks a separate thread for the runserver, and any time you make a code edit, it respawns the thread. This normally works fine, but if you're sitting in pdb when the thread gets killed, the terminal goes insane. You can fix this by breaking out of runserver, runniny 'stty sane', then starting runserver again.Gormley
@daniel-roseman Hi, I get ModuleNotFoundError: No module named 'IPython.Debugger', ModuleNotFoundError: No module named 'IPython.Shell' and ImportError: cannot import name 'ipapi'Fourth
@memoselyk Hi, I get ModuleNotFoundError: No module named 'IPython.Debugger', ModuleNotFoundError: No module named 'IPython.Shell' and ImportError: cannot import name 'ipapi'Fourth
There is a way to get the breakpoint() function to get into ipdb.Killjoy
@Killjoy use the environment variable PYTHONBREAKPOINTSubadar
A
60

In IPython 0.11, you can embed IPython directly in your code like this

Your program might look like this

In [5]: cat > tmpf.py
a = 1

from IPython import embed
embed() # drop into an IPython session.
        # Any variables you define or modify here
        # will not affect program execution

c = 2

^D

This is what happens when you run it (I arbitrarily chose to run it inside an existing ipython session. Nesting ipython sessions like this in my experience can cause it to crash).

In [6]:

In [6]: run tmpf.py
Python 2.7.2 (default, Aug 25 2011, 00:06:33)
Type "copyright", "credits" or "license" for more information.

IPython 0.11 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: who
a       embed

In [2]: a
Out[2]: 1

In [3]:
Do you really want to exit ([y]/n)? y


In [7]: who
a       c       embed
Adapa answered 14/9, 2011 at 5:0 Comment(7)
This dropping into an IPython session is very cool. Thank you so much!Morphophoneme
I foolishly placed this inside an (almost infinite) loop. How can I ever get out?Killjoy
@gerrit, press Ctrl + d if you are still in there.Bye
@Bye That would have been mightily infinite, 6 months later ;-)Killjoy
One advantage this has over pdb and ipdb is that any exceptions caused by the code you run get full tracebacks (because you aren't already "in" one). This is super useful for me, since I have a tendency to use pdb as a way to set up a bunch of variables for an interactive shell.Fleabane
This is the right answer folks. ipdb is great, but it's not even close to the same UX as ipython.Ayo
@gerrit, If you're stuck in an embed loop: def f() : pass ; IPython.embed = f so that the embed() call is a noop, then Ctrl + DCheyenne
B
12

If you're using a more modern version of IPython (> 0.10.2) you can use something like

from IPython.core.debugger import Pdb
Pdb().set_trace()

But it's probably better to just use ipdb

Bandy answered 21/9, 2012 at 10:41 Comment(0)
L
11

The equivalent of

import pdb; pdb.set_trace()

with IPython is something like:

from IPython.ipapi import make_session; make_session()
from IPython.Debugger import Pdb; Pdb().set_trace()

It's a bit verbose, but good to know if you don't have ipdb installed. The make_session call is required once to set up the color scheme, etc, and set_trace calls can be placed anywhere you need to break.

Lowminded answered 15/7, 2009 at 0:40 Comment(0)
S
8

Normally, when I use ipython, I turn automatic debugging on with the "pdb" command inside it.

I then run my script with the "run myscript.py" command in the directory where my script is located.

If I get an exception, ipython stops the program inside the debugger. Check out the help command for the magic ipython commands (%magic)

Steelhead answered 14/7, 2009 at 18:8 Comment(1)
so there's no way of writing something like ipython.set_trace() ? :)Cupped
D
8

I like to simply paste this one-liner in my scripts where I want to set a breakpoint:

__import__('IPython').Debugger.Pdb(color_scheme='Linux').set_trace()

Newer version might use:

__import__('IPython').core.debugger.Pdb(color_scheme='Linux').set_trace()
Devaughn answered 29/8, 2012 at 11:58 Comment(0)
A
6

Looks like modules have been shuffled around a bit recently. On IPython 0.13.1 the following works for me

from IPython.core.debugger import Tracer; breakpoint = Tracer()

breakpoint() # <= wherever you want to set the breakpoint

Though alas, it's all pretty worthless in qtconsole.

Acme answered 22/1, 2013 at 17:43 Comment(0)
B
5

Newer versions of IPython provide an easy mechanism for embedding and nesting IPython sessions into any Python programs. You can follow the following recipe to embed IPython sessions:

try:
    get_ipython
except NameError:
    banner=exit_msg=''
else:
    banner = '*** Nested interpreter ***'
    exit_msg = '*** Back in main IPython ***'

# First import the embed function
from IPython.frontend.terminal.embed import InteractiveShellEmbed
# Now create the IPython shell instance. Put ipshell() anywhere in your code
# where you want it to open.
ipshell = InteractiveShellEmbed(banner1=banner, exit_msg=exit_msg)

Then use ipshell() whenever you want to drop into an IPython shell. This will allow you to embed (and even nest) IPython interpreters in your code.

Bedevil answered 27/3, 2013 at 17:22 Comment(0)
I
3

From the IPython docs:

import IPython.ipapi
namespace = dict(
    kissa = 15,
    koira = 16)
IPython.ipapi.launch_new_instance(namespace)

will launch an IPython shell programmatically. Obviously the values in the namespace dict are just dummy values - it might make more sense to use locals() in practice.

Note that you have to hard-code this in; it's not going to work the way pdb does. If that's what you want, DoxaLogos' answer is probably more like what you're looking for.

Insomniac answered 14/7, 2009 at 18:15 Comment(0)
A
3

The fast-and-easy way:

from IPython.Debugger import Tracer
debug = Tracer()

Then just write

debug()

wherever you want to start debugging your program.

Alkalinize answered 3/11, 2010 at 12:57 Comment(1)
ImportError: No module named 'IPython.Debugger' on python 3.4 / IPython 3Voccola
K
3

I had to google this a couple if times the last few days so adding an answer... sometimes it's nice to be able run a script normally and only drop into ipython/ipdb on errors, without having to put ipdb.set_trace() breakpoints into the code

ipython --pdb -c "%run path/to/my/script.py --with-args here"

(first pip install ipython and pip install ipdb of course)

Kirven answered 16/3, 2015 at 17:11 Comment(1)
Thank you! A bit simpler: ipython --pdb -- ./path/to/my/script --with-args hereFumy
Z
0

This is pretty simple:

ipython some_script.py --pdb

It needs iPython installing, usually this works: pip install ipython

I use ipython3 instead of ipython, so I know it's a recent version of Python.

This is simple to remember because you just use iPython instead of python, and add --pdb to the end.

Zsolway answered 2/8, 2018 at 13:21 Comment(0)
A
0

To get IPython's REPL using terminal colors, I had to do this:

from IPython import start_ipython

start_ipython()

https://ipython.readthedocs.io/en/stable/api/generated/IPython.html#IPython.start_ipython

Amphidiploid answered 18/1, 2020 at 20:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.