Я хотел бы создать пакет Python, содержащий код Cython . У меня код Cython работает нормально. Однако теперь я хочу знать, как лучше его упаковать.
Для большинства людей, которые просто хотят установить пакет, я хотел бы включить .c
файл, который создает Cython, и организовать setup.py
его компиляцию для создания модуля. Тогда пользователю не нужно устанавливать Cython для установки пакета.
Но для людей, которые могут захотеть изменить пакет, я также хотел бы предоставить .pyx
файлы Cython и каким-то образом также разрешить setup.py
создавать их с помощью Cython (чтобы этим пользователям был установлен Cython).
Как мне структурировать файлы в пакете, чтобы удовлетворить оба этих сценария?
Документация Cython дает небольшое руководство . Но в нем не говорится, как сделать сингл, setup.py
который обрабатывает как случаи с Cython, так и без него.
Ответы:
Я сам сделал это сейчас в пакете Python
simplerandom
( репозиторий BitBucket - EDIT: теперь github ) (я не ожидаю, что это будет популярный пакет, но это был хороший шанс изучить Cython).Этот метод основан на том факте, что при создании
.pyx
файлаCython.Distutils.build_ext
(по крайней мере, с Cython версии 0.14) всегда создается впечатление, что.c
файл создается в том же каталоге, что и исходный.pyx
файл.Вот сокращенная версия,
setup.py
которая, я надеюсь, показывает самое главное:Я также отредактировал,
MANIFEST.in
чтобы убедиться, чтоmycythonmodule.c
он включен в исходный дистрибутив (исходный дистрибутив, созданный с помощьюpython setup.py sdist
):Я не использую
mycythonmodule.c
"ствол" контроля версий (или "по умолчанию" для Mercurial). Когда я делаю выпуск, мне нужно не забыть сделатьpython setup.py build_ext
первый, чтобы убедиться, чтоmycythonmodule.c
он присутствует и обновлен для распространения исходного кода. Я также делаю релизную ветку и фиксирую C-файл в ветке. Таким образом, у меня есть историческая запись файла C, который был распространен с этим выпуском.источник
Добавление к ответу Крейга Маккуина: см. Ниже, как переопределить
sdist
команду, чтобы Cython автоматически компилировал ваши исходные файлы перед созданием исходного дистрибутива.Таким образом, вы не рискуете случайно распространить устаревшие
C
источники. Это также помогает в случае, когда у вас ограниченный контроль над процессом распределения, например, при автоматическом создании распределений из непрерывной интеграции и т. Д.источник
http://docs.cython.org/en/latest/src/userguide/source_files_and_compilation.html#distributing-cython-modules
источник
Самый простой - включить оба, но просто использовать c-файл? Включение файла .pyx - это хорошо, но в любом случае это не нужно, если у вас есть файл .c. Люди, которые хотят перекомпилировать .pyx, могут установить Pyrex и сделать это вручную.
В противном случае вам понадобится специальная команда build_ext для distutils, которая сначала создает файл C. Cython уже включает один. http://docs.cython.org/src/userguide/source_files_and_compilation.html
В этой документации не говорится, как сделать это условным, но
Должен справиться с этим.
источник
setup.py
можно было собирать непосредственно из.pyx
файла при установке Cython. Мой ответ тоже реализовал это.Включение сгенерированных (Cython) файлов .c довольно странно. Особенно, когда мы включаем это в git. Я бы предпочел использовать setuptools_cython . Когда Cython недоступен, он создаст яйцо со встроенной средой Cython, а затем построит ваш код, используя яйцо.
Возможный пример: https://github.com/douban/greenify/blob/master/setup.py
Обновление (2017-01-05):
Поскольку
setuptools 18.0
в использовании нет необходимостиsetuptools_cython
. Вот пример создания проекта Cython с нуля без использованияsetuptools_cython
.источник
'setuptools>=18.0'
setup_requires вместо создания методаis_installed
?setuptools>=18.0
установлен, то вам нужно только положить'Cython >= 0.18'
вsetup_requires
, и Cython будут установлены в процессе установки прогресса. Но если вы используете setuptools <18.0, даже если у вас конкретный cython в setup_requires, он не будет установлен, в этом случае вам следует рассмотреть возможность использованияsetuptools_cython
.pip install wheel
. Тогда это должна быть причина 1. Сначала установите колесо и попробуйте снова.Это сценарий установки, который я написал, который упрощает включение вложенных каталогов в сборку. Его нужно запускать из папки внутри пакета.
Структура Givig такая:
setup.py
Удачной компиляции;)
источник
Я придумал простой способ:
Просто установите Cython, если его не удалось импортировать. Вероятно, не стоит делиться этим кодом, но для моих собственных зависимостей он достаточно хорош.
источник
Все остальные ответы либо полагаются на
Cython.Build
, что создает проблему с курицей и яйцом между запросом cython viasetup_requires
и его импортом.Современное решение - использовать вместо этого setuptools, см. Этот ответ (для автоматической обработки расширений Cython требуется setuptools 18.0, т. Е. Он доступен уже много лет). Современный стандарт
setup.py
с обработкой требований, точкой входа и модулем cython может выглядеть так:источник
Cython.Build
во время настройки вызывает у меня ImportError. Установочные инструменты для компиляции pyx - лучший способ сделать это.Самый простой способ, который я нашел, используя только setuptools вместо distutils с ограниченными возможностями, - это
источник
Cython.Build
, см. Мой ответ.Я думаю, что нашел довольно хороший способ сделать это, предоставив специальную
build_ext
команду. Идея такая:Я добавляю заголовки numpy, переопределяя
finalize_options()
и выполняя ихimport numpy
в теле функции, что позволяет избежать проблемы недоступности numpy доsetup()
его установки.Если cython доступен в системе, он
check_extensions_list()
подключается к методу команды и путем cythonизирует все устаревшие модули cython, заменяя их расширениями C, которые впоследствии могут обрабатываться этимbuild_extension()
методом. Мы просто предоставляем последнюю часть функциональности в нашем модуле: это означает, что если cython недоступен, но у нас есть расширение C, оно все равно работает, что позволяет вам делать исходные дистрибутивы.Вот код:
Это позволяет просто записывать
setup()
аргументы, не беспокоясь об импорте и о том, доступен ли cython:источник