禁用鼻子运行设置()

时间:2014-05-20 00:21:33

标签: python python-sphinx nose doctest

nose包通常用于运行doctests以及专用测试文件中的测试。即使在doctest文件中,它也会尝试运行setupteardown灯具。

当用于doctesting的模块碰巧需要一个名为setup的函数用于其他目的时 - 例如,它可能是Sphinx extension - nosetests将调用setup并失败。

要清楚,这是一个例子:

def my_tricky_function(arg):
    """Do something testable

    >>> my_tricky_function(1)
    2
    """
    return arg + arg


def my_extension(app):
    ...


def setup(app):
    """Establish sphinx hooks"""
    app.connect('build-finished', my_extension)

运行nosestests会导致:

File ".../site-packages/nose/suite.py", line 291, in setUp
    self.setupContext(ancestor)
  File ".../site-packages/nose/suite.py", line 314, in setupContext
    try_run(context, names)
  File ".../site-packages/nose/util.py", line 468, in try_run
    return func(obj)
  File "sphinx_ext.py", line 14, in setup
    app.connect('build-finished', my_extension)
AttributeError: 'module' object has no attribute 'connect'

(注意:当setup接受参数时,nosetest会传递setup是名称的范围,在本例中是模块。)

请注意,以下内容(似乎)不适用:

  • setup添加属性__test__ = False(或使用this decorator)并不会阻止它被调用。
  • 没有等同于--ignore-files
  • 的命令行选项
  • 设置my_tricky_function.setup = None不会停止模块级设置(h / t @alecxe)

2 个答案:

答案 0 :(得分:1)

虽然joeln自己的答案很漂亮,但它确实污染了模块的顶级命名空间。

我会检查setup()的参数,以区分鼻子测试呼叫和普通呼叫。在您的情况下,如果app是一个模块(或没有connect属性),则只需返回并不执行任何操作。

def setup(app):
    """Establish sphinx hooks"""
    if hasattr(app, 'connect'):
        app.connect('build-finished', my_extension)

我有这个问题,自定义setuptools.setup(**kwargs)绊倒了鼻子。虽然nosetests在没有任何参数的情况下调用它,但setup()的正常用法总是会传递给某些关键字参数,这使我可以区分这两种情况。

答案 1 :(得分:0)

我发现了以下有点愚蠢的解决方案:添加另一个函数setup_module,它会隐藏setup。{/ p>

...

def setup(app):
    """Establish sphinx hooks"""
    app.connect('build-finished', my_extension)

def setup_module():
    pass