Search code examples
pythonpython-3.xipythonreloadread-eval-print-loop

How do I make IPython reload a file passed to `ipython -i ...`


I have a file /tmp/throwaway_code.py with something like

def hello():
    print("world")

and try it with IPython:

$ ipython3 -i /tmp/throwaway_code.py
In [1]: hello()
world

now I changed something in the file and want to reload. How do I do it without restarting IPython or modularizing the code?

My failed attempt:

In [2]: %load_ext autoreload

In [3]: %autoreload 2

# change source file    

In [4]: hello()
world
# Expected: world2.

Alternatively, how do I leave and re-enter IPython session with minimal effort (currently 6 keystrokes: Ctrl, D, y, Return, Up, Return)?


Solution

  • autoreload won't work here, the module isn't placed in sys.modules with the -i option:

    from sys import modules
    
    modules['throwaway_code'] # KeyError
    

    so reload won't find the module you want it to reload.

    A way around it is to explicitly import the module which places it in sys.modules, then autoreload will grab the changes each time. So you should exit IPython and start it with appropriate PYTHONPATH so that your code can be imported as a module. Your session should look like this:

    In [4]: ^D
    Do you really want to exit ([y]/n)? y
    $ PYTHONPATH=/tmp ipython3
    
    In [1]: from throwaway_code import *
    
    In [2]: %load_ext autoreload
    
    In [3]: %autoreload 2
    
    In [4]: hello()
    world
    
    In [5]: hello()
    world2