【问题标题】:Mocking Python iterables for use with Sphinx模拟 Python 迭代以与 Sphinx 一起使用
【发布时间】:2013-12-18 18:54:04
【问题描述】:

我正在使用 Sphinx 来记录一个依赖于 wxPython 的项目,使用 autodocs 扩展名,以便它会自动从我们的文档字符串生成页面。 autodocs 扩展会自动在您import 的每个模块上运行,这对我们的包来说很好,但是当我们import 像 wxPython 这样的大型外部库时就会出现问题。因此,我没有让它从 wxPython 生成所有内容,而是使用unittest.mocklibrary module(以前是外部包Mock)。最基本的设置对 wxPython 的大多数部分都适用,但我遇到了一种我看不到简单方法的情况(可能是因为直到本周我对 mock 相对不熟悉)。

目前,我的conf.py 文件末尾有以下内容:

MOCK_MODULES = ['wx.lib.newevent']  # I've skipped irrelevant entries...

for module_name in MOCK_MODULES:
    sys.modules[module_name] = mock.Mock()

对于除wx.lib.newevent 之外的所有wxPython 模块,这都能完美运行。但是,这里我使用newevent.NewCommandEvent() 函数[1] 为特定场景创建事件。在这种情况下,我在NewCommandEvent() 调用中收到警告,并附注TypeError: 'Mock' object is not iterable

虽然我可以看到如何使用 patching 来处理此问题以构建单元测试(我将在下个月进行此操作!),但我很难理解如何以简单的方式集成它我的 Sphinx 配置中的级别。

编辑:我刚刚也尝试过使用MagicMock();这仍然会在同一点产生错误,尽管它现在会产生ValueError: need more than 0 values to unpack。这似乎是朝着正确方向迈出的一步,但我仍然不确定如何处理这个问题,而不是为这个模块明确设置它。不过,也许这是最好的解决方案?


脚注

  1. 是的,这是一个函数,尽管命名约定使它看起来像一个类; wxPython 遵循整个 wxWidgets 工具包中使用的 C++ 命名约定。

【问题讨论】:

  • 在我与 Sphinx 的所有接触中,它从来没有自动记录我没有明确告诉它的东西,所以您能否详细说明一下 Sphinx 的哪个部分导致了这种行为?
  • 好。这是导致问题的autodoc 模块:它自动包含import 语句引用的所有模块。我将把它添加到问题中。

标签: python mocking python-sphinx python-mock


【解决方案1】:

从错误来看,它看起来实际上是在执行newevent.NewCommandEvent(),所以我假设您的代码中的某处有这样的顶级行:

import wx.lib.newevent
...
event, binder = wx.lib.newevent.NewCommandEvent()

当 autodoc 导入模块时,它会尝试运行这行代码,但由于 NewCommandEvent 实际上是一个 Mock 对象,Python 无法将其输出绑定到 (event, binder) 元组。有两种可能的解决方案。第一个是将您的代码更改为在导入时不执行,可能通过将其包装在if __name__ == '__main__' 中。我会推荐这个解决方案,因为在导入时创建这样的对象通常会产生问题的副作用。

第二种解决方案是告诉Mock 对象返回适当的值:

wx.lib.newevent.NewCommandEvent = mock.Mock(return_value=(Mock(), Mock()))

但是,如果您在代码中使用返回的值执行任何操作,您可能会遇到同样的问题。

【讨论】:

  • 这是有道理的。稍后我会试一试,并确认它为我解决了这个问题——假设它解决了,我会接受答案。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多