This is still the header! Main site

Python REPLs anywhere

2024/02/15
(Status: might need more testing; this might have been written overly too quickly.)

Programming languages that have an interactive prompt (REPL: a "read-eval-print loop") are nice because you can try out your code interactively, without having to stop & recompile everything; you can just type in your functions one by one and see whether they work.

Except... no one really wants to type in functions one by one. This is why Jupyter notebooks exist: they let you push this story a little bit further; you can at least edit your functions in cells, so no re-typing / up-arrow-pressing needed. But then, once you have a decent amount of code, you'd want to write an Actual Python Program. And how do you test those with REPLs?

PDB

Well, round one: PDB the debugger exists. You just

import pdb
          

at the beginning of the code, and then you can drop in a breakpoint with

pdb.set_trace()
          
It's fairly easy to do & it's more convenient to look at program state with it vs. a lot of print statements.

A less known feature of PDB is that you can get a full interactive shell prompt with the "i" command. While the (pdb) one is also OK for printing things, this one is less picky about what it evaluates. Thus... you now have a full REPL at the spot in your code where you actually need one, not just outside.

code.interact()

In case you want to drop into an interactive shell right away... you can use the actual module Python uses for interactive shells!

Try

import code

# ... and then in your code

code.interact()
          

This will give you the nice interactive prompt... except it's literally just that, without any local variables you have. Pretty useless, but it's a good starting point.

You can improve it by

code.interact(local=locals())
          
which gives you local variables... not the symbols in your module though. To fix that, you can just also add them:

code.interact(local={**locals(), **sys.modules[__name__].__dict__})
          

This way you can test out functions too.

iPython

Update 2024/05/19: if you have iPython installed, you can accomplish pretty much the same thing without as much ugliness:

IPython.embed()
          

Similarly to the above solutions, this works from the middle of a function too & can access local variables, with a nicer shell to interact with them. Thanks Anil for the email, pointing this out!

... comments welcome, either in email or on the (eventual) Mastodon post on Fosstodon.