How to force IPython to see an updated library? - python

I do the following in my IPython notebook:
import sys
sys.path.append('my_directory')
from db import *
It works fine. But then I added a new function to the db.py and IPython does not see it. It OK. But it does not see it even if I reset everything end re-execute the cell that imports everything. It does not see it even if I user reload. It does not see it even if I close the IPython notebook and restart it.
What is the way to force IPython (or python) to see the updated content of the file?

You need to use autoreload. Check the manual at http://ipython.org/ipython-doc/dev/config/extensions/autoreload.html. Seems you need:
%autoreload 2
The above will automatically reload all imported modules. Except those inlcuded in a separate special list of modules specified by %aimport modulename. Those will only be autoreloaded if you specify %autoreload 1.

Related

Rerun import in Jupyter notebook

In jupyter notebook, I have a cell including all imports. Those imports some of my own modules.
When I rerun the cell, it does not pick up the updates in the modules. I need to to a kernel restart and rerun the whole notebook. Is there any other way to fix this problem?
You can also use the reload magic by placing this in your notebook. It will automatically reload code.
%reload_ext autoreload
%autoreload 2
The only time this may cause confusion is, if you instantiated an object, change the code and then wonder, why the already instantiated object does not have the new functions. Besides this case, it works well.
This question is also asked here.

How do I load and run specific packages when I launch 'matplotlib'?

I see how to change certain settings for matplotlib in such a way that the are used to configure it each time I launch, including when I launch interactively with
ipython --pylab
but I'm not sure how run arbitrary code each time I launch in this way, or how to ensure that certain packages have been imported. For example I'd like to do the following whenever I launch as above:
from mpltools import style
style.use('ggplot')
How do I load and run specific packages when I launch 'matplotlib'?
From the ipython website it seems you can place any .py file in the startup folder of your profile and it will be run when ipython is initiated. For help finding the profile where your startup folder is [see here].
To get the effect your looking for you need to check that matplotlib has been imported, the only way I can think of doing that is to add the following
import sys
if "matplotlib" in sys.modules:
# Do something
print
print "This seems to be working"
I have left it with the test so you can quickly determine if it is working.
Two things to note: I am using ipython 2.0.0-dev (in case this has any bearing), and secondly I suspect that calling sys.modules is not recommended, or at least that was the impression I had off the SO post I borrowed the idea from, perhaps someone better than I can enlighten us.

using 'from __future__' with ipython and PYTHONSTARTUP

I would like to have
from __future__ import (absolute_import, division, print_function, unicode_literals)
loaded in each interactive session, using a PYTHONSTARTUP file. This works with basic python (2.7.5, installed with Anaconda), but does not work with ipython (1.0.0, Anaconda). Other import statements work with ipython, but __future__ ones are just ignored (although they work if I enter them on the command line). Is this an ipython bug, or is there something I'm missing?
There are two issues here.
The first one is more general than __future__ statements: At least in my tests, ipython 1.0.0 and earlier just don't process the PYTHONSTARTUP environment variable at all. You can see this pretty easily:
$ echo -e 'print "PYTHONSTARTUP!"\n' > pythonstartup.py
$ PYTHONSTARTUP=./pythonstartup.py ipython
Nothing extra gets printed out.
#2706 suggested that it should do so, #3569 patched it, and 1.1.0 seems to be the first version with the change.
So, the fix is to upgrade to 1.1.0. Or, if you're stuck with an older version, do what was suggested in #2706, and add this to your first $IPYTHONDIR/profile_default/startup/*py file:
import os
if os.environ['PYTHONSTARTUP']:
execfile(os.environ['PYTHONSTARTUP'])
However, that still won't fix the problem.
The way $PYTHONSTARTUP gets run (either explicitly by you or implicitly by iPython) is equivalent to an exec. It does explicitly give the appropriate globals to the exec, which ensures that you end up with the print_function tuple available… but that won't affect the parser. (Compare typing exec('from __future__ import print_function)` at the interactive shell.)
And the same is true for the startup files described above, the backward-compat ipython.rc file (if you have that enabled), and any other files that are supposed to be executed in your interactive environment—they're actually just exec'd in your globals, which isn't quite the same thing.
Even files executed as part of the exec_files mechanism in your ipython_config.py or other app-config script are handled this way.
However, lines executed as part of the exec_lines mechanism are not. So, that's the solution.
Edit or create ~/.ipython/profile_default/ipython_config.py. (If you're using a different profile, ipythondir, app name, etc., you presumably know that, and know how to adjust.)
If it's not already present, add this line:
c = get_config()
Then add this:
c.InteractiveShellApp.exec_lines = ['from __future__ import print_function']
See Configuring the ipython command line application for more details.
If you really wanted to, you could probably do something like this:
import os
try:
# Make sure to pop it so it won't get exec'd later in the startup
pythonstartup = os.environ.pop('PYTHONSTARTUP')
with open(pythonstartup) as f:
c.InteractiveShellApp.exec_lines.append(list(f))
except KeyError:
pass
But that seems pretty hacky.

IPython 0.13: autoreloading modules every time I enter a command?

Say I have a script that imports various modules in Python.
import my_module
from some_other_module import foo
...
I then run this script from IPython.
Say I make changes to the function bar in my_module and foo in some_other_module.
Say that I now want to interactively call either my_module.bar() or foo() from my IPython session.
Is there a way to have IPython automatically reload every loaded module when I invoke a command before executing the command?
If not automatically, how can I reload every loaded module manually in IPython without having to explicitly name the module?
Finally, is there a way to set up my IPython session in my ipython_config.py (startup file) so that it supports this functionality off-the-shelf?
I would suggest a %load_ext autoreload followed by a %autoreload? to see how to use it.
You can also have a look at InteractiveShellApp.extensions and InteractiveShellApp.extra_extension configuration options for extension at startup.
Finally, you can also add a .py file in your IPython profile dir ($ ipython locate to get it), put it in the startup subfolder, it will be executed at startup time.
There is a restriction though, C modules cannot be reloaded.

reload (update) a module file in the interpreter

Let's say I have this python script script.py and I load it in the interpreter by typing
import script
and then I execute my function by typing:
script.testFunction(testArgument)
OK so far so good, but when I change script.py, if I try to import again the script doesn't update. I have to exit from the interpreter, restart the interpreter, and then import the new version of the script for it to work.
What should I do instead?
You can issue a reload script, but that will not update your existing objects and will not go deep inside other modules.
Fortunately this is solved by IPython - a better python shell which supports auto-reloading.
To use autoreloading in IPython, you'll have to type import ipy_autoreload first, or put it permanently in your ~/.ipython/ipy_user_conf.py.
Then run:
%autoreload 1
%aimport script
%autoreload 1 means that every module loaded with %aimport will be reloaded before executing code from the prompt. This will not update any existing objects, however.
See http://ipython.org/ipython-doc/dev/config/extensions/autoreload.html for more fun things you can do.
http://docs.python.org/library/functions.html#reload
reload(module)
Reload a previously imported module. The argument must
be a module object, so it must have been successfully imported before.
This is useful if you have edited the module source file using an
external editor and want to try out the new version without leaving
the Python interpreter. The return value is the module object (the
same as the module argument).
An alternative solution that has helped me greatly is to maintain a copy of sys.modules keys and pop the new modules after the import to force re-imports of deep imports:
>>> oldmods = set(sys.modules.keys())
>>> import script
>>> # Do stuff
>>> for mod in set(sys.modules.keys()).difference(oldmods): sys.modules.pop(mod)
>>> import script

Categories

Resources