【问题标题】:Pin dependencies for bdist wheels while keeping unpinned for development固定 bdist 轮子的依赖项,同时保持未固定以进行开发
【发布时间】:2021-08-16 23:51:25
【问题描述】:

我打算将我的 Python 项目作为带有固定依赖版本的 bdist 轮分发,以便对上游依赖项的更改不会破坏我的代码。但是,当有人安装我的项目的开发版本时,例如通过pip install -e,我希望引入最新版本的依赖项,以便我可以不断地针对它们测试我的代码。

依赖列在setup.py:

from setuptools import setup

setup(
    ...
    install_requires=["numpy", "scipy", "matplotlib"],
)

我从项目根目录(包含setup.py 的那个)创建轮子:

pip wheel . --no-deps

创建的轮子在安装后也将安装 Numpy、Scipy 和 Matplotlib 的最新版本。解压后的wheel的METADATA文件(安装时pip用来确定项目的依赖关系)显示了这种情况:

...other metadata...
Requires-Dist: numpy
Requires-Dist: scipy
Requires-Dist: matplotlib

如果我更改 setup.py 中的 install_requires 以设置依赖项的显式版本(例如使用 install_requires=["numpy==1.20.0", ...etc...]),则创建的轮子的 METADATA 会列出:

...other metadata...
Requires-Dist: numpy (==1.20.0)
...other dependencies...

这告诉最终用户机器上的pip 获取 Numpy 1.20.0。这就是我想要的轮子,但是每当有人运行 pip install -e . 时,他们也会得到这些固定版本。

有没有办法以编程方式指定“开发”依赖项而不是“轮子”依赖项?还是我坚持告诉人们手动运行pip install -r unpinned-requirements.txtpip install -e . --no-deps

【问题讨论】:

    标签: python pip setuptools setup.py


    【解决方案1】:

    更新:

    所以基本上你想要做的是将需求固定在轮子上,而不是在开发环境中。

    将需求固定在setup.py:

    import sys
    import subprocess
    from packaging.requirements import InvalidRequirement, Requirement
    
    if 'bdist_wheel' in sys.argv:  # building the wheel
    
        if your_environment_is_clean:  # e.g. in a build pipeline
            # get requirements from pip freeze
            # NOTE: this also pins all sub-requirements
    
            res = subprocess.run([sys.executable, "-m", "pip", "freeze"], check=True, capture_output=True, text=True)
            requirements = res.stdout.split('\n')
    
        elif you_want_to_pin_your_requirements_here:
            requirements = [
                "numpy==1.20.0",  # pinned versions for wheel
                # ...
            ]
    
        else:
            # load pinned requirements from file
    
            with open("requirements.txt") as file:
                lines = file.readlines()
            
            requirements = []
            for line in lines:
                try:  
                    # check if lines are valid requirements
                    req = Requirement(line)
                    requirements.append(str(req))
                except InvalidRequirement:
                    pass
    else:
        # not building a wheel
    
        requirements = [
            "numpy",  # unpinned versions for development
            # ...
        ]
    
    setuptools.setup(
        install_requires=requirements,
        # ...
    )
    

    构建后手动调整轮子:

    您只能将版本固定在轮子上。我不知道是否存在任何工具,但您可以手动完成:

    [pip install wheel]
    pip wheel --no-deps [-e] .
    wheel unpack <package>-<spec>.whl
    

    将版本固定在package-&lt;version&gt;/&lt;package&gt;-&lt;spec&gt;/METADATA 并重新打包:

    wheel pack <package>
    

    然后展开轮子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-27
      • 1970-01-01
      • 2018-09-12
      • 1970-01-01
      • 2014-11-04
      • 2020-03-25
      相关资源
      最近更新 更多