setup.py里的几个require

在setup.py中,一般需要要调用setup()函数。 这个函数有诸多参数,其中一类是require,指定了一些需要的Python包。

本文仅介绍setuptools里的setup(),也仅介绍其中require相关的参数。

install_requires

如果按重要性排序,首屈一指的当属install_requires。 这个参数把孤立的Python包按照依赖关系组织起来,在python setup.py installpip install .时自动安装。 上古时候,Python包往往以『无依赖』作为一个宣传点。 而这个参数出现后,依赖管理变得无比简单,让Python的生态得以向更复杂的形式进化。

install_requires流行以前,往往会使用requrements.txt来声明依赖。 大概形式如下:

docutils >= 0.3
Django >= 1.11, != 1.11.1, \
    <= 2
requests[security, socks] >= 2.18.4
setuptools==38.2.4

install_requires来说,只是把上述形式换成字符串列表而已。比如:

setup(
    ...
    install_requires=[
        'argparse',
        'setuptools==38.2.4',
        'docutils >= 0.3',
        'Django >= 1.11, != 1.11.1, <= 2',
        'requests[security, socks] >= 2.18.4',
    ],
)

以上展示了五种常用形式:

  1. 'argparse',只包含包名。 这种形式只检查包的存在性,不检查版本。 方便,但不利于控制风险。
  2. 'setuptools==38.2.4',指定版本。 这种形式把风险降到了最低,确保了开发、测试与部署的版本一致,不会出现意外。 缺点是不利于更新,每次更新都需要改动代码。
  3. 'docutils >= 0.3',这是比较常用的形式。 当对某个库比较信任时,这种形式可以自动保持版本为最新。
  4. 'Django >= 1.11, != 1.11.1, <= 2',这是比较复杂的形式。 如这个例子,保证了Django的大版本在1.11和2之间,也即1.11.x;并且,排除了已知有问题的版本1.11.1(仅举例)。 对于一些大型、复杂的库,这种形式是最合适的。
  5. 'requests[security, socks] >= 2.18.4',这是包含了额外的可选依赖的形式。 正常安装requests会自动安装它的install_requires中指定的依赖,而不会安装securitysocks这两组依赖。 这两组依赖是定义在它的extras_require中。 这种形式,用在深度使用某些库时。

指定包名是必须的,而版本控制与可选依赖,则是高级形式。 这不仅仅是install_requires的形式,而是对setup.py的所有require都适用。

如果其中某些依赖,在官方的PyPI中不存在,而是发布在某些私有源中,则需要指定dependency_links

setup(
    ...
    dependency_links=[
        'https://pypi.python.org/simple',
        'http://my.company.com/pypi/',
        ...
    ],
)

extras_require

extras_require指定了可选的功能与依赖。 某些特殊的、偏门的功能,可能绝大多数用户不会去使用。 这些功能的依赖,不适合放在install_requires里。 这时就可以用extras_require来指定。

setup(
    ...
    extras_require={
        'security': ['pyOpenSSL>=0.14', 'cryptography>=1.3.4', 'idna>=2.0.0'],
        'socks': ['PySocks>=1.5.6, !=1.5.7'],
    },
)

以上以requests的设置为例。 extras_require需要一个dict,其中按(自定义的)功能名称进行分组,每组一个列表,与install_requires规则相同。

使用时,可以用类似'requests[security, socks]'的形式来指定。

python_requires

python_requires指定运行时需要的Python版本。

现在还在使用Python 2的,基本上都是用Python 2.7.x版本。 它仅做维护性修改,基本上没有代码的兼容性问题。 而使用Python 3的,则每一个小版本都有变化,代码可能出现不兼容问题。 指定python_requires可以避免这类问题,在安装时就会报错、提示。

比如下例,指定该库仅在Python 2.7.x版本使用。

setup(
    ...
    python_requires='>=2.7, <=3',
)

tests_require

tests_require是仅仅在测试时需要使用的依赖。

有些依赖库,仅仅在测试代码中使用,在正常发布的代码中是没有用的。 比如,pytestpytest-cov等,放在install_requires中不合适。 这些都放在tests_require即可,可以帮助搭建测试环境,而不影响用户的正常使用。

setup_requires

setup_requires是只在执行setup.py时需要的依赖。 这通常是为一些setuptools插件而准备的配置,比如pytest-runner

setup(
    ...
    tests_require=[
        'pytest>=3.3.1',
        'pytest-cov>=2.5.1',
    ],
    setup_requires=[
        'pytest-runner>=3.0',
    ],
)

比如,进行以上配置后,在执行python setup.py test时,可以自动安装这三个库,确保测试的正常运行。

一个下载问题

有一个需要注意的问题,可能会卡住执行setup.py的过程。

在中国,对官方PyPI的访问速度慢,并且不稳定。 在某些隔绝网络的环境下,需要配置代理或私有源。 通常,俺们会用pip来做包管理,这些都配置在~/.pip/pip.conf中。

setup()函数的这些require,尤其是tests_requiresetup_requires,是通过easy_install来安装的。 如果使用python setup.py install的方式来安装,那么install_requiresextras_require也会出事。

easy_install的配置文件是~/.pydistutils.cfg,在其中指定index-url即可避免访问官方PyPI。 以下以阿里源为例。

[easy_install]
index-url=http://mirrors.aliyun.com/pypi/simple/

参考


相关笔记