Hello, I am the co-developer of reedsolo, a Reed-Solomon codec. It provides both a pure-python implementation and a faster cythonized extension, both bundled together because they aim to provide the same interface and same coverage and math guarantees (the pure python implementation being the reference). Before pep517, users could install either :
- by default the pure python implementation, that did not require any dependency nor a C compiler apart from the CPython interpreter.
- optionally by supplying a
--cythonize
argument (ie,python setup.py --cythonize
, orpip install reedsolo --install-option=--cythonize
): the creedsolo.pyx file would be cythonized and then compiled into a creedsolo.dll or creedsolo.so module.
I am now moving to a modern packaging specificaton, with a pyproject.toml file instead of setup.py for most purposes. I could successfully use extras to allow the optional install of Cython. Nevertheless, setup.py is still required by setuptools for extensions, or other custom classes for other backends, because contrary to python scripts packaging, extensions packaging is not standardized under the latest PEPs.
Now, my latest remaining issue is that it seems there is no way to allow explict optional cythonization:
- implicit optional cythonization is possible with other backends than setuptools, such as poetry. Enscons may also work, Hatch does not yet. However, implicit optional cythonization is not robust from a user standpoint: this is what we used to do for reedsolo for years, but we kept seeing issues pop up from users who had Cython installed but no C compiler (especially on Windows). This is why we had to switch to explicit optional cythonization (ie, the user can trigger cythonization manually with a commandline flag).
- for explicit optional cythonization to work, I need a way to pass a flag to my setup.py before the build process. Before,
--install-option
could be used withpip
, but this has been deprecated in issue #11358. Clearly, the recommended workaround (not solution) is to pass an environment variable. However, I don’t like relying on the OS, just like we don’t just provide all the build metadata as environment variables but inside a pyproject.toml file, I would also prefer to use a standard mechanism to propagate some custom flag from the user to my build process. - It seems there is an attempt at standardizing extensions packaging with extensionlib, but it seems the project is lacking updates at the moment and it’s not clear how it can be used for my purpose or even if it can allow explicit optional cythonizatino.
I ended up doing the following two things to make it work:
- pass the
--cythonize
flag through--config-setting
. But since documentation was lacking, I had a very hard time understanding how to pass the flag to by setup.py build process, I ended up using the following:pip install --upgrade reedsolo --config-setting="--build-option=--cythonize" --use-pep517 --verbose
. - I dropped my attempts to make cython an extra/optional dependency, because when I did so, setuptools would not do its magic to make the Cython module available in setup.py, so it resulted in an ImportError. I ended up making cython a required dependency in pyproject.toml, but I can live with that. Before, I wanted to make it an optional dependency to avoid overwriting user’s cython (I am using a beta release), but now with isolated builds this is a non issue. I will regardless open an issue (/EDIT: see issue #3880 on setuptools) because I guess it may bite others too.
Is this correct? I mean, am I propagating the flag properly, via --config-setting="--build-option=--cythonize"
, won’t this get deprecated?
Thank you very much in advance for your insights!