show a short and nice traceback for funcarg lookup errors
--HG-- branch : trunk
This commit is contained in:
parent
7bd60b5abb
commit
f95877a09b
|
@ -1,6 +1,7 @@
|
|||
Changes between 1.2.1 and 1.2.0
|
||||
=====================================
|
||||
|
||||
- display a short and concise traceback if a funcarg lookup fails
|
||||
- early-load "test*/conftest.py" files, i.e. conftest.py files in
|
||||
directories starting with 'test'. allows to conveniently keep and access
|
||||
test-related options without having to put a conftest.py into the package root dir.
|
||||
|
|
|
@ -64,7 +64,7 @@ class FuncargRequest:
|
|||
_argprefix = "pytest_funcarg__"
|
||||
_argname = None
|
||||
|
||||
class Error(LookupError):
|
||||
class LookupError(LookupError):
|
||||
""" error on performing funcarg request. """
|
||||
|
||||
def __init__(self, pyfuncitem):
|
||||
|
@ -170,7 +170,6 @@ class FuncargRequest:
|
|||
if name not in available:
|
||||
available.append(name)
|
||||
fspath, lineno, msg = self._pyfuncitem.reportinfo()
|
||||
line = "%s:%s" %(fspath, lineno)
|
||||
msg = "funcargument %r not found for: %s" %(argname, line)
|
||||
msg = "LookupError: no factory found for function argument %r" % (argname,)
|
||||
msg += "\n available funcargs: %s" %(", ".join(available),)
|
||||
raise self.Error(msg)
|
||||
raise self.LookupError(msg)
|
||||
|
|
|
@ -5,6 +5,7 @@ import py
|
|||
import inspect
|
||||
from py._test.collect import configproperty, warnoldcollect
|
||||
from py._test import funcargs
|
||||
from py._code.code import TerminalRepr
|
||||
|
||||
class PyobjMixin(object):
|
||||
def obj():
|
||||
|
@ -252,12 +253,38 @@ class FunctionMixin(PyobjMixin):
|
|||
traceback = ntraceback.filter()
|
||||
return traceback
|
||||
|
||||
def _repr_failure_py(self, excinfo):
|
||||
if excinfo.errisinstance(funcargs.FuncargRequest.LookupError):
|
||||
fspath, lineno, msg = self.reportinfo()
|
||||
lines, _ = inspect.getsourcelines(self.obj)
|
||||
for i, line in enumerate(lines):
|
||||
if line.strip().startswith('def'):
|
||||
return FuncargLookupErrorRepr(fspath, lineno,
|
||||
lines[:i+1], str(excinfo.value))
|
||||
return super(FunctionMixin, self)._repr_failure_py(excinfo)
|
||||
|
||||
def repr_failure(self, excinfo, outerr=None):
|
||||
assert outerr is None, "XXX outerr usage is deprecated"
|
||||
return self._repr_failure_py(excinfo)
|
||||
|
||||
shortfailurerepr = "F"
|
||||
|
||||
class FuncargLookupErrorRepr(TerminalRepr):
|
||||
def __init__(self, filename, firstlineno, deflines, errorstring):
|
||||
self.deflines = deflines
|
||||
self.errorstring = errorstring
|
||||
self.filename = filename
|
||||
self.firstlineno = firstlineno
|
||||
|
||||
def toterminal(self, tw):
|
||||
tw.line()
|
||||
for line in self.deflines:
|
||||
tw.line(" " + line.strip())
|
||||
for line in self.errorstring.split("\n"):
|
||||
tw.line(" " + line.strip(), red=True)
|
||||
tw.line()
|
||||
tw.line("%s:%d" % (self.filename, self.firstlineno+1))
|
||||
|
||||
class Generator(FunctionMixin, PyCollectorMixin, py.test.collect.Collector):
|
||||
def collect(self):
|
||||
# test generators are seen as collectors but they also
|
||||
|
|
|
@ -30,7 +30,8 @@ class TestFillFuncArgs:
|
|||
return 42
|
||||
""")
|
||||
item = testdir.getitem("def test_func(some): pass")
|
||||
exc = py.test.raises(LookupError, "funcargs.fillfuncargs(item)")
|
||||
exc = py.test.raises(funcargs.FuncargRequest.LookupError,
|
||||
"funcargs.fillfuncargs(item)")
|
||||
s = str(exc.value)
|
||||
assert s.find("xyzsomething") != -1
|
||||
|
||||
|
@ -560,3 +561,18 @@ def test_funcarg_non_pycollectobj(testdir): # rough jstests usage
|
|||
funcargs.fillfuncargs(clscol)
|
||||
assert clscol.funcargs['arg1'] == 42
|
||||
|
||||
|
||||
def test_funcarg_lookup_error(testdir):
|
||||
p = testdir.makepyfile("""
|
||||
def test_lookup_error(unknown):
|
||||
pass
|
||||
""")
|
||||
result = testdir.runpytest()
|
||||
result.stdout.fnmatch_lines([
|
||||
"*ERROR at setup of test_lookup_error*",
|
||||
"*def test_lookup_error(unknown):*",
|
||||
"*LookupError: no factory found*unknown*",
|
||||
"*available funcargs*",
|
||||
"*1 error*",
|
||||
])
|
||||
assert "INTERNAL" not in result.stdout.str()
|
||||
|
|
Loading…
Reference in New Issue