我正在尝试构建一个分发包,其中包含我想在上传到 PyPI 之前编译成二进制文件的 cython 代码。为此,我正在使用 pypa 的
build
,
python -m build
在项目的根目录中。这 cythonizes 代码并为我的系统生成二进制文件,然后在
dist
目录中创建 sdist 和 wheel。然而,轮子被命名为“--py3-none-any.whl”。当我解压缩 .whl
时,我确实找到了适当的二进制文件,
(例如,cycode.cp39-win_amd64.pyd
)。问题是我计划在为多个 python 版本和操作系统构建二进制文件的 GitHub 工作流中运行它。该工作流工作正常,但在上传到 PyPI 时会覆盖(或导致重复版本错误),因为来自各种操作系统的所有轮子都共享相同的名称。然后,如果我在另一个操作系统上从 PyPI 安装,我会收到“找不到模块”错误,因为该操作系统的二进制文件不存在,并且由于它是一个轮子,安装没有重新编译 cython 文件。
我正在使用 64 位 Windows、MacOS 和 Ubuntu。 Python 版本 3.8-3.10。以及下面列出的一小组其他软件包。
有人看到我在这里做错了什么吗?谢谢!
简化包
Tests\
Project\
__init__.py
pycode.py
cymod\
__init__.py
_cycode.pyx
_build.py
pyproject.toml
pyproject.toml
[project]
name='Project'
version = '0.1.0'
description = 'My Project'
authors = ...
requires-python = ...
dependencies = ...
[build-system]
requires = [
'setuptools>=64.0.0',
'numpy>=1.22',
'cython>=0.29.30',
'wheel>=0.38'
]
build-backend = "setuptools.build_meta"
[tool.setuptools]
py-modules = ["_build"]
include-package-data = true
packages = ["Project",
"Project.cymod"]
[tool.setuptools.cmdclass]
build_py = "_build._build_cy"
_build.py
import os
from setuptools.extension import Extension
from setuptools.command.build_py import build_py as _build_py
class _build_cy(_build_py):
def run(self):
self.run_command("build_ext")
return super().run()
def initialize_options(self):
super().initialize_options()
import numpy as np
from Cython.Build import cythonize
print('!-- Cythonizing')
if self.distribution.ext_modules == None:
self.distribution.ext_modules = []
# Add to ext_modules list
self.distribution.ext_modules.append(
Extension(
'Project.cymod.cycode',
sources=[os.path.join('Project', 'cymod', '_cycode.pyx')],
include_dirs=[os.path.join('Project', 'cymod'), np.get_include()]
)
)
# Add cythonize ext_modules
self.distribution.ext_modules = cythonize(
self.distribution.ext_modules,
compiler_directives={'language_level': "3"},
include_path=['.', np.get_include()]
)
print('!-- Finished Cythonizing')
通过将几乎空的 setup.py 文件添加到 pyproject.toml 旁边的根目录中解决了这个问题。其余文件与原始帖子相同。
# setup.py
from setuptools import Extension, setup
extensions = [
Extension(
'Project.cymod.cycode',
sources=[os.path.join('Project', 'cymod', '_cycode.pyx')],
include_dirs=[os.path.join('Project', 'cymod'), np.get_include()]
)
]
setup(
ext_modules=extensions
)
现在正在构建特定于操作系统的轮子,而不是损坏的泛型。目前看来这是 pyproject.toml 的限制。