2

mymodule.c 开始如下:

#define PY_SSIZE_T_CLEAN
#define Py_LIMITED_API 0x03070000 
#include "Python.h"

它构建时没有错误和警告。然而,生成的文件被命名为

mymodulename.cpython-37m-x86_64-linux-gnu.so

构建命令:

$ python setup.py build

当我改为发出

$ pip wheel .

轮子中包含的扩展名相同,因此轮子也没有 ABI3 标签。

我期望一个带有 abi3 或类似名称的文件名,如 PEP 425 中所述。

到目前为止,我的研究令人沮丧。我查看了 PEP 384 和 425、docs.python.org 上的文档和相关教程,特别是它的 C/API 和 distutils、PYPA 的文档、setuptools、wheel 和 pip 上的文档 - 无济于事。

当前 Python 源代码发行版中包含的文件 /modules/xxmodule.c 仅具有历史意义。
我在这里想念什么?

4

1 回答 1

5

这取决于后端;并非所有构建后端都支持 PEP 384。

distutils

例如,当使用纯distutils(所以

from distutils.core import setup

setup(...)

),无法更改扩展后缀;这就是为什么几年前我不得不问更改 Cython 对 .so 文件的命名规则的问题。但是你现在不应该使用 pure distutils,所以本节只是为了完整起见。

setuptools

如果您使用setuptools,则必须py_limited_api=True在创建Extension对象时传递。例子:

from setuptools import setup, Extension


setup(
    ...,
    ext_modules=[
        # this extension will have the SOABI suffix, e.g.
        # cpython-37m-darwin or cpython-39-x86_64-linux-gnu etc.
        Extension("foo", ["foo.c"]),
        # this extension will have the `abi3.so` suffix
        Extension("bar", ["bar.c"], py_limited_api=True),
    ],
)

setuptools_rust

奖励:如果您正在从 Rust 代码构建扩展模块并且碰巧使用setuptools_rust,那么从 v0.11.4 开始,现在也可以构建符合 PEP 384 的扩展:

from setuptools import setup
from setuptools_rust import RustExtension


setup(
    ...,
    rust_extensions=[
        RustExtension("foo.rust", py_limited_api=True, features=["pyo3/abi3"]),
    ],
)

pip wheel: 构建正确的车轮标签

当我发出

$ pip wheel .

轮子中包含的扩展名相同,因此轮子也没有 ABI3 标签。

车轮标签是一个不同的故事。它独立于它打包的扩展名。要设置有限的 ABI,在以通常的方式构建轮子时,会发出

$ python setup.py bdist_wheel --py-limited-api=cp37

生成的轮子将具有名称<pkg>-<ver>-cp37-abi3-<platform>.whl

但是,这不起作用,pip wheel因为您无法将选项传递给bdist_wheel子命令。因此,您可以将其保留在setup.cfg

# setup.cfg
[bdist_wheel]
py_limited_api = cp37

现在运行时pip wheel .bdist_wheel将从中选择选项setup.cfg并组装正确的车轮名称。

于 2021-02-04T23:25:57.823 回答