当前位置: 首页 > news >正文

Python中的递归可选依赖

我喜欢将元数据打包到可执行文件中的(慢慢消失的)原因之一setup.py是能够具有可选依赖项,这些依赖项是其他依赖项的组合。从pip 21.2 开始,无需运行代码就可以做到这一点。

包的可选依赖项(也称为extras)是一组命名的依赖项,通过将它们的名称放在包名称后面的方括号内来安装。例如pip install httpx[http2],将安装httpx以及支持 HTTP/2 所需的可选依赖项。您可以一次指定多个额外的:pip install httpx[http2,cli]将安装 HTTP/2 和httpx的 CLI 界面所需的一切。


我喜欢在开发中使用可选依赖项的组合,通过dev额外包含运行测试、构建文档和在交互式开发中有用但不应该出现在 CI 中的工具所需的一切。在运行测试时我不需要Sphinx而在构建文档时我不需要pytest。但是当我在这个项目上工作时,我需要一个更好的调试器或MyPy。

在一个setup.py文件中,它看起来像这样:

extras = {
    "tests": ["pytest"],
    "docs": ["sphinx"],
}
​
extras["dev"] = extras["tests"] + extras["docs"] + ["pdbpp"]
​
setup(
    name="my-pkg",
    # ...
    extras_require=extras,
)

pip install -e .[dev]现在将安装pytest、sphinx和pdbpp. 这样,我的开发环境就准备好了。这对于公共项目特别有用,因为为您的贡献者设置本地开发环境的工作减少到了一行。


这很方便,它让我在很长一段时间内无法使用pyproject.toml(PEP 621 )进行静态配置。其中,这意味着我的可选依赖项中的重复.

然而,我也一直对静态元数据和Hatch或Flit等现代打包工具很感兴趣。

Cog:静态模板

当我和 Python 社区一起发现Cog时,我第一次将脚趾伸入静态水域。Cog允许通过将模板逻辑隐藏在注释后面来在静态文件中应用内联模板。

所以我声明了我的开发特定依赖项(在这种情况下只是pdbpp),然后是一个Cog模板块,它读取和解析pyproject.toml(本身!)并添加来自testsand的依赖项docs:

[project.optional-dependencies]
tests = ["pytest"]
docs = ["sphinx"]
​
dev = [
    "pdbpp",
    # [[[cog
    # import pathlib, tomli
    # cfg = tomli.loads(pathlib.Path("pyproject.toml").read_text())
    # opt = cfg["project"]["optional-dependencies"]
    # for dep in opt["tests"] + opt["docs"]:
    #     print(f'"{dep}",')
    # ]]]
    "pytest",
    "sphinx",
    # [[[end]]]
]

如您所见,pytest和Sphinx是dev列表的一部分,每当我更改tests或docs运行Cog# ]]]时,列表和之间的列表# [[[end]]]都会更新。


为了运行Cog并确保文件没有过期,我使用了两个同样在 CI 中运行的tox目标:cogCheck

[tox]
envlist = cogCheck,cog  # ...
​
[testenv:cogCheck]
description = "Ensure pyproject.toml is up to date"
skip_install = true
deps = {[testenv:cog]deps}
commands = python -m cogapp --check -P pyproject.toml
​
[testenv:cog]
description = "Update pyproject.toml's metadata"
skip_install = true
deps =
    cogapp>=3.3.0
    tomli
commands = python -m cogapp -rP pyproject.toml

这很酷,而且我还使用Cog将我的 README 导入并修改为 PyPI 的长描述,所以它会保留下来。但是,它也有点笨拙,尤其是对于没有长描述的公司内部项目。

终于把我们带到了今天的话题!

开源阅读3.0免费小说神器,支持第三方书源的替换,无广告告别VIP!

pip 21.2:递归依赖

Python 的打包进度可能很慢,但很稳定。从pip 21.2 开始,您可以在可选依赖项中引用您自己的项目:

[project]
name = "my-pkg"
​
[project.optional-dependencies]
tests = ["pytest"]
docs = ["sphinx"]
dev = [
    "my-pkg[tests,docs]",  # <-- !!!
    "pdbpp",
]

由于dev最终用户不使用,因此需要一个前沿(也就是只有一年的)pip版本并不是什么大问题。

这是一个在野外看起来如何的示例:structlog的pyproject.toml.


可能会为您节省一些时间的额外提示:额外的名称像包名称一样标准化。额外foo_bar的必须称为foo-bar. 理想情况下完全停止在额外名称中使用下划线。

去哪儿dev?

对于那些对版本固定非常直言不讳的人来说,我使用可选依赖项而不是 pin 文件可能会令人惊讶。

我没有固定我的开源包的开发依赖项,因为没有足够的活动来证明依赖项更新的不断提交流失是合理的。就目前而言,更实际的是在发生中断的 CI 时修复它(这种情况很少见),而不是成为大多数提交是依赖项更新的项目之一。

这是我的权衡计算——你的可能完全不同。如果您的 CI 由于依赖项更新而定期中断,您应该查看 pin 文件和服务,例如Dependabot。


当然,递归可选依赖关系不仅仅对我用于说明的这个示例有用。

相关文章:

  • 前端Fetch API接收数据
  • 公众号网课接口系统
  • 数据库概述03(jdbc连接)
  • CSS基础知识---扫盲必备~~~
  • 大学网课搜题公众号制作
  • [Codeforces] probabilities (R1600) Part.1
  • 笔试强训(十)
  • 这个 MySQL 问题困扰了我一个月,现在终于把他解决了
  • SOD酶活性测定丨Abbkine超氧化物歧化酶(SOD)活性检测试剂盒
  • 参数解释安捷伦86142B光学分析仪
  • 利用回调函数在driver中收集覆盖率
  • ch05 pointer
  • Java:Kubernetes原生Java与Quarkus
  • 15天深度复习JavaWeb的详细笔记(十二)——综合案例
  • AD生成Gerber及CAM350检查
  • 〔开发系列〕一次关于小程序开发的深度总结
  • cookie和session
  • ECS应用管理最佳实践
  • Flex布局到底解决了什么问题
  • Js基础知识(四) - js运行原理与机制
  • PHP CLI应用的调试原理
  • spring security oauth2 password授权模式
  • SQLServer之索引简介
  • Vultr 教程目录
  • windows下使用nginx调试简介
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 不上全站https的网站你们就等着被恶心死吧
  • 分布式任务队列Celery
  • 服务器之间,相同帐号,实现免密钥登录
  • 关于使用markdown的方法(引自CSDN教程)
  • 批量截取pdf文件
  • 如何解决微信端直接跳WAP端
  • 使用parted解决大于2T的磁盘分区
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 我是如何设计 Upload 上传组件的
  • 责任链模式的两种实现
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • #HarmonyOS:Web组件的使用
  • #WEB前端(HTML属性)
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (Oracle)SQL优化技巧(一):分页查询
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (转)一些感悟
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .net web项目 调用webService
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .net获取当前url各种属性(文件名、参数、域名 等)的方法
  • .NET实现之(自动更新)
  • .NET序列化 serializable,反序列化
  • .vimrc php,修改home目录下的.vimrc文件,vim配置php高亮显示