16

I see that PyCharm supports Cython.

I could always compile and run in terminal, but I'm wondering if there is a way to do this in PyCharm. In the link it says: "Compilation is done using external tools. The preferred build systems (Makefile, setup.py, etc.) should be configured as external tools." I'm wondering how to do this configuration. A small Hello World example in PyCharm using Cython would be much appreciated.

Thanks

eharbitz
  • 489
  • 1
  • 3
  • 11

1 Answers1

23

Answering my own question here:

Let's say we have the function fib.pyx:

def fib(n):
"""Print the Fibonacci series up to n."""
a, b = 0, 1
while b < n:
    print b,
    a, b = b, a + b

There are two ways to compile and run this

  1. Use a setup file. Make the file setup.py:

    from distutils.core import setup
    from Cython.Build import cythonize
    
    ext_options = {"compiler_directives": {"profile": True}, "annotate": True}
    setup(
        ext_modules = cythonize("fib.pyx", **ext_options)
    )
    

    The ext_options is included here to generate the html file with annotations. To run this file you have to go to Tools --> Run setup.py Task. Then type in build_ext as task name and when prompted for Command Line input type --inplace. The files fib.c, fib.o and the executable file fib.so is generated. The annotation file fib.html is also created.

    Now, the following code should work in any python file, for example main.py:

    import fib
    fib.fib(2000)
    
  2. The much easier way to go is to use pyximport. No setup file is needed. Note that this can only be used if "your module doesn’t require any extra C libraries or a special build setup." The file main.py should now look like:

    import pyximport; pyximport.install()
    import fib
    fib.fib(2000)
    

    As far as I understand the same compilation of code takes place even though the fib.c, fib.o and fib.so files don't end up in the project folder. The fib.html code is not generated either, but this can be fixed by adding two lines to the main file. With the new lines main.py is now:

    import pyximport; pyximport.install()
    import subprocess
    subprocess.call(["cython", "-a", "fib.pyx"])
    import fib
    fib.fib(2000)
    
eharbitz
  • 489
  • 1
  • 3
  • 11
  • In addition to these instructions, we also have to ensure that PyCharm knows that the package fodler contains a Python module, or else it will ignore it. See https://stackoverflow.com/questions/40203488/pycharm-does-not-recognize-cython-modules-located-in-path – Contango Aug 07 '17 at 07:30
  • how can I add a function that is inside a package? I mean my main.py is in the root, and I have a package named "my_package" and there I have "my_py_file.py" and inside there "my_function()". If I refactor my "my_py_file.py" to "my_py_file.pyx" and use your second method, I get the error in main.py: import my_package.my_py_file as mpf ModuleNotFoundError: No module named 'my_package.my_py_file' – Fierce82 Oct 03 '18 at 11:01
  • I have a question regarding debugging a Cython code in PyCharm https://stackoverflow.com/q/54014959/2227222. Would you care to take a look and see if you have any advice? – Hans Jan 06 '19 at 03:29