Python系列Bug修复PyCharm控制台pip install报错:如何解决 pip install -r requirements.txt 报错 In –require-hashes mode, all requirements must have their versions pinned with ‘==’ 问题
摘要: 在日常使用 PyCharm 进行Python项目依赖管理时,执行 pip install -r requirements.txt –require-hashes 命令突然抛出 In –require-hashes mode, all requirements must have their versions pinned with == 报错,是令无数开发者头疼的"拦路虎"。该问题本质上是 pip 的强安全校验机制 在发挥作用——它要求所有依赖(包括直接依赖与间接依赖)必须使用 == 精确固定版本,并附带 sha256 等哈希值用于完整性校验。本文将从 开发场景还原、环境配置、根因剖析、十大解决方案、Mermaid可视化排障流程、常见错误速查表 等维度,手把手带你彻底攻克这一难题,适用于 Python 3.10+、PyCharm 2025、macOS/Windows 全平台场景。
文章目录
- Python系列Bug修复PyCharm控制台pip install报错:如何解决 pip install -r requirements.txt 报错 In –require-hashes mode, all requirements must have their versions pinned with '==' 问题
-
- 一、开发背景与异常场景还原
-
- 1.1 典型报错场景
- 1.2 什么情况下会触发该报错?
- 二、开发环境说明
- 三、问题根源深度剖析
-
- 3.1 `–require-hashes` 安全机制解析
- 3.2 报错根因拆解
- 3.3 新手常见误判(90%的人踩过这些坑)
- 四、系统化解决方案大全 🔧
-
- 4.1 方案一:生成带哈希的合规 requirements.txt(核心方案)
- 4.2 方案二:使用 pip-tools 自动化管理依赖(企业级推荐)
- 4.3 方案三:去掉 `–require-hashes` 参数(快速绕过)
- 4.4 方案四:处理间接依赖版本冲突(进阶排障)
- 4.5 方案五:网络问题切换国内镜像源
- 4.6 方案六:升级 pip 至最新版本
- 4.7 方案七:检查 PYTHONPATH 与包导入路径
- 4.8 方案八:排查包名冲突与 `__init__.py` 缺失
- 4.9 方案九:处理可编辑安装项 `-e .` 的哈希问题
- 4.10 方案十:使用 `–no-deps` 参数规避依赖解析
- 4.11 方案十一:不恰当使用相对导入的修复
- 4.12 方案十二:pip 缓存污染清理
- 五、Mermaid 可视化排障流程
-
- 5.1 完整排障时序图
- 5.2 状态流转图
- 六、常见错误速查表 📋
- 七、最佳实践与预防措施
-
- 7.1 个人开发环境
- 7.2 企业 / CI-CD 环境
- 八、总结
- 🔔 温馨提示
- ✍️ 作者名片

一、开发背景与异常场景还原
1.1 典型报错场景
在团队协作或企业级项目中,为了保障依赖包的 完整性与安全性,防止中间人攻击或镜像源恶意替换包,通常会在 requirements.txt 中启用 –require-hashes 模式。此时在 PyCharm 控制台执行:
pip install -r requirements.txt –require-hashes
却可能遭遇如下报错:
ERROR: In –require-hashes mode, all requirements must have their versions pinned with ==. These do not:
numpy>=1.22.0 from https://files.pythonhosted.org/packages/xxx/numpy-1.22.4-xxx.whl
(from scipy==1.7.1->-r requirements.txt (line 3))
或者:
ERROR: Hashes are required in –require-hashes mode, but they are missing for the following requirements:
– requests==2.32.0
Hint: You must add hashes for all dependencies, including indirect ones.
💡 核心认知: 这不是版本号写错了,也不是网络问题,而是 pip 的安全校验机制 在拒绝"不完整的依赖声明"。
1.2 什么情况下会触发该报错?
| pip freeze > requirements.txt 直接生成 | pip freeze 默认不带哈希值,直接用于 –require-hashes 必报错 |
| 手动编写的 requirements.txt 缺少 –hash | 仅写了 包名==版本号,未附加哈希校验值 |
| 存在间接依赖未声明 | flask 依赖 werkzeug,但 requirements.txt 只写了 flask 的哈希 |
| 使用了宽松版本符 | 如 >=、<=、~= 等,无法确定唯一哈希值 |
| 可编辑安装 -e . | –require-hashes 模式下不支持可编辑安装,无法生成哈希 |
| 镜像源包与 PyPI 官方哈希不一致 | 国内镜像源缓存的包可能与官方哈希不同,导致校验失败 |
二、开发环境说明
在开始排障之前,请先确认你的开发环境是否与本文一致,以便精准定位问题:
| 🐍 Python | 3.10.12(建议 3.10+) | –require-hashes 在 3.6+ 均支持,但新版 pip 兼容性更好 |
| 💻 操作系统 | macOS 15 / Windows 11 / Linux | 全平台均复现,解决方案通用 |
| 💡 IDE | PyCharm 2025.1 专业版 | 控制台 pip 执行环境 |
| 📦 pip 版本 | 24.0+ | 请务必保持最新,旧版对哈希模式支持不完善 |
| 🌐 网络环境 | 中国大陆 / 海外 | 国内用户建议配置镜像源加速 |
⚠️ 环境检查命令: 在 PyCharm 控制台执行以下命令,快速确认环境信息:
python –version && pip –version
三、问题根源深度剖析
3.1 –require-hashes 安全机制解析
–require-hashes 是 pip 的 强安全校验模式,其核心设计目标有三:
📌 三条铁律(必须遵守):
3.2 报错根因拆解
#mermaid-svg-2QZkLeHSApuVLQTN{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-2QZkLeHSApuVLQTN .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-2QZkLeHSApuVLQTN .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-2QZkLeHSApuVLQTN .error-icon{fill:#552222;}#mermaid-svg-2QZkLeHSApuVLQTN .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2QZkLeHSApuVLQTN .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-2QZkLeHSApuVLQTN .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2QZkLeHSApuVLQTN .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2QZkLeHSApuVLQTN .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-2QZkLeHSApuVLQTN .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2QZkLeHSApuVLQTN .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2QZkLeHSApuVLQTN .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2QZkLeHSApuVLQTN .marker.cross{stroke:#333333;}#mermaid-svg-2QZkLeHSApuVLQTN svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2QZkLeHSApuVLQTN p{margin:0;}#mermaid-svg-2QZkLeHSApuVLQTN .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-2QZkLeHSApuVLQTN .cluster-label text{fill:#333;}#mermaid-svg-2QZkLeHSApuVLQTN .cluster-label span{color:#333;}#mermaid-svg-2QZkLeHSApuVLQTN .cluster-label span p{background-color:transparent;}#mermaid-svg-2QZkLeHSApuVLQTN .label text,#mermaid-svg-2QZkLeHSApuVLQTN span{fill:#333;color:#333;}#mermaid-svg-2QZkLeHSApuVLQTN .node rect,#mermaid-svg-2QZkLeHSApuVLQTN .node circle,#mermaid-svg-2QZkLeHSApuVLQTN .node ellipse,#mermaid-svg-2QZkLeHSApuVLQTN .node polygon,#mermaid-svg-2QZkLeHSApuVLQTN .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-2QZkLeHSApuVLQTN .rough-node .label text,#mermaid-svg-2QZkLeHSApuVLQTN .node .label text,#mermaid-svg-2QZkLeHSApuVLQTN .image-shape .label,#mermaid-svg-2QZkLeHSApuVLQTN .icon-shape .label{text-anchor:middle;}#mermaid-svg-2QZkLeHSApuVLQTN .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-2QZkLeHSApuVLQTN .rough-node .label,#mermaid-svg-2QZkLeHSApuVLQTN .node .label,#mermaid-svg-2QZkLeHSApuVLQTN .image-shape .label,#mermaid-svg-2QZkLeHSApuVLQTN .icon-shape .label{text-align:center;}#mermaid-svg-2QZkLeHSApuVLQTN .node.clickable{cursor:pointer;}#mermaid-svg-2QZkLeHSApuVLQTN .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-2QZkLeHSApuVLQTN .arrowheadPath{fill:#333333;}#mermaid-svg-2QZkLeHSApuVLQTN .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-2QZkLeHSApuVLQTN .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-2QZkLeHSApuVLQTN .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2QZkLeHSApuVLQTN .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-2QZkLeHSApuVLQTN .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2QZkLeHSApuVLQTN .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-2QZkLeHSApuVLQTN .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-2QZkLeHSApuVLQTN .cluster text{fill:#333;}#mermaid-svg-2QZkLeHSApuVLQTN .cluster span{color:#333;}#mermaid-svg-2QZkLeHSApuVLQTN div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-2QZkLeHSApuVLQTN .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-2QZkLeHSApuVLQTN rect.text{fill:none;stroke-width:0;}#mermaid-svg-2QZkLeHSApuVLQTN .icon-shape,#mermaid-svg-2QZkLeHSApuVLQTN .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2QZkLeHSApuVLQTN .icon-shape p,#mermaid-svg-2QZkLeHSApuVLQTN .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-2QZkLeHSApuVLQTN .icon-shape .label rect,#mermaid-svg-2QZkLeHSApuVLQTN .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2QZkLeHSApuVLQTN .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-2QZkLeHSApuVLQTN .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-2QZkLeHSApuVLQTN :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
存在 >= / <= / ~=
缺少 –hash
间接依赖无哈希
全部合规
执行 pip install –require-hashes
解析requirements.txt
报错: 版本未固定
报错: 哈希值缺失
报错: 隐藏依赖缺失
下载并校验哈希
修改为 == 精确版本
pip hash 生成哈希
pip hash 包名==版本
写入 –hash=sha256:xxx
pip show 查看依赖树
找出所有间接依赖
为间接依赖生成哈希
重新执行安装
安装成功 ✅
3.3 新手常见误判(90%的人踩过这些坑)
🚫 误判一: “版本号明明是对的,怎么还报错?”
真相:版本正确 ≠ 哈希正确,–require-hashes 校验的是哈希值,不是版本号。
🚫 误判二: “给哈希值加个引号试试?”
真相:"–hash=sha256:abc123" 会被判定为格式错误,正确写法无需引号。
🚫 误判三: “升级 pip / 换镜像源就能解决?”
真相:哈希校验规则与 pip 版本、镜像源无关,这是安全机制的硬性要求。
🚫 误判四: “只给主要依赖加哈希就够了?”
真相:间接依赖(如 flask → werkzeug)也必须加哈希,否则仍会报错。
四、系统化解决方案大全 🔧
4.1 方案一:生成带哈希的合规 requirements.txt(核心方案)
这是最根本的解决方案。使用 pip hash 命令自动生成哈希值:
步骤 1:确认所有依赖使用 == 精确版本
# ❌ 错误写法(宽松版本)
numpy>=1.22.0
requests~=2.32.0
# ✅ 正确写法(精确版本)
numpy==1.22.4
requests==2.32.0
步骤 2:生成单个包的哈希值
# PyCharm 控制台执行
pip hash numpy==1.22.4
# 输出示例
Hash for numpy==1.22.4 (numpy-1.22.4-cp310-cp310-macosx_11_0_arm64.whl):
sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
步骤 3:批量生成所有依赖的哈希值(推荐)
# 步骤 A:下载所有依赖包到本地 wheels 目录(不安装)
pip download -r requirements.txt -d ./wheels
# 步骤 B:生成所有包的哈希值并覆盖写入 requirements.txt
pip hash –format=requirements ./wheels/*.whl > requirements.txt
步骤 4:修正后的 requirements.txt 示例
# 直接依赖 + 哈希
numpy==1.22.4 \\
–hash=sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
requests==2.32.0 \\
–hash=sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890
# 间接依赖也必须补充(如 flask 依赖 werkzeug)
flask==2.3.0 \\
–hash=sha256:fedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321
werkzeug==2.3.7 \\
–hash=sha256:abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd
✅ 验证命令:
pip install -r requirements.txt –require-hashes
4.2 方案二:使用 pip-tools 自动化管理依赖(企业级推荐)
对于大型项目,手动维护哈希值容易出错,推荐使用 pip-tools 自动化生成:
# 安装 pip-tools
pip install pip-tools
# 创建 requirements.in(只写直接依赖,无需哈希)
cat > requirements.in << EOF
flask==2.3.0
requests==2.32.0
numpy==1.22.4
EOF
# 自动生成带哈希的 requirements.txt
pip-compile –generate-hashes requirements.in
# 安装时直接使用
pip install -r requirements.txt –require-hashes
💡 优势: pip-compile 会自动解析间接依赖、固定版本、生成哈希,一劳永逸。
4.3 方案三:去掉 –require-hashes 参数(快速绕过)
如果你处于 本地开发环境,且不需要严格的安全校验,可以直接去掉该参数:
# ❌ 报错命令
pip install -r requirements.txt –require-hashes
# ✅ 绕过命令
pip install -r requirements.txt
⚠️ 注意: 生产环境、CI/CD 流水线不建议禁用,会失去安全校验保护。
4.4 方案四:处理间接依赖版本冲突(进阶排障)
有时报错并非直接依赖的问题,而是 间接依赖使用了宽松版本:
ERROR: In –require-hashes mode, all requirements must have their versions pinned with ==. These do not:
google-api-core[grpc]>=1.22.1,<3.0.0dev
(from firebase-admin==5.2.0)
解决步骤:
# 步骤 1:查看报错中的间接依赖实际版本
pip show google-api-core
# 步骤 2:在 requirements.in 中显式固定该间接依赖的精确版本
echo "google-api-core[grpc]==2.11.0" >> requirements.in
# 步骤 3:重新编译生成 requirements.txt
pip-compile –generate-hashes requirements.in
# 步骤 4:重新安装
pip install -r requirements.txt –require-hashes
4.5 方案五:网络问题切换国内镜像源
在中国大陆网络环境下,PyPI 官方源访问缓慢甚至超时,建议配置国内镜像源:
macOS / Linux 配置:
mkdir -p ~/.pip
cat > ~/.pip/pip.conf << EOF
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
trusted-host = pypi.tuna.tsinghua.edu.cn
timeout = 120
retries = 5
[install]
use-mirrors = true
mirrors = https://pypi.tuna.tsinghua.edu.cn/simple
EOF
Windows 配置:
在 %APPDATA%\\pip\\pip.ini 中写入:
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
trusted-host = pypi.tuna.tsinghua.edu.cn
timeout = 120
国内常用 pip 镜像源速查表:
| 🏫 清华大学 | https://pypi.tuna.tsinghua.edu.cn/simple | ⭐⭐⭐⭐⭐ |
| 🏫 阿里云 | https://mirrors.aliyun.com/pypi/simple/ | ⭐⭐⭐⭐⭐ |
| 🏫 腾讯云 | https://mirrors.cloud.tencent.com/pypi/simple/ | ⭐⭐⭐⭐ |
| 🏫 豆瓣 | https://pypi.doubanio.com/simple/ | ⭐⭐⭐⭐ |
| 🏫 华为云 | https://repo.huaweicloud.com/repository/pypi/simple/ | ⭐⭐⭐⭐ |
💡 临时使用镜像源(不修改配置):
pip install -r requirements.txt –require-hashes -i https://pypi.tuna.tsinghua.edu.cn/simple

4.6 方案六:升级 pip 至最新版本
旧版本 pip 对 –require-hashes 模式的支持存在 bug,强烈建议升级:
# 在 PyCharm 控制台执行
python -m pip install –upgrade pip
# 验证版本
pip –version
# 期望输出:pip 24.0+ (或更高)
📌 PyCharm 中升级 pip 的注意事项:
如果 PyCharm 使用的是虚拟环境,请确保在 激活虚拟环境后 执行升级,否则升级的是系统 pip。
4.7 方案七:检查 PYTHONPATH 与包导入路径
有时 pip install 成功但 import 报错,或反之,可能是 PYTHONPATH 配置问题:
# 查看当前 PYTHONPATH
echo $PYTHONPATH
# 临时添加项目路径(macOS/Linux)
export PYTHONPATH=$PYTHONPATH:/your/project/path
# 永久添加(写入 ~/.zshrc 或 ~/.bash_profile)
echo 'export PYTHONPATH=$PYTHONPATH:/your/project/path' >> ~/.zshrc
source ~/.zshrc
⚠️ 常见陷阱: 如果自建的 module 包所在路径不在 PYTHONPATH 下,Python 解释器无法找到该模块,会误以为是 pip install 失败。
4.8 方案八:排查包名冲突与 __init__.py 缺失
场景 A:自定义包名与安装的包名相同
如果你在项目中创建了 requests.py 文件,再执行 import requests 时,Python 会优先导入本地文件,而非通过 pip 安装的 requests 库:
# ❌ 错误:本地 requests.py 覆盖了 pip 安装的 requests
# 项目结构:
# myproject/
# requests.py ← 自定义文件,与 pip 包冲突!
# main.py
# main.py
import requests
print(requests.__file__) # 可能指向本地文件而非 site-packages
解决方案: 重命名本地文件,避免与第三方包同名。
场景 B:缺少 __init__.py 文件
# ❌ 错误结构
myproject/
utils/
helper.py ← 缺少 __init__.py
main.py
# main.py
from utils.helper import foo # ImportError: No module named 'utils'
解决方案: 在 utils 目录下创建空文件 __init__.py:
touch myproject/utils/__init__.py
✅ 验证包是否正确安装:
pip list | grep requests
python -c "import requests; print(requests.__version__)"
4.9 方案九:处理可编辑安装项 -e . 的哈希问题
–require-hashes 模式下 不支持 -e . 可编辑安装,因为可编辑安装无法生成固定哈希:
# ❌ 报错写法
-e .
requests==2.32.0 \\
–hash=sha256:xxx
解决方案: 将可编辑安装替换为本地包 + 哈希:
# 步骤 1:生成本地包的 whl 文件
pip wheel -w ./wheels .
# 步骤 2:生成哈希值
pip hash ./wheels/my_pkg-0.1.0-py3-none-any.whl
# 步骤 3:在 requirements.txt 中写入
my-pkg==0.1.0 \\
–hash=sha256:xxx
4.10 方案十:使用 –no-deps 参数规避依赖解析
如果 requirements.txt 已经包含了所有直接和间接依赖(如由 Poetry 导出),可以使用 –no-deps 跳过 pip 的依赖解析:
# 跳过依赖解析,直接安装 requirements.txt 中列出的包
pip install –require-hashes –no-deps -r requirements.txt
💡 适用场景: 使用 Poetry 导出 requirements.txt 时,所有依赖已扁平化列出,无需 pip 再次解析依赖树。
4.11 方案十一:不恰当使用相对导入的修复
在 Python 包内部使用相对导入时,如果执行方式不当也会引发导入错误:
# ❌ 错误:在顶层脚本中使用相对导入
# package/
# __init__.py
# module.py
# main.py
# main.py
from . import module # ImportError: attempted relative import with no known parent package
解决方案:
# 方式 1:使用 -m 参数从包外执行
python -m package.main
# 方式 2:改为绝对导入
from package import module
4.12 方案十二:pip 缓存污染清理
有时 pip 缓存中的包文件损坏,导致哈希校验失败:
# 清理 pip 缓存
pip cache purge
# 重新下载并安装
pip install -r requirements.txt –require-hashes –no-cache-dir
🔧 –no-cache-dir 强制 pip 从远程重新下载包,绕过本地缓存。
五、Mermaid 可视化排障流程
5.1 完整排障时序图
requirements.txt
PyPI镜像源
pip命令
PyCharm控制台
开发者
requirements.txt
PyPI镜像源
pip命令
PyCharm控制台
开发者
#mermaid-svg-REuOF5K3hS8Ow9Wr{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-REuOF5K3hS8Ow9Wr .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-REuOF5K3hS8Ow9Wr .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-REuOF5K3hS8Ow9Wr .error-icon{fill:#552222;}#mermaid-svg-REuOF5K3hS8Ow9Wr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-REuOF5K3hS8Ow9Wr .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-REuOF5K3hS8Ow9Wr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-REuOF5K3hS8Ow9Wr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-REuOF5K3hS8Ow9Wr .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-REuOF5K3hS8Ow9Wr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-REuOF5K3hS8Ow9Wr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-REuOF5K3hS8Ow9Wr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-REuOF5K3hS8Ow9Wr .marker.cross{stroke:#333333;}#mermaid-svg-REuOF5K3hS8Ow9Wr svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-REuOF5K3hS8Ow9Wr p{margin:0;}#mermaid-svg-REuOF5K3hS8Ow9Wr .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-REuOF5K3hS8Ow9Wr text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-REuOF5K3hS8Ow9Wr .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-REuOF5K3hS8Ow9Wr .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-REuOF5K3hS8Ow9Wr .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-REuOF5K3hS8Ow9Wr .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-REuOF5K3hS8Ow9Wr #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-REuOF5K3hS8Ow9Wr .sequenceNumber{fill:white;}#mermaid-svg-REuOF5K3hS8Ow9Wr #sequencenumber{fill:#333;}#mermaid-svg-REuOF5K3hS8Ow9Wr #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-REuOF5K3hS8Ow9Wr .messageText{fill:#333;stroke:none;}#mermaid-svg-REuOF5K3hS8Ow9Wr .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-REuOF5K3hS8Ow9Wr .labelText,#mermaid-svg-REuOF5K3hS8Ow9Wr .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-REuOF5K3hS8Ow9Wr .loopText,#mermaid-svg-REuOF5K3hS8Ow9Wr .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-REuOF5K3hS8Ow9Wr .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-REuOF5K3hS8Ow9Wr .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-REuOF5K3hS8Ow9Wr .noteText,#mermaid-svg-REuOF5K3hS8Ow9Wr .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-REuOF5K3hS8Ow9Wr .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-REuOF5K3hS8Ow9Wr .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-REuOF5K3hS8Ow9Wr .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-REuOF5K3hS8Ow9Wr .actorPopupMenu{position:absolute;}#mermaid-svg-REuOF5K3hS8Ow9Wr .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-REuOF5K3hS8Ow9Wr .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-REuOF5K3hS8Ow9Wr .actor-man circle,#mermaid-svg-REuOF5K3hS8Ow9Wr line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-REuOF5K3hS8Ow9Wr :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
alt
[版本未固定]
[哈希值缺失]
[间接依赖缺失]
alt
[依赖项缺少哈希值]
执行 pip install -r requirements.txt –require-hashes
1
传递命令参数
2
解析依赖列表
3
返回无哈希的依赖项
4
抛出 ERROR: In –require-hashes mode…
5
显示报错信息
6
判断问题类型
7
修改 >= 为 ==
8
pip hash 生成哈希
9
返回 sha256 哈希值
10
补充 –hash=sha256:xxx
11
pip show 查看依赖树
12
返回完整依赖关系
13
为间接依赖生成哈希
14
返回哈希值
15
补充间接依赖+哈希
16
重新执行安装命令
17
传递命令
18
重新解析(全部合规)
19
下载并校验哈希
20
返回匹配包文件
21
安装成功 ✅
22
Successfully installed
23
5.2 状态流转图
#mermaid-svg-n0be3pEg5Z3u7x5i{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-n0be3pEg5Z3u7x5i .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-n0be3pEg5Z3u7x5i .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-n0be3pEg5Z3u7x5i .error-icon{fill:#552222;}#mermaid-svg-n0be3pEg5Z3u7x5i .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-n0be3pEg5Z3u7x5i .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-n0be3pEg5Z3u7x5i .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-n0be3pEg5Z3u7x5i .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-n0be3pEg5Z3u7x5i .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-n0be3pEg5Z3u7x5i .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-n0be3pEg5Z3u7x5i .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-n0be3pEg5Z3u7x5i .marker{fill:#333333;stroke:#333333;}#mermaid-svg-n0be3pEg5Z3u7x5i .marker.cross{stroke:#333333;}#mermaid-svg-n0be3pEg5Z3u7x5i svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-n0be3pEg5Z3u7x5i p{margin:0;}#mermaid-svg-n0be3pEg5Z3u7x5i defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-n0be3pEg5Z3u7x5i g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-n0be3pEg5Z3u7x5i g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-n0be3pEg5Z3u7x5i g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-n0be3pEg5Z3u7x5i g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-n0be3pEg5Z3u7x5i g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-n0be3pEg5Z3u7x5i .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-n0be3pEg5Z3u7x5i .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-n0be3pEg5Z3u7x5i .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-n0be3pEg5Z3u7x5i .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-n0be3pEg5Z3u7x5i .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-n0be3pEg5Z3u7x5i .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-n0be3pEg5Z3u7x5i .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-n0be3pEg5Z3u7x5i .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-n0be3pEg5Z3u7x5i .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-n0be3pEg5Z3u7x5i .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-n0be3pEg5Z3u7x5i .edgeLabel .label text{fill:#333;}#mermaid-svg-n0be3pEg5Z3u7x5i .label div .edgeLabel{color:#333;}#mermaid-svg-n0be3pEg5Z3u7x5i .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-n0be3pEg5Z3u7x5i .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-n0be3pEg5Z3u7x5i .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-n0be3pEg5Z3u7x5i .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-n0be3pEg5Z3u7x5i .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-n0be3pEg5Z3u7x5i .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-n0be3pEg5Z3u7x5i .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-n0be3pEg5Z3u7x5i #statediagram-barbEnd{fill:#333333;}#mermaid-svg-n0be3pEg5Z3u7x5i .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-n0be3pEg5Z3u7x5i .cluster-label,#mermaid-svg-n0be3pEg5Z3u7x5i .nodeLabel{color:#131300;}#mermaid-svg-n0be3pEg5Z3u7x5i .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-n0be3pEg5Z3u7x5i .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-n0be3pEg5Z3u7x5i .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-n0be3pEg5Z3u7x5i .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-n0be3pEg5Z3u7x5i .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-n0be3pEg5Z3u7x5i .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-n0be3pEg5Z3u7x5i .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-n0be3pEg5Z3u7x5i .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-n0be3pEg5Z3u7x5i .note-edge{stroke-dasharray:5;}#mermaid-svg-n0be3pEg5Z3u7x5i .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-n0be3pEg5Z3u7x5i .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-n0be3pEg5Z3u7x5i .statediagram-note text{fill:black;}#mermaid-svg-n0be3pEg5Z3u7x5i .statediagram-note .nodeLabel{color:black;}#mermaid-svg-n0be3pEg5Z3u7x5i .statediagram .edgeLabel{color:red;}#mermaid-svg-n0be3pEg5Z3u7x5i #dependencyStart,#mermaid-svg-n0be3pEg5Z3u7x5i #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-n0be3pEg5Z3u7x5i .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-n0be3pEg5Z3u7x5i :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
pip install -r requirements.txt –require-hashes
读取requirements.txt
版本已固定 ==
发现 >= / <= / ~=
哈希完整
缺少 –hash
全部合规
隐藏依赖无哈希
修改为 ==
pip hash 生成
补充间接依赖哈希
重新执行
命令执行
解析依赖
版本检查
哈希检查
版本修复
间接依赖检查
哈希修复
安装成功
间接依赖修复
重新生成
六、常见错误速查表 📋
| 1 | In –require-hashes mode, all requirements must have their versions pinned with == | 使用了 >= / <= / ~= 等宽松版本符 | 方案一、四 |
| 2 | Hashes are required but missing for … | 依赖项缺少 –hash 哈希值 | 方案一、二 |
| 3 | Hash mismatch / Hashes mismatch | 哈希值与实际下载的包不匹配 | 方案六、十二 |
| 4 | 间接依赖报错(如 from flask==2.3.0) | 未为间接依赖生成哈希 | 方案一、四、十 |
| 5 | Could not find a version that satisfies… | 网络问题或镜像源无该版本 | 方案五 |
| 6 | ImportError: No module named 'xxx' | 包未安装或 PYTHONPATH 错误 | 方案七、八 |
| 7 | attempted relative import with no known parent package | 不恰当使用相对导入 | 方案十一 |
| 8 | -e . 不支持哈希模式 | 可编辑安装无法生成哈希 | 方案九 |
| 9 | PyCharm 执行报错,终端正常 | PyCharm 解释器/环境变量不一致 | 方案六、七 |
| 10 | pip 命令不存在或版本过低 | pip 未安装或版本太旧 | 方案六 |
七、最佳实践与预防措施
7.1 个人开发环境
使用 pip-tools 管理依赖:
pip-compile –generate-hashes requirements.in
在 README 中记录哈希生成命令:
## 生成依赖哈希值
```bash
pip download -r requirements.txt -d ./wheels
pip hash –format=requirements ./wheels/*.whl > requirements.txt
定期清理 pip 缓存:
pip cache purge
7.2 企业 / CI-CD 环境
流水线中强制启用哈希校验:
# .gitlab-ci.yml 示例
install:
script:
– pip install –r requirements.txt ––require–hashes || { echo "Hash check failed!"; exit 1; }
哈希合规性检查脚本:
# check_hashes.sh
grep -v " –hash=" requirements.txt | grep -v "^#" | grep -v "^$" | grep -v "^-e"
if [ $? -eq 0 ]; then
echo "❌ Error: Some dependencies are missing hashes!"
exit 1
fi
echo "✅ All dependencies have valid hashes."
统一团队依赖源:使用私有 PyPI 源或统一镜像源,避免哈希不一致。
八、总结
本文从 PyCharm 控制台 pip install -r requirements.txt –require-hashes 报错 出发,系统性地拆解了 –require-hashes 安全机制的工作原理,提供了 十二大解决方案,涵盖:
| 🔐 安全机制 | –require-hashes 强制要求所有依赖使用 == 精确版本并附带哈希值 |
| 🛠️ 核心方案 | 使用 pip hash 或 pip-tools 自动生成合规的 requirements.txt |
| 🌐 网络优化 | 配置清华大学/阿里云等国内镜像源加速下载 |
| 🔍 间接依赖 | 必须补充间接依赖的哈希值,避免隐藏报错 |
| 🧹 环境排查 | 检查 PYTHONPATH、包名冲突、__init__.py、pip 版本等 |
| ⚡ 快速绕过 | 开发环境可去掉 –require-hashes,生产环境不建议 |
💬 一句话总结: –require-hashes 不是 bug,而是 pip 的"安全守门员"。只要遵循"精确版本 + 完整哈希 + 全量依赖"三大原则,就能彻底告别该报错!
🔔 温馨提示
更多 Bug 解决方案请查看 ==> 全栈Bug解决方案专栏 https://blog.csdn.net/lyzybbs/category_12988910.html
✍️ 作者名片






