【问题标题】:Check if my Python has all required packages检查我的 Python 是否具有所有必需的包
【发布时间】:2013-04-24 01:46:25
【问题描述】:

我有一个requirements.txt 文件,其中包含我的虚拟环境所需的软件包列表。是否可以找出文件中提到的所有包是否都存在。如果缺少某些包,如何找出丢失的包?

【问题讨论】:

    标签: python pip requirements.txt


    【解决方案1】:

    更新

    通过distutils.text_file.TextFile 可以实现这一点的最新改进方法。有关详细信息,请参阅下面的 Acumenus 的answer

    原创

    pythonic 的方式是通过pkg_resourcesAPI。要求以 setuptools 可以理解的格式编写。例如:

    Werkzeug>=0.6.1
    Flask
    Django>=1.3
    

    示例代码:

    import pkg_resources
    from pkg_resources import DistributionNotFound, VersionConflict
    
    # dependencies can be any iterable with strings, 
    # e.g. file line-by-line iterator
    dependencies = [
      'Werkzeug>=0.6.1',
      'Flask>=0.9',
    ]
    
    # here, if a dependency is not met, a DistributionNotFound or VersionConflict
    # exception is thrown. 
    pkg_resources.require(dependencies)
    

    【讨论】:

    • 作为奖励,这会自动递归检测冲突的版本要求——这些将无法满足。
    • 用 try 循环遍历 require 调用:除了 pkg_resources.DistributionNotFound 包装调用。然后在异常情况下打印。这样它会告诉你所有丢失的依赖项,而不是在找到第一个丢失的依赖项时死掉。
    • 更新链接到 Asclepius 的答案。但是,它不像这个答案的文字所示那样使用distutils.text_file.TextFile
    【解决方案2】:

    基于answer by Zaur,假设您确实使用了需求文件,您可能需要一个单元测试,可能在tests/test_requirements.py 中,以确认包的可用性。

    此外,这种方法使用subtest 来独立确认每个要求。这很有用,以便记录所有故障。如果没有子测试,则只会记录一次失败。

    """Test availability of required packages."""
    
    import unittest
    from pathlib import Path
    
    import pkg_resources
    
    _REQUIREMENTS_PATH = Path(__file__).parent.with_name("requirements.txt")
    
    
    class TestRequirements(unittest.TestCase):
        """Test availability of required packages."""
    
        def test_requirements(self):
            """Test that each required package is available."""
            # Ref: https://stackoverflow.com/a/45474387/
            requirements = pkg_resources.parse_requirements(_REQUIREMENTS_PATH.open())
            for requirement in requirements:
                requirement = str(requirement)
                with self.subTest(requirement=requirement):
                    pkg_resources.require(requirement)
    

    【讨论】:

    • 这真是个好主意!
    • 更新了接受的答案并引用了您的答案。
    • @R.Ilma 通过子测试,您可以准确了解失败的需求的完整子集,因此在测试时它经常很有用。没有子测试,你只知道第一次失败。
    • @sinoroc 实际上,这个答案曾经使用过pkg_resources.parse_requirements,您可以在其编辑历史中确认。我不得不停止使用它,因为它的 API 非常不稳定并且过去一直在中断。现在我再次编辑了答案,以便按照您的建议重新使用它。
    • @Juan-Kabbali 即使有可能,它也是非常不标准的。包应该由包管理器管理,例如pip、诗歌、conda 等,因此必须运行相同的包。然而,标准工作流程是首先安装定义的包列表(根据所选包管理器的使用说明),然后才运行单元测试。
    【解决方案3】:

    您可以运行pip freeze 来查看您已安装的内容并将其与您的requirements.txt 文件进行比较。

    如果你想安装缺失的模块,你可以运行pip install -r requirements.txt,它会安装所有缺失的模块,并在最后告诉你哪些缺失并安装了。

    【讨论】:

      【解决方案4】:

      如果您有兴趣从命令行执行此操作,pip-missing-reqs 将列出丢失的包。示例:

      $ pip-missing-reqs directory
      Missing requirements:
      directory/exceptions.py:11 dist=grpcio module=grpc
      

      pip checkpipdeptree --warn fail 仅审核已安装的软件包是否相互兼容,而不检查requirements.txt。)

      【讨论】:

      • pip check 不会验证需求文件中的包是否已安装。 pip check 验证已安装的软件包是否具有兼容/未损坏的依赖项。
      【解决方案5】:

      您可以使用pip freeze 中的-r 选项来验证这一点。它为未安装的软件包生成WARNING 日志。为了显示WARNING 消息,应选择一种适当的详细模式。例如:

      $ pip -vvv freeze -r requirements.txt | grep "not installed"
      
      WARNING: Requirement file [requirements.txt] contains six==1.15.0, but package 'six' is not installed
      

      【讨论】:

        【解决方案6】:

        如果您不想知道 哪些 软件包未安装,这里有一个基于 Zaur Nasibov 的回答的单线:

        python3 -c "import pkg_resources; pkg_resources.require(open('requirements.txt',mode='r'))" &>/dev/null
        

        命令是否成功完成,然后可以用来进行 pip 安装。

        作为 Ruby 的 bundle check || bundle install 的等效项,我们正在做:

        python3 -c "import pkg_resources; pkg_resources.require(open('requirements.txt',mode='r'))" &>/dev/null || pip3 install --ignore-installed -r requirements.txt
        

        我意识到这并没有解决确切的问题,但是当谷歌搜索时,这个页面首先出现。无论如何,您只是真的想知道缺少的依赖项是什么,然后才能满足它们。

        我们不能只使用pip3 check,因为它看不到requirements.txt

        【讨论】:

          【解决方案7】:

          跑步

          pip freeze -r requirements.txt
          

          它将已安装的文件与需求文件进行比较并警告您哪些不是

          【讨论】:

            【解决方案8】:

            除了检查requirements.txt 中列出的模块是否已安装之外,您可能还需要检查您的项目使用的所有模块是否确实在requirements.txt 文件中列出。

            如果您使用 flake8 进行样式检查,您可以为 flake8 添加 flake8-requirements 插件。它将自动检查在setup.pyrequirements.txtpyproject.toml 文件中是否存在导入的模块。此外,对于自定义模块,您可以使用已知模块添加自定义配置(以防止 flake8 警告)。有关更多配置选项,请参阅 flake8-requirements 项目的描述。

            【讨论】:

              【解决方案9】:

              如果 requirements.txt 是这样的:

              django
              oursql
              sys
              notexistingmodule
              

              然后下面的脚本会告诉你缺少哪些模块:

              #!/usr/bin/python3
              fname = 'requirements.txt'
              with open(fname, 'r', encoding='utf-8') as fhd:
                  for line in fhd:
                      try:
                          exec("import " + line)
                      except:
                          print("[ERROR] Missing module:", line)
              

              这将打印:

              [ERROR] Missing module: notexistingmodule
              

              【讨论】:

              • 如果 requirements.txt 包含版本信息,例如,这将失败django==1.5.1
              • 确实如此。如果模块也列在一行中,它将失败。如上所述,如果 requirements.txt 每行列出一个模块,它将起作用。
              • 你确定包名和模块名一样吗?
              • python-memcacheddjango-json-fielddjango-statsd-mozilla 等呢?
              • exec 永远不应使用。它将代码开放给外部操作。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-12-01
              • 2015-06-19
              • 1970-01-01
              • 2019-08-10
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多