diff options
author | Ronny Pfannschmidt <opensource@ronnypfannschmidt.de> | 2018-05-23 16:48:46 +0200 |
---|---|---|
committer | Ronny Pfannschmidt <opensource@ronnypfannschmidt.de> | 2018-05-23 16:48:46 +0200 |
commit | 703e4b11ba76171eccd3f13e723c47b810ded7ef (patch) | |
tree | 1d573c62db1f5d876360a0793891eb4d6103f635 /_pytest/_code/code.py | |
parent | 3e1590bcfcce1a28619abc31425f407cb0459b75 (diff) | |
download | pytest-703e4b11ba76171eccd3f13e723c47b810ded7ef.tar.gz |
run black
Diffstat (limited to '_pytest/_code/code.py')
-rw-r--r-- | _pytest/_code/code.py | 182 |
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 |