【问题标题】:Conditional requirements in setup.pysetup.py 中的条件要求
【发布时间】:2019-07-05 07:40:45
【问题描述】:

我正在编写一个依赖于file-magiclibrary,它适用于大多数 平台,但在Alpine Linux 中,文件魔术不起作用,所以我需要改为使用python-magic 库。

现在我知道如何编写自己的代码来处理不同的 Python 库 API,但我不知道如何编写我的 setup.cfgsetup.py 以根据系统有不同的要求我们正在其上进行安装。

我认为最好的选择是使用PEP 508 规则,但我不知道如何说“libmagic like Alpine”或该语法中的某些内容,更不用说是否可以在包的设置中使用。 py。确实,如果不安装file-magic 并看着它死掉,我什至无法弄清楚如何区分架构之间的区别:-(

当然,这种事情一定有最佳实践吗?

更新

在下面蒂姆的一些更广泛的理解之后,我拼凑出这个 hack 来让它工作:

def get_requirements():
    """
    Alpine is problematic in how it doesn't play nice with file-magic -- a
    module that appears to be the standard for most other Linux distros.  As a
    work-around for this, we swap out file-magic for python-magic in the Alpine
    case.
    """

    config = configparser.ConfigParser()
    config.read("setup.cfg")
    requirements = config["options"]["install_requires"].split()

    os_id = None
    try:
        with open("/etc/os-release") as f:
            os_id = [_ for _ in f.readlines() if _.startswith("ID=")][0] \
                .strip() \
                .replace("ID=", "")
    except (FileNotFoundError, OSError, IndexError):
        pass

    if os_id == "alpine":
        requirements[1] = "python-magic>=0.4.15"

    return requirements


setuptools.setup(install_requires=get_requirements())

这允许 setup.cfg 的声明性语法,但如果安装目标是 Alpine 系统,则会调整 install_requires 值。

【问题讨论】:

    标签: python package libmagic


    【解决方案1】:

    您可能想使用platform module 来尝试识别系统详细信息。

    最好的办法是尝试使用 platform.architecture()platform.platform()platform.system() 的组合,并适当处理错误并考虑所有可能的返回信息。

    示例:

    我在 Win10 上运行,这里是这些函数的输出(还有一个):

    >>> import platform
    >>> print(platform.architecture())
    ('32bit', 'WindowsPE')
    >>> print(platform.platform())
    Windows-10-10.0.17134-SP0
    >>> print(platform.processor())
    Intel64 Family 6 Model 142 Stepping 10, GenuineIntel
    >>> print(platform.system())
    Windows
    

    编辑

    上述答案不一定会返回您想要的信息(我没有提及平台模块中的任何已弃用功能)。

    再深入一点,得到this SO result,它解释了用于收集发行版名称的内置平台函数已被弃用。

    官方文档指向名为distro 的 PyPi 包。 PyPi 上的发行版文档承认需要这种类型的信息,并且在那里找到的示例用法如下所示:

    >>> import distro
    >>> distro.linux_distribution(full_distribution_name=False)
    ('centos', '7.1.1503', 'Core')
    

    【讨论】:

    • 不幸的是,platform 模块只从 host 系统返回数据,这在您测试 Alpine 时显然是个问题。 distro 模块正是我所需要的,但由于我不能指望该模块存在于目标系统(尤其是 Alpine)上,因此该解决方案也不适用于我。此时我正在考虑挖掘发行版模块并将其代码复制/粘贴到我的 setup.py 中,这会很丑陋,但也许是我唯一的选择?
    • 我认为可能需要 distro 模块作为安装过程的一部分,然后可以在 setup.py 中使用它。其他人会比我更清楚。查看this link on install_requires
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 2019-05-02
    • 1970-01-01
    • 2012-10-07
    • 2017-10-05
    • 2017-07-11
    • 2015-09-23
    相关资源
    最近更新 更多