Ginger
Ginger

Reputation: 8650

How to import a Cython Module into IPython Notebook and compile it

I am using IPython and Cython.

I am editing my Cython functions in modules in an external text editor.

I would like to import these modules and use them in IPython, but with IPython compiling them when importing.

What is the syntax for doing this? I do not want my code inside my IPython notebooks.

Upvotes: 4

Views: 3565

Answers (1)

Caleb Hattingh
Caleb Hattingh

Reputation: 9225

This is an unusual workflow but it should be possible to get something working. Firstly, for things to be importable in your IPython session, they must appear in sys.path. You can insert new folders in that list like this:

enter image description here

The path you would be adding would be the folder(s) in which your compiled Cython modules would be placed. Whichever of the next strategies you use, at a minimum the path to your compiled (.pyd) Cython modules needs to be on sys.path to be able to be imported.

Secondly, you need a way to compile your Cython modules. If you're using the recommended approach, you would have a setup.py file with your cython sources and python setup.py build_ext to produce the compiled .pyd files. You would have to restart your IPython Kernel every time you recompiled your Cython modules.

There are alternatives to setup.py. One of them is my easycython which is a command-line tool that compiles .pyx source into .pyd without needing a setup.py. This tool is AFAIK only used/tested by me, so it may not work, ymmv etc. You would still have to restart your IPython Kernel every time you recompiled your Cython modules. (I mention it here only because it is one of my babies.)

A better approach would be to use pyximport, because it will compile on demand and has reload support:

# This is inside your IPython Notebook
import pyximport
pyximport.install(reload_support=True)
import my_cython_module

You can reload the module with

reload(my_cython_module)

You could try to be clever with some kind of logic to make it so that simply rerunning the notebook will either reload or import:

# Speculative code: I have not tried this!
# This is inside your IPython Notebook
import pyximport
pyximport.install(reload_support=True)
if 'my_cython_module' in dir(): # Maybe sys.modules is better?
    reload(my_cython_module)
else:
    import my_cython_module

You may have to play around a bit to find something that works, but something should be workable for your use-case.

Upvotes: 6

Related Questions