setup_requires с Cython?
Я создаю setup.py
файл для проекта с некоторыми модулями расширения Cython.
Я уже получил это на работу:
from setuptools import setup, Extension
from Cython.Build import cythonize
setup(
name=...,
...,
ext_modules=cythonize([ ... ]),
)
Это устанавливает нормально. Тем не менее, это предполагает, что Cython установлен. Что делать, если он не установлен? Я понимаю, что это то, что setup_requires
параметр для:
from setuptools import setup, Extension
from Cython.Build import cythonize
setup(
name=...,
...,
setup_requires=['Cython'],
...,
ext_modules=cythonize([ ... ]),
)
Однако, если Cython еще не установлен, это, конечно, завершится ошибкой:
$ python setup.py install
Traceback (most recent call last):
File "setup.py", line 2, in <module>
from Cython.Build import cythonize
ImportError: No module named Cython.Build
Какой правильный способ сделать это? Мне нужно как-то импортировать Cython
только после setup_requires
шаг бежит, но мне нужно Cython
для того, чтобы указать ext_modules
ценности.
2 ответа
Вы должны обернуть from Cython.Build import cythonize
в try-except
и в except
определить cythonize
в качестве фиктивной функции. Таким образом, скрипт может быть загружен без ImportError
,
Потом, когда setup_requires
аргумент обработан, Cython
будет установлен и сценарий установки будет перезапущен. Так как в этот момент Cython
установлен, вы сможете успешно импортировать cythonize
try:
from Cython.Build import cythonize
except ImportError:
def cythonize(*args, **kwargs):
from Cython.Build import cythonize
return cythonize(*args, **kwargs)
РЕДАКТИРОВАТЬ
Как отмечено в комментариях, после того, как setuptools решит проблему с отсутствующими зависимостями, он не будет перезагружать Cython. Я не думал об этом раньше, но вы также можете попробовать поздний обязательный подход к потушению cythonize
Начиная с версии 18.0 setuptools
(выпущено 2015-06-23) можно указать Cython
в setup_requires
и передать *.pyx
модули источников для регулярных setuptools.Extension
:
from setuptools import setup, Extension
setup(
# ...
setup_requires=[
# Setuptools 18.0 properly handles Cython extensions.
'setuptools>=18.0',
'cython',
],
ext_modules=[
Extension(
'mylib',
sources=['src/mylib.pyx'],
),
],
)
Кажется, есть третий способ установить зависимости сборки перед выполнением фактического setup.py
описано здесь (требуется pip
):
https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html
По сути:
- Создайте файл
pyproject.toml
со следующим содержанием:
[build-system]
requires = ["setuptools", "wheel", "Cython"]
- Использовать
pip install -e .
для настройки