设置setuptools以创建带有头文件的可导入包 [英] Set setuptools to create cimportable package with headers availible

查看:50
本文介绍了设置setuptools以创建带有头文件的可导入包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试实现答案 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代码,而只是复制它.

解决方案

正如我在评论中所说,

  from setuptools导入设置,扩展从Cython.Build导入cythonize从Cython.Distutils导入build_extNAME ="some_name"ext_abc =扩展名(name ="wrapper.wrap",来源= [包装/wrap.pyx"])扩展名= [ext_abc]如果__name__ =="__main__":设置(zip_safe = False,名称= NAME,包装= [包装"],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 安装了它,但是我敢肯定,通过轮子进行的操作基本上是相同的.


要让另一个模块使用您的文件,这非常简单:

来自wrapper.wrap cimport FuncWrapper的

  

该其他模块的setup.py不需要任何特殊内容-您绝对不需要 include_dirs = wrap.get_include()之类的东西.

如果您希望有一个不需要子模块的接口,那么只需

来自包装器cimport FuncWrapper的

  

然后只使用包含以下内容的 __ init __.py :

从.wrap导入

  * 

__ init __.pxd 包含:

来自wrapper.wrap cimport的

  *#我认为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 in wrapper 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 and include_dirs=wrap.get_include() to custom/setup.py like it is done in numpy
  • I run python setup.py bdist_wheel in custom 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆