Cython: pyximport ignores install() language_level setting when using a pyxbld file

Created on 5 May 2019  Â·  3Comments  Â·  Source: cython/cython

If I use pyximport with a pyxbld file then setting language_level in install() gets ignored. Sometimes you have to use a pyxbld file because the install() options do not provide functionality for some use cases, e.g. setting extra_compile_args.

Maybe I'm doing something wrong, though I couldn't find anywhere in the docs why this is happening. I found a workaround by setting # cython: directives in the header of the pyx files, though as a new user I spent quite a bit of time trying to fix the problem. I believe if you set something, no matter where you set it as long as it's valid, it should honor the setting.

Related to this, I commented in #1288 that as of Cython 0.29.7 I do not see that Cython automatically sets the language_level setting, you have to do it manually.

Most helpful comment

I managed to successfully provide language_level in .pyxbld like this:

def make_ext(modname, pyxfilename):
    from distutils.extension import Extension
    ext = Extension(
        modname,
        sources = [pyxfilename],
        language = 'c++',
    )
    ext.cython_directives = {'language_level': 3}
    return ext

All 3 comments

Hmmm. I actually consider pyxbld files a rather brutal way of configuring the build. Interfering with that by sneaking in some options from the global setup seems fragile, and I'm not sure it would help to make the configuration more obvious overall. Basically, when you say "I know better" by providing a low-level pyxbld file, then I don't think it's pyximport's job to say "but you probably meant this".

OTOH, I guess it can be argued that the language_level is important/special enough to make sure it's always set, and at least inherit it if it's not provided at all in the Extension but was set by pyximport.install().

Then again, the problem should mostly resolve itself with the release of Cython 3 later this year, which will use language_level=3str by default, i.e. Python 3 syntax. And a change in pyximport's behaviour wouldn't be released before that either, so…

Hmmm. I actually consider pyxbld files a rather brutal way of configuring the build. Interfering with that by sneaking in some options from the global setup seems fragile, and I'm not sure it would help to make the configuration more obvious overall. Basically, when you say "I know better" by providing a low-level pyxbld file, then I don't think it's pyximport's job to say "but you probably meant this".

I didn't know how to turn off the deprecated numpy 1.7 API warning without using a pyxbld file and Extension object extra_compile_args provided option:

import numpy as np

def make_ext(modname, pyxfilename):
    from distutils.extension import Extension
    return Extension(
        name=modname,
        sources=[pyxfilename],
        include_dirs=[np.get_include()],
        extra_compile_args=['-DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION']
    )

OTOH, I guess it can be argued that the language_level is important/special enough to make sure it's always set, and at least inherit it if it's not provided at all in the Extension but was set by pyximport.install().

@scoder How do you specify the language_level in the Extension object?

I managed to successfully provide language_level in .pyxbld like this:

def make_ext(modname, pyxfilename):
    from distutils.extension import Extension
    ext = Extension(
        modname,
        sources = [pyxfilename],
        language = 'c++',
    )
    ext.cython_directives = {'language_level': 3}
    return ext
Was this page helpful?
0 / 5 - 0 ratings