Setup.py для пакетов, которые зависят как от cython, так и от f2py
Я хотел бы создать setup.py script для пакета python с несколькими подмодулями, которые зависят как от cython, так и от f2py. Я попытался использовать setuptools и numpy.distutils, но до сих пор не удалось:
Использование setuptools
Я могу скомпилировать мои расширения cython (и создать установку для остальной части пакета) с помощью setuptools. Однако мне не удалось выяснить, как использовать setuptools для генерации расширения f2py. После обширного поиска я нашел довольно старые сообщения, подобные этому, в которых говорится, что модули f2py должны быть скомпилированы с помощью numpy.distutils.
Использование numpy.distutils
Я могу скомпилировать мои расширения f2py (и создать установку для остальной части пакета) с помощью numpy.distutils. Однако мне не удалось выяснить, как получить numpy.distutils для компиляции моих расширений cython, поскольку он всегда пытается использовать pyrex для его компиляции (и я использую расширения, специфичные для cython) в последнее время. Я сделал поиск, чтобы выяснить, как получить numpy.distutils для файлов cython и - по крайней мере, год назад - они рекомендуют применять патч обезьяны до numpy. Distutils. Кажется, применение такого патча обезьяны также ограничивает возможности, которые могут быть переданы Cython.
Мой вопрос: какой рекомендуемый способ написать setup.py script для пакетов, которые зависят как от f2py, так и от cython? Является ли применение патча к numpy.distutils действительно способом по-прежнему оставаться?
Ответы
Ответ 1
Вы можете просто вызвать их отдельно в файле setup.py, как в
http://answerpot.com/showthread.php?601643-cython%20and%20f2py
# Cython extension
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup(
ext_modules = [Extension( 'cext', ['cext.pyx'] )],
cmdclass = {'build_ext': build_ext},
script_args = ['build_ext', '--inplace'],
)
# Fortran extension
from numpy.distutils.core import setup, Extension
setup(
ext_modules = [Extension( 'fext', ['fext.f90'] )],
)
Ваш контекст вызова (я думаю, что они называют это пространство имен, не уверены)
должен измениться относительно того, что текущий объект Расширение и функция
setup() есть.
Первый вызов setup(), это distutils.extension.Extension
и distutils.core.setup()
Второй вызов setup(), это numpy.distutils.core.Extension
и numpy.distutils.core.setup()
Ответ 2
Оказывается, это уже не так. С setuptools
и distutils
(по крайней мере, версия numpy
) возможно иметь расширения с C, Cython и f2py. Единственное предостережение в том, что для компиляции модулей f2py всегда нужно использовать numpy.distutils
для функций setup
и Extension
. Но setuptools
все еще можно использовать для установки (например, разрешая установку версии разработчика с python setup.py develop
).
Чтобы использовать distutils
исключительно, вы используете следующее:
from numpy.distutils.core import setup
from numpy.distutils.extension import Extension
Чтобы использовать setuptools
, вам нужно импортировать его до импорта distutils
:
import setuptools
И тогда остальная часть кода идентична:
from numpy import get_include
from Cython.Build import cythonize
NAME = 'my_package'
NUMPY_INC = get_include()
extensions = [
Extension(name=NAME + ".my_cython_ext",
include_dirs=[NUMPY_INC, "my_c_dir"]
sources=["my_cython_ext.pyx", "my_c_dir/my_ext_c_file.c"]),
Extension(name=NAME + ".my_f2py_ext",
sources=["my_f2py_ext.f"]),
]
extensions = cythonize(extensions)
setup(..., ext_modules=extensions)
Очевидно, вам нужно поместить все остальные вещи в вызов setup()
. В приведенном выше примере я предполагаю, что вы будете использовать numpy с Cython вместе с внешним C файлом (my_ext_c_file.c
), который будет в my_c_dir/
, и что модуль f2py
является только одним файлом Fortran. При необходимости отрегулируйте.