MEP11: 第三方依赖#

本 MEP 试图改进 matplotlib 中第三方依赖项的处理方式。

状态#

已完成 -- 需要合并

分支和拉取请求#

#1157: 使用自动依赖解析

#1290: 解绑 pyparsing

#1261: 将 six 更新到 1.2

摘要#

matplotlib 的目标之一是尽可能保持其易于安装。为此,一些第三方依赖项包含在源代码树中,并且在某些情况下,与 matplotlib 一起安装。此 MEP 旨在解决该方法的一些问题,同时保持一致性,并继续使安装变得方便。

在当时最初完成时,setuptoolseasy_installPyPI 还不够成熟,无法依赖。然而,目前我们应该能够安全地利用这些工具的“现代”版本,即 distributepip

虽然 matplotlib 依赖于 Python 库和 C/C++ 库,但此 MEP 仅处理 Python 库,以避免混淆问题。C 库代表了一组更大且基本正交的问题。

详细描述#

matplotlib 依赖于以下第三方 Python 库:

  • Numpy

  • dateutil (纯Python)

  • pytz (纯 Python)

  • six -- 由 dateutil 所需(纯 Python)

  • pyparsing (纯 Python)

  • PIL (可选)

  • GUI 框架:pygtk, gobject, tkinter, PySide, PyQt4, wx(全部可选,但需要一个用于交互式 GUI)

当前行为#

从源代码安装时,可以使用 git 检出或 pip:

  • setup.py 尝试 导入 numpy。如果失败,安装将失败。

  • 对于 dateutilpytzsix 中的每一个,setup.py 尝试从顶层命名空间导入它们。如果失败,matplotlib 会将库的本地副本安装到顶层命名空间中。

  • pyparsing 总是安装在 matplotlib 命名空间内。

当与 pip 一起使用时,这种行为最为令人惊讶,因为即使这些包可能都能正常工作,也不会执行 pip 的依赖关系解析。

pyparsing 安装在 matplotlib 命名空间中的事实据报道(#1290)让一些用户误以为它是一个与 matplotlib 相关的模块,并从那里导入它,而不是从顶层导入。

在使用 Windows 安装程序安装时,dateutilpytzsix 总是会被安装在顶层,这可能会覆盖已经安装的这些库的副本。

TODO: 描述与 OS-X 安装程序的行为。

当使用包管理器(Debian、RedHat、MacPorts 等)安装时,这种行为实际上是正确的,matplotlib 包中没有特殊的补丁来处理我们以这种方式处理 dateutilpytzsix 的事实。然而,我们应该注意,无论我们转向哪种方法,都应继续在该环境中有效。

在 matplotlib 树中维护这些包并确保它们是最新的,这是一个维护负担。由于这种负担,可能需要第三方纯 Python 库的高级新功能在纳入时面临更高的门槛。

期望的行为#

第三方依赖项通过利用 pipdistributePyPI 从其规范位置下载和安装。

dateutilpytzpyparsing 应该被设置为可选依赖项——尽管如果它们没有安装,某些功能将会失效。这将允许用户决定是否要安装某个特定功能。

实现#

对于从源代码安装,假设用户已经安装了所有C级别的编译器和依赖项,这可以通过使用 distribute 并按照 这里 的说明来相当容易地完成。对matplotlib库代码的唯一预期更改是从顶级命名空间导入 pyparsing 而不是从matplotlib内部导入。请注意,distribute 还将允许我们移除对 six 的直接依赖,因为严格来说,它只是 dateutil 的直接依赖。

对于二进制安装,有多种选择(这里从最好/最难到最差/最易排序):

  1. distutils wininst 安装程序允许运行安装后脚本。可能可以让这个脚本运行 pip 来安装其他依赖项。(参见 这个帖子 了解之前有人走过这条路的情况)。

  2. 在我们的安装程序中继续包含 dateutilpytzsixpyparsing,但使用安装后脚本来安装它们 仅当 它们尚未被找到时。

  3. 将所有这些包移动到一个(新的)``matplotlib.extern`` 命名空间中,以便外部用户清楚这些是外部包。在核心 matplotlib 代码库中添加一些条件导入,以便首先尝试顶层的 dateutil,如果失败则使用 matplotlib.extern.dateutil

2 和 3 是不理想的,因为它们仍然需要在我们树中维护这些包的副本——而且由于它们使用较少,这一点更加严重——仅在二进制安装程序中使用。这三种方法都没有解决 Numpy 的问题,它仍然需要使用安装程序手动安装。

TODO: 这与Mac OS-X安装程序有何关联?

向后兼容性#

目前,可以在没有第三方依赖且没有互联网连接的机器上从源代码安装 matplotlib。在此更改之后,首次安装 matplotlib 将需要互联网连接(以及一个可用的 PyPI)。(后续的 matplotlib 更新或开发工作将无需访问网络)。

替代方案#

分发二进制蛋并不像是一个可行的解决方案。这首先需要安装 easy_install,而 Windows 用户通常更喜欢众所周知的 .exe.msi 安装程序,这些安装程序开箱即用。