首页 > 解决方案 > 即使在使用显式版本的 Pipfile 和 Pipfile.lock 之后用户之间的差异

问题描述

对不起,这是一个非常复杂的 pipenv 情况。

在我的公司,我们使用 pipenv (同时带有PipfilePipfile.lock)来控制不同工程师笔记本电脑上使用的软件包。这对我们来说甚至比对大多数团队更重要,因为我们也使用 Zappa 来部署 AWS Lambda 代码,而且它显然直接从部署者的笔记本电脑打包依赖项来部署它们。因此,如果人们的笔记本电脑在依赖关系方面没有完全一致,我们可以在云中获得不同的行为,具体取决于部署它的人。

我们发现,即使在尝试使用 和 完全控制依赖关系之后PipfilePipfile.lock我们最终也会在不同的笔记本电脑上获得不同的 Python 包,如pip freeze部署代码中的错误所示。

这是显示我的笔记本电脑和我老板的笔记本电脑之间差异的确切过程(我引用的 Pipfile 代码位于多行但我将其压缩为一行,因为我遇到了 SO 格式问题):

  1. 一开始,我们只有一个Pipfile用通配符指定的包,比如[requires] python_version = "3.6" [packages] flask = "*". 另外,我们没有Pipfile.lock,我的老板(他是这个项目的第一个编码员)一直在运行--skip-lock
  2. 为了更好地控制事情,我首先升级我们的Pipfile以用显式版本替换通配符,并使我们的 Python 版本更具体,比如[requires] python_version = "3.6.4" [packages] Flask = "==1.0.2". 为此,我得到了老板pip freeze输出的副本,并将版本复制到与Pipfile那里列出的名称匹配的位置(我跳过了任何不匹配的内容,因为我认为它是上游依赖项而我们不是还没碰那个)。我犯了这个。
  3. 我们仍然遇到问题,所以我们决定开始使用Pipfile.lock来控制上游依赖项。所以我的老板第一次在pip install没有--skip-lock的情况下创建了一个,并承诺了这一点。
  4. 我拉了Pipfile.lock,删除了我的环境pipenv --rm并重新创建了它pipenv install
  5. 我们都运行pip freeze并比较了输出,但我们仍然有许多不同之处。

我想我可以让我的老板删除他的pipenv环境并根据提交的 and 重新安装PipfilePipfile.lock但是由于它们是基于他pip freeze的,如果这改变了任何东西,我会有点惊讶。

所以我只是想知道:这种行为真的出乎意料吗?我一直认为 , 和 的组合pipenv可以Pipfile保证Pipfile.lock两个人拥有相同的包,只要每个版本都用==[version]. 我们还需要做些什么来获得非常精确的匹配吗?

如果这真的出乎意料,我唯一能想到的另一件事是,也许他没有跑pipenv shell在他之前pip freeze,但我认为他这样做是因为事情很顺利Pipfiles

旁注:我还没有将我们[dev-packages]的版本转换Pipfile为有版本,因为我不确定那是什么,我假设它是无关紧要的。所以那些仍然像pylint = "*"

附加信息

以下是回应评论的一些附加信息......但首先我注意到了一些有趣的事情:

为了回应评论......这是我和我老板的笔记本电脑上 pip freeze 输出(都来自 pipenv shell 内)之间差异的第一部分:

在此处输入图像描述

Pipfile.lock以下是我和我老板的笔记本电脑之间的一些差异。Pipfile.lock是通过让他运行pipenv lockpipenv shell尽管我认为这无关紧要)然后立即提交而获得的。然后我拉了它,删除了我的环境pipenv --rm,运行pipenv install,并得到了与Pipfile.lock他刚刚提交的以下差异。他的版本又在左边。

这些都是差异——我不明白的一件事是为什么我们在这里的差异比 with 少pip freeze。我们Pipfile两个之间还是一样的。

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

标签: pythonpipenv

解决方案


确保您共享完全相同的环境的唯一方法是与相同的Pipfile.lock, with pipenv sync(可选pipenv sync --dev)同步。

Pipfile是人类的助手,是Pipfile.lock创造的中间人,它并不能确保依赖关系完全一样。

pipenv install在后台调用 2pipenv函数:locksync. pipenv lock将从Pipfile.lock您的Pipfile. 即使在 中使用固定版本Pipfile,如果它们是在不同时刻生成的,也可能会有不同Pipfile.lock,因为固定包的依赖项可能不会被固定(取决于发布者)。pipenv sync然后安装在Pipfile.lock.

要直接安装你的环境中的依赖项Pipfile.lock,你必须使用pipenv --python 3.6 install --ignore-pipfile,否则Pipfile.lock会从Pipfile.

为了轻松解决您的问题,请修复一个Pipfile.lock版本(如果您使用版本控制,您可以提交它,但您当然会这样做;),然后都使用pipenv sync.

然后Pipfile.lock,只要您处理次要版本、错误修复......并随时重新生成它以获得主要版本的最新依赖项,请保持完全相同。在我的项目中,几乎所有依赖Pipfile项都没有固定,当我们启动一个新的主要版本时,我们会更新Pipfile.lock以尝试新的依赖项版本,测试所有内容,有时如果最新引入的向后不兼容的更改将依赖项固定到以前的版本,并且我们修复Pipfile.lock直到下一个主要版本。


推荐阅读