简体   繁体   English

setup.py中的条件要求

[英]Conditional requirements in setup.py

I'm writing a library that's dependent on file-magic , which works just fine for most platforms, but in Alpine Linux, file-magic won't work so I need to instead use the python-magic library. 我正在编写一个依赖于file-magic ,该大多数平台上都可以正常运行,但是在Alpine Linux中,file-magic无法正常工作,因此我需要改用python-magic库。

Now I know how to write my own code to handle the different Python library APIs, but what I don't know how to do is to write my setup.cfg or setup.py to have a different requirements based on the system on which we're doing the installation. 现在,我知道如何编写自己的代码来处理不同的Python库API,但是我不知道该怎么做,就是根据我们所使用的系统编写setup.cfgsetup.py以具有不同的要求正在安装。

I figured the best option would be to use the PEP 508 rules, but I can't figure out how to say "libmagic like Alpine" or something in that syntax, let alone if that would work in a package's setup.py. 我认为最好的选择是使用PEP 508规则,但是我无法弄清楚如何说“像Alpine这样的libmagic”或这种语法,更不用说在包的setup.py中可以使用了。 Indeed, I can't even figure out how to tell the difference between the architectures without installing file-magic and watching it die :-( 确实,如果不安装file-magic并看着它消失,我什至无法弄清楚如何分辨这些体系结构之间的区别:-(

Surely, there must be a best practise for this sort of thing? 当然,这种事情一定有最佳实践吗?

Update 更新

After some broader understanding from Tim below, I cobbled together this hack to get it working: 在从下面的Tim那里获得了更广泛的理解之后,我整理了这个技巧以使其正常工作:

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())

This allows for the declarative syntax of setup.cfg , but tweaks the install_requires value if the installation target is an Alpine system. 这允许使用setup.cfg的声明性语法,但是如果安装目标是Alpine系统,则可以调整install_requires值。

You probably want to use the platform module to try to identify the system details. 您可能要使用平台模块来尝试识别系统详细信息。

Best bet is to try and use a combo of platform.architecture() , platform.platform() , and platform.system() with proper error handling and consideration of all possible return info. 最好的选择是尝试使用platform.architecture()platform.platform()platform.system()的组合,并进行适当的错误处理并考虑所有可能的返回信息。

Example: 例:

I am running on Win10, here are the outputs of those functions (and one more): 我在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

Edit 编辑

The above answer does not necessarily return the info that you want (I left out mention of any deprecated functions from the platform module). 上面的答案不一定返回您想要的信息(我没有提到平台模块中所有不推荐使用的功能)。

Digging a little deeper, yields this SO result which explains that the built-in platform functions for gathering distro names are deprecated. 深入研究,将得出此SO结果 ,这说明已弃用了用于收集发行名称的内置平台功能。

The official docs point in the direction of a PyPi package called distro . 官方文档指向名为distro的PyPi软件包的方向。 The distro docs on PyPi acknowledge the need for this type of info and an example usage found there looks like this: PyPi上的发行文档承认需要这种类型的信息,并且在其中找到的示例用法如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM