[python]python使用setup.cfg打一个wheel
0. 目的
工作中发现openstack的setup.cfg用来管理wheel包,现在来写一个demo测试下此功能
0.1 介绍
在 Python 中,setup.cfg 是一个配置文件,用于定义包的元数据和构建选项。它通常与 setup.py 文件一起使用,但也可以完全替代 setup.py 文件,特别是在使用现代的构建工具(如 setuptools 和 wheel)时。setup.cfg 文件的格式基于 INI 文件格式,易于阅读和维护。
0.2 setup.cfg 的作用
setup.cfg 文件的主要作用是:
- 定义包的元数据:如包名、版本、作者、描述等。
- 指定构建选项:如依赖项、入口点、包数据等。
- 配置构建工具:如
setuptools和wheel的行为。
0.3 ironic的setup.cfg的语法解释
# [metadata] 节定义了项目的元数据,这些信息将显示在 PyPI 上,也可能被其他工具使用
[metadata]
name = ironic # 项目名称
summary = OpenStack Bare Metal Provisioning # 项目简短描述
description_file = # 包含项目详细描述的文件
README.rst
author = OpenStack # 项目作者
author_email = openstack-discuss@lists.openstack.org # 作者邮箱
home_page = https://docs.openstack.org/ironic/latest/ # 项目主页 URL
python_requires = >=3.9 # 指定支持的 Python 版本
classifier = # 项目的分类信息,用于在 PyPI 上分类项目
Environment :: OpenStack
Intended Audience :: Information Technology
Intended Audience :: System Administrators
License :: OSI Approved :: Apache Software License
Operating System :: POSIX :: Linux
Programming Language :: Python
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
# [files] 节定义了项目中包含的文件和目录
[files]
# TODO(dtantsur): remove rootwrap files after the packagers drop them.
data_files = # 定义了要包含在分发包中的数据文件
etc/ironic =
etc/ironic/rootwrap.conf
etc/ironic/rootwrap.d = etc/ironic/rootwrap.d/*
share/ironic/vnc-container = tools/vnc-container/*
packages = # 定义了要包含的 Python 包
ironic
# [entry_points] 节定义了项目的入口点,这些入口点可以是命令行脚本、WSGI 应用程序或其他类型的插件
[entry_points]
oslo.config.opts = # 定义了 oslo.config 的选项
ironic = ironic.conf.opts:list_opts
oslo.config.opts.defaults = # 定义了 oslo.config 的默认选项
ironic = ironic.conf.opts:update_opt_defaults
oslo.policy.enforcer = # 定义了 oslo.policy 的执行器
ironic = ironic.common.policy:get_oslo_policy_enforcer
oslo.policy.policies = # 定义了 oslo.policy 的策略
ironic.api = ironic.common.policy:list_policies
console_scripts = # 定义了控制台脚本
ironic = ironic.command.singleprocess:main
ironic-api = ironic.command.api:main
ironic-dbsync = ironic.command.dbsync:main
ironic-conductor = ironic.command.conductor:main
ironic-novncproxy = ironic.command.novncproxy:main
ironic-rootwrap = oslo_rootwrap.cmd:main
ironic-status = ironic.command.status:main
ironic-pxe-filter = ironic.command.pxe_filter:main
wsgi_scripts = # 定义了 WSGI 脚本
ironic-api-wsgi = ironic.api.wsgi:initialize_wsgi_app
ironic.dhcp = # 定义了 Ironic 的 DHCP 接口
dnsmasq = ironic.dhcp.dnsmasq:DnsmasqDHCPApi
neutron = ironic.dhcp.neutron:NeutronDHCPApi
none = ironic.dhcp.none:NoneDHCPApi
ironic.hardware.interfaces.bios = # 定义了 Ironic 的 BIOS 接口
fake = ironic.drivers.modules.fake:FakeBIOS
idrac-redfish = ironic.drivers.modules.drac.bios:DracRedfishBIOS
ironic.hardware.interfaces.boot = # 定义了 Ironic 的启动接口
fake = ironic.drivers.modules.fake:FakeBoot
idrac-redfish-virtual-media = ironic.drivers.modules.drac.boot:DracRedfishVirtualMediaBoot
ilo-pxe = ironic.drivers.modules.ilo.boot:IloPXEBoot
ironic.hardware.interfaces.console = # 定义了 Ironic 的控制台接口
fake = ironic.drivers.modules.fake:FakeConsole
fake-graphical = ironic.drivers.modules.fake:FakeGraphicalConsole
ironic.hardware.interfaces.deploy = # 定义了 Ironic 的部署接口
anaconda = ironic.drivers.modules.pxe:PXEAnacondaDeploy
ansible = ironic.drivers.modules.ansible.deploy:AnsibleDeploy
ironic.hardware.interfaces.firmware = # 定义了 Ironic 的固件接口
fake = ironic.drivers.modules.fake:FakeFirmware
no-firmware = ironic.drivers.modules.noop:NoFirmware
redfish = ironic.drivers.modules.redfish.firmware:RedfishFirmware
ironic.hardware.interfaces.inspect = # 定义了 Ironic 的检查接口
agent = ironic.drivers.modules.inspector:AgentInspect
fake = ironic.drivers.modules.fake:FakeInspect
idrac-redfish = ironic.drivers.modules.drac.inspect:DracRedfishInspect
ironic.hardware.interfaces.management = # 定义了 Ironic 的管理接口
fake = ironic.drivers.modules.fake:FakeManagement
idrac-redfish = ironic.drivers.modules.drac.management:DracRedfishManagement
ilo = ironic.drivers.modules.ilo.management:IloManagement
ironic.hardware.interfaces.network = # 定义了 Ironic 的网络接口
flat = ironic.drivers.modules.network.flat:FlatNetwork
neutron = ironic.drivers.modules.network.neutron:NeutronNetwork
noop = ironic.drivers.modules.network.noop:NoopNetwork
ironic.hardware.interfaces.power = # 定义了 Ironic 的电源接口
agent = ironic.drivers.modules.agent_power:AgentPower
fake = ironic.drivers.modules.fake:FakePower
ironic.hardware.interfaces.raid = # 定义了 Ironic 的 RAID 接口
agent = ironic.drivers.modules.agent:AgentRAID
fake = ironic.drivers.modules.fake:FakeRAID
idrac-redfish = ironic.drivers.modules.drac.raid:DracRedfishRAID
ironic.hardware.interfaces.rescue = # 定义了 Ironic 的救援接口
agent = ironic.drivers.modules.agent:AgentRescue
fake = ironic.drivers.modules.fake:FakeRescue
no-rescue = ironic.drivers.modules.noop:NoRescue
ironic.hardware.interfaces.storage = # 定义了 Ironic 的存储接口
fake = ironic.drivers.modules.fake:FakeStorage
noop = ironic.drivers.modules.storage.noop:NoopStorage
ironic.hardware.interfaces.vendor = # 定义了 Ironic 的供应商接口
fake = ironic.drivers.modules.fake:FakeVendorB
idrac-redfish = ironic.drivers.modules.drac.vendor_passthru:DracRedfishVendorPassthru
ironic.hardware.types = # 定义了 Ironic 的硬件类型
fake-hardware = ironic.drivers.fake_hardware:FakeHardware
idrac = ironic.drivers.drac:IDRACHardware
ilo = ironic.drivers.ilo:IloHardware
ironic.database.migration_backend = # 定义了 Ironic 的数据库迁移后端
sqlalchemy = ironic.db.sqlalchemy.migration
ironic.inspection.hooks = # 定义了 Ironic 的检查钩子
ramdisk-error = ironic.drivers.modules.inspector.hooks.ramdisk_error:RamdiskErrorHook
validate-interfaces = ironic.drivers.modules.inspector.hooks.validate_interfaces:ValidateInterfacesHook
ports = ironic.drivers.modules.inspector.hooks.ports:PortsHook
architecture = ironic.drivers.modules.inspector.hooks.architecture:ArchitectureHook
ironic.console.container = # 定义了 Ironic 的控制台容器
systemd = ironic.console.container.systemd:SystemdConsoleContainer
fake = ironic.console.container.fake:FakeConsoleContainer
# [extras] 节定义了项目的额外依赖项,这些依赖项可以根据用户的需求选择性安装
[extras]
guru_meditation_reports = # guru_meditation_reports 依赖项
oslo.reports>=1.18.0 # Apache-2.0
i18n = # i18n 依赖项
oslo.i18n>=3.20.0 # Apache-2.0
devstack = # devstack 依赖项
virtualbmc>=1.4.0 # Apache-2.0
# [codespell] 节定义了代码拼写检查工具 codespell 的配置
[codespell]
quiet-level = 4 # 设置安静级别
ignore-words-list = selectin,exept,taks,ser,wit,cna,myraid,dum,assertin,checkin,authenticatin,burnin # 定义了要忽略的单词列表
skip = AUTHORS,ChangeLog,*.pyc,*.inv,*.svg,*.png,*.sample,./doc/build/*,./api-ref/build/*,./releasenotes/build/*,./api-ref/build/*,./build/* # 定义了要跳过的文件和目录
1. 创建项目结构
首先,创建一个基本的项目结构:
my_package/
├── my_package/
│ ├── __init__.py
│ └── example.py
├── setup.cfg
└── README.md
2. 编写 setup.cfg 文件
在 my_package 目录下创建 setup.cfg 文件,并添加以下内容:
[metadata]
name = my_package
version = 1.0.0
author = Your Name
author_email = your.email@example.com
description = A simple example package
long_description = file: README.md
long_description_content_type = text/markdown
url = https://github.com/yourusername/my_package
license = MIT
classifiers =
Programming Language :: Python :: 3
License :: OSI Approved :: MIT License
Operating System :: OS Independent
[options]
package_dir =
= .
packages = find:
python_requires = >=3.6
install_requires =
requests
[options.packages.find]
where = .
[build_sdist]
include = README.md
3. 创建 setup.py 文件
虽然可以完全使用 setup.cfg,但有时仍然需要一个简单的 setup.py 文件来触发构建过程。创建一个空的 setup.py 文件:
from setuptools import setup
setup()
4. 创建 README.md 文件
在项目根目录下创建 README.md 文件,内容如下:
# My Package
A simple example package.
5. 创建 my_package 模块
在 my_package 目录下创建 src/my_package/__init__.py 和 src/my_package/example.py 文件。
src/my_package/__init__.py:
from .example import hello
__all__ = ["hello"]
src/my_package/example.py:
def hello():
print("Hello from my_package!")
6. 安装构建工具
确保你已经安装了 setuptools 和 wheel。如果没有安装,可以使用以下命令安装:
pip install setuptools wheel
7. 构建 wheel 文件
在项目根目录下运行以下命令来构建 wheel 文件:
python setup.py sdist bdist_wheel
这将生成一个 dist 目录,其中包含构建的源分发包(sdist)和 wheel 文件(bdist_wheel)。
8. 安装 wheel 文件
可以使用以下命令安装生成的 wheel 文件:
pip install dist/my_package-1.0.0-py3-none-any.whl
9. 测试安装
安装完成后,可以测试是否可以正常使用生成的包:
python -c "from my_package import hello; hello()"
如果一切正常,会看到输出:
Hello from my_package!
10. 查看wheel的元数据
pip show my_package
$ pip show my_package
Name: my_package
Version: 1.0.0
Summary: A simple example package
Home-page: https://github.com/yourusername/my_package
Author: Your Name
Author-email: your.email@example.com
License: MIT
Location: /home/hanwang/python_practise/make_wheel/myenv/lib/python3.12/site-packages
Requires: requests
Required-by:
总结
通过使用 setup.cfg 文件,你可以清晰地定义包的元数据和构建选项,使包的构建过程更加简单和可维护。上述步骤展示了如何从头开始创建一个 Python 包,并生成 wheel 文件,以便于分发和安装。

浙公网安备 33010602011771号