Python能做大项目(6)Poetry -- 项目管理的诗和远方之一

news2024/9/23 7:26:49

[Poetry] 是一个依赖管理和打包工具。Poetry 的作者解释开发 Poetry 的初衷时说:

在这里插入图片描述

通过前面的案例,我们已经提出了一些问题。但不止于此。

当您将依赖加入到 requirements.txt 时,没有人帮你确定它是否与既存的依赖能够和平共处,这个过程要比我们想象的复杂许多,不仅仅是直接依赖,还需要考虑彼此的传递依赖是否也能彼此兼容;所以一般的做法是,先将它们加进来,完成开发和测试,在打包之前,运行pip freeze > requirements.txt来锁定依赖库的版本。但我们也在前面的案例中提到,这种方法可能会将不必要的开发依赖打入到发行版中;此外,它也会过度锁定版本,从而使得一些活跃的第三方库失去自动更新热修复和安全更新的机会。

项目的版本管理也是一个问题。在老旧的 Python 项目中,一般我们使用 bumpversion 来管理版本,它需要使用三个文件。在我的日常使用时,它常常会出现各种问题,最常见的是单双引号导致把__version__ = 0.1当成一个版本号,而不是0.1。这样打出来的包名也会奇怪地多一个无意义的 version 字样。单双引号则是因为你的 format 工具对字符串常量应该使用什么样的引号规则有自己的意见。

项目进行打包和发布需要准备太多的文件,正如 Poetry 的开发者所说,要确保这些文件的内容完全正确,对一个有经验的开发者来说,也不是轻而易举的事。

Poetry 解决了所有这些问题(除了案例中的第一个,该问题要通过 tox 和 CI 来解决)。它提供了版本管理、依赖解析、构建和发布的一站式服务,并将所有的配置,集中到一个文件中,即 pyproject.toml。此外,Poetry 还提供了一个简单的工程创建向导。不过这个向导的功能仍然过于简单,我们的推荐则是使用上一章介绍的 python project wizard。

在这里插入图片描述

现在,让我们看一眼 sample 项目中的 pyproject.toml 文件:

[tool]
[tool.poetry]
name = "sample"
version = "0.1.0"
homepage = "https://github.com/zillionare/sample"
description = "Skeleton project created by Python Project Wizard (ppw)."
authors = ["aaron yang <aaron_yang@jieyu.ai>"]
readme = "README.md"
license =  "MIT"
classifiers=[
    'Development Status :: 2 - Pre-Alpha',
    'Intended Audience :: Developers',
    'License :: OSI Approved :: MIT License',
    'Natural Language :: English',
    'Programming Language :: Python :: 3',
    'Programming Language :: Python :: 3.7',
    'Programming Language :: Python :: 3.8',
    'Programming Language :: Python :: 3.9',
    'Programming Language :: Python :: 3.10',
]
packages = [
    { include = "sample" },
    { include = "tests", format = "sdist" },
]

[tool.poetry.dependencies]
python = ">=3.7.1,<4.0"
fire = "0.4.0"

black  = { version = "^22.3.0", optional = true}
isort  = { version = "5.10.1", optional = true}
flake8  = { version = "4.0.1", optional = true}
flake8-docstrings = { version = "^1.6.0", optional = true }
pytest  = { version = "^7.0.1", optional = true}
pytest-cov  = { version = "^3.0.0", optional = true}
tox  = { version = "^3.24.5", optional = true}
virtualenv  = { version = "^20.13.1", optional = true}
pip  = { version = "^22.0.3", optional = true}
mkdocs  = { version = "^1.2.3", optional = true}
mkdocs-include-markdown-plugin  = { version = "^3.2.3", optional = true}
mkdocs-material  = { version = "^8.1.11", optional = true}
mkdocstrings  = { version = "^0.18.0", optional = true}
mkdocs-material-extensions  = { version = "^1.0.3", optional = true}
twine  = { version = "^3.8.0", optional = true}
mkdocs-autorefs = {version = "^0.3.1", optional = true}
pre-commit = {version = "^2.17.0", optional = true}
toml = {version = "^0.10.2", optional = true}
livereload = {version = "^2.6.3", optional = true}
pyreadline = {version = "^2.1", optional = true}
mike = { version="^1.1.2", optional=true}

[tool.poetry.extras]
test = [
    "pytest",
    "black",
    "isort",
    "flake8",
    "flake8-docstrings",
    "pytest-cov"
    ]

dev = ["tox", "pre-commit", "virtualenv", "pip", "twine", "toml"]

doc = [
    "mkdocs",
    "mkdocs-include-markdown-plugin",
    "mkdocs-material",
    "mkdocstrings",
    "mkdocs-material-extension",
    "mkdocs-autorefs",
    "mike"
    ]

[tool.poetry.scripts]
sample = 'sample.cli:main'

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.black]
line-length = 88
include = '\.pyi?$'
exclude = '''
/(
    \.eggs
  | \.git
  | \.hg
  | \.mypy_cache
  | \.tox
  | \.venv
  | _build
  | buck-out
  | build
  | dist
)/
'''
[tool.isort]
profile = "black"

我们简单地解读一下这个文件:
在 [tool.poetry] 那一节,定义了包的名字(这里是 sample)、版本号(这里是 0.1.0)和其它的一些字段,比如 classifiers,这是打包和发布时需要的。如果您熟悉 python setup tools,那么对这些字段将不会陌生。packages 字段指明了打包时需要包含的文件。在示例中,我们要求在以.whl 格式发布的包中,将 sample 目录下的所有文件打包发布;而以 sdist 格式(即.tar.gz) 发布的包中,还要包含 tests 目录下的文件。

接下来是 [tool.poetry.dependencies] 一节,这是我们声明项目依赖的地方。首先是项目要求的 python 版本声明。这里我们要求必须在 3.7.1 以上,4.0 以下的 python 环境中运行。因此,python 3.7.1,3.8, 3.9, 3.10 都是恰当的 python 版本,但 4.0 则不允许。

接下来就是工程中需要用到的其它第三方依赖,有运行时的(即当最终用户使用我们的程序时,必须安装的那些第三方依赖),也有开发时的(即只在开发和测试过程中使用到的,比如文档工具类 mkdocs,测试类 tox, pytest 等)。

我们对运行时和开发时需要的依赖进行了分组。对开发时需要的依赖,我们分成 dev, test 和 doc 三组,通过 [tool.poetry.extras] 中进行分组声明。对于归入到 dev, test 和 doc 分组中的依赖,我们在 [tool.poetry.dependencies] 中,将其声明为 optional 的,这样在安装最终分发包时,这些声明为 optional 的第三方依赖将不会安装到用户环境中。

再接下来,[tool.poetry.scripts] 声明了一个 console script 入口。Console script 是一种特殊的 Python 脚本,它使得您可以象调用普通的 shell 命令一样来调用这个脚本。

[tool.poetry.scripts]
sample = 'sample.cli:main'

在这里插入图片描述

当 sample 包被安装后,就往安装环境里注入了一个名为sample的shell 命令。它可以接受各种参数,最终将交给 sample\cli.py 中的 main 函数来执行。

接下来就是关于如何构建的相关指示,在 [build-system] 中。如果你的程序中只包含纯粹的 Python 代码,那么这部分可不做任何修改。如果你的程序包含了一些原生的代码(比如 c 的),那么就需要自己定义构建脚本。

在示例代码中,还有 [tool.black] 和 [tool.isort] 两个小节,分别是 black(代码格式化工具)和 isort(将导入进行排序的工具)的配置文件。它们是对 pyproject.toml 的扩展,并不是 poetry 所要求的。

版本管理

poetry 为我们的 package 提供了基于语义 (semantic version) 的版本管理功能。它通过poetry version这个命令,让我们查看 package 的版本,并且实现版本号的升级。

假设您已经使用 [python project wizard] 生成了一个工程框架,那么应该可以在根目录下找到 pyproject.toml 文件,其中有一项:

version = 0.1

如果您现在运行poetry version这个命令,就会显示0.1这个版本号。

Poetry 使用基于语义的版本 (semantic version) 表示法。

在 Poetry 中,当我们需要修改版本号时,并不是直接指定新的版本号,而是通过poetry version semver来修改版本。semver可以是patch, minor, major, prepatch, preminor, premajorprerelease中的一个。这些关键字定义在规范 PEP 440 中。

semver与您当前的版本号相结合,通过运算,就得出了新的版本号:

rulebeforeafter
major1.3.02.0.0
minor2.1.42.2.0
patch4.1.14.1.2
premajor1.0.22.0.0-alpha.0
preminor1.0.21.1.0-alpha.0
prepatch1.0.21.0.3-alpha.0
prerelease1.0.21.0.3-alpha.0
prerelease1.0.3-alpha.01.0.3-alpha.1
prerelease1.0.3-beta.01.0.3-beta.1

可以看出,poetry 对版本号的管理是完全符合 semantic version 的要求的。当你完成了一个小的修订(比如修复了一个 bug,或者增强了性能,或者修复了安全漏洞),此时只应该递增 package 的修订号,即 x.y.z 中的’z’,这时我们就应该使用命令:

$ poetry version patch

如果之前的版本是 0.1.0,那么运行上述命令后,版本号将变更为 0.1.1。
如果我们的 package 新增加了一些功能,而之前提供的功能(API)都还能不加修改,继续使用,那么我们应该递增次版本号,即 x.y.z 中的’y’。这时我们应该使用命令:

$ poetry version minor

如果之前的版本是 0.1.1,那么运行上述命令后,版本号将变更为 0.2.0

如果我们的 package 进行了大幅的修改,并且之前提供的功能(API)的签名已经变掉,从而使得调用者必须修改他们的程序才能继续使用这些 API,又或者新的版本不再能兼容老版本的数据格式,用户必须对数据进行额外的迁移,那么,我们就认为这是一次破坏性的更新,必须升级主版本号:

$ poetry version major

如果之前的版本号是 0.3.1, 那么运行上述命令之后,版本号将变更为 1.0.0;如果之前的版本号是 1.2.1,那么运行上述命令之后,版本号将变更为 2.0.0。

除此之外,poetry 还提供了预发布版本号的支持。比如,上一个发布的版本是 0.1.0,那么我们在正式发布 0.1.1 这个修订之前,可以使用 0.1.1.a0 这个版本号:

$ poetry version prerelease
Bumping version from 0.1.0 to 0.1.1a0

如果需要再出一个 alpha 版本,则可以再次运行上述命令:

$ poetry version prerelease
Bumping version from 0.1.1a0 to 0.1.1a1

如果 alpha 版本已经完成,可以正式发布,运行下面的命令:

$ poetry version patch
Bumping version from 0.1.1a1 to 0.1.1

poetry 暂时还没有提供从 alpha 转到 beta 版本系列的命令。如果有此需要,您需要手工编辑 pyproject.toml 文件。

除了 poetry version prerelease 之外,我们还注意到上面列出的 premajor, preminor 和 prepatch 选项。它们的作用也是将版本号修改为 alpha 版本系列,但无论你运行多少次,它们并不会象 prerelease 选项一样,递增 alpha 版本号。所以在实际的 alpha 版本管理中,似乎只使用poetry version prerelease就可以了。


本文来源于《Python能做大项目》(暂定名),将由机械工业出版社出版。全书已经在大富翁量化官网上首发,欢迎提前阅读。


【本系列其它文章】

Python能做大项目(1) - 为什么要学Python之一
Python能做大项目(2) - 开发环境构建
Python能做大项目(3) - 依赖地狱与Conda虚拟环境
Python能做大项目(4) - 项目布局与生成向导
Python能做大项目(5) - 基于语义的版本管理
Python能做大项目(6) - Poetry: 项目管理的诗和远方之一

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1335527.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java数据结构与算法刷题-----LeetCode633. 平方数之和

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 思路一&#xff1a;双指针 可以使用双指针&#xff0c;不断从两个方向匹配…

分享71个Java源码总有一个是你想要的

分享71个Java源码总有一个是你想要的 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/1frK-W3GT8WrydSlQ-E3o6A?pwd6666 提取码&#xff1a;6666 UI代码 def __init__(self):import …

大数据技术学习笔记(十一)—— Flume

目录 1 Flume 概述1.1 Flume 定义1.2 Flume 基础架构 2 Flume 安装3 Flume 入门案例3.1 监控端口数据3.2 实时监控单个追加文件3.3 实时监控目录下多个新文件3.4 实时监控目录下的多个追加文件 4 Flume 进阶4.1 Flume 事务4.2 Flume Agent 内部原理4.3 Flume 拓扑结构4.3.1 简单…

C++之多层 if-else-if 结构优化(三)

C之多层 if-else-if 结构优化(二)-CSDN博客 接上面的内容继续讲解多层 if-else-if结构优化 8、利用规则执行器来进行优化 8.1 业务场景介绍 if (未注册用户){return false; }if (是否国外用户) {return false; }if (刷单用户) {return false; }if (未付费用户 && 不…

数据仓库【2】:架构

数据仓库【2】&#xff1a;架构 1、架构图2、ETL流程2.1、ETL -- Extract-Transform-Load2.1.1、数据抽取&#xff08;Extraction&#xff09;2.1.2、数据转换&#xff08;Transformation&#xff09;2.1.3、数据加载&#xff08; Loading &#xff09; 2.2、ETL工具2.2.1、结构…

github新建仓库推送代码教学

之前一直用gitee&#xff0c;准备转到github。因为一步一步尝试。如果是新手或许文章会有帮助 点击 new 创建 拉代码 Idea 打开 复制一个 pom 文件作为 maven 管理 提交代码 不出意外的出意外&#xff0c;报错 点击authorize JetBrains 失败 分析问题 本质就是没有…

零基础入门网络安全必看的5本书籍(附PDF)

书中自有黄金屋&#xff0c;书中自有颜如玉。很多人学习一门技术都会看大量的书籍&#xff0c;经常也有朋友询问&#xff1a;零基础刚入门&#xff0c;应该看哪些书&#xff1f;应该怎么学&#xff1f;等等问题。今天就整理了5本零基础入门网络安全必看书籍&#xff0c;希望能帮…

Ubuntu 22.04.3 Server 设置静态IP 通过修改yaml配置文件方法

目录 1.查看网卡信息 2.修改yaml配置文件 3.应用新的网络配置 4.重新启动网络服务 文章内容 本文介绍Ubuntu 22.04.3 Server系统通过修改yaml配置文件配置静态 ip 的方法。 1.查看网卡信息 使用ifconfig命令查看网卡信息获取网卡名称​ 如果出现Command ifconfig not fo…

若依SQL Server开发使用教程

1. sys_menu表中的将菜单ID修改为自动ID,解决不能增加菜单的问题&#xff0c;操作流程如下&#xff1a; 解决方案如下 菜单栏->工具->选项 点击设计器&#xff0c;去掉阻止保存要求更新创建表的更改选项&#xff0c;点确认既可以保存了 2 自动生成代码找不表的解决方案…

智能优化算法应用:基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.指数分布算法4.实验参数设定5.算法结果6.…

20231225使用BLE-AnalyzerPro WCH升级版BLE-PRO蓝牙分析仪抓取BLE广播数据

20231225使用BLE-AnalyzerPro WCH升级版BLE-PRO蓝牙分析仪抓取BLE广播数据 2023/12/25 20:05 结论&#xff1a;硬件蓝牙分析仪 不一定比 手机端的APK的效果好&#xff01; 亿佰特E104-2G4U04A需要3片【单通道】&#xff0c;电脑端的UI为全英文的。 BLE-AnalyzerPro WCH升级版B…

前端---css 的介绍

1. css 的定义 css(Cascading Style Sheet)层叠样式表&#xff0c;它是用来美化页面的一种语言。 没有使用css的效果图 使用css的效果图 2. css 的作用 美化界面, 比如: 设置标签文字大小、颜色、字体加粗等样式。控制页面布局, 比如: 设置浮动、定位等样式。 3. css 的基本语…

B/S和C/S的区别和联系

B/S和C/S的区别和联系 1 B/S2 C/S3 B/S和C/S区别4 B/S和C/S联系 1 B/S B/S&#xff08;Brower/Server&#xff09;架构&#xff0c;也称为B/S结构或B/S模式&#xff0c;是Web兴起后的一种网络结构模式。在这种模式下&#xff0c;Web浏览器成为客户端最主要的软件。系统功能实现…

MongoDB文档操作

3.3 文档操作 3.1 文档介绍 文档的数据结构和 JSON 基本一样。 所有存储在集合中的数据都是 BSON 格式。 BSON 是一种类似 JSON 的二进制形式的存储格式&#xff0c;是 Binary JSON 的简称。 文档是一组键值(key-value)对(即 BSON)&#xff0c;一个简单的文档例子如下&…

AI 引擎系列 8 - 运行时比率参数简介

简介 在 Versal AI 引擎 2 一文 中&#xff0c;我们注意到计算图 (graph) 文件中有一行内容用于为每个内核实例定义运行时比率参数。 在本文中&#xff0c;我们将讲解该参数如何影响 AI 引擎应用的资源使用率和性能。 要求 下文要求您通读前几篇 AI 引擎系列博文。 AI 引擎系…

低代码实施复杂应用的实践方法

内容来自演讲&#xff1a;韦有炬 | 柳州知行远企业管理咨询有限公司 | 总经理 摘要 本文探讨了在全民开发时代如何使用低代码实施复杂应用并降低上线风险。文章分析了复杂系统实施失败的风险&#xff0c;包括项目规划不周、人员变动、企业基础管理不足等&#xff0c;并对比了低…

基于JavaServelet的同学录管理系统(Java毕业设计)

点击咨询源码 大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的…

智能优化算法应用:基于卷积优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于卷积优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于卷积优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.卷积优化算法4.实验参数设定5.算法结果6.…

搭建react+ant design pro+umi 项目框架

一、 写本文的原因 我搭建reactantdumi这个框架的原始资料主要是来源于&#xff08;ReactUmi4从零快速搭建中后台系统保姆级记录教程&#xff08;一、项目创建及初始化&#xff09;&#xff09; 而我写这篇文章的本意就是用来记录我用搭建时候的步骤汇总。 二、 npm和node版…

找不到msvcr90.dll文件怎么办?msvcr90.dll丢失如何修复?

在日常使用计算机的过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“msvcr90.dll缺失”。那么&#xff0c;msvcr90.dll到底是什么&#xff1f;为什么会出现丢失的情况&#xff1f;本文将为您详细介绍msvcr90.dll的定义、丢失原因以及提供5种不同的解决…