Personal tools

Contact Us 24/7 > 1 866.SIX FEET

Skip to content. | Skip to navigation

Home > Blog > Set up IPython for Plone Development

EVERYONE.NET SCHEDULED MAINTENANCE will be performing maintenance on their databases Friday October 28th, 2016 between 9:00PM PT to 3:00AM PT / 12:00AM ET to 06:00AM ET. During this time, all services including web mail, POP, IMAP, and SMTP relay may experience degraded performance and inbound mail delivery delays. We apologize for any inconvenience.


Set up IPython for Plone Development

written by Clayton Parker on Thursday January 12, 2012
Comments | Filed under: , , ,

IPython is a powerful interactive Python shell that can be used with Zope to aid in debugging issues in your Plone development activities. Syntax highlighting, tab completion and code introspection are just a few reasons to use it.

Think of the Zope-enabled IPython shell as bin/instance debug on steroids. When you start up the default Zope instance debugger, you are only given an app variable to access the current Zope instance. The IPython Zope profile enhances this with some useful defaults. It sets the variable portal to the first Plone site that it finds, sets up a dummy request on it and then does a setSite to make the component architecture work properly. There is also a utils object that is set up to allow you to sync the database, commit your changes, switch users and a host of other things. This gives you a series of effective tools to improve your Plone development practices.

A while back, Kees Hink wrote up a blog post about using IPython with the powerful content management system Plone 4. Since then, a newer version of IPython has come out and is no longer compatible with Python 2.4. This post will help you get it working with Python 2.4 and IPython 0.10 (for Plone sites on version 3.x or earlier), then Python 2.6 and IPython 0.11 or 0.12 (for Plone sites running Plone 4+).

Add Zope enabled IPython to buildout

We will assume that your Zope instance is created with a part named [instance] and, in the case of Plone 3, Zope is installed with a part called [zope2]. Here is what the Zope enabled IPython part looks like (uncomment the Plone 3 lines if needed).

parts =
# NOTE: You will have a zope2 part if using Plone 3
#    zope2
versions = version

# NOTE: Use IPython 0.10 for Plone 3
#ipython = 0.10.2
ipython = 0.12

recipe = zc.recipe.egg
eggs = ipython ${instance:eggs}
initialization =
    import sys, os
    # NOTE: Include this line for Plone 3
    #os.environ["SOFTWARE_HOME"] = "${instance:zope2-location}/lib/python"
    os.environ["INSTANCE_HOME"] = "${instance:location}"
    sys.argv[1:1] = "--profile zope2".split()
# NOTE: Include this line for Plone 3
#extra-paths = ${instance:zope2-location}/lib/python
scripts = ipython=ipzope

Notice that the --profile option is new, they removed the -p option in the latest IPython. The --profile still works with IPython 0.10, so we can keep that option for both versions of our part. We are also calling the profile zope2 instead of the normal zope. This is because IPython 0.10 was bundled with the zope profile, so we won't be able to use our new and improved profile unless we rename it.

Set up the zope2 IPython profile

Now that we have this added to our buildout, we need to get IPython set up with the profile. This is where things get difficult. The profile format has changed from 0.10 to 0.12, this means we should make a copy before we do anything else. This directory will only be present if you have already used IPython in the past.

$ cd
$ cp -r .ipython .ipython_0.10

If you don't have an IPython directory, running ipython or bin/ipzope will create one for you. The 0.10 version will tell you that it is creating it, the 0.12 version just silently does it. Let's go ahead and create the config skeleton.

$ cd path/to/buildout
$ bin/ipzope

Now let's add in the Zope profile. I have merged the Plone 4 branch that Kees created and fixed up a few other things, so we can now use the trunk. Let's check that out for use later.

$ cd
$ svn co .dotipython

Now let's symlink into the proper places. The 0.10 profile expects this to be a file named ipy_profile_<name>.py, where <name> is the profile name.

$ cd ~/.ipython
$ ln -s ~/.dotipython/

Notice that we have renamed it to zope2 here to avoid the clash with the profile included with IPython.

Now let's add a 0.12 friendly version. The latest version expects a profile to be a directory in the format profile_<name>. The actual Python file will live in a startup sub-folder of the profile.

$ cd ~/.ipython
$ mkdir -p profile_zope2/startup
$ cd profile_zope2/startup
$ ln -s ~/.dotipython/ .

In this case, it doesn't matter what the name of the Python file is inside the startup directory. IPython will just read each file in alphabetically.

Now we can start up ipzope and we will have all of the Zope features that we are accustomed to.

$ cd path/to/buildout
$ bin/ipzope

Just remember that you will have to change the [ipzope] part slightly and require ipython = 0.10 for use on Plone 3.

Working with 0.10 and 0.11+

The last nagging issue that you will run into is that when you run a IPython 0.12 shell, it will automatically upgrade your ~/.ipython directory. If you want the prompt to work correctly with 0.10, you will have to have a copy of your ipythonrc and files handy to put back in place. We can use the copy we made earlier.

$ cp ~/.ipython_10/ipythonrc ~/.ipython/.
$ cp ~/.ipython_10/ ~/.ipython/.

Now you can use the 0.10 version properly again. If you don't have a copy of a 0.10 ~/.ipython, you can run the 0.10 version of ipython to generate a new ~/.ipython directory (you will have to move the current one out of the way first).


If you are doing Plone development without the use of a good interactive debugger, you are missing out because you can't run code interactively and figure out an issue efficiently. Try setting up IPython or try out bpython for an alternate option. This will take your Plone development to the next level by getting you closer to the code and making you more productive.

UPDATE: To use the 0.10 version after having used 0.12, you need the also. Instructions above updated.

Posted by Giacomo Spettoli on Jan 12, 2012 12:52 PM
Excellent article! Just one thing: it seems that the initialization parameter should be: sys.argv[1:1] = "--profile=zope2".split()
Posted by Clayton Parker on Jan 12, 2012 01:50 PM
Thanks, Giacomo. Both with and without the = seem to work for me.
Posted by Giacomo Spettoli on Jan 12, 2012 02:00 PM
actually the init parameter is not much important (for ipython 0.12..for 0.11 it is with the =). But it doesn't seems to get the profile and there's no error output to check
Posted by Clayton Parker on Jan 12, 2012 02:16 PM
In the newer IPython, it doesn't error out or give you any kind of warning about a missing profile, it will just create it. $ ipython --profile=foobar Then it will tell you what profile it loaded. IPython profile: foobar Then if you look in the ~/.ipython folder, you will see a new profile_foobar/ folder.
Posted by Antti on Feb 08, 2012 12:43 PM
Hi, Have been trying to get this working in OS X (Snow Leopard) for hours now. However I get the following error when starting ipzope: MultipleInstanceError: Multiple incompatible subclass instances of TerminalInteractiveShell are being created. No Google results (which is always worrying). Anyone had ipzope working in OS X? Best regards, Jussi
Posted by Clayton Parker on Feb 20, 2012 11:36 AM
Unfortunately, I've never run into that error. Not sure what could be causing it without a full traceback.
Posted by Davidjb on Mar 06, 2012 09:16 PM
Fantastic. Thanks for your work on this. Working well with IPython 0.12. I've changed my initialization to be: argv_len = len(sys.argv) sys.argv[argv_len:argv_len] = "--profile=zope2".split() so that the profile argument gets put at the end. This means that it will work the new IPython subcommands (eg bin/ipython {console,kernel,etc}
Posted by Davidjb on Mar 06, 2012 09:18 PM
Fantastic. Thanks for your work on this. Working well with IPython 0.12. I've changed my initialization to be: argv_len = len(sys.argv) sys.argv[argv_len:argv_len] = "--profile=zope2".split() so that the profile argument gets put at the end. This means that it will work the new IPython subcommands (eg bin/ipython {console,kernel,etc}
Posted by Jean Jordaan on Nov 01, 2013 03:07 AM
I've imported dotipython to the github collective organization, and improved the docs a bit:
Posted by jim on Nov 01, 2013 11:09 AM
Cool, thanks for the update Jean
Add comment

You can add a comment by filling out the form below. Plain text formatting.


Next Steps

Select a type of support:

Contact our sales team

First name:
Last name:
Phone Number:
Fight spam:
What is + ?
Call Us 1 866.SIX FEET