poetry install的hash不一致错误的解决思路

最近 poetry install 总是碰到 hash 不匹配的错误,记录一些解决方案

poetry 简介

Poetry - Python dependency management and packaging made easy 是一款现代化的 Python 的包管理工具,有着诸多良好的特性。其可以管理包版本、管理虚拟环境、发布包、跟踪依赖、构建包等,功能强大,简单易用。与此类似的还有 hatchPDM 等包管理工具。

今天的主题不是 poetry,所以对工具不做过多的介绍,有时间再单独写一篇博客来介绍 poetry。安装了 poetry 之后,使用了很长一段时间都没啥问题。但是最近很容易碰到一个哈希不匹配的错误。

hash 不匹配的错误

错误截图如下所示,我想安装 pyecharts 库,并安装到 dev 分组里面。

https://lynne-markdown.oss-cn-hangzhou.aliyuncs.com/img/image-2023-11-24.png

这个时候,我掏出了 everything,直接在本地搜索这个 whl 文件:

https://lynne-markdown.oss-cn-hangzhou.aliyuncs.com/img/image-2023-11-24-1.png

从上图可以看到,这里文件的大小是 14KB,路径是在 poetry 配置的 cahe-dir 中的 artifacts 目录下。可以使用 poetry config 看到自己的配置目录,我的配置如下所示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
PS D:\> poetry config --list
cache-dir = "F:\\ProgramData\\PoetryEnv"
experimental.system-git-client = false
installer.max-workers = null
installer.modern-installation = true
installer.no-binary = null
installer.parallel = true
virtualenvs.create = true
virtualenvs.in-project = null
virtualenvs.options.always-copy = false
virtualenvs.options.no-pip = false
virtualenvs.options.no-setuptools = false
virtualenvs.options.system-site-packages = false
virtualenvs.path = "{cache-dir}\\virtualenvs"  # F:\ProgramData\PoetryEnv\virtualenvs
virtualenvs.prefer-active-python = false
virtualenvs.prompt = "{project_name}-py{python_version}"

打开 git bash 算一下本地的文件的 hash

https://lynne-markdown.oss-cn-hangzhou.aliyuncs.com/img/image-2023-11-24-2.png

然后去网上搜一下最新版的prettytable-3.9.0-py3-none-any.whlhttps://lynne-markdown.oss-cn-hangzhou.aliyuncs.com/img/image-2023-11-24-3.png

hash 明显对不上,再看下大小:

https://lynne-markdown.oss-cn-hangzhou.aliyuncs.com/img/image-2023-11-24-4.png

好家伙,是 27.8KB,然而本地只有 14KB,所以合理推测没有完全把这个包给下载下来。

这个时候,我先把本地缓存的这个包给删掉,然后重新执行 poetry add pyecharts -G dev -vvv,随后便是一长串的报错,定位到最后,就是:

https://lynne-markdown.oss-cn-hangzhou.aliyuncs.com/img/image-2023-11-24-5.png

所以,错误原因显而易见:在下载包的时候,网络连接错误,导致包只下载了一半就停止下载了。只下载了一半的包,其 sha256 自然会匹配错误。

翻了下 poetry 的源码,发现他下载包的逻辑是这样的,先到 pypi 网站上获取包的信息,直接 get 请求,我本地用 http 代替:

https://lynne-markdown.oss-cn-hangzhou.aliyuncs.com/img/image-2023-11-24-7.png 得到输出: https://lynne-markdown.oss-cn-hangzhou.aliyuncs.com/img/image-2023-11-24-6.png

然后再根据这个 url 去请求下载包。

解决方案

多试几遍

不得不说,最朴素的方法是多试几遍,毕竟网络不可能一直不好~那么,多尝试几遍的步骤如下:

  1. 删掉 poetry 的缓存文件,具体来说,就是你 cache-dir 下的 cache 子文件夹和 artifacts 子文件夹,直接删除即可
  2. 删除 poetry.lock 文件
  3. 重新执行 poetry add/install 命令

有时候我多试了几遍,他又可以下载完全了,就很迷。

手动下载 whl 文件

所谓头痛医头,脚痛医脚。既然检测出来哈希不一致,那就想办法让他们一致!

根据 poetry 的报错,自己去 pypi 上下载对应出错的 whl 文件,然后替换掉本地下载的那个不完全的 whl 文件,接着继续执行 poetry add 命令,直到所有的 whl 都下载了完整版的,就不会报错了。

手动可能比较麻烦,可以写一个脚本来自动化地完成这个工作

使用 pip 下载

比较推荐,步骤很简单:

  1. 手动添加 pyproject.toml 中的包的依赖信息,注意版本
  2. 删掉 poetry.lock 文件
  3. 执行 poetry shell 进入虚拟环境
  4. 使用 pip 下载对应地包
  5. 然后执行 poetry install

也可以把缓存文件都删掉,再执行上述步骤。

比如我要安装 pyecharts 包,我先在 pyproject.toml 文件里面添加一行:pyecharts = "^2.0.4",然后手动使用 pip install pyecharts==2.0.4 安装,安装好了后直接 pip install

只要理解了 poetry 的设计思路,你就会发现可以把安装包这一步从 poetry add 的命令中剥离出来,单独使用 pip 或者 pipx 去安装。不会影响到项目的版本管理。

总结

😢 村里网不好,总是下不下来包,特别是 poetry,我能怎么办,只能手搓了呀!

闲来无事去 poetryissue 搜索了以下,发现很多人都有这个问题:

我不理解,为什么不看看日志呢?我还不理解,poetry 的下载模块怕不是有啥猫病,为啥总会突然中断。

所以啊,执行命令的时候记得把 -vvvvvvv 带上~

Buy me a coffee~
roderick 支付宝支付宝
roderick 微信微信
0%