简体   繁体   English

如何在命令行获取“setup.cfg”元数据(Python)

[英]How to get `setup.cfg` metadata at the command line (Python)

When you have a setup.py file, you can get the name of the package via the command:当您有setup.py文件时,您可以通过以下命令获取 package 的名称:

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

And this would print the name of the package to the command line.这会将 package 的名称打印到命令行。

In an attempt to adhere to best practice, I'm trying to migrate away from setup.py by putting everything in setup.cfg since everything that was previously in setup.py was static content.为了坚持最佳实践,我试图通过将所有内容都放在setup.cfg中来从setup.py迁移,因为之前setup.py中的所有内容都是 static 内容。

But our build pipeline depends on being able to call python setup.py --name .但是我们的构建管道依赖于能够调用python setup.py --name I'm looking to rewrite the pipeline in such a way that I don't need to create a setup.py file.我希望以不需要创建setup.py文件的方式重写管道。

Is there way to get the name of the package when you have a setup.cfg but not a setup.py file?当您有setup.cfg但没有setup.py文件时,有没有办法获取 package 的名称?

Maybe using the ConfigParser Python module?也许使用ConfigParser Python 模块?

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

For an "over-kill" solution that allows getting any meta-data field from any PEP 517 -compatible project (ie pyproject.toml ), with the help of the build project :对于允许从任何PEP 517兼容项目(即pyproject.toml )获取任何元数据字段的“过度杀伤”解决方案,在build项目的帮助下:

#!/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()

This will actually call the build back-end ( setuptools , poetry , flit , pdm , or watever), so this might take some seconds.这实际上会调用构建后端( setuptoolspoetryflitpdm或 waterver),因此这可能需要几秒钟。

The build.util API is documented here (on " latest ") and it was added in "0.7.0 (16-09-2021)" , in this change . build.util API 记录在此处(在“最新”上)并在 “0.7.0 (16-09-2021)”中添加,在此更改中。


But yes, realistically, as you have already said it I would recommend just keeping a minimal setup.py :但是,是的,实际上,正如你已经说过的那样,我建议只保留一个最小的setup.py

#!/usr/bin/env python3

import setuptools
setuptools.setup()

so that python setup.py --name keeps working这样python setup.py --name继续工作

And of course, as others have already said it, parsing is a viable and simple solution.当然,正如其他人已经说过的那样,解析是一种可行且简单的解决方案。 setuptools uses ConfigParser from the standard library to read the setup.cfg file, so you can do it as well. setuptools使用标准库中的ConfigParser来读取setup.cfg文件,因此您也可以这样做。


Another possible solution ( credit to wim ):另一种可能的解决方案(归功于 wim ):

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

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

In your case, this line will give the name of the package:在您的情况下,此行将给出 package 的名称:

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

Edit:编辑:

In setuptools v61.0.0 (24 Mar 2022)setuptools.config.read_configuration was deprecated .在 setuptools v61.0.0(2022 年 3 月 24 日)中, setuptools.config.read_configuration已弃用 Using the new API, the command becomes:使用新的 API,命令变为:

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

Explanation:解释:

Setuptools exposes a read_configuration() function for parsing metadata and options sections of the configuration. Setuptools 公开了一个read_configuration() function 用于解析配置的元数据和选项部分。 Internally, setuptools uses the configparser module to parse the configuration file setup.cfg .在内部,setuptools 使用configparser模块来解析配置文件setup.cfg For simple str -type data such as the "name" key, configparser can be used to read the data.对于简单的str类型的数据,例如“name”键,可以使用 configparser 来读取数据。 However, setuptools also allows dynamic configuration using directives that cannot be directly parsed with configparser.但是,setuptools 也允许使用无法直接用 configparser 解析的指令进行动态配置

Here is an example that shows the difference between the two approaches for replacing python setup.py --version :这是一个示例,显示了替换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__

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

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