python - 如何在 pipenv 环境中处理 `pip install`(不反映在 Pipfile 中,仅反映在 `pipenv graph` 中)?
问题描述
如果有人不小心使用pip install
而不是pipenv install
在 pipenv 环境中使用,则该包不会反映在 Pipfile 上的包列表中,也不会反映在 Pipfile.lock 中。
问题是您可能会使用此 Pipfile.lock 进行部署,以为您拥有所需的一切,而实际上您缺少包。
我正在查看文档https://pipenv.pypa.io/以找出当您运行pip install
而不是pipenv install
(即使是错误地)时实际发生的情况,但我找不到对此的解释。
如果你运行pipenv graph
它,它实际上会显示通过 pip 安装的包!所以我知道 pipenv 不知何故知道这些包。但是我需要做什么才能使这些反映在 Pipfile 中?
解决方案
首先,让我们澄清一下该pipenv install
命令只是pip
. 如果您使用 安装--verbose
,您会看到它也只是在使用pip install
包并将其放置在同一个已激活的虚拟环境中。所以答案
我正在查看文档https://pipenv.pypa.io/以了解当您运行
pip install
而不是pipenv install
(即使是错误地)时实际发生的情况
只是pipenv
- 特定的操作不会被执行。这包括更新Pipfile和Pipfile.lock(这是首先使用的主要原因之一pipenv
)以获得确定性构建。Pipfile您可以手动更新自己,但对于Pipfile.lock ...您不能。
如果你运行 pipenv graph 它实际上会显示通过 pip 安装的包!
是的,因为正如我所说,他们都只使用pip
. 这两种方法都会将软件包安装在同一个虚拟环境中,并且pipenv graph
只是检查同一个环境。这些包将被存储在一个文件夹中lib/pythonX.Y/site-packages
,无论是 withpipenv
还是 plain pip
。
现在谈谈你的实际问题:
但是我需要做什么才能使这些反映在 Pipfile 中?
D Malan 对 using 的评论pipenv clean
是一个很好的方法。从文档:
$ pipenv clean --help
Usage: pipenv clean [OPTIONS]
Uninstalls all packages not specified in Pipfile.lock.
Options:
--bare Minimal output.
--dry-run Just output unneeded packages.
...
如前所述,您只需要运行该命令来检查不一致之处。添加--dry-run
命令,使其仅报告,而不是实际卸载它们。
然后,您可以为此制作一个脚本,例如这个 Bash 脚本:
#!/usr/local/bin/bash
echo "Checking if there are packages in venv not in Pipfile.lock"
# Get packages pipenv did not find in Pipfile.lock
# NOTE:
# Here, mapfile requires Bash 4.x syntax
# For alternatives: https://stackoverflow.com/a/32931403/2745495
mapfile -t packages < <(pipenv clean --dry-run)
if [ ${#packages[@]} -eq 0 ]; then
echo "All good!"
else
echo "Found ${#packages[@]} not in Pipfile.lock!"
for pkg in "${packages[@]}"; do
echo " ${pkg}"
done
echo ""
echo "Check if they need to be 'pipenv install'-ed or deleted with 'pipenv clean'"
# Make sure script exits with a non-zero code here
exit 1
fi
在带有pip install
-ed 包(例如 mypy)和pipenv install
-ed 包(例如 flake8)的测试环境上运行它:
(my-test-repo) $ pipenv graph
flake8==3.8.4
- mccabe [required: >=0.6.0,<0.7.0, installed: 0.6.1]
- pycodestyle [required: >=2.6.0a1,<2.7.0, installed: 2.6.0]
- pyflakes [required: >=2.2.0,<2.3.0, installed: 2.2.0]
mypy==0.790
- mypy-extensions [required: >=0.4.3,<0.5.0, installed: 0.4.3]
- typed-ast [required: >=1.4.0,<1.5.0, installed: 1.4.1]
- typing-extensions [required: >=3.7.4, installed: 3.7.4.3]
(my-test-repo) $ cat Pipfile.lock | grep mypy
(my-test-repo) $ ./check.sh
Checking if there are packages in venv not in Pipfile.lock
Found 4 not in Pipfile.lock!
typing-extensions
typed-ast
mypy
mypy-extensions
Check if they need to be 'pipenv install'-ed or deleted with 'pipenv clean'
(my-test-repo) $ pipenv install mypy
...
✔ Success!
Updated Pipfile.lock (e60379)!
Installing dependencies from Pipfile.lock (e60379)...
▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:
(my-test-repo) $ ./check.sh
Checking if there are packages in venv not in Pipfile.lock
All good!
为了解决问题
您可能会使用此 Pipfile.lock 进行部署,以为您拥有所需的一切,而实际上您缺少包。
如果您使用的是 Git,请将脚本作为您的git pre-commit hook的一部分。
预提交挂钩首先运行,甚至在您输入提交消息之前。它用于检查即将提交的快照、查看您是否忘记了某些内容、确保测试运行或检查您需要在代码中检查的任何内容。从此钩子中退出非零值会中止提交,尽管您可以使用
git commit --no-verify
.
(my-test-repo) $ cp check.sh .git/hooks/pre-commit
(my-test-repo) $ chmod +x .git/hooks/pre-commit
(my-test-repo) $ git add .
(my-test-repo) $ git commit
Checking if there are packages in venv not in Pipfile.lock
Found 4 not in Pipfile.lock!
typing-extensions
mypy
mypy-extensions
typed-ast
Check if they need to be 'pipenv install'-ed or deleted with 'pipenv clean'
(my-test-repo) $
发现不一致时会中止提交,从而防止您提交可能不完整的 Pipfile.lock。
推荐阅读
- excel - VBA - 复制粘贴到另一个工作簿
- python - Python 3.X 中数据库中字符串值的尾随零
- html - 将底部的页脚与可变内容高度对齐
- python - 向 pandas 列中的字符串添加零取决于长度
- angular - Angular + Service Worker:如何将 `apiUrl` 从`environment.ts` 传递给`sw-sync.js`?
- javascript - 如何从 CSV json 对象中删除一个值?
- java - 使用 web.xml 在 Tomcat 8 上设置自定义过滤器
- python-3.x - 将输入文件修改为所需的输出文件
- javascript - 使用 jquery 倒计时
- vue.js - 我可以访问本地系统环境吗?使用 vue-cli 时的变量?