简体   繁体   English

如何在不使用 setup.py 文件的情况下构建源代码分发?

[英]How to build a source distribution without using setup.py file?

With the following package structure具有以下 package 结构

.
├── my_package
│   └── __init__.py
├── setup.cfg
└── setup.py

Contents of setup.py setup.py的内容

from setuptools import setup
setup()

Contents of setup.cfg setup.cfg的内容

[metadata]
name = my_package
version = 0.1

[options]
packages = find:

I can build wheel or a source distribution for my_package like this我可以像这样为my_package构建轮子或源代码分发

pip wheel --no-deps -w dist .
# generates file ./dist/my_package-0.1-py3-none-any.whl
python setup.py sdist
# generates file ./dist/my_package-0.1.tar.gz

But according to maintainer of setuptools , a declarative build configuration is ideal and using an imperative build is going to be a code smell.但是根据setuptools 的维护者的说法,声明式构建配置是理想的,使用命令式构建将是一种代码味道。 So we replace setup.py with pyproject.toml :所以我们用pyproject.toml替换setup.py

.
├── my_package
│   └── __init__.py
├── setup.cfg
└── pyproject.toml

Contents of pyproject.toml pyproject.toml的内容

[build-system]
build-backend = "setuptools.build_meta"
requires = ["setuptools", "wheel"]

And you can still build a wheel the same way as before, it works.你仍然可以像以前一样制造一个轮子,它可以工作。 But sdist doesn't work:但是 sdist 不起作用:

python: can't open file 'setup.py': [Errno 2] No such file or directory

So how should you actually build the.tar.gz file using setuptools ?那么您应该如何使用 setuptools实际构建 .tar.gz 文件呢? What's the user-facing tool to create sdist?创建 sdist 的面向用户的工具是什么? I do not want to change the build backend.我不想更改构建后端。 It looks like other packaging tools all write their own build entry points, but I thought the whole point of defining a declarative build system in the metadata was so that you didn't have to get hands-on with the build system, learning how each different packaging tool expects to be invoked or having to go into the interpreter and calling a Python API manually.看起来其他打包工具都编写了自己的构建入口点,但我认为在元数据中定义声明式构建系统的全部意义在于,您不必亲自动手构建系统,了解每个构建系统是如何工作的不同的打包工具期望被调用或必须 go 进入解释器并手动调用 Python API。 But the PEP for build system requirements is over 2 years old now.但是构建系统要求的 PEP 现在已经超过 2 年了。 Am I missing something obvious here?我在这里遗漏了一些明显的东西吗?

How to build a source distribution without using setup.py file?如何在不使用setup.py文件的情况下构建源代码分发?

This is a somewhat controversial topic, and the answer for the moment is that there is no one single tool that everyone agrees is the "right way" to build source distributions, nor what that tool would be.这是一个有争议的话题,目前的答案是,没有一个工具是每个人都同意的构建源代码分发的“正确方法”,也没有那个工具会是什么。 You can see a long thread about it on the Python Packaging discourse .您可以在 Python Packaging discourse 上看到一个关于它的长线程

I hesitate to give too much packaging advice in durable formats because the sands are always shifting, but as of November 2019, setup.py sdist is not deprecated, but it does have all the downsides that PEP 517 and PEP 518 were intended to fix - namely that you have to create the build environment yourself (and know about all the build dependencies), and it only works with setuptools/distutils and their equivalents.我不愿提供太多耐用格式的包装建议,因为沙子总是在变化,但截至 2019 年 11 月, setup.py sdist并未被弃用,但它确实具有 PEP 517 和 PEP 518 旨在修复的所有缺点 -即您必须自己创建构建环境(并了解所有构建依赖项),并且它适用于 setuptools/distutils 及其等价物。

It is not an "official" recommendation, but the current (Dec. 2020) best replacement for setup.py sdist and setup.py bdist_wheel is using pypa-build .这不是“官方”建议,但当前(2020 年 12 月) setup.py sdistsetup.py bdist_wheel的最佳替代品是使用pypa-build Install once with安装一次

pip install build

and use as并用作

python -m build --sdist --wheel

This builds source distribution and wheel at the same time.这同时构建了源分发和轮子。 This is how I build my PEP 517-compatible packages.这就是我构建 PEP 517 兼容包的方式。

This requires that your project have a pyproject.toml , and the pyproject.toml must have build-system.requires and build-system.build-backend keys, but it will work for any project with a PEP 517-compatible backend (including flit ).这要求您的项目具有pyproject.toml ,并且pyproject.toml必须具有build-system.requires system.requires 和build-system.build-backend键,但它适用于任何具有 PEP 517 兼容后端的项目(包括flit )。

Other tools其他工具

Why not use flit or poetry or hatch ?为什么不使用flitpoetryhatch Those tools are all available for those who want to use them, but they are not an answer to this question .这些工具都可供想要使用它们的人使用,但它们不是这个问题的答案。 This question is asking about projects build with setuptools that use the declarative setup.cfg format.这个问题询问有关使用声明性setup.cfg格式的setuptools构建的项目。 Neither flit nor poetry act as generic PEP 517 build front-ends, and so they only work as build commands for projects using their respective backends. flitpoetry都不能作为通用的 PEP 517 构建前端,因此它们只能作为使用各自后端的项目的构建命令。

I am not familiar enough with hatch to say whether or not it can manage projects with backends other than setuptools, but (again, as of November 2019), it is not a PEP 517 frontend, and it will not work if you don't have a setup.py (it will raise the error "can't open file setup.py", and it will ignore your pyproject.toml file).我对hatch不够熟悉,无法说明它是否可以使用 setuptools以外的后端管理项目,但是(同样,截至 2019 年 11 月),它不是PEP 517 前端,如果你不这样做,它将无法工作有一个setup.py (它会引发错误“无法打开文件 setup.py”,它会忽略你的pyproject.toml文件)。

If you don't want to install a 3rd party tool and dont want to create a temporary setup.py , you also could use如果您不想安装 3rd 方工具并且不想创建临时setup.py ,您也可以使用

python -c "import setuptools; setuptools.setup()" sdist

There's nothing "obvious" when it comes to Python packaging. Python 包装没有什么“明显”的。 Indeed, for the time being, at least if you are using distutils/setuptools it is necessary to create a (nearly) empty setup.py file, even if you are using a fully declarative setup.cfg :事实上,就目前而言,至少如果您使用的是 distutils/setuptools ,则有必要创建一个(几乎)空的setup.py文件,即使您使用的是完全声明性的setup.cfg

#!/usr/bin/env python
from setuptools import setup
setup()

I also recommend chmod +x setup.py .我还推荐chmod +x setup.py

In this case you are just writing the "entry point" to the build system yourself, and setup() is just the main() function for it--but now all the arguments that were traditionally passed to setup() can be read from setup.cfg instead.在这种情况下,您只是自己编写构建系统的“入口点”,而setup()只是它的main() function - 但现在所有传统上传递给setup()的 arguments 都可以从setup.cfg代替。

Now you can still use setup.py sdist if you want to make a source tarball:现在,如果您想制作源 tarball,您仍然可以使用setup.py sdist

./setup.py sdist

You could also try one of the alternative build systems that are enabled via pyproject.toml , such as Flit .您还可以尝试通过pyproject.toml启用的替代构建系统之一,例如Flit

As far as I know, one of these:据我所知,其中之一:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM