【问题标题】:How to get `setup.cfg` metadata at the command line (Python)如何在命令行获取“setup.cfg”元数据(Python)
【发布时间】:2022-08-11 02:45:12
【问题描述】:

当你有一个setup.py 文件时,你可以通过以下命令获取包的名称:

C:\\some\\dir>python setup.py --name

这会将包的名称打印到命令行。

为了坚持最佳实践,我试图通过将所有内容放入setup.cfg 来从setup.py 迁移,因为之前在setup.py 中的所有内容都是静态内容。

但是我们的构建管道依赖于能够调用python setup.py --name。我希望以不需要创建setup.py 文件的方式重写管道。

当您有 setup.cfg 但没有 setup.py 文件时,有没有办法获取包的名称?

  • setuptools.pypa.io/en/latest/… 谈了一点关于 setup-cfg-only 项目模拟一个简单地运行 setuptools.setup() 的虚拟 setup.py 文件。显式创建一个调用 no-arg setup() 方法的 setup.py 文件实际上会读取 setup.cfg 并且足以让我得到名称,但我仍然想知道是否有更好的方法。
  • 保持最小的setup.py 是一个有效的解决方案。否则使用解析。安装工具使用标准库中的ConfigParser 读取setup.cfg,因此如答案中所述,这是一个有效的解决方案。很快安装工具应该支持使用 TOML 格式的PEP 621 标准,并且 TOML 解析器将被添加到 Python 的标准库(Python 3.11)中,因此应该很容易为几乎任何构建后端提取信息(不是只是安装工具)。
  • 如果想更进一步,能够从任何PEP 517 项目(又名pyproject.toml)获取元数据(名称等),那么可以构建某种政治人物 517“构建前端”只是为了这个目的,只关注prepare_metadata_for_build_wheel() 方面,也许pep517 library 可以帮助解决这个问题。

标签: python setuptools setup.py python-packaging


【解决方案1】:

对于允许在build project 的帮助下从任何PEP 517 兼容项目(即pyproject.toml)获取任何元数据字段的“过度杀伤”解决方案:

#!/usr/bin/env python3

import argparse
import pathlib

import build.util

def _main():
    args_parser = argparse.ArgumentParser()
    args_parser.add_argument('path')
    args = args_parser.parse_args()
    path_name = getattr(args, 'path')
    path = pathlib.Path(path_name)
    #
    metadata = build.util.project_wheel_metadata(path)
    print(metadata)

if __name__ == '__main__':
    _main()

这实际上将调用构建后端(安装工具,诗歌,掠过,数据管理器,或水),所以这可能需要几秒钟。

build.util API 记录在 here (on "latest") 中,并在 "0.7.0 (16-09-2021)" 中添加,在此 change 中。


但是,是的,实际上,正如你已经说过的那样,我建议只保留最小的setup.py

#!/usr/bin/env python3

import setuptools
setuptools.setup()

以便python setup.py --name 继续工作

当然,正如其他人已经说过的那样,解析是一种可行且简单的解决方案。安装工具使用标准库中的ConfigParser 来读取setup.cfg文件,所以你也可以这样做。


另一种可能的解决方案(credit to wim):

python -c 'import setuptools; setuptools.setup()' --name

【讨论】:

【解决方案2】:

也许使用ConfigParser Python 模块?

python -c "from configparser import ConfigParser; cf = ConfigParser(); cf.read('setup.cfg'); print(cf['metadata']['name'])"

【讨论】:

【解决方案3】:

TL;DR,使用 setuptools 配置 APIhttps://setuptools.pypa.io/en/latest/setuptools.html#configuration-api

在您的情况下,此行将给出包的名称:

python -c 'from setuptools.config import read_configuration as c; print(c("setup.cfg")["metadata"]["name"])'

编辑:

在 setuptools v61.0.0(2022 年 3 月 24 日)setuptools.config.read_configuration was deprecated 中。使用新的 API,命令变为:

python -c 'from setuptools.config.setupcfg import read_configuration as c; print(c("setup.cfg")["metadata"]["name"])'

解释:

Setuptools 公开了一个 read_configuration() 函数,用于解析配置的元数据和选项部分。在内部,setuptools 使用configparser 模块来解析配置文件setup.cfg。对于简单的str-type 数据,例如“name”键,可以使用 configparser 读取数据。但是,setuptools 也允许使用 configparser 无法直接解析的dynamic configuration using directives

这是一个示例,显示了替换 python setup.py --version 的两种方法之间的区别:

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

1 directory, 3 files

$ cat setup.cfg
[metadata]
name = my_package
version = attr:my_package.__version__

[options]
packages = find:

$ cat my_package/__init__.py 
__version__ = "1.0.0"

$ cat pyproject.toml

$ python -c 'from setuptools.config import read_configuration as c; print(c("setup.cfg")["metadata"]["version"])'
1.0.0

$ python -c 'from configparser import ConfigParser; c = ConfigParser(); c.read("setup.cfg"); print(c["metadata"]["version"])'
attr:my_package.__version__

【讨论】:

    猜你喜欢
    • 2012-01-03
    • 2011-07-19
    • 2013-06-13
    • 2011-09-12
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    • 2019-06-09
    • 1970-01-01
    相关资源
    最近更新 更多