【问题标题】:Set setuptools to create cimportable package with headers availible设置 setuptools 以创建带有可用标头的可导入包
【发布时间】:2019-12-20 22:18:09
【问题描述】:

我尝试实现答案https://stackoverflow.com/a/57480599/7482208,但我坚持从另一个包导入一个包。

代码在这里:https://github.com/iamishalkin/setuptools_cython_question

我想要的是从包装文件夹中获得一个独立的包wrap,这样您就可以在没有cust 包的情况下使用它。

我还希望能够通过从wrap 继承FuncWrapper 类来创建自定义函数。

我做什么:

  • 首先我在wrapper 文件夹中运行python setup.py bdist_wheel(我想这是我做错了,因为它只给了我二进制文件)
  • 下一个pip instal dist/(some_name).whl
  • 接下来我将import wrapinclude_dirs=wrap.get_include() 添加到custom/setup.py,就像在numpy 中完成的一样
  • 我在custom 文件夹中运行python setup.py bdist_wheel 但失败了,第一步没有创建除二进制文件之外的文件

所以问题是:如何将.pxd 文件添加到最终包中。

我还尝试了sdist,它不会编译 cython 代码而只是复制它。

【问题讨论】:

标签: python cython setuptools cimport


【解决方案1】:

正如我在评论中所说,the Cython documentation recommends putting .pxd files in package_data to install them。这需要稍微不同的结构:

| 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 然后创建一个名为 wrapper 的“包”(这是根据您的版本修改的,因此可以进一步简化):

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"],
    },
        )

请注意,我已将扩展名更改为“wrapper.wrap”,以确保它作为包的一部分安装。然后package_data 能够将 .pxd 文件识别为您要安装的wrapper 的一部分。 这不起作用,除非你把它放在一个“包”中

然后安装它。我刚刚用python3 setup.py install 安装了它,但我确信通过轮子可以做同样的事情。


让另一个模块使用你的文件非常简单:

from wrapper.wrap cimport FuncWrapper

其他模块的 setup.py 不需要什么特别的 - 你绝对不需要像 include_dirs=wrap.get_include() 这样的东西。

如果你想有一个不需要子模块的界面,那么可以这样做

from wrapper cimport FuncWrapper

然后只需使用 __init__.py 包含:

from .wrap import *

还有一个 __init__.pxd 包含:

from wrapper.wrap cimport * # relative import is a little broken in Cython I think

我确信还有其他方法可以做到这一点 - 我只是真正使用 setuptools 来编译 Cython 的东西,从不担心分发太多,所以我不是专家 - 但这看起来是标准方法。

【讨论】:

  • 谢谢,我也在github上找到了例子,但是还没有实现这个我的问题来回答github.com/jkleckner/cython_example
  • 发生了一些奇怪的事情,当我将from wrap cimport * 添加到__init__.pxd 构建自定义时,我得到__init__.pxd:1:0: 'wrap.pxd' not found,如果我不这样做,那么当我调用PyClass().py_wrap(add, 5, 5) 时,我得到Argument 'func' has incorrect type (expected wrap.FuncWrapper, got wrapper.wrap.FuncWrapper)
  • 我已经编辑了答案,所以__init__.p* 有效(我还必须删除从 wrap.pxd 导入自身的稍微奇怪的尝试)
  • 我已经应用了这些更改,但这并没有解决类型问题。我用问题更新了 github repo。我的同事已经用诗歌解决了这个问题,当我明白了解决方案时,我会在这里分享它
猜你喜欢
  • 2014-06-16
  • 1970-01-01
  • 2019-11-18
  • 2023-01-04
  • 2018-05-11
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多