【问题标题】:PIP Constraints FilesPIP 约束文件
【发布时间】:2020-12-07 22:47:25
【问题描述】:

我正在阅读 docs 并且无法理解它:

约束文件是要求文件,只控制哪些 已安装需求的版本,而不是是否已安装 不是。它们的语法和内容几乎与需求相同 文件。

有一个关键区别:在约束文件中包含一个包 不会触发安装包。

  • 这是否意味着我需要先要求文件然后运行约束?
  • 需要同时拥有 requirements.txt 和约束.txt?
  • 或者只是-c requirements.txt

谁能用简单的英语解释一下新的 PIP 功能:Constraints Files 有什么作用?

【问题讨论】:

    标签: python pip


    【解决方案1】:

    更新: pip 20.3,于 2020 年 11 月 30 日发布,引入了 a new resolver,修复了一些设计问题。它还重新实现了the constraints feature。现在很难或不可能按照我在下面描述的方式使用该功能。我不明白新的约束实现,我不再使用它。我从pip-tools 获得了pip-compile 的成功。我在requirements.in 中指定了顶级需求,pip-compile 生成一个带有特定版本的requirements.txt 一个包哈希。有关工作示例,请参阅 ichnaea 项目中的 requirements.inrequirements.txt

    以下原始答案,适用于 pip 20.2 及之前的版本

    我认为约束文件是将“真实”需求与完整安装列表分开的好方法。

    good practice 在您的需求文件中完全指定包版本。例如,如果您使用 Django LTS 安装 django-allauth,请将其固定到最新版本(根据我的回答):

    Django==1.8.12
    django-allauth==0.25.2
    

    当您安装软件包时,它最终也会安装一些必需的软件包。因此,您也可以添加这些,以便每个人都获得相同版本的包:

    Django==1.8.12
    django-allauth==0.25.2
    oauthlib==1.0.3
    python-openid==2.2.5
    requests==2.9.1
    requests-oauthlib==0.6.1
    

    然后您会收到错误报告“在 Python 3 下不起作用”。糟糕,python-openid 仅适用于 Python 2,而使用了python3-openid,进一步需要defusedxml

    Django==1.8.12
    django-allauth==0.25.2
    oauthlib==1.0.3
    python-openid==2.2.5   ; python_version < '3.0'
    python3-openid==3.0.10 ; python_version >= '3.0'
    defusedxml==0.4.1      ; python_version >= '3.0'
    requests==2.9.1
    requests-oauthlib==0.6.1
    

    现在 requirements.txt 越来越难看,乱七八糟的很难看到 Django 和 django-allauth 的“需求”。

    这是一个引用约束文件的requirements.txt

    -c constraints.txt
    Django==1.8.12
    django-allauth==0.25.2
    

    还有constraints.txt 提供有用的评论:

    # django-allauth requirements
    oauthlib==1.0.3
    python-openid==2.2.5
    python3-openid==3.0.10
    defusedxml==0.4.1
    requests==2.9.1
    requests-oauthlib==0.6.1
    

    不需要 Python 分类器,因为只有在包需要约束时才会安装约束,否则会被忽略。此外,如果一个软件包在 2 年后不再需要另一个软件包,那么全新安装将停止安装它。

    我认为,加上一些 cmets,这是一种有用的方式来传达您正在为项目使用哪些包,以及包含哪些包,因为它们是依赖项。

    如果您使用 pip 8.x 的 hash-checking mode,我认为它会变得更加有用,这需要指定依赖关系的版本。如果你走这条路,我推荐hashin 来帮助你管理哈希。请参阅browsercompat,了解使用约束和散列的复杂需求设置。

    【讨论】:

    • 嗨,我有点困惑,在约束中指定 python-openid==2.2.5python3-openid==3.0.10 将有助于根据 python 版本确定使用哪一个?
    • 根据 Python 版本选择python-openidpython3-openid 的代码在django-allauth's setup.py 中。如果您使用的是 Python 2.x,django-allauth 将请求 python-openid &gt;= 2.2.5constraints.txt 文件将显示“并使其完全成为 2.2.5 版”。
    • @jwhitlock 通过将-c constraints.txt 包含在requirements.txt 文件的顶部pip install 将获取它。但是你如何使它适用于pip freeze -r requirements.txt? (这不是会抛出一个Invalid requirement: '-c constraints.txt' 吗?)
    • @RuiCarvalho 是的,我得到Invalid requirement: '-c constraints.txt' 点数为 19.03。我认为约束与pip freeze 工作流不兼容。我可能会在项目开始时使用pip freeze(如果我记得它存在的话),但我会为成熟、复杂的项目手动维护需求文件,在这些项目中,约束值得维护。
    【解决方案2】:

    来自书"Secret Recipes of the Python Ninja"

    约束文件与需求文件在一个关键方面不同:将包放在约束文件中不会导致安装包,而需求文件将安装列出的所有包。约束文件只是控制将安装哪个版本的包的要求文件,但不提供对实际安装的控制。

    假设您有包含以下代码的 requirements.txt 文件

    # requirements.txt
    pandas
    

    和约束.txt

    # constraints.txt
     # math / science / graph stuff
      bokeh==0.11.1
      numpy==1.10.4
      pandas==0.17.1
      scipy==0.17.0
      openpyxl==2.3.3
      patsy==0.4.1
      matplotlib==1.5.1
      ggplot==0.6.8
      seaborn==0.7.0
      scikit-learn==0.17
    

    执行

    pip install -c constraints.txt

    将从 requirements.txt 安装所有包,并使用 constraints.txt 文件进行版本约束。

    【讨论】:

      【解决方案3】:

      当您为生产环境提供针对生产基础设施的优化包编译时,约束文件非常有用。

      我们在 docker 容器中提供此类环境,其中包含针对我们的生产服务器优化的 numpy、scipy、tensorflow、opencv 等版本。为了确保开发人员为使环境可重现而设置的需求文件不会覆盖这些优化的安装,我们使用约束文件。它们是作为构建过程的一部分编写的。 pip 通过设置 PIP_CONSTRAINT 环境变量来了解这些约束。

      以前,开发人员总是必须确保他们的需求与 prod 容器中可用的内容一致,考虑到一些次要版本号的迭代速度非常快,这可能会很痛苦。

      【讨论】:

        【解决方案4】:

        我自己没有使用过约束文件,所以我可能是错的,但这是我从文档中理解的。

        假设您有多个使用 pip 安装的项目。其中一些直接依赖于流行的包 foobar,一些间接(通过它们的依赖项),一些根本不依赖它。

        有一天,您决定稍微更改 foobar 代码,以解决与您的环境相关的一些问题,因此您继续创建 foobar 的本地副本。现在您想确保您的所有项目都使用这个本地副本,但您不想花时间找出它们中的哪些依赖于 foobar 然后编辑它们的 requirements.txtsetup.py 文件.

        这里是约束文件,您可以在其中指出 foobar 的本地副本并将其用于所有项目,而不用关心其中哪些需要 foobar,因为约束文件仅适用于正在安装的项目实际上依赖于 foobar(无论是直接还是间接)。


        reddit 上有一个更好的可能用法示例。

        【讨论】:

        • 那么如何结合需求文件使用
        • @JamesLin 不确定我是否正确理解了您的问题,但这是一种可能的情况:您的 requirements.txt 包含单个包 Flask。这取决于您出于任何原因修改的 Werkzeug,并希望 Flask 依赖于您的本地版本。所以你把它放到constraints.txt 并运行pip install -r requirements.txt -c constraints.txt。在这种简单的情况下,您可以只使用 requirements.txt,但当您有多个项目具有复杂的依赖关系树时,使用 constrains.txt 更有意义。
        猜你喜欢
        • 2022-12-05
        • 1970-01-01
        • 1970-01-01
        • 2023-03-19
        • 2011-07-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-24
        相关资源
        最近更新 更多