How do you tell pyximport to use the cython --cplus option?
Asked Answered
S

4

20

pyximport is super handy but I can't figure out how to get it to engage the C++ language options for Cython. From the command line you'd run cython --cplus foo.pyx. How do you achieve the equivalent with pyximport? Thanks!

Shelashelagh answered 1/10, 2011 at 11:39 Comment(1)
I doesn't look like there is an easier way right now. It would be nice if something like this were added to pyximport. I just tried the commented compiler directives shown at docs.cython.org/src/userguide/… and they don't seem to work with pyximport.Enlighten
N
21

One way to make Cython create C++ files is to use a pyxbld file. For example, create foo.pyxbld containing the following:

def make_ext(modname, pyxfilename):
    from distutils.extension import Extension
    return Extension(name=modname,
                     sources=[pyxfilename],
                     language='c++')
Nenitanenney answered 1/10, 2011 at 12:37 Comment(2)
Just to be clear, will pyximport automagically observe the directives given in foo.pyxbld?Shelashelagh
I am curious about this last point too. How/where are pyxbld files taken into account ?Yetta
H
9

Here's a hack.

The following code monkey-patches the get_distutils_extension function in pyximport so that the Extension objects it creates all have their language attribute set to c++.

import pyximport
from pyximport import install

old_get_distutils_extension = pyximport.pyximport.get_distutils_extension

def new_get_distutils_extension(modname, pyxfilename, language_level=None):
    extension_mod, setup_args = old_get_distutils_extension(modname, pyxfilename, language_level)
    extension_mod.language='c++'
    return extension_mod,setup_args

pyximport.pyximport.get_distutils_extension = new_get_distutils_extension

Put the above code in pyximportcpp.py. Then, instead of using import pyximport; pyximport.install(), use import pyximportcpp; pyximportcpp.install().

Hyperspace answered 3/6, 2015 at 2:51 Comment(0)
C
5

A more lightweight/less intrusive solution would be to use setup_args/script_args, which pyximport would pass to distutils used under the hood:

script_args = ["--cython-cplus"]
setup_args = {
    "script_args": script_args,
}
pyximport.install(setup_args=setup_args, language_level=3)

Other options for python setup.py build_ext can be passed in similar maner, e.g. script_args = ["--cython-cplus", "--force"].

The corresponding part of the documentation mentions the usage of setup_args, but the exact meaning is probably clearest from the code itself (here is a good starting point).

Cherise answered 23/4, 2021 at 5:7 Comment(0)
B
3

You can have pyximport recognize the header comment # distutils : language = c++ by having pyximport make extensions using the cythonize command. To do so, you can create a new file filename.pyxbld next to your filename.pyx:

# filename.pyxbld

from Cython.Build import cythonize

def make_ext(modname, pyxfilename):
    return cythonize(pyxfilename, language_level = 3, annotate = True)[0]

and now you can use the distutils header comments:

# filename.pyx

# distutils : language = c++

Pyximport will use the make_ext function from your .pyxbld file to build the extension. And cythonize will recognize the distutils header comments.

Botulinus answered 22/4, 2021 at 22:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.