Skip to main content
 首页 » 编程设计

python之如何获取 nose.plugins.base.Plugin.addFailure 中的异常

2025年05月04日7qlqwjy

我正在尝试为 nose 编写一个插件,它可以在 GUI 中为某些类型的异常生成和显示额外的调试信息。我想在插件中执行此操作的原因是因为我希望仅在给出 --enable-gui 选项时启动 GUI,并且插件是添加命令行的唯一方法 Nose 跑道的选项。

根据文档,我需要覆盖 addFailure(step, err) 和 addError(step, err),他们说 err 是 sys.exc_info() 元组:

http://nose.readthedocs.org/en/latest/plugins/interface.html

不幸的是,我得到了完全不同的东西:异常被替换为代表它的字符串值。这是我的代码:

def addError(self, test, err): 
    info = ', '.join((type(x).__name__) for x in err) 
    open('/tmp/xxxxx', 'a').write(info + '\n') 
 
def addFailure(self, test, err): 
    info = ', '.join((type(x).__name__) for x in err) 
    open('/tmp/xxxxx', 'a').write(info + '\n') 

这是输出:

type, str, traceback 
type, str, traceback 

因此,我得到的不是 exc_type, exc_value, exc_tb,而是 exc_type, str(exc_value), exc_tb。

这是对我的覆盖方法的调用堆栈:

Traceback (most recent call last): 
  File "runtests.py", line 6, in <module> 
    nose.main(module=tests, addplugins=tests.plugins.get_all_plugins()) 
  File "/usr/lib/python2.7/dist-packages/nose/core.py", line 118, in __init__ 
    **extra_args) 
  File "/usr/lib/python2.7/unittest/main.py", line 95, in __init__ 
    self.runTests() 
  File "/usr/lib/python2.7/dist-packages/nose/core.py", line 197, in runTests 
    result = self.testRunner.run(self.test) 
  File "/usr/lib/python2.7/dist-packages/nose/core.py", line 61, in run 
    test(result) 
  File "/usr/lib/python2.7/dist-packages/nose/suite.py", line 176, in __call__ 
    return self.run(*arg, **kw) 
  File "/usr/lib/python2.7/dist-packages/nose/suite.py", line 223, in run 
    test(orig) 
  File "/usr/lib/python2.7/dist-packages/nose/suite.py", line 176, in __call__ 
    return self.run(*arg, **kw) 
  File "/usr/lib/python2.7/dist-packages/nose/suite.py", line 223, in run 
    test(orig) 
  File "/usr/lib/python2.7/dist-packages/nose/suite.py", line 176, in __call__ 
    return self.run(*arg, **kw) 
  File "/usr/lib/python2.7/dist-packages/nose/suite.py", line 223, in run 
    test(orig) 
  File "/usr/lib/python2.7/dist-packages/nose/case.py", line 45, in __call__ 
    return self.run(*arg, **kwarg) 
  File "/usr/lib/python2.7/dist-packages/nose/case.py", line 138, in run 
    result.addError(self, err) 
  File "/usr/lib/python2.7/dist-packages/nose/proxy.py", line 134, in addError 
    plugins.addError(self.test, err) 
  File "/usr/lib/python2.7/dist-packages/nose/plugins/manager.py", line 94, in __call__ 
    return self.call(*arg, **kw) 
  File "/usr/lib/python2.7/dist-packages/nose/plugins/manager.py", line 162, in simple 
    result = meth(*arg, **kw) 
  File "<snip>/plugins.py", line 31, in addError 
    open('/tmp/xxxxx', 'a').write(info + '\n') 

我无法从 sys.exc_info() 中提取异常,因为它已经被另一个替换(特别是 UnicodeEncodeError 在 __str__ 所引发的异常)。

有什么方法可以从某个地方提取 exc_value,比如回溯?

一个潜在的解决方法:我知道我可以让我的插件成为一个全局变量,而不是在其中处理异常,我可以直接将信息发送到插件本身。不幸的是,这不是一个非常干净的解决方案,所以我想避免它。

为什么我需要一个 GUI:我得到的错误是由扭曲创建的彩色 HTML 回溯,无论我是打印 HTML 还是使用 html2text 表示,它在控制台中都是不可读的。

请您参考如下方法:

err 元组实际上是:(异常类型、实际异常、回溯)。您应该能够从异常或回溯中访问所需的信息。

请注意,在您的代码中,您将所有内容写入一个字符串:

info = ', '.join((type(x).__name__) for x in err) 

这意味着它确实会被转换为一个字符串,如果我理解正确的话,这就是您所提示的...