python - 设置 setuptools 以创建带有可用标头的 cimportable 包
问题描述
我尝试实现答案https://stackoverflow.com/a/57480599/7482208,但我坚持从另一个包导入一个包。
代码在这里:https ://github.com/iamishalkin/setuptools_cython_question
我想要的是wrap
从 wrapper 文件夹中获得一个独立的包,这样您就可以在没有cust
包的情况下使用它。
而且我还希望能够通过FuncWrapper
从wrap
.
我所做的:
- 首先我
python setup.py bdist_wheel
在wrapper
文件夹中运行(我想这是我做错了,因为它只给了我二进制文件) - 下一个
pip instal dist/(some_name).whl
- 接下来我添加
import wrap
并include_dirs=wrap.get_include()
喜欢custom/setup.py
它完成numpy
- 我
python setup.py bdist_wheel
在custom
文件夹中运行,但失败了,第一步没有创建除二进制文件之外的文件
所以问题是:如何将.pxd
文件添加到最终包中。
我也试过sdist
不编译 cython 代码而只是复制它。
解决方案
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.
推荐阅读
- python - socket.gaierror: [Errno 8] nodename or servname provided, or not known : Dash App
- java - 在“用户名”和“密码”字段中使用 Junit 5 进行参数化测试
- c++ - 打开一个 csv 文件进行测试,但 myfile.is_open() 返回 false
- javascript - Python中的JavaScript toString(16)用于浮点数?
- c - strtoll 溢出时未将 errno 设置为 ERANGE
- arrays - 将元素附加到数组后,它应该显示更多元素
- c++ - 无法在 Visual Studio 的 C++ 中使用graphic.h
- html - 停止 CSS 过渡在页面加载时运行
- etl - 在运行时更新 Talend 中的设计工作流程
- python - Python新手:如何在我的程序中定义'nl'?