根据解释器版本在setup.py中解决安装时的Python依赖关系

时间:2012-12-11 02:02:00

标签: python pip dependency-management

假设我有一堆需求文件,如:

requirements.txt   # common for both 2.x and 3.x
requirements-2.txt # 2.x
requirements-3.txt # 3.x

我希望根据当前的Python解释器版本在install_requires文件中填充setup.py参数。当然假设 pip 处理安装过程。

解决方案1:当然,我可以编写一个简单的函数来读取并返回正确的要求。在多个项目的情况下,这显然是不可接受的,因为我将不得不在任何地方复制该功能。

解决方案2:这里的下一个想法是写一个简单的包为我做,但问题是它不仅应该在分发时可用(如python setup.py sdist) ,但更重要的是,安装在一台机器上。

我设法编写了一个简单的模块来执行该操作,我们称之为depmodule。我也跟随setup.py

# -*- coding: utf-8 -*-

from setuptools import setup, find_packages

try:
    from depmodule import find_requirements
except ImportError:
    # this line is executed when reading setup.py for the first time
    # since depmodule is not installed yet
    find_requirements = lambda: []

setup(
    name='some-package',
    packages=find_packages(),
    # snip...
    platforms='any',

    # note that depmodule is listed here as a requirement, so it will be
    # installed before some-package, thus will be available when it comes
    # to running setup.py of some-package
    install_requires=['depmodule'] + find_requirements(),
)

说到pip install some-package 实际上正确地解析了依赖关系,但它们没有被pip选中,所以它只安装:depmodule some-package(按此顺序) depmodule dep1 dep2 ... some-package

我尝试使用setup_requires参数,但没有运气。已下载依赖项,但我无法访问它,因为它是一个egg包(未提取)。

有什么办法可以解决这个问题吗?是否有任何替代方案(其他方法)可以帮助解决这个问题?

谢谢!

1 个答案:

答案 0 :(得分:0)

由于您不想为多个项目复制代码,因此可以考虑从单个源生成setup.py和/或更新setup.py的某些部分。 这类似于从Makefile模板生成Makefile.in

我有一个py_setup程序。我用py_setup --new调用它来在当前目录中生成一个新的setup.py,将py_setup的一部分作为模板。当py_setup时 以文件名作为参数运行,它尝试更新该文件中的段,但保持其余部分不变。 如果在没有参数的情况下运行且没有选项py_setup,则会更新所有*/setup.py个文件中的细分。

py_setup(以及setup.py文件)中的细分由#_## segement_name表单的注释行分隔,或以#_#结尾。段之前或之间的任何内容都会被复制,但永远不会在setup.py中更新 永远不会复制py_setup中#_###行之后的任何内容,即实际的py_setup程序代码

大多数行都是逐字复制的,除了段分隔符注释(在段名称后删除)和以以下内容开头的行:

setup = setup

从该行开始,setup =被删除,因此最终会在setup.py中调用setup(),但在运行py_setup时则不会。

更新时,只有目标setup.py中的现有细分受到py_setup中相同命名细分的行替换。删除或更改段名称可确保不会更改代码更改。