即使在使用显式版本的 Pipfile 和 Pipfile.lock 之后用户之间的差异 [英] differences between users even after using Pipfile and Pipfile.lock with explicit versions

查看:32
本文介绍了即使在使用显式版本的 Pipfile 和 Pipfile.lock 之后用户之间的差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

抱歉,篇幅过长,这是一个非常复杂的 pipenv 情况.

Sorry for the length, this is a pretty intricate pipenv situation.

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

At my company we are using pipenv (with both Pipfile and Pipfile.lock) to control packages used on different engineers' laptops. This is even more important for us than for most teams because we're also using Zappa to deploy AWS Lambda code, and it apparently packages the dependencies directly from the deployer's laptop to deploy them. So if people's laptops aren't totally aligned in terms of dependencies, we can get different behavior in the cloud depending on who deployed it.

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

We have found that even after attempting to fully control dependencies with Pipfile and Pipfile.lock, we end up getting different Python packages on our different laptops, as shown by pip freeze and as indicated by errors in deployed code.

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

Here is the exact process that is showing differences between my laptop and my boss's (the Pipfile code I quote is on multiple lines but I'm condensing it to one line because I'm having trouble with SO formatting):

  1. 一开始,我们只有一个Pipfile,其中包含使用通配符指定的包,例如[requires] python_version = "3.6" [packages] flask = "*".另外,我们没有 Pipfile.lock,我的老板(他是这个项目的第一个编码员)总是运行 --skip-lock
  2. 为了更好地控制事情,我首先升级了我们的 Pipfile 以用显式版本替换通配符,并使我们的 Python 版本更加具体,例如 [requires] python_version = "3.6.4" [包] Flask = "==1.0.2".为此,我得到了我老板的 pip freeze 输出的副本,并将版本复制到 Pipfile 中,其中名称与那里列出的内容匹配(我跳​​过了任何内容这不匹配,因为我认为它是上游依赖项,而我们还没有触及它).我犯了这个错误.
  3. 我们仍然遇到问题,因此我们决定开始使用 Pipfile.lock 来控制上游依赖项.所以我的老板第一次通过在没有 --skip-lock 的情况下运行 pip install 创建了一个,并提交了.
  4. 我拉取了 Pipfile.lock,使用 pipenv --rm 删除了我的环境,并使用 pipenv install
  5. 重新创建了它
  6. 我们都运行了 pip freeze 并比较了输出,但我们仍然有许多不同之处.
  1. At the very beginning, all we had was a Pipfile with packages specified with wildcards like [requires] python_version = "3.6" [packages] flask = "*". Also, we didn't have a Pipfile.lock, my boss (who was the first coder on this project) had always run --skip-lock
  2. To control things better, I started by upgrading our Pipfile to replace the wildcards with explicit versions and also make our Python version more specific, like [requires] python_version = "3.6.4" [packages] Flask = "==1.0.2". To do this, I got a copy of my boss's pip freeze output and copied the versions into the Pipfile where there was a name match with what was listed there (I skipped anything that didn't match because I assumed it was an upstream dependency and we weren't touching that yet). I committed this.
  3. We were still having problems, so we decided to start using Pipfile.lock to control upstream dependencies. So my boss created one by running pip install without --skip-lock for the first time, and committed that.
  4. I pulled the Pipfile.lock, deleted my environment with pipenv --rm and recreated it with pipenv install
  5. We both ran pip freeze and compared outputs, but we both still have a number of differences.

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

I suppose I can have my boss delete his pipenv environment and reinstall based on the committed Pipfile and Pipfile.lock, but since they are based on his pip freeze I would be a little surprised if that changed anything.

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

So I'm just wondering: is this behavior truly unexpected? I always thought the combination of pipenv, Pipfile, and Pipfile.lock would guarantee two people have the same packages, as long as every version is locked with ==[version]. Is there anything else we would need to do to get a very exact match?

如果真的出乎意料,我唯一能想到的就是他在 pip freeze 之前没有运行 pipenv shell,但我认为他这样做是因为事情与 Pipfiles 一致.

If it's truly unexpected, the only other thing I can think is that maybe he hadn't run pipenv shell before his pip freeze, but I think he did because things lined up well against the Pipfiles.

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

Side note: I haven't converted our [dev-packages] in Pipfile to have versions because I'm not sure what that does and I'm assuming it's irrelevant. So those are still like pylint = "*"

附加信息

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

Below is some additional info to respond to the comments... but first a couple of interesting things I noticed:

  • 第一个屏幕截图中的所有差异(对于 pip freeze 差异)都在 Pipfile 中.
  • 看起来我的 pip freeze 输出与 Pipfile.lock 内容匹配,但我老板的不匹配.我认为这可能解释了差异,但令人惊讶的是他的 pip freeze 输出与他自己的 pipenv lock<创建的 Pipfile.lock 不匹配/code>,除非问题是他从 pipenv shell 外部运行了 pipenv lock.
  • None of the differences in the first screenshot (for pip freeze diffs) are in the Pipfile.
  • It looks like my pip freeze output matches the Pipfile.lock contents, but my boss's doesn't. I think this might explain the differences, but it's a bit surprising that his pip freeze output wouldn't match the Pipfile.lock created by his own pipenv lock, unless the problem is that he ran pipenv lock from outside of pipenv shell.

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

To respond to the comments... Here is the first part of the diff between the pip freeze outputs (both from within pipenv shell) on my and my boss's laptops:

这是我和我老板的笔记本电脑之间 Pipfile.lock 的一些差异.Pipfile.lock 是通过让他运行 pipenv lock(在 pipenv shell 之外虽然我认为这无关紧要)然后提交来获得的刚才那个.然后我拉了它,用 pipenv --rm 删除了我的环境,运行 pipenv install,并得到了与 Pipfile.lock 的以下区别他刚刚犯了.他的版本又在左边了.

Here are some diffs in the Pipfile.lock between my and my boss's laptops. The Pipfile.lock was obtained by having him run pipenv lock (outside of pipenv shell although I assume that doesn't matter) and then committing that just now. I then pulled that, deleted my environment with pipenv --rm, ran pipenv install, and got the following differences with the Pipfile.lock that he had just committed. His version is on the left again.

这些都是不同之处 - 我不明白的一件事是为什么我们在这里的差异比 pip freeze 少.我们两个的Pipfile还是一样的.

These are all of the differences - one thing I don't get is why we have fewer differences here than with pip freeze. Our Pipfile is still the same between the two of us.

推荐答案

确保您共享完全相同环境的唯一方法是使用相同的 Pipfile.lockpipenv 同步同步(可选pipenv sync --dev).

The only way to ensure you share the exact same environment is to synchronize with the same Pipfile.lock, with pipenv sync (optionally pipenv sync --dev).

Pipfile 是人类的帮手,Pipfile.lock 创建的中间件,它不保证依赖完全相同.

Pipfile is a helper for humans, an intermediate in the Pipfile.lock creation, it does not ensure that dependencies are exactly the same.

pipenv install 在底层调用了 2 pipenv 函数:locksync.pipenv lock 将从您的 Pipfile 生成一个 Pipfile.lock.即使在 Pipfile 中有 pinned 版本,如果它们在不同的时刻生成,也可能有不同的 Pipfile.lock,因为 pinned 包的依赖项可能不会被 pinned(取决于出版商).pipenv sync 然后安装在 Pipfile.lock 中找到的确切包.

pipenv install calls under the hood 2 pipenv function: lock and sync. pipenv lock will generate a Pipfile.lock from your Pipfile. Even with pinned version in Pipfile, it is possible to have different Pipfile.lock if they are generated at different moments because dependencies of the pinned packages may not be pinned (depending of the publisher). pipenv sync then install the exact packages found in the Pipfile.lock.

要从 Pipfile.lock 中的依赖项直接安装您的环境,您必须使用 pipenv --python 3.6 install --ignore-pipfile,否则使用 Pipfile.lock 将从 Pipfile 重新生成.

To directly install your environment from the dependencies in Pipfile.lock, you have to use pipenv --python 3.6 install --ignore-pipfile, otherwise Pipfile.lock will be regenerated from the Pipfile.

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

To easily solve your problem, fix a Pipfile.lock version (you can commit it if you use version control, but you do, of course ;), then both use pipenv sync.

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

Then keep the Pipfile.lock exactly the same as long as you work on minor version, bug fixes... and feel free to regenerate it to get up-to-date dependencies for major versions. In my project, almost all dependencies in the Pipfile are not pinned, and when we start a new major version we update the Pipfile.lock to try fresh dependency versions, test everything, sometimes pin a dependency to a previous version if the latest introduced backward incompatible changes, and we fix the Pipfile.lock until the next major version.

这篇关于即使在使用显式版本的 Pipfile 和 Pipfile.lock 之后用户之间的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆