【问题标题】:How to handle `pip install` inside a pipenv environment (not reflected in the Pipfile, only in the `pipenv graph`)?如何在 pipenv 环境中处理 `pip install`(不反映在 Pipfile 中,仅反映在 `pipenv graph` 中)?
【发布时间】:2020-07-25 00:26:46
【问题描述】:

如果有人在 pipenv 环境中不小心使用了pip install 而不是pipenv install,则该包不会反映在 Pipfile 上的包列表或 Pipfile.lock 中。

问题在于,您可能会使用此 Pipfile.lock 进行部署,以为您拥有所需的一切,而实际上您缺少包。

我正在查看文档 https://pipenv.pypa.io/ 以了解当您运行 pip install 而不是 pipenv install(即使是错误的)时实际发生了什么,但我找不到对此的解释。

如果您运行pipenv graph,它实际上会向您显示通过 pip 安装的软件包!所以我知道 pipenv 不知何故知道这些包。但是我需要做什么才能让这些反映在 Pipfile 中?

【问题讨论】:

  • pipenv graph 使用独立于 pipenv 的pipdeptree。我不知道自动将 pip 依赖项添加到您的 Pipfile 的方法,但您可以使用 pipenv clean 命令卸载此类依赖项。它还有一个--dry-run 选项。您可以将其添加到预提交挂钩中,以在提交之前检查您是否没有任何此类依赖项。

标签: python pip pipenv


【解决方案1】:

首先,让我们澄清pipenv install 命令只是pip 的包装。如果您使用--verbose 安装,您会发现它也只是使用pip install 并将软件包放在同一个激活的虚拟环境中。所以回答

我正在查看文档 https://pipenv.pypa.io/ 以了解当您运行 pip install 而不是 pipenv install 时实际发生了什么(即使是错误的)

只是pipenv-特定操作将不会完成。这包括更新 PipfilePipfile.lock(这是首先使用 pipenv 的主要原因之一)以获得确定性构建。 Pipfile 你可以手动更新自己,但是对于 Pipfile.lock...你不能。

如果您运行 pipenv graph,它实际上会显示通过 pip 安装的包!

是的,因为正如我所说,他们都只使用pip。这两种方法都会将包安装在同一个虚拟环境中,pipenv graph 只是检查 same 环境。包将存储在lib/pythonX.Y/site-packages 下的文件夹中,无论是pipenv 还是普通pip

现在开始你的实际问题:

但是我需要做些什么才能使这些反映在 Pipfile 中?

D Malan's comment of 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。

【讨论】:

    猜你喜欢
    • 2019-03-26
    • 2021-07-14
    • 1970-01-01
    • 2023-02-11
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    • 1970-01-01
    • 2021-06-03
    相关资源
    最近更新 更多