MEP11:第三方依赖项#

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

状态#

已完成 -- 需要合并

分支和 Pull requests#

#1157:使用自动依赖项解析

#1290:解绑 pyparsing

#1261:将 six 更新到 1.2

摘要#

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

最初这样做的时候,setuptools_,easy_install_ 和 PyPI 还不够成熟,无法依赖.但是,目前,我们应该能够安全地利用这些工具的"现代"版本 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 checkout 或 pip:

  • setup.py 尝试 import numpy .如果失败,则安装失败.

  • 对于 dateutil,pytz_ 和 six 中的每一个, setup.py 尝试导入它们(从顶级命名空间).如果失败,matplotlib 会将其本地库副本安装到顶级命名空间中.

  • pyparsing 始终安装在 matplotlib 命名空间内.

当与 pip 一起使用时,此行为最令人惊讶,因为不执行任何 pip 依赖项解析,即使它可能适用于所有这些包.

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

使用 Windows 安装程序安装时,dateutil_,pytz_ 和 six 始终安装在顶层,可能会覆盖这些库的已安装副本.

待办:描述使用 OS-X 安装程序的行为.

当使用包管理器(Debian,RedHat,MacPorts 等)安装时,此行为实际上做了正确的事情,并且 matplotlib 包中没有特殊的补丁来处理我们以这种方式处理 dateutil,pytz_ 和 six 的事实.但是,应该注意,无论我们采取何种方法,都应继续在这种情况下工作.

在 matplotlib 树中维护这些软件包并确保它们是最新的,这是一个维护负担.由于这个负担,可能需要第三方纯 Python 库的高级新功能具有更高的包含门槛.

期望的行为#

第三方依赖项通过利用 pip,distribute_ 和 PyPI 从其规范位置下载和安装.

dateutil,pytz_ 和 pyparsing 应该成为可选的依赖项 -- 尽管如果未安装它们,某些功能显然会失败.这将允许用户决定他们是否想费心安装特定功能.

实施#

对于从源代码安装,并假设用户拥有所有的 C 级编译器和依赖项,这可以很容易地使用 distribute 完成,并遵循 here 中的说明.matplotlib 库代码中唯一预期的更改是从顶级命名空间而不是从 matplotlib 内部导入 pyparsing.请注意,distribute_ 也将允许我们删除对 six 的直接依赖,因为它严格来说只是 dateutil 的直接依赖.

对于二进制安装,有许多替代方法(这里按最佳/最难到最差/最容易排序):

  1. distutils wininst 安装程序允许运行安装后脚本.可能会让这个脚本运行 pip 来安装其他依赖项.(参见 this thread 以了解之前涉足过的人).

  2. 继续在我们的安装程序中发布 dateutil,pytz_,six_ 和 pyparsing,但仅当无法找到它们时才使用安装后脚本安装它们.

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

2 和 3 是不可取的,因为它们仍然需要在我们的树中维护这些软件包的副本 -- 并且由于它们的使用频率较低(仅在二进制安装程序中),这会加剧这种情况.这 3 种方法都不能解决 Numpy 的问题,Numpy 仍然必须使用安装程序手动安装.

待办:这与 Mac OS-X 安装程序有什么关系?

向后兼容性#

目前,可以在没有第三方依赖项且没有互联网连接的机器上从源代码安装 matplotlib.在此更改之后,首次安装 matplotlib 将需要互联网连接(以及工作的 PyPI).(随后的 matplotlib 更新或开发工作将在不访问网络的情况下运行).

替代方案#

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