如何将 setup.py 替换为 pyproject.toml 以获取本机 C 构建依赖项?

2023-12-13

我碰到this用于创建 C 编译版本的小项目布莱克-斯科尔斯python 中要使用的函数。

虽然示例代码似乎是今年7月发布的,但似乎使用setup.py旧版构建之外的构建类型已被弃用。任何编译失败,先抱怨缺失MS C++ 14编译器(这不是真的),然后进一步调查,似乎表明 setup.py 不能再使用。

Q: 我怎样才能转换setup.py到有效的pyproject.toml file?

from setuptools import setup, Extension

ext = Extension('bs', sources=['black_scholes/bs.c'])

setup(
    name="black_scholes",
    version="0.0.1",
    description="European Options Pricing Library",
    packages=['black_scholes'],
    ext_modules=[ext]
)

从有点模糊的网站(上面),我创建了以下树结构。

$ tree -L 3 ./
./
├── black_scholes
│   ├── black_scholes
│   │   ├── Makefile
│   │   ├── __init__.py
│   │   └── bs.c
│   ├── pyproject.toml
│   └── setup.py
├── README.md
└── bs_test.py

可能相关的问题:

  • 有没有一种简单的方法将 setup.py 转换为 pyproject.toml
  • Pip 错误:需要 Microsoft Visual C++ 14.0
  • 安装Python包时出现“错误:需要Microsoft Visual C++ 14.0或更高版本”如何解决?
  • 每次我在 VSCode 中打开终端时都会出现“setup.py install is deprecated”警告

在浪费了两天时间试图规避所需的要求之后视觉工作室C++ Build tools要求,唯一可行的不幸选择是提交给>7GB下载以便让我的 20 行 C 函数能够很好地编译和安装Py3.10。 (跟随this.)

使用外部_custom_build.py

以下是有效的文件:

# setup.py
from setuptools import setup, Extension

ext = Extension('bs', sources=['black_scholes/bs.c'])

setup(
    name="black_scholes",
    version="0.0.1",
    description="European Options Pricing Library",
    packages=['black_scholes'],
    ext_modules=[ext]
)

那么对于pyproject.toml:

# pyproject.toml
[build-system]
requires = ["setuptools>=61.0", "cython"]
build-backend = "setuptools.build_meta"

[project]
name        = "black_scholes"
description = "European Options Pricing Library"
version     = "0.0.1"
readme      = "README.md"
requires-python = ">=3.7"
authors = [
  { name="Example Author", email="[email protected]" },
]
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]
keywords = ["quant", "portfolio"]

[project.urls]
"Homepage" = "https://pyquantnews.com/how-to-45x-python-performance-with-c/"

[tool.setuptools]
py-modules = ["_custom_build"]

[tool.setuptools.cmdclass]
build_py = "_custom_build.build_py"

这是使用名为的外部构建文件_custom_build.py,如上面的 SO 链接所建议的。

# _custom_build.py

from setuptools import Extension
from setuptools.command.build_py import build_py as _build_py

class build_py(_build_py):
    def run(self):
        self.run_command("build_ext")
        return super().run()

    def initialize_options(self):
        super().initialize_options()
        if self.distribution.ext_modules == None:
            self.distribution.ext_modules = []

        self.distribution.ext_modules.append(

            Extension(
                "bs",
                sources=["black_scholes/bs.c"],
                extra_compile_args=["-std=c17", "-lm", "-Wl", "-c", "-fPIC"],
            )
        )

然而,似乎extra_compile_args完全被忽略了...

如果有人能提出使用较小的编译器构建的替代解决方案,那就太好了,例如MinGW or so.

最终的树应该是这样的:

$ tree -L 3
.
├── black_scholes
│   ├── black_scholes
│   │   ├── Makefile
│   │   └── bs.c
│   ├── .gitignore
│   ├── README.md
│   ├── __init__.py
│   ├── _custom_build.py
│   ├── pyproject.toml
│   └── setup.py
└── bs_test.py

Using a src构建与setup.py & pyproject.toml

更新:2022-11-14

上面的过程非常混乱,而且根据你的使用方式也给出了不同的结果pip install。最后我完全改变了平面文件夹结构以使用src为基础的结构。现在的工作项目如下所示:

# tree -L 3
.
├── docs
├── examples
│   └── fbs_test.py
├── src
│   ├── black_scholes
│   │   └── __init__.py
│   └── lib
│       ├── Makefile
│       └── fbs.c
├── .gitignore
├── LICENSE.md
├── README.md
├── clean.sh
├── pyproject.toml
└── setup.py

文件的内容是这样的:

# setup.py

from setuptools import setup, find_packages, Extension

ext = Extension(
    name                = 'black_scholes.fbs',          # 'mypackage.mymodule'
    sources             = ['src/lib/fbs.c'],            # list of source files (to compile)
    include_dirs        = ['src/lib'],                  # list of directories to search for C/C++ header files (in Unix form for portability)
    py_limited_api      = True                          # opt-in flag for the usage of Python's limited API <python:c-api/stable>.
)

setup_args = dict(
    packages        = find_packages(where="src"),       # list 
    package_dir     = {"": "src"},                      # mapping
    ext_modules     = [ext],                            # list
    scripts         = ["examples/fbs_test.py"]          # list
)

setup(**setup_args)

and

# pyproject.toml

[build-system]
requires        = ['setuptools>=61.0']                  # 'cython'
build-backend   = 'setuptools.build_meta'   

[project]
name            = 'black_scholes'

# ...

[tool.setuptools]
package-dir = {"" = "src"}
#py-modules = ["_custom_build"]

[tool.setuptools.packages.find]
where = ["src"]

这里是很重要包名称与src/black_scholes目录名称。如果没有,即使在编译和安装包之后,您也会遇到各种非常奇怪的运行时错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 setup.py 替换为 pyproject.toml 以获取本机 C 构建依赖项? 的相关文章

随机推荐