即使使用显式版本的Pipfile和Pipfile.lock,用户之间的差异

时间:2019-04-30 18:35:11

标签: python pipenv

很抱歉,这是一个非常复杂的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环境,然后根据提交的PipfilePipfile.lock重新安装,但是由于它们基于他的pip freeze,我会如果这有任何改变,一定会感到惊讶。

所以我只是想知道:这种行为真的出乎意料吗?我一直认为pipenvPipfilePipfile.lock的组合将确保两个人拥有相同的软件包,只要每个版本都被==[version]锁定。为了实现完全匹配,我们还需要做其他事情吗?

如果这确实是出乎意料,那么我唯一能想到的就是也许他没有在pipenv shell之前跑过pip freeze,但是我认为他这样做是因为与{{ 1}}。

旁注:我尚未将Pipfiles中的[dev-packages]转换为具有版本,因为我不确定这样做是什么,并且我认为这无关紧要。所以那些仍然像Pipfile

其他信息

以下是一些其他信息,可用于回复评论……但首先我注意到了一些有趣的事情:

  • 第一个屏幕截图(pylint = "*"差异)的所有差异都没有出现在pip freeze中。
  • 看起来我的Pipfile输出与pip freeze的内容匹配,但老板的却不匹配。我认为这可以解释差异,但是令人惊讶的是他的Pipfile.lock的输出与他自己的pip freeze创建的Pipfile.lock不匹配,除非问题是他跑了{{ 1}}来自pipenv lock之外。

要回复评论...这是我和我老板的笔记本电脑上的pip冻结输出(均来自pipenv shell内部)之间的区别的第一部分:

enter image description here

以下是我和老板的笔记本电脑上pipenv lock之间的区别。 pipenv shell是通过让他运行Pipfile.lock(尽管我认为没关系,在Pipfile.lock之外)然后立即提交来获得的。然后,我撤消了该任务,使用pipenv lock删除了我的环境,运行了pipenv shell,并与他刚提交的pipenv --rm有以下区别。他的版本再次在左侧。

这些都是差异-我不明白的是,为什么我们这里的差异少于pipenv install。我们两个人之间的Pipfile.lock仍然相同。

enter image description here

enter image description here

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:2)

确保共享完全相同的环境的唯一方法是与相同的Pipfile.lockpipenv sync(可选地pipenv sync --dev)进行同步。

Pipfile是人类的帮助者,是Pipfile.lock创作的中间产物,它不能确保依赖性完全相同。

pipenv install在幕后2 pipenv函数下的调用:locksyncpipenv 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修复到下一个主要版本。

答案 1 :(得分:0)

pipenv install从Pipfile安装。上游依赖性可能有所不同。

pipenv sync从Pipfile.lock安装。没什么不同。

这是我阅读命令帮助后的理解。

$ pipenv
Usage: pipenv [OPTIONS] COMMAND [ARGS]...

Commands:
  # ...
  install    Installs provided packages and adds them to Pipfile, or (if no
  # ...
  sync       Installs all packages specified in Pipfile.lock.