MEP11: 第三方依赖#
本 MEP 试图改进 matplotlib 中第三方依赖项的处理方式。
状态#
已完成 -- 需要合并
分支和拉取请求#
#1157: 使用自动依赖解析
#1290: 解绑 pyparsing
#1261: 将 six 更新到 1.2
摘要#
matplotlib 的目标之一是尽可能保持其易于安装。为此,一些第三方依赖项包含在源代码树中,并且在某些情况下,与 matplotlib 一起安装。此 MEP 旨在解决该方法的一些问题,同时保持一致性,并继续使安装变得方便。
在当时最初完成时,setuptools、easy_install 和 PyPI 还不够成熟,无法依赖。然而,目前我们应该能够安全地利用这些工具的“现代”版本,即 distribute 和 pip。
虽然 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。如果失败,安装将失败。对于 dateutil、pytz 和 six 中的每一个,
setup.py尝试从顶层命名空间导入它们。如果失败,matplotlib 会将库的本地副本安装到顶层命名空间中。pyparsing 总是安装在 matplotlib 命名空间内。
当与 pip 一起使用时,这种行为最为令人惊讶,因为即使这些包可能都能正常工作,也不会执行 pip 的依赖关系解析。
pyparsing 安装在 matplotlib 命名空间中的事实据报道(#1290)让一些用户误以为它是一个与 matplotlib 相关的模块,并从那里导入它,而不是从顶层导入。
在使用 Windows 安装程序安装时,dateutil、pytz 和 six 总是会被安装在顶层,这可能会覆盖已经安装的这些库的副本。
TODO: 描述与 OS-X 安装程序的行为。
当使用包管理器(Debian、RedHat、MacPorts 等)安装时,这种行为实际上是正确的,matplotlib 包中没有特殊的补丁来处理我们以这种方式处理 dateutil、pytz 和 six 的事实。然而,我们应该注意,无论我们转向哪种方法,都应继续在该环境中有效。
在 matplotlib 树中维护这些包并确保它们是最新的,这是一个维护负担。由于这种负担,可能需要第三方纯 Python 库的高级新功能在纳入时面临更高的门槛。
期望的行为#
第三方依赖项通过利用 pip、distribute 和 PyPI 从其规范位置下载和安装。
dateutil、pytz 和 pyparsing 应该被设置为可选依赖项——尽管如果它们没有安装,某些功能将会失效。这将允许用户决定是否要安装某个特定功能。
实现#
对于从源代码安装,假设用户已经安装了所有C级别的编译器和依赖项,这可以通过使用 distribute 并按照 这里 的说明来相当容易地完成。对matplotlib库代码的唯一预期更改是从顶级命名空间导入 pyparsing 而不是从matplotlib内部导入。请注意,distribute 还将允许我们移除对 six 的直接依赖,因为严格来说,它只是 dateutil 的直接依赖。
对于二进制安装,有多种选择(这里从最好/最难到最差/最易排序):
distutils wininst 安装程序允许运行安装后脚本。可能可以让这个脚本运行 pip 来安装其他依赖项。(参见 这个帖子 了解之前有人走过这条路的情况)。
在我们的安装程序中继续包含 dateutil、pytz、six 和 pyparsing,但使用安装后脚本来安装它们 仅当 它们尚未被找到时。
将所有这些包移动到一个(新的)``matplotlib.extern`` 命名空间中,以便外部用户清楚这些是外部包。在核心 matplotlib 代码库中添加一些条件导入,以便首先尝试顶层的 dateutil,如果失败则使用
matplotlib.extern.dateutil。
2 和 3 是不理想的,因为它们仍然需要在我们树中维护这些包的副本——而且由于它们使用较少,这一点更加严重——仅在二进制安装程序中使用。这三种方法都没有解决 Numpy 的问题,它仍然需要使用安装程序手动安装。
TODO: 这与Mac OS-X安装程序有何关联?
向后兼容性#
目前,可以在没有第三方依赖且没有互联网连接的机器上从源代码安装 matplotlib。在此更改之后,首次安装 matplotlib 将需要互联网连接(以及一个可用的 PyPI)。(后续的 matplotlib 更新或开发工作将无需访问网络)。
替代方案#
分发二进制蛋并不像是一个可行的解决方案。这首先需要安装 easy_install,而 Windows 用户通常更喜欢众所周知的 .exe 或 .msi 安装程序,这些安装程序开箱即用。