how to include numpy with cythonize-script?

Question:

Recently I start looking into Cython, and the Anaconda distribution have this handy script cythonize which allow to do

 >cythonize -i foo.pyx

to compile files in place.

My question is how I can use that script to include numpy so my cimport numpy work properly??

I have try with

>cythonize -X include_path=C:Anaconda3libsite-packagesnumpycoreinclude  -i foo.pyx
>cythonize -s include_path=C:Anaconda3libsite-packagesnumpycoreinclude  -i foo.pyx

also with include_dir=..., include_dirs=... both with -X and -s

if I use -X I get

Traceback (most recent call last):
  File "C:Anaconda3Scriptscythonize-script.py", line 5, in <module>
    sys.exit(Cython.Build.Cythonize.main())
  File "C:Anaconda3libsite-packagesCythonBuildCythonize.py", line 185, in main
    options, paths = parse_args(args)
  File "C:Anaconda3libsite-packagesCythonBuildCythonize.py", line 172, in parse_args
    options, args = parser.parse_args(args)
  File "C:Anaconda3liboptparse.py", line 1387, in parse_args
    stop = self._process_args(largs, rargs, values)
  File "C:Anaconda3liboptparse.py", line 1431, in _process_args
    self._process_short_opts(rargs, values)
  File "C:Anaconda3liboptparse.py", line 1536, in _process_short_opts
    option.process(opt, value, values, self)
  File "C:Anaconda3liboptparse.py", line 785, in process
    self.action, self.dest, opt, value, values, parser)
  File "C:Anaconda3liboptparse.py", line 805, in take_action
    self.callback(self, opt, value, parser, *args, **kwargs)
  File "C:Anaconda3libsite-packagesCythonBuildCythonize.py", line 38, in parse_directives
    value, relaxed_bool=True, current_settings=old_directives)
  File "C:Anaconda3libsite-packagesCythonCompilerOptions.py", line 424, in parse_directive_list
    raise ValueError('Unknown option: "%s"' % name)
ValueError: Unknown option: "include_path"

with -s I get

Traceback (most recent call last):
  File "C:Anaconda3Scriptscythonize-script.py", line 5, in <module>
    sys.exit(Cython.Build.Cythonize.main())
  File "C:Anaconda3libsite-packagesCythonBuildCythonize.py", line 196, in main
    cython_compile(path, options)
  File "C:Anaconda3libsite-packagesCythonBuildCythonize.py", line 90, in cython_compile
    **options.options)
  File "C:Anaconda3libsite-packagesCythonBuildDependencies.py", line 809, in cythonize
    ctx = c_options.create_context()
  File "C:Anaconda3libsite-packagesCythonCompilerMain.py", line 581, in create_context
    self.cplus, self.language_level, options=self)
  File "C:Anaconda3libsite-packagesCythonCompilerMain.py", line 90, in __init__
    self.include_directories = include_directories + [standard_include_path]
TypeError: unsupported operand type(s) for +: 'bool' and 'list'

Yes, I can make a setup.py, but I find that very annoying and it leave that build folder there, while cythonize don’t do that.

Asked By: Copperfield

||

Answers:

It looks like it’s not possible to pass in the include dirs via the command line version of cythonize.

The problem is that looking in the cython source code, it expects options to be boolean:

https://github.com/cython/cython/blob/master/Cython/Build/Cythonize.py#L48

So when you include a path, it gets converted to True:

cythonize -i -s include_path=path_to_numpy_include test.pyx

and the options are parsed as:

{'directives': {}, 'options': {'include_path': True}, 'python3_mode': None, 'annotate': None, 'excludes': [], 'build': True, 'build_inplace': True, 'parallel': 12, 'force': None, 'quiet': None, 'lenient': None, 'keep_going': None}

which results in the type error you’re reporting:

TypeError: unsupported operand type(s) for +: 'bool' and 'list'

I think your best bet is to just use a proper setup.py.

Answered By: JoshAdel

You can do this by setting environment variables interpreted by your C compiler (which cythonize runs as a subprocess). For example, with GCC or clang:

C_INCLUDE_PATH=$(python -c 'import numpy; print(numpy.get_include())') cythonize -i foo.pyx
Answered By: Qualia