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

По сути:

  1. Создайте файл pyproject.toml со следующим содержанием:
[build-system]
requires = ["setuptools", "wheel", "Cython"]
  1. Использовать pip install -e . для настройки
Другие вопросы по тегам