设置setuptools以创建带有头文件的可导入包 [英] Set setuptools to create cimportable package with headers availible
问题描述
我尝试实现答案 https://stackoverflow.com/a/57480599/7482208 ,但是我是卡住了从另一个导入一个包的过程.
代码在这里: https://github.com/iamishalkin/setuptools_cython_question
我想要的是从wrapper文件夹中获得一个独立的程序包 wrap
,这样您就可以在没有 cust
程序包的情况下使用它.
我还希望能够通过从 wrap
继承 FuncWrapper
类来创建自定义函数.
我做什么:
- 首先,我在
wrapper
文件夹中运行python setup.py bdist_wheel
(我想这是我做错了,因为它只给我二进制文件) - 下一个
pip安装区dist/(some_name).whl
- 接下来,我将
import wrap
和include_dirs = wrap.get_include()
添加到custom/setup.py
中,就像在中完成操作一样> numpy
- 我在
custom
文件夹中运行python setup.py bdist_wheel
,并且失败,在第一步中,除了二进制文件之外,没有其他文件被创建
所以问题是:如何将 .pxd
文件添加到最终程序包中.
我还尝试过 sdist
,它不编译cython代码,而只是复制它.
该其他模块的setup.py不需要任何特殊内容-您绝对不需要 include_dirs = wrap.get_include()
之类的东西.
如果您希望有一个不需要子模块的接口,那么只需
来自包装器cimport FuncWrapper的
然后只使用包含以下内容的 __ init __.py
:
*
和 __ init __.pxd
包含:
*#我认为Cython中的相对导入有点中断
我敢肯定还有其他方法可以做到这一点-我只使用过setuptools来编译Cython的东西,从不真正担心分配过多,所以不是专家-但这似乎是标准方法./p>
I try to implement the answer https://stackoverflow.com/a/57480599/7482208, but I am stuck on cimporting one package from another.
The code is here: https://github.com/iamishalkin/setuptools_cython_question
What I want is to have one independent package wrap
from wrapper folder such that you can use it without cust
package.
And I also want to be able to create custom functions by inheriting FuncWrapper
class from wrap
.
What I do:
- Firstly I run
python setup.py bdist_wheel
inwrapper
folder (this is what I am doing wrong, I suppose, as it gives me only binary file) - Next
pip instal dist/(some_name).whl
- Next I add
import wrap
andinclude_dirs=wrap.get_include()
tocustom/setup.py
like it is done innumpy
- I run
python setup.py bdist_wheel
incustom
folder and this fails, on the first step no files except binary one were created
So the question is: how to add .pxd
files to the final package.
I also tried sdist
which does not compile cython code but just copies it.
As I said in a comment, the Cython documentation recommends putting .pxd files in package_data
to install them. This necessitates a slightly different structure:
| setup.py
+ wrapper
| wrap.pxd
| wrap.pyx
| __init__.py # just so it's recognised as a package
# may be unnecessary with recent Python versions
setup.py then creates a "package" called wrapper (this is modified from your version so it's possible it could be simplied further):
from setuptools import setup, Extension
from Cython.Build import cythonize
from Cython.Distutils import build_ext
NAME = "some_name"
ext_abc = Extension(name="wrapper.wrap",
sources=["wrapper/wrap.pyx"]
)
EXTENSIONS = [
ext_abc
]
if __name__ == "__main__":
setup(
zip_safe=False,
name=NAME,
packages=["wrapper"],
cmdclass={"build_ext": build_ext},
ext_modules=cythonize(EXTENSIONS, language_level=3),
package_data = {
"wrapper": ["*.pxd"],
},
)
Note that I've changed the name of the extension to "wrapper.wrap" to ensure that it's installed as part of the package. The package_data
is then able to recognised .pxd files as part of wrapper
that you want to install. This doesn't work unless you put it in a "package".
You then install it. I just installed it with python3 setup.py install
but I'm sure going through a wheel does largely the same thing.
For another module to use you file it's very simple:
from wrapper.wrap cimport FuncWrapper
The setup.py for that other module need have nothing special - you definitely don't need anything like include_dirs=wrap.get_include()
.
If you want to have an interface where you don't need submodules so can just do
from wrapper cimport FuncWrapper
then just use an __init__.py
containing:
from .wrap import *
and an __init__.pxd
containing:
from wrapper.wrap cimport * # relative import is a little broken in Cython I think
I'm sure there are other ways of doing this - I've only really used setuptools for compiling Cython stuff and never really worried about distributing too much so am not an expert - but this looks to be the standard approach.
这篇关于设置setuptools以创建带有头文件的可导入包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!