[英]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.这实际上会调用构建后端( setuptools 、 poetry 、 flit 、 pdm或 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.