summaryrefslogtreecommitdiff
path: root/_pytest/_code/code.py
diff options
context:
space:
mode:
authorRonny Pfannschmidt <opensource@ronnypfannschmidt.de>2018-05-23 16:48:46 +0200
committerRonny Pfannschmidt <opensource@ronnypfannschmidt.de>2018-05-23 16:48:46 +0200
commit703e4b11ba76171eccd3f13e723c47b810ded7ef (patch)
tree1d573c62db1f5d876360a0793891eb4d6103f635 /_pytest/_code/code.py
parent3e1590bcfcce1a28619abc31425f407cb0459b75 (diff)
downloadpytest-703e4b11ba76171eccd3f13e723c47b810ded7ef.tar.gz
run black
Diffstat (limited to '_pytest/_code/code.py')
-rw-r--r--_pytest/_code/code.py182
1 files changed, 121 insertions, 61 deletions
diff --git a/_pytest/_code/code.py b/_pytest/_code/code.py
index 46abb15bb..41f232dc8 100644
--- a/_pytest/_code/code.py
+++ b/_pytest/_code/code.py
@@ -10,6 +10,7 @@ from weakref import ref
from _pytest.compat import _PY2, _PY3, PY35, safe_str
import py
+
builtin_repr = repr
if _PY3:
@@ -61,6 +62,7 @@ class Code(object):
""" return a _pytest._code.Source object for the full source file of the code
"""
from _pytest._code import source
+
full, _ = source.findsource(self.raw)
return full
@@ -69,6 +71,7 @@ class Code(object):
"""
# return source only for that part of code
import _pytest._code
+
return _pytest._code.Source(self.raw)
def getargs(self, var=False):
@@ -101,6 +104,7 @@ class Frame(object):
def statement(self):
""" statement this frame is at """
import _pytest._code
+
if self.code.fullsource is None:
return _pytest._code.Source("")
return self.code.fullsource.getstatement(self.lineno)
@@ -144,7 +148,7 @@ class Frame(object):
try:
retval.append((arg, self.f_locals[arg]))
except KeyError:
- pass # this can occur when using Psyco
+ pass # this can occur when using Psyco
return retval
@@ -166,6 +170,7 @@ class TracebackEntry(object):
@property
def frame(self):
import _pytest._code
+
return _pytest._code.Frame(self._rawentry.tb_frame)
@property
@@ -188,6 +193,7 @@ class TracebackEntry(object):
def getlocals(self):
return self.frame.f_locals
+
locals = property(getlocals, None, None, "locals of underlaying frame")
def getfirstlinesource(self):
@@ -199,6 +205,7 @@ class TracebackEntry(object):
# we use the passed in astcache to not reparse asttrees
# within exception info printing
from _pytest._code.source import getstatementrange_ast
+
source = self.frame.code.fullsource
if source is None:
return None
@@ -209,8 +216,9 @@ class TracebackEntry(object):
astnode = astcache.get(key, None)
start = self.getfirstlinesource()
try:
- astnode, _, end = getstatementrange_ast(self.lineno, source,
- astnode=astnode)
+ astnode, _, end = getstatementrange_ast(
+ self.lineno, source, astnode=astnode
+ )
except SyntaxError:
end = self.lineno + 1
else:
@@ -230,10 +238,10 @@ class TracebackEntry(object):
mostly for internal use
"""
try:
- tbh = self.frame.f_locals['__tracebackhide__']
+ tbh = self.frame.f_locals["__tracebackhide__"]
except KeyError:
try:
- tbh = self.frame.f_globals['__tracebackhide__']
+ tbh = self.frame.f_globals["__tracebackhide__"]
except KeyError:
return False
@@ -246,7 +254,7 @@ class TracebackEntry(object):
try:
fn = str(self.path)
except py.error.Error:
- fn = '???'
+ fn = "???"
name = self.frame.code.name
try:
line = str(self.statement).lstrip()
@@ -258,6 +266,7 @@ class TracebackEntry(object):
def name(self):
return self.frame.code.raw.co_name
+
name = property(name, None, None, "co_name of underlaying code")
@@ -270,11 +279,13 @@ class Traceback(list):
def __init__(self, tb, excinfo=None):
""" initialize from given python traceback object and ExceptionInfo """
self._excinfo = excinfo
- if hasattr(tb, 'tb_next'):
+ if hasattr(tb, "tb_next"):
+
def f(cur):
while cur is not None:
yield self.Entry(cur, excinfo=excinfo)
cur = cur.tb_next
+
list.__init__(self, f(tb))
else:
list.__init__(self, tb)
@@ -292,11 +303,16 @@ class Traceback(list):
for x in self:
code = x.frame.code
codepath = code.path
- if ((path is None or codepath == path) and
- (excludepath is None or not hasattr(codepath, 'relto') or
- not codepath.relto(excludepath)) and
- (lineno is None or x.lineno == lineno) and
- (firstlineno is None or x.frame.code.firstlineno == firstlineno)):
+ if (
+ (path is None or codepath == path)
+ and (
+ excludepath is None
+ or not hasattr(codepath, "relto")
+ or not codepath.relto(excludepath)
+ )
+ and (lineno is None or x.lineno == lineno)
+ and (firstlineno is None or x.frame.code.firstlineno == firstlineno)
+ ):
return Traceback(x._rawentry, self._excinfo)
return self
@@ -345,35 +361,41 @@ class Traceback(list):
f = entry.frame
loc = f.f_locals
for otherloc in values:
- if f.is_true(f.eval(co_equal,
- __recursioncache_locals_1=loc,
- __recursioncache_locals_2=otherloc)):
+ if f.is_true(
+ f.eval(
+ co_equal,
+ __recursioncache_locals_1=loc,
+ __recursioncache_locals_2=otherloc,
+ )
+ ):
return i
values.append(entry.frame.f_locals)
return None
-co_equal = compile('__recursioncache_locals_1 == __recursioncache_locals_2',
- '?', 'eval')
+co_equal = compile(
+ "__recursioncache_locals_1 == __recursioncache_locals_2", "?", "eval"
+)
class ExceptionInfo(object):
""" wraps sys.exc_info() objects and offers
help for navigating the traceback.
"""
- _striptext = ''
- _assert_start_repr = "AssertionError(u\'assert " if _PY2 else "AssertionError(\'assert "
+ _striptext = ""
+ _assert_start_repr = "AssertionError(u'assert " if _PY2 else "AssertionError('assert "
def __init__(self, tup=None, exprinfo=None):
import _pytest._code
+
if tup is None:
tup = sys.exc_info()
if exprinfo is None and isinstance(tup[1], AssertionError):
- exprinfo = getattr(tup[1], 'msg', None)
+ exprinfo = getattr(tup[1], "msg", None)
if exprinfo is None:
exprinfo = py.io.saferepr(tup[1])
if exprinfo and exprinfo.startswith(self._assert_start_repr):
- self._striptext = 'AssertionError: '
+ self._striptext = "AssertionError: "
self._excinfo = tup
#: the exception class
self.type = tup[0]
@@ -398,7 +420,7 @@ class ExceptionInfo(object):
removed from the beginning)
"""
lines = format_exception_only(self.type, self.value)
- text = ''.join(lines)
+ text = "".join(lines)
text = text.rstrip()
if tryshort:
if text.startswith(self._striptext):
@@ -415,8 +437,14 @@ class ExceptionInfo(object):
path, lineno = entry.frame.code.raw.co_filename, entry.lineno
return ReprFileLocation(path, lineno + 1, exconly)
- def getrepr(self, showlocals=False, style="long",
- abspath=False, tbfilter=True, funcargs=False):
+ def getrepr(
+ self,
+ showlocals=False,
+ style="long",
+ abspath=False,
+ tbfilter=True,
+ funcargs=False,
+ ):
""" return str()able representation of this exception info.
showlocals: show locals per traceback entry
style: long|short|no|native traceback style
@@ -424,16 +452,23 @@ class ExceptionInfo(object):
in case of style==native, tbfilter and showlocals is ignored.
"""
- if style == 'native':
- return ReprExceptionInfo(ReprTracebackNative(
- traceback.format_exception(
- self.type,
- self.value,
- self.traceback[0]._rawentry,
- )), self._getreprcrash())
-
- fmt = FormattedExcinfo(showlocals=showlocals, style=style,
- abspath=abspath, tbfilter=tbfilter, funcargs=funcargs)
+ if style == "native":
+ return ReprExceptionInfo(
+ ReprTracebackNative(
+ traceback.format_exception(
+ self.type, self.value, self.traceback[0]._rawentry
+ )
+ ),
+ self._getreprcrash(),
+ )
+
+ fmt = FormattedExcinfo(
+ showlocals=showlocals,
+ style=style,
+ abspath=abspath,
+ tbfilter=tbfilter,
+ funcargs=funcargs,
+ )
return fmt.repr_excinfo(self)
def __str__(self):
@@ -455,8 +490,7 @@ class ExceptionInfo(object):
"""
__tracebackhide__ = True
if not re.search(regexp, str(self.value)):
- assert 0, "Pattern '{!s}' not found in '{!s}'".format(
- regexp, self.value)
+ assert 0, "Pattern '{!s}' not found in '{!s}'".format(regexp, self.value)
return True
@@ -508,6 +542,7 @@ class FormattedExcinfo(object):
def get_source(self, source, line_index=-1, excinfo=None, short=False):
""" return formatted and marked up source lines. """
import _pytest._code
+
lines = []
if source is None or line_index >= len(source.lines):
source = _pytest._code.Source("???")
@@ -532,7 +567,7 @@ class FormattedExcinfo(object):
lines = []
indent = " " * indent
# get the real exception information out
- exlines = excinfo.exconly(tryshort=True).split('\n')
+ exlines = excinfo.exconly(tryshort=True).split("\n")
failindent = self.fail_marker + indent[1:]
for line in exlines:
lines.append(failindent + line)
@@ -547,7 +582,7 @@ class FormattedExcinfo(object):
keys.sort()
for name in keys:
value = locals[name]
- if name == '__builtins__':
+ if name == "__builtins__":
lines.append("__builtins__ = <builtins>")
else:
# This formatting could all be handled by the
@@ -565,6 +600,7 @@ class FormattedExcinfo(object):
def repr_traceback_entry(self, entry, excinfo=None):
import _pytest._code
+
source = self._getentrysource(entry)
if source is None:
source = _pytest._code.Source("???")
@@ -641,11 +677,16 @@ class FormattedExcinfo(object):
except Exception as e:
max_frames = 10
extraline = (
- '!!! Recursion error detected, but an error occurred locating the origin of recursion.\n'
- ' The following exception happened when comparing locals in the stack frame:\n'
- ' {exc_type}: {exc_msg}\n'
- ' Displaying first and last {max_frames} stack frames out of {total}.'
- ).format(exc_type=type(e).__name__, exc_msg=safe_str(e), max_frames=max_frames, total=len(traceback))
+ "!!! Recursion error detected, but an error occurred locating the origin of recursion.\n"
+ " The following exception happened when comparing locals in the stack frame:\n"
+ " {exc_type}: {exc_msg}\n"
+ " Displaying first and last {max_frames} stack frames out of {total}."
+ ).format(
+ exc_type=type(e).__name__,
+ exc_msg=safe_str(e),
+ max_frames=max_frames,
+ total=len(traceback),
+ )
traceback = traceback[:max_frames] + traceback[-max_frames:]
else:
if recursionindex is not None:
@@ -673,18 +714,24 @@ class FormattedExcinfo(object):
else:
# fallback to native repr if the exception doesn't have a traceback:
# ExceptionInfo objects require a full traceback to work
- reprtraceback = ReprTracebackNative(traceback.format_exception(type(e), e, None))
+ reprtraceback = ReprTracebackNative(
+ traceback.format_exception(type(e), e, None)
+ )
reprcrash = None
repr_chain += [(reprtraceback, reprcrash, descr)]
if e.__cause__ is not None:
e = e.__cause__
- excinfo = ExceptionInfo((type(e), e, e.__traceback__)) if e.__traceback__ else None
- descr = 'The above exception was the direct cause of the following exception:'
+ excinfo = ExceptionInfo(
+ (type(e), e, e.__traceback__)
+ ) if e.__traceback__ else None
+ descr = "The above exception was the direct cause of the following exception:"
elif (e.__context__ is not None and not e.__suppress_context__):
e = e.__context__
- excinfo = ExceptionInfo((type(e), e, e.__traceback__)) if e.__traceback__ else None
- descr = 'During handling of the above exception, another exception occurred:'
+ excinfo = ExceptionInfo(
+ (type(e), e, e.__traceback__)
+ ) if e.__traceback__ else None
+ descr = "During handling of the above exception, another exception occurred:"
else:
e = None
repr_chain.reverse()
@@ -692,10 +739,11 @@ class FormattedExcinfo(object):
class TerminalRepr(object):
+
def __str__(self):
s = self.__unicode__()
if _PY2:
- s = s.encode('utf-8')
+ s = s.encode("utf-8")
return s
def __unicode__(self):
@@ -711,6 +759,7 @@ class TerminalRepr(object):
class ExceptionRepr(TerminalRepr):
+
def __init__(self):
self.sections = []
@@ -724,6 +773,7 @@ class ExceptionRepr(TerminalRepr):
class ExceptionChainRepr(ExceptionRepr):
+
def __init__(self, chain):
super(ExceptionChainRepr, self).__init__()
self.chain = chain
@@ -742,6 +792,7 @@ class ExceptionChainRepr(ExceptionRepr):
class ReprExceptionInfo(ExceptionRepr):
+
def __init__(self, reprtraceback, reprcrash):
super(ReprExceptionInfo, self).__init__()
self.reprtraceback = reprtraceback
@@ -768,8 +819,11 @@ class ReprTraceback(TerminalRepr):
entry.toterminal(tw)
if i < len(self.reprentries) - 1:
next_entry = self.reprentries[i + 1]
- if entry.style == "long" or \
- entry.style == "short" and next_entry.style == "long":
+ if (
+ entry.style == "long"
+ or entry.style == "short"
+ and next_entry.style == "long"
+ ):
tw.sep(self.entrysep)
if self.extraline:
@@ -777,6 +831,7 @@ class ReprTraceback(TerminalRepr):
class ReprTracebackNative(ReprTraceback):
+
def __init__(self, tblines):
self.style = "native"
self.reprentries = [ReprEntryNative(tblines)]
@@ -826,12 +881,11 @@ class ReprEntry(TerminalRepr):
self.reprfileloc.toterminal(tw)
def __str__(self):
- return "%s\n%s\n%s" % ("\n".join(self.lines),
- self.reprlocals,
- self.reprfileloc)
+ return "%s\n%s\n%s" % ("\n".join(self.lines), self.reprlocals, self.reprfileloc)
class ReprFileLocation(TerminalRepr):
+
def __init__(self, path, lineno, message):
self.path = str(path)
self.lineno = lineno
@@ -849,6 +903,7 @@ class ReprFileLocation(TerminalRepr):
class ReprLocals(TerminalRepr):
+
def __init__(self, lines):
self.lines = lines
@@ -858,6 +913,7 @@ class ReprLocals(TerminalRepr):
class ReprFuncArgs(TerminalRepr):
+
def __init__(self, args):
self.args = args
@@ -885,22 +941,26 @@ def getrawcode(obj, trycall=True):
try:
return obj.__code__
except AttributeError:
- obj = getattr(obj, 'im_func', obj)
- obj = getattr(obj, 'func_code', obj)
- obj = getattr(obj, 'f_code', obj)
- obj = getattr(obj, '__code__', obj)
- if trycall and not hasattr(obj, 'co_firstlineno'):
- if hasattr(obj, '__call__') and not inspect.isclass(obj):
+ obj = getattr(obj, "im_func", obj)
+ obj = getattr(obj, "func_code", obj)
+ obj = getattr(obj, "f_code", obj)
+ obj = getattr(obj, "__code__", obj)
+ if trycall and not hasattr(obj, "co_firstlineno"):
+ if hasattr(obj, "__call__") and not inspect.isclass(obj):
x = getrawcode(obj.__call__, trycall=False)
- if hasattr(x, 'co_firstlineno'):
+ if hasattr(x, "co_firstlineno"):
return x
return obj
if PY35: # RecursionError introduced in 3.5
+
def is_recursion_error(excinfo):
return excinfo.errisinstance(RecursionError) # noqa
+
+
else:
+
def is_recursion_error(excinfo):
if not excinfo.errisinstance(RuntimeError):
return False