101

i have a python module with a function:

def do_stuff(param1 = 'a'):
    if type(param1) == int:
        # enter python interpreter here
        do_something()
    else:
        do_something_else()

is there a way to drop into the command line interpreter where i have the comment? so that if i run the following in python:

>>> import my_module
>>> do_stuff(1)

i get my next prompt in the scope and context of where i have the comment in do_stuff()?

aaronstacy
  • 6,189
  • 13
  • 59
  • 72
  • Possible duplicate of [Enter Interactive Mode In Python](http://stackoverflow.com/questions/13432717/enter-interactive-mode-in-python) – Mad Physicist Nov 06 '15 at 21:17

3 Answers3

158

If you want a standard interactive prompt (instead of the debugger, as shown by prestomation), you can do this:

import code
code.interact(local=locals())

See: the code module.

If you have IPython installed, and want an IPython shell instead, you can do this for IPython >= 0.11:

import IPython; IPython.embed()

or for older versions:

from IPython.Shell import IPShellEmbed
ipshell = IPShellEmbed()
ipshell(local_ns=locals())
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Matt Anderson
  • 19,311
  • 11
  • 41
  • 57
  • 27
    for IPython>=0.11, there's no more module Shell in IPython...so start it using "import IPython; IPython.embed()" instead. – evandrix Sep 12 '11 at 10:06
  • Is it possible to continue after entering `code.interact()`, a la PDB `c(ontinue)`? – Nick T Feb 15 '14 at 06:13
  • 4
    `code.interact()` is a blocking call. Your program will stop and wait for it to finish. If you exit the interactive interpreter, your program should resume with the statement immediately following. – Matt Anderson Feb 15 '14 at 06:18
  • and also for bpython: `import bpython`, then `bpython.embed(locals())` – Auxiliary Jun 03 '16 at 22:07
  • 1
    What's the difference between an interactive prompt and a debugger? – StockB Aug 08 '16 at 13:51
  • 1
    @StockB It's the *standard* interactive prompt that makes it important. The debugger is *an* interactive prompt, but it's not the same. In PDB, you cannot do multi-line statements, the built-in `help` function is overridden, etc. – kbrose Jan 19 '18 at 21:30
  • To resume code execution: https://stackoverflow.com/questions/18836061/resume-code-execution-from-code-interact-in-python – StockB May 01 '18 at 14:20
68

Inserting

import pdb; pdb.set_trace()

will enter the python debugger at that point

See here: http://docs.python.org/library/pdb.html

prestomation
  • 7,225
  • 3
  • 39
  • 37
  • `pdb` is great vanilla python; if you have room for bringing in an external package, `ipdb` is great -- same functionality as the debugger, but with the syntax highlighting, tab completion, etc of ipython – khstacking Jun 07 '17 at 19:41
  • Update — `ipdb` was deprecated, nowadays I use [`pdbpp` (`pdb++`)](https://pypi.org/project/pdbpp/), which has similar features, and works with `import pdb; pdb.set_trace()` (i.e. it patches that import, so it is a drop-in replacement) – floer32 Sep 07 '18 at 21:39
  • @hangtwenty: why do you say `ipdb` was deprecated? I can't find any news of that. – Nick Matteo Mar 05 '19 at 02:30
  • 1
    @Kundor huh, you're right. I distinctly remember reading somewhere that the authors had decided to stop maintaining the project and pointed to another project to use instead. Maybe that happened for a bit and then it was resurrected? I could be wrong! In either case, I enjoyed `ipdb` before, but have enjoyed `pdbpp` since – floer32 Mar 05 '19 at 19:41
  • One problem with this approach is that (for example) `> list([1, 2])` will not work. The debugger has a list command that takes precedence. Multiline commands (like a for loop) do not work either for me in a pdb session. Maybe some config can help that, but I am not aware of one. – Matyas Apr 26 '22 at 04:14
  • 1
    @Matyas pdb lets you prefix python statements/expressions with `!` to avoid name clashes with pdb commands. So `!list([1, 2])` will work as you expect. To enter multiline statements, you can use pdb's `interact` command, which is equivalent to `code.interact(local={**globals(), **locals()})`. – John Mellor Jun 08 '23 at 15:04
35

If you want a default Python interpreter, you can do

import code
code.interact(local=dict(globals(), **locals()))

This will allow access to both locals and globals.

If you want to drop into an IPython interpreter, the IPShellEmbed solution is outdated. Currently what works is:

from IPython import embed
embed()
Ronan Paixão
  • 8,297
  • 1
  • 31
  • 27
  • 8
    thanks, `code.interact(local=dict(globals(), **locals()))` is so much better than `code.interact(local=locals())` because the latter makes you re-import packages – s2t2 Nov 24 '15 at 03:00
  • 1
    This answer worked better for me since I was using a bash script to call my python code. I could not interact with my python code using the accepted answer. Thanks! – jonathanking Jun 15 '16 at 17:23