Commits

Alexander Hesse  committed e56516e

moved py to pypy._py

  • Participants
  • Parent commits f929623
  • Branches prepare-split

Comments (0)

Files changed (68)

File py/__init__.py

-"""
-py.test and pylib: rapid testing and development utils
-
-this module uses apipkg.py for lazy-loading sub modules
-and classes.  The initpkg-dictionary  below specifies
-name->value mappings where value can be another namespace
-dictionary or an import path.
-
-(c) Holger Krekel and others, 2004-2010
-"""
-__version__ = '1.4.7'
-
-from py import _apipkg
-
-# so that py.error.* instances are picklable
-import sys
-sys.modules['py.error'] = _apipkg.AliasModule("py.error", "py._error", 'error')
-
-_apipkg.initpkg(__name__, attr={'_apipkg': _apipkg}, exportdefs={
-    # access to all standard lib modules
-    'std': '._std:std',
-    # access to all posix errno's as classes
-    'error': '._error:error',
-
-    '_pydir' : '.__metainfo:pydir',
-    'version': 'py:__version__', # backward compatibility
-
-    # pytest-2.0 has a flat namespace, we use alias modules
-    # to keep old references compatible
-    'test' : 'pytest',
-    'test.collect' : 'pytest',
-    'test.cmdline' : 'pytest',
-
-    # hook into the top-level standard library
-    'process' : {
-        '__doc__'        : '._process:__doc__',
-        'cmdexec'        : '._process.cmdexec:cmdexec',
-        'kill'           : '._process.killproc:kill',
-        'ForkedFunc'     : '._process.forkedfunc:ForkedFunc',
-    },
-
-    'apipkg' : {
-        'initpkg'   : '._apipkg:initpkg',
-        'ApiModule' : '._apipkg:ApiModule',
-    },
-
-    'iniconfig' : {
-        'IniConfig'      : '._iniconfig:IniConfig',
-        'ParseError'     : '._iniconfig:ParseError',
-    },
-
-    'path' : {
-        '__doc__'        : '._path:__doc__',
-        'svnwc'          : '._path.svnwc:SvnWCCommandPath',
-        'svnurl'         : '._path.svnurl:SvnCommandPath',
-        'local'          : '._path.local:LocalPath',
-        'SvnAuth'        : '._path.svnwc:SvnAuth',
-    },
-
-    # python inspection/code-generation API
-    'code' : {
-        '__doc__'           : '._code:__doc__',
-        'compile'           : '._code.source:compile_',
-        'Source'            : '._code.source:Source',
-        'Code'              : '._code.code:Code',
-        'Frame'             : '._code.code:Frame',
-        'ExceptionInfo'     : '._code.code:ExceptionInfo',
-        'Traceback'         : '._code.code:Traceback',
-        'getfslineno'       : '._code.source:getfslineno',
-        'getrawcode'        : '._code.code:getrawcode',
-        'patch_builtins'    : '._code.code:patch_builtins',
-        'unpatch_builtins'  : '._code.code:unpatch_builtins',
-        '_AssertionError'   : '._code.assertion:AssertionError',
-        '_reinterpret_old'  : '._code.assertion:reinterpret_old',
-        '_reinterpret'      : '._code.assertion:reinterpret',
-        '_reprcompare'      : '._code.assertion:_reprcompare',
-        '_format_explanation' : '._code.assertion:_format_explanation',
-    },
-
-    # backports and additions of builtins
-    'builtin' : {
-        '__doc__'        : '._builtin:__doc__',
-        'enumerate'      : '._builtin:enumerate',
-        'reversed'       : '._builtin:reversed',
-        'sorted'         : '._builtin:sorted',
-        'any'            : '._builtin:any',
-        'all'            : '._builtin:all',
-        'set'            : '._builtin:set',
-        'frozenset'      : '._builtin:frozenset',
-        'BaseException'  : '._builtin:BaseException',
-        'GeneratorExit'  : '._builtin:GeneratorExit',
-        '_sysex'         : '._builtin:_sysex',
-        'print_'         : '._builtin:print_',
-        '_reraise'       : '._builtin:_reraise',
-        '_tryimport'     : '._builtin:_tryimport',
-        'exec_'          : '._builtin:exec_',
-        '_basestring'    : '._builtin:_basestring',
-        '_totext'        : '._builtin:_totext',
-        '_isbytes'       : '._builtin:_isbytes',
-        '_istext'        : '._builtin:_istext',
-        '_getimself'     : '._builtin:_getimself',
-        '_getfuncdict'   : '._builtin:_getfuncdict',
-        '_getcode'       : '._builtin:_getcode',
-        'builtins'       : '._builtin:builtins',
-        'execfile'       : '._builtin:execfile',
-        'callable'       : '._builtin:callable',
-    },
-
-    # input-output helping
-    'io' : {
-        '__doc__'             : '._io:__doc__',
-        'dupfile'             : '._io.capture:dupfile',
-        'TextIO'              : '._io.capture:TextIO',
-        'BytesIO'             : '._io.capture:BytesIO',
-        'FDCapture'           : '._io.capture:FDCapture',
-        'StdCapture'          : '._io.capture:StdCapture',
-        'StdCaptureFD'        : '._io.capture:StdCaptureFD',
-        'TerminalWriter'      : '._io.terminalwriter:TerminalWriter',
-        'ansi_print'          : '._io.terminalwriter:ansi_print',
-        'get_terminal_width'  : '._io.terminalwriter:get_terminal_width',
-        'saferepr'            : '._io.saferepr:saferepr',
-    },
-
-    # small and mean xml/html generation
-    'xml' : {
-        '__doc__'            : '._xmlgen:__doc__',
-        'html'               : '._xmlgen:html',
-        'Tag'                : '._xmlgen:Tag',
-        'raw'                : '._xmlgen:raw',
-        'Namespace'          : '._xmlgen:Namespace',
-        'escape'             : '._xmlgen:escape',
-    },
-
-    'log' : {
-        # logging API ('producers' and 'consumers' connected via keywords)
-        '__doc__'            : '._log:__doc__',
-        '_apiwarn'           : '._log.warning:_apiwarn',
-        'Producer'           : '._log.log:Producer',
-        'setconsumer'        : '._log.log:setconsumer',
-        '_setstate'          : '._log.log:setstate',
-        '_getstate'          : '._log.log:getstate',
-        'Path'               : '._log.log:Path',
-        'STDOUT'             : '._log.log:STDOUT',
-        'STDERR'             : '._log.log:STDERR',
-        'Syslog'             : '._log.log:Syslog',
-    },
-
-})

File py/__metainfo.py

-import py
-pydir = py.path.local(py.__file__).dirpath()

File py/_apipkg.py

-"""
-apipkg: control the exported namespace of a python package.
-
-see http://pypi.python.org/pypi/apipkg
-
-(c) holger krekel, 2009 - MIT license
-"""
-import os
-import sys
-from types import ModuleType
-
-__version__ = '1.2.dev6'
-
-def initpkg(pkgname, exportdefs, attr=dict()):
-    """ initialize given package from the export definitions. """
-    oldmod = sys.modules.get(pkgname)
-    d = {}
-    f = getattr(oldmod, '__file__', None)
-    if f:
-        f = os.path.abspath(f)
-    d['__file__'] = f
-    if hasattr(oldmod, '__version__'):
-        d['__version__'] = oldmod.__version__
-    if hasattr(oldmod, '__loader__'):
-        d['__loader__'] = oldmod.__loader__
-    if hasattr(oldmod, '__path__'):
-        d['__path__'] = [os.path.abspath(p) for p in oldmod.__path__]
-    if '__doc__' not in exportdefs and getattr(oldmod, '__doc__', None):
-        d['__doc__'] = oldmod.__doc__
-    d.update(attr)
-    if hasattr(oldmod, "__dict__"):
-        oldmod.__dict__.update(d)
-    mod = ApiModule(pkgname, exportdefs, implprefix=pkgname, attr=d)
-    sys.modules[pkgname]  = mod
-
-def importobj(modpath, attrname):
-    module = __import__(modpath, None, None, ['__doc__'])
-    if not attrname:
-        return module
-
-    retval = module
-    names = attrname.split(".")
-    for x in names:
-        retval = getattr(retval, x)
-    return retval
-
-class ApiModule(ModuleType):
-    def __docget(self):
-        try:
-            return self.__doc
-        except AttributeError:
-            if '__doc__' in self.__map__:
-                return self.__makeattr('__doc__')
-    def __docset(self, value):
-        self.__doc = value
-    __doc__ = property(__docget, __docset)
-
-    def __init__(self, name, importspec, implprefix=None, attr=None):
-        self.__name__ = name
-        self.__all__ = [x for x in importspec if x != '__onfirstaccess__']
-        self.__map__ = {}
-        self.__implprefix__ = implprefix or name
-        if attr:
-            for name, val in attr.items():
-                #print "setting", self.__name__, name, val
-                setattr(self, name, val)
-        for name, importspec in importspec.items():
-            if isinstance(importspec, dict):
-                subname = '%s.%s'%(self.__name__, name)
-                apimod = ApiModule(subname, importspec, implprefix)
-                sys.modules[subname] = apimod
-                setattr(self, name, apimod)
-            else:
-                parts = importspec.split(':')
-                modpath = parts.pop(0)
-                attrname = parts and parts[0] or ""
-                if modpath[0] == '.':
-                    modpath = implprefix + modpath
-
-                if not attrname:
-                    subname = '%s.%s'%(self.__name__, name)
-                    apimod = AliasModule(subname, modpath)
-                    sys.modules[subname] = apimod
-                    if '.' not in name:
-                        setattr(self, name, apimod)
-                else:
-                    self.__map__[name] = (modpath, attrname)
-
-    def __repr__(self):
-        l = []
-        if hasattr(self, '__version__'):
-            l.append("version=" + repr(self.__version__))
-        if hasattr(self, '__file__'):
-            l.append('from ' + repr(self.__file__))
-        if l:
-            return '<ApiModule %r %s>' % (self.__name__, " ".join(l))
-        return '<ApiModule %r>' % (self.__name__,)
-
-    def __makeattr(self, name):
-        """lazily compute value for name or raise AttributeError if unknown."""
-        #print "makeattr", self.__name__, name
-        target = None
-        if '__onfirstaccess__' in self.__map__:
-            target = self.__map__.pop('__onfirstaccess__')
-            importobj(*target)()
-        try:
-            modpath, attrname = self.__map__[name]
-        except KeyError:
-            if target is not None and name != '__onfirstaccess__':
-                # retry, onfirstaccess might have set attrs
-                return getattr(self, name)
-            raise AttributeError(name)
-        else:
-            result = importobj(modpath, attrname)
-            setattr(self, name, result)
-            try:
-                del self.__map__[name]
-            except KeyError:
-                pass # in a recursive-import situation a double-del can happen
-            return result
-
-    __getattr__ = __makeattr
-
-    def __dict__(self):
-        # force all the content of the module to be loaded when __dict__ is read
-        dictdescr = ModuleType.__dict__['__dict__']
-        dict = dictdescr.__get__(self)
-        if dict is not None:
-            hasattr(self, 'some')
-            for name in self.__all__:
-                try:
-                    self.__makeattr(name)
-                except AttributeError:
-                    pass
-        return dict
-    __dict__ = property(__dict__)
-
-
-def AliasModule(modname, modpath, attrname=None):
-    mod = []
-
-    def getmod():
-        if not mod:
-            x = importobj(modpath, None)
-            if attrname is not None:
-                x = getattr(x, attrname)
-            mod.append(x)
-        return mod[0]
-
-    class AliasModule(ModuleType):
-
-        def __repr__(self):
-            x = modpath
-            if attrname:
-                x += "." + attrname
-            return '<AliasModule %r for %r>' % (modname, x)
-
-        def __getattribute__(self, name):
-            return getattr(getmod(), name)
-
-        def __setattr__(self, name, value):
-            setattr(getmod(), name, value)
-
-        def __delattr__(self, name):
-            delattr(getmod(), name)
-
-    return AliasModule(modname)

File py/_builtin.py

-import sys
-
-try:
-    reversed = reversed
-except NameError:
-    def reversed(sequence):
-        """reversed(sequence) -> reverse iterator over values of the sequence
-
-        Return a reverse iterator
-        """
-        if hasattr(sequence, '__reversed__'):
-            return sequence.__reversed__()
-        if not hasattr(sequence, '__getitem__'):
-            raise TypeError("argument to reversed() must be a sequence")
-        return reversed_iterator(sequence)
-
-    class reversed_iterator(object):
-
-        def __init__(self, seq):
-            self.seq = seq
-            self.remaining = len(seq)
-
-        def __iter__(self):
-            return self
-
-        def next(self):
-            i = self.remaining
-            if i > 0:
-                i -= 1
-                item = self.seq[i]
-                self.remaining = i
-                return item
-            raise StopIteration
-
-        def __length_hint__(self):
-            return self.remaining
-
-try:
-    any = any
-except NameError:
-    def any(iterable):
-        for x in iterable:
-            if x:
-                return True
-        return False
-
-try:
-    all = all
-except NameError:
-    def all(iterable):
-        for x in iterable:
-            if not x:
-                return False
-        return True
-
-try:
-    sorted = sorted
-except NameError:
-    builtin_cmp = cmp # need to use cmp as keyword arg
-
-    def sorted(iterable, cmp=None, key=None, reverse=0):
-        use_cmp = None
-        if key is not None:
-            if cmp is None:
-                def use_cmp(x, y):
-                    return builtin_cmp(x[0], y[0])
-            else:
-                def use_cmp(x, y):
-                    return cmp(x[0], y[0])
-            l = [(key(element), element) for element in iterable]
-        else:
-            if cmp is not None:
-                use_cmp = cmp
-            l = list(iterable)
-        if use_cmp is not None:
-            l.sort(use_cmp)
-        else:
-            l.sort()
-        if reverse:
-            l.reverse()
-        if key is not None:
-            return [element for (_, element) in l]
-        return l
-
-try:
-    set, frozenset = set, frozenset
-except NameError:
-    from sets import set, frozenset
-
-# pass through
-enumerate = enumerate
-
-try:
-    BaseException = BaseException
-except NameError:
-    BaseException = Exception
-
-try:
-    GeneratorExit = GeneratorExit
-except NameError:
-    class GeneratorExit(Exception):
-        """ This exception is never raised, it is there to make it possible to
-        write code compatible with CPython 2.5 even in lower CPython
-        versions."""
-        pass
-    GeneratorExit.__module__ = 'exceptions'
-
-_sysex = (KeyboardInterrupt, SystemExit, MemoryError, GeneratorExit)
-
-if sys.version_info >= (3, 0):
-    exec ("print_ = print ; exec_=exec")
-    import builtins
-
-    # some backward compatibility helpers
-    _basestring = str
-    def _totext(obj, encoding=None, errors=None):
-        if isinstance(obj, bytes):
-            if errors is None:
-                obj = obj.decode(encoding)
-            else:
-                obj = obj.decode(encoding, errors)
-        elif not isinstance(obj, str):
-            obj = str(obj)
-        return obj
-
-    def _isbytes(x):
-        return isinstance(x, bytes)
-    def _istext(x):
-        return isinstance(x, str)
-
-    def _getimself(function):
-        return getattr(function, '__self__', None)
-
-    def _getfuncdict(function):
-        return getattr(function, "__dict__", None)
-
-    def _getcode(function):
-        return getattr(function, "__code__", None)
-
-    def execfile(fn, globs=None, locs=None):
-        if globs is None:
-            back = sys._getframe(1)
-            globs = back.f_globals
-            locs = back.f_locals
-            del back
-        elif locs is None:
-            locs = globs
-        fp = open(fn, "r")
-        try:
-            source = fp.read()
-        finally:
-            fp.close()
-        co = compile(source, fn, "exec", dont_inherit=True)
-        exec_(co, globs, locs)
-
-    def callable(obj):
-        return hasattr(obj, "__call__")
-
-else:
-    import __builtin__ as builtins
-    _totext = unicode
-    _basestring = basestring
-    execfile = execfile
-    callable = callable
-    def _isbytes(x):
-        return isinstance(x, str)
-    def _istext(x):
-        return isinstance(x, unicode)
-
-    def _getimself(function):
-        return getattr(function, 'im_self', None)
-
-    def _getfuncdict(function):
-        return getattr(function, "__dict__", None)
-
-    def _getcode(function):
-        try:
-            return getattr(function, "__code__")
-        except AttributeError:
-            return getattr(function, "func_code", None)
-
-    def print_(*args, **kwargs):
-        """ minimal backport of py3k print statement. """
-        sep = ' '
-        if 'sep' in kwargs:
-            sep = kwargs.pop('sep')
-        end = '\n'
-        if 'end' in kwargs:
-            end = kwargs.pop('end')
-        file = 'file' in kwargs and kwargs.pop('file') or sys.stdout
-        if kwargs:
-            args = ", ".join([str(x) for x in kwargs])
-            raise TypeError("invalid keyword arguments: %s" % args)
-        at_start = True
-        for x in args:
-            if not at_start:
-                file.write(sep)
-            file.write(str(x))
-            at_start = False
-        file.write(end)
-
-    def exec_(obj, globals=None, locals=None):
-        """ minimal backport of py3k exec statement. """
-        __tracebackhide__ = True
-        if globals is None:
-            frame = sys._getframe(1)
-            globals = frame.f_globals
-            if locals is None:
-                locals = frame.f_locals
-        elif locals is None:
-            locals = globals
-        exec2(obj, globals, locals)
-
-if sys.version_info >= (3,0):
-    def _reraise(cls, val, tb):
-        __tracebackhide__ = True
-        assert hasattr(val, '__traceback__')
-        raise val
-else:
-    exec ("""
-def _reraise(cls, val, tb):
-    __tracebackhide__ = True
-    raise cls, val, tb
-def exec2(obj, globals, locals):
-    __tracebackhide__ = True
-    exec obj in globals, locals
-""")
-
-def _tryimport(*names):
-    """ return the first successfully imported module. """
-    assert names
-    for name in names:
-        try:
-            return __import__(name, None, None, '__doc__')
-        except ImportError:
-            excinfo = sys.exc_info()
-    _reraise(*excinfo)

File py/_code/__init__.py

-""" python inspection/code generation API """

File py/_code/_assertionnew.py

-"""
-Find intermediate evalutation results in assert statements through builtin AST.
-This should replace _assertionold.py eventually.
-"""
-
-import sys
-import ast
-
-import py
-from py._code.assertion import _format_explanation, BuiltinAssertionError
-
-
-if sys.platform.startswith("java") and sys.version_info < (2, 5, 2):
-    # See http://bugs.jython.org/issue1497
-    _exprs = ("BoolOp", "BinOp", "UnaryOp", "Lambda", "IfExp", "Dict",
-              "ListComp", "GeneratorExp", "Yield", "Compare", "Call",
-              "Repr", "Num", "Str", "Attribute", "Subscript", "Name",
-              "List", "Tuple")
-    _stmts = ("FunctionDef", "ClassDef", "Return", "Delete", "Assign",
-              "AugAssign", "Print", "For", "While", "If", "With", "Raise",
-              "TryExcept", "TryFinally", "Assert", "Import", "ImportFrom",
-              "Exec", "Global", "Expr", "Pass", "Break", "Continue")
-    _expr_nodes = set(getattr(ast, name) for name in _exprs)
-    _stmt_nodes = set(getattr(ast, name) for name in _stmts)
-    def _is_ast_expr(node):
-        return node.__class__ in _expr_nodes
-    def _is_ast_stmt(node):
-        return node.__class__ in _stmt_nodes
-else:
-    def _is_ast_expr(node):
-        return isinstance(node, ast.expr)
-    def _is_ast_stmt(node):
-        return isinstance(node, ast.stmt)
-
-
-class Failure(Exception):
-    """Error found while interpreting AST."""
-
-    def __init__(self, explanation=""):
-        self.cause = sys.exc_info()
-        self.explanation = explanation
-
-
-def interpret(source, frame, should_fail=False):
-    mod = ast.parse(source)
-    visitor = DebugInterpreter(frame)
-    try:
-        visitor.visit(mod)
-    except Failure:
-        failure = sys.exc_info()[1]
-        return getfailure(failure)
-    if should_fail:
-        return ("(assertion failed, but when it was re-run for "
-                "printing intermediate values, it did not fail.  Suggestions: "
-                "compute assert expression before the assert or use --no-assert)")
-
-def run(offending_line, frame=None):
-    if frame is None:
-        frame = py.code.Frame(sys._getframe(1))
-    return interpret(offending_line, frame)
-
-def getfailure(failure):
-    explanation = _format_explanation(failure.explanation)
-    value = failure.cause[1]
-    if str(value):
-        lines = explanation.splitlines()
-        if not lines:
-            lines.append("")
-        lines[0] += " << %s" % (value,)
-        explanation = "\n".join(lines)
-    text = "%s: %s" % (failure.cause[0].__name__, explanation)
-    if text.startswith("AssertionError: assert "):
-        text = text[16:]
-    return text
-
-
-operator_map = {
-    ast.BitOr : "|",
-    ast.BitXor : "^",
-    ast.BitAnd : "&",
-    ast.LShift : "<<",
-    ast.RShift : ">>",
-    ast.Add : "+",
-    ast.Sub : "-",
-    ast.Mult : "*",
-    ast.Div : "/",
-    ast.FloorDiv : "//",
-    ast.Mod : "%",
-    ast.Eq : "==",
-    ast.NotEq : "!=",
-    ast.Lt : "<",
-    ast.LtE : "<=",
-    ast.Gt : ">",
-    ast.GtE : ">=",
-    ast.Pow : "**",
-    ast.Is : "is",
-    ast.IsNot : "is not",
-    ast.In : "in",
-    ast.NotIn : "not in"
-}
-
-unary_map = {
-    ast.Not : "not %s",
-    ast.Invert : "~%s",
-    ast.USub : "-%s",
-    ast.UAdd : "+%s"
-}
-
-
-class DebugInterpreter(ast.NodeVisitor):
-    """Interpret AST nodes to gleam useful debugging information. """
-
-    def __init__(self, frame):
-        self.frame = frame
-
-    def generic_visit(self, node):
-        # Fallback when we don't have a special implementation.
-        if _is_ast_expr(node):
-            mod = ast.Expression(node)
-            co = self._compile(mod)
-            try:
-                result = self.frame.eval(co)
-            except Exception:
-                raise Failure()
-            explanation = self.frame.repr(result)
-            return explanation, result
-        elif _is_ast_stmt(node):
-            mod = ast.Module([node])
-            co = self._compile(mod, "exec")
-            try:
-                self.frame.exec_(co)
-            except Exception:
-                raise Failure()
-            return None, None
-        else:
-            raise AssertionError("can't handle %s" %(node,))
-
-    def _compile(self, source, mode="eval"):
-        return compile(source, "<assertion interpretation>", mode)
-
-    def visit_Expr(self, expr):
-        return self.visit(expr.value)
-
-    def visit_Module(self, mod):
-        for stmt in mod.body:
-            self.visit(stmt)
-
-    def visit_Name(self, name):
-        explanation, result = self.generic_visit(name)
-        # See if the name is local.
-        source = "%r in locals() is not globals()" % (name.id,)
-        co = self._compile(source)
-        try:
-            local = self.frame.eval(co)
-        except Exception:
-            # have to assume it isn't
-            local = False
-        if not local:
-            return name.id, result
-        return explanation, result
-
-    def visit_Compare(self, comp):
-        left = comp.left
-        left_explanation, left_result = self.visit(left)
-        for op, next_op in zip(comp.ops, comp.comparators):
-            next_explanation, next_result = self.visit(next_op)
-            op_symbol = operator_map[op.__class__]
-            explanation = "%s %s %s" % (left_explanation, op_symbol,
-                                        next_explanation)
-            source = "__exprinfo_left %s __exprinfo_right" % (op_symbol,)
-            co = self._compile(source)
-            try:
-                result = self.frame.eval(co, __exprinfo_left=left_result,
-                                         __exprinfo_right=next_result)
-            except Exception:
-                raise Failure(explanation)
-            try:
-                if not result:
-                    break
-            except KeyboardInterrupt:
-                raise
-            except:
-                break
-            left_explanation, left_result = next_explanation, next_result
-
-        rcomp = py.code._reprcompare
-        if rcomp:
-            res = rcomp(op_symbol, left_result, next_result)
-            if res:
-                explanation = res
-        return explanation, result
-
-    def visit_BoolOp(self, boolop):
-        is_or = isinstance(boolop.op, ast.Or)
-        explanations = []
-        for operand in boolop.values:
-            explanation, result = self.visit(operand)
-            explanations.append(explanation)
-            if result == is_or:
-                break
-        name = is_or and " or " or " and "
-        explanation = "(" + name.join(explanations) + ")"
-        return explanation, result
-
-    def visit_UnaryOp(self, unary):
-        pattern = unary_map[unary.op.__class__]
-        operand_explanation, operand_result = self.visit(unary.operand)
-        explanation = pattern % (operand_explanation,)
-        co = self._compile(pattern % ("__exprinfo_expr",))
-        try:
-            result = self.frame.eval(co, __exprinfo_expr=operand_result)
-        except Exception:
-            raise Failure(explanation)
-        return explanation, result
-
-    def visit_BinOp(self, binop):
-        left_explanation, left_result = self.visit(binop.left)
-        right_explanation, right_result = self.visit(binop.right)
-        symbol = operator_map[binop.op.__class__]
-        explanation = "(%s %s %s)" % (left_explanation, symbol,
-                                      right_explanation)
-        source = "__exprinfo_left %s __exprinfo_right" % (symbol,)
-        co = self._compile(source)
-        try:
-            result = self.frame.eval(co, __exprinfo_left=left_result,
-                                     __exprinfo_right=right_result)
-        except Exception:
-            raise Failure(explanation)
-        return explanation, result
-
-    def visit_Call(self, call):
-        func_explanation, func = self.visit(call.func)
-        arg_explanations = []
-        ns = {"__exprinfo_func" : func}
-        arguments = []
-        for arg in call.args:
-            arg_explanation, arg_result = self.visit(arg)
-            arg_name = "__exprinfo_%s" % (len(ns),)
-            ns[arg_name] = arg_result
-            arguments.append(arg_name)
-            arg_explanations.append(arg_explanation)
-        for keyword in call.keywords:
-            arg_explanation, arg_result = self.visit(keyword.value)
-            arg_name = "__exprinfo_%s" % (len(ns),)
-            ns[arg_name] = arg_result
-            keyword_source = "%s=%%s" % (keyword.arg)
-            arguments.append(keyword_source % (arg_name,))
-            arg_explanations.append(keyword_source % (arg_explanation,))
-        if call.starargs:
-            arg_explanation, arg_result = self.visit(call.starargs)
-            arg_name = "__exprinfo_star"
-            ns[arg_name] = arg_result
-            arguments.append("*%s" % (arg_name,))
-            arg_explanations.append("*%s" % (arg_explanation,))
-        if call.kwargs:
-            arg_explanation, arg_result = self.visit(call.kwargs)
-            arg_name = "__exprinfo_kwds"
-            ns[arg_name] = arg_result
-            arguments.append("**%s" % (arg_name,))
-            arg_explanations.append("**%s" % (arg_explanation,))
-        args_explained = ", ".join(arg_explanations)
-        explanation = "%s(%s)" % (func_explanation, args_explained)
-        args = ", ".join(arguments)
-        source = "__exprinfo_func(%s)" % (args,)
-        co = self._compile(source)
-        try:
-            result = self.frame.eval(co, **ns)
-        except Exception:
-            raise Failure(explanation)
-        pattern = "%s\n{%s = %s\n}"
-        rep = self.frame.repr(result)
-        explanation = pattern % (rep, rep, explanation)
-        return explanation, result
-
-    def _is_builtin_name(self, name):
-        pattern = "%r not in globals() and %r not in locals()"
-        source = pattern % (name.id, name.id)
-        co = self._compile(source)
-        try:
-            return self.frame.eval(co)
-        except Exception:
-            return False
-
-    def visit_Attribute(self, attr):
-        if not isinstance(attr.ctx, ast.Load):
-            return self.generic_visit(attr)
-        source_explanation, source_result = self.visit(attr.value)
-        explanation = "%s.%s" % (source_explanation, attr.attr)
-        source = "__exprinfo_expr.%s" % (attr.attr,)
-        co = self._compile(source)
-        try:
-            result = self.frame.eval(co, __exprinfo_expr=source_result)
-        except Exception:
-            raise Failure(explanation)
-        explanation = "%s\n{%s = %s.%s\n}" % (self.frame.repr(result),
-                                              self.frame.repr(result),
-                                              source_explanation, attr.attr)
-        # Check if the attr is from an instance.
-        source = "%r in getattr(__exprinfo_expr, '__dict__', {})"
-        source = source % (attr.attr,)
-        co = self._compile(source)
-        try:
-            from_instance = self.frame.eval(co, __exprinfo_expr=source_result)
-        except Exception:
-            from_instance = True
-        if from_instance:
-            rep = self.frame.repr(result)
-            pattern = "%s\n{%s = %s\n}"
-            explanation = pattern % (rep, rep, explanation)
-        return explanation, result
-
-    def visit_Assert(self, assrt):
-        test_explanation, test_result = self.visit(assrt.test)
-        if test_explanation.startswith("False\n{False =") and \
-                test_explanation.endswith("\n"):
-            test_explanation = test_explanation[15:-2]
-        explanation = "assert %s" % (test_explanation,)
-        if not test_result:
-            try:
-                raise BuiltinAssertionError
-            except Exception:
-                raise Failure(explanation)
-        return explanation, test_result
-
-    def visit_Assign(self, assign):
-        value_explanation, value_result = self.visit(assign.value)
-        explanation = "... = %s" % (value_explanation,)
-        name = ast.Name("__exprinfo_expr", ast.Load(),
-                        lineno=assign.value.lineno,
-                        col_offset=assign.value.col_offset)
-        new_assign = ast.Assign(assign.targets, name, lineno=assign.lineno,
-                                col_offset=assign.col_offset)
-        mod = ast.Module([new_assign])
-        co = self._compile(mod, "exec")
-        try:
-            self.frame.exec_(co, __exprinfo_expr=value_result)
-        except Exception:
-            raise Failure(explanation)
-        return explanation, value_result

File py/_code/_assertionold.py

-import py
-import sys, inspect
-from compiler import parse, ast, pycodegen
-from py._code.assertion import BuiltinAssertionError, _format_explanation
-
-passthroughex = py.builtin._sysex
-
-class Failure:
-    def __init__(self, node):
-        self.exc, self.value, self.tb = sys.exc_info()
-        self.node = node
-
-class View(object):
-    """View base class.
-
-    If C is a subclass of View, then C(x) creates a proxy object around
-    the object x.  The actual class of the proxy is not C in general,
-    but a *subclass* of C determined by the rules below.  To avoid confusion
-    we call view class the class of the proxy (a subclass of C, so of View)
-    and object class the class of x.
-
-    Attributes and methods not found in the proxy are automatically read on x.
-    Other operations like setting attributes are performed on the proxy, as
-    determined by its view class.  The object x is available from the proxy
-    as its __obj__ attribute.
-
-    The view class selection is determined by the __view__ tuples and the
-    optional __viewkey__ method.  By default, the selected view class is the
-    most specific subclass of C whose __view__ mentions the class of x.
-    If no such subclass is found, the search proceeds with the parent
-    object classes.  For example, C(True) will first look for a subclass
-    of C with __view__ = (..., bool, ...) and only if it doesn't find any
-    look for one with __view__ = (..., int, ...), and then ..., object,...
-    If everything fails the class C itself is considered to be the default.
-
-    Alternatively, the view class selection can be driven by another aspect
-    of the object x, instead of the class of x, by overriding __viewkey__.
-    See last example at the end of this module.
-    """
-
-    _viewcache = {}
-    __view__ = ()
-
-    def __new__(rootclass, obj, *args, **kwds):
-        self = object.__new__(rootclass)
-        self.__obj__ = obj
-        self.__rootclass__ = rootclass
-        key = self.__viewkey__()
-        try:
-            self.__class__ = self._viewcache[key]
-        except KeyError:
-            self.__class__ = self._selectsubclass(key)
-        return self
-
-    def __getattr__(self, attr):
-        # attributes not found in the normal hierarchy rooted on View
-        # are looked up in the object's real class
-        return getattr(self.__obj__, attr)
-
-    def __viewkey__(self):
-        return self.__obj__.__class__
-
-    def __matchkey__(self, key, subclasses):
-        if inspect.isclass(key):
-            keys = inspect.getmro(key)
-        else:
-            keys = [key]
-        for key in keys:
-            result = [C for C in subclasses if key in C.__view__]
-            if result:
-                return result
-        return []
-
-    def _selectsubclass(self, key):
-        subclasses = list(enumsubclasses(self.__rootclass__))
-        for C in subclasses:
-            if not isinstance(C.__view__, tuple):
-                C.__view__ = (C.__view__,)
-        choices = self.__matchkey__(key, subclasses)
-        if not choices:
-            return self.__rootclass__
-        elif len(choices) == 1:
-            return choices[0]
-        else:
-            # combine the multiple choices
-            return type('?', tuple(choices), {})
-
-    def __repr__(self):
-        return '%s(%r)' % (self.__rootclass__.__name__, self.__obj__)
-
-
-def enumsubclasses(cls):
-    for subcls in cls.__subclasses__():
-        for subsubclass in enumsubclasses(subcls):
-            yield subsubclass
-    yield cls
-
-
-class Interpretable(View):
-    """A parse tree node with a few extra methods."""
-    explanation = None
-
-    def is_builtin(self, frame):
-        return False
-
-    def eval(self, frame):
-        # fall-back for unknown expression nodes
-        try:
-            expr = ast.Expression(self.__obj__)
-            expr.filename = '<eval>'
-            self.__obj__.filename = '<eval>'
-            co = pycodegen.ExpressionCodeGenerator(expr).getCode()
-            result = frame.eval(co)
-        except passthroughex:
-            raise
-        except:
-            raise Failure(self)
-        self.result = result
-        self.explanation = self.explanation or frame.repr(self.result)
-
-    def run(self, frame):
-        # fall-back for unknown statement nodes
-        try:
-            expr = ast.Module(None, ast.Stmt([self.__obj__]))
-            expr.filename = '<run>'
-            co = pycodegen.ModuleCodeGenerator(expr).getCode()
-            frame.exec_(co)
-        except passthroughex:
-            raise
-        except:
-            raise Failure(self)
-
-    def nice_explanation(self):
-        return _format_explanation(self.explanation)
-
-
-class Name(Interpretable):
-    __view__ = ast.Name
-
-    def is_local(self, frame):
-        source = '%r in locals() is not globals()' % self.name
-        try:
-            return frame.is_true(frame.eval(source))
-        except passthroughex:
-            raise
-        except:
-            return False
-
-    def is_global(self, frame):
-        source = '%r in globals()' % self.name
-        try:
-            return frame.is_true(frame.eval(source))
-        except passthroughex:
-            raise
-        except:
-            return False
-
-    def is_builtin(self, frame):
-        source = '%r not in locals() and %r not in globals()' % (
-            self.name, self.name)
-        try:
-            return frame.is_true(frame.eval(source))
-        except passthroughex:
-            raise
-        except:
-            return False
-
-    def eval(self, frame):
-        super(Name, self).eval(frame)
-        if not self.is_local(frame):
-            self.explanation = self.name
-
-class Compare(Interpretable):
-    __view__ = ast.Compare
-
-    def eval(self, frame):
-        expr = Interpretable(self.expr)
-        expr.eval(frame)
-        for operation, expr2 in self.ops:
-            if hasattr(self, 'result'):
-                # shortcutting in chained expressions
-                if not frame.is_true(self.result):
-                    break
-            expr2 = Interpretable(expr2)
-            expr2.eval(frame)
-            self.explanation = "%s %s %s" % (
-                expr.explanation, operation, expr2.explanation)
-            source = "__exprinfo_left %s __exprinfo_right" % operation
-            try:
-                self.result = frame.eval(source,
-                                         __exprinfo_left=expr.result,
-                                         __exprinfo_right=expr2.result)
-            except passthroughex:
-                raise
-            except:
-                raise Failure(self)
-            expr = expr2
-
-class And(Interpretable):
-    __view__ = ast.And
-
-    def eval(self, frame):
-        explanations = []
-        for expr in self.nodes:
-            expr = Interpretable(expr)
-            expr.eval(frame)
-            explanations.append(expr.explanation)
-            self.result = expr.result
-            if not frame.is_true(expr.result):
-                break
-        self.explanation = '(' + ' and '.join(explanations) + ')'
-
-class Or(Interpretable):
-    __view__ = ast.Or
-
-    def eval(self, frame):
-        explanations = []
-        for expr in self.nodes:
-            expr = Interpretable(expr)
-            expr.eval(frame)
-            explanations.append(expr.explanation)
-            self.result = expr.result
-            if frame.is_true(expr.result):
-                break
-        self.explanation = '(' + ' or '.join(explanations) + ')'
-
-
-# == Unary operations ==
-keepalive = []
-for astclass, astpattern in {
-    ast.Not    : 'not __exprinfo_expr',
-    ast.Invert : '(~__exprinfo_expr)',
-    }.items():
-
-    class UnaryArith(Interpretable):
-        __view__ = astclass
-
-        def eval(self, frame, astpattern=astpattern):
-            expr = Interpretable(self.expr)
-            expr.eval(frame)
-            self.explanation = astpattern.replace('__exprinfo_expr',
-                                                  expr.explanation)
-            try:
-                self.result = frame.eval(astpattern,
-                                         __exprinfo_expr=expr.result)
-            except passthroughex:
-                raise
-            except:
-                raise Failure(self)
-
-    keepalive.append(UnaryArith)
-
-# == Binary operations ==
-for astclass, astpattern in {
-    ast.Add    : '(__exprinfo_left + __exprinfo_right)',
-    ast.Sub    : '(__exprinfo_left - __exprinfo_right)',
-    ast.Mul    : '(__exprinfo_left * __exprinfo_right)',
-    ast.Div    : '(__exprinfo_left / __exprinfo_right)',
-    ast.Mod    : '(__exprinfo_left % __exprinfo_right)',
-    ast.Power  : '(__exprinfo_left ** __exprinfo_right)',
-    }.items():
-
-    class BinaryArith(Interpretable):
-        __view__ = astclass
-
-        def eval(self, frame, astpattern=astpattern):
-            left = Interpretable(self.left)
-            left.eval(frame)
-            right = Interpretable(self.right)
-            right.eval(frame)
-            self.explanation = (astpattern
-                                .replace('__exprinfo_left',  left .explanation)
-                                .replace('__exprinfo_right', right.explanation))
-            try:
-                self.result = frame.eval(astpattern,
-                                         __exprinfo_left=left.result,
-                                         __exprinfo_right=right.result)
-            except passthroughex:
-                raise
-            except:
-                raise Failure(self)
-
-    keepalive.append(BinaryArith)
-
-
-class CallFunc(Interpretable):
-    __view__ = ast.CallFunc
-
-    def is_bool(self, frame):
-        source = 'isinstance(__exprinfo_value, bool)'
-        try:
-            return frame.is_true(frame.eval(source,
-                                            __exprinfo_value=self.result))
-        except passthroughex:
-            raise
-        except:
-            return False
-
-    def eval(self, frame):
-        node = Interpretable(self.node)
-        node.eval(frame)
-        explanations = []
-        vars = {'__exprinfo_fn': node.result}
-        source = '__exprinfo_fn('
-        for a in self.args:
-            if isinstance(a, ast.Keyword):
-                keyword = a.name
-                a = a.expr
-            else:
-                keyword = None
-            a = Interpretable(a)
-            a.eval(frame)
-            argname = '__exprinfo_%d' % len(vars)
-            vars[argname] = a.result
-            if keyword is None:
-                source += argname + ','
-                explanations.append(a.explanation)
-            else:
-                source += '%s=%s,' % (keyword, argname)
-                explanations.append('%s=%s' % (keyword, a.explanation))
-        if self.star_args:
-            star_args = Interpretable(self.star_args)
-            star_args.eval(frame)
-            argname = '__exprinfo_star'
-            vars[argname] = star_args.result
-            source += '*' + argname + ','
-            explanations.append('*' + star_args.explanation)
-        if self.dstar_args:
-            dstar_args = Interpretable(self.dstar_args)
-            dstar_args.eval(frame)
-            argname = '__exprinfo_kwds'
-            vars[argname] = dstar_args.result
-            source += '**' + argname + ','
-            explanations.append('**' + dstar_args.explanation)
-        self.explanation = "%s(%s)" % (
-            node.explanation, ', '.join(explanations))
-        if source.endswith(','):
-            source = source[:-1]
-        source += ')'
-        try:
-            self.result = frame.eval(source, **vars)
-        except passthroughex:
-            raise
-        except:
-            raise Failure(self)
-        if not node.is_builtin(frame) or not self.is_bool(frame):
-            r = frame.repr(self.result)
-            self.explanation = '%s\n{%s = %s\n}' % (r, r, self.explanation)
-
-class Getattr(Interpretable):
-    __view__ = ast.Getattr
-
-    def eval(self, frame):
-        expr = Interpretable(self.expr)
-        expr.eval(frame)
-        source = '__exprinfo_expr.%s' % self.attrname
-        try:
-            self.result = frame.eval(source, __exprinfo_expr=expr.result)
-        except passthroughex:
-            raise
-        except:
-            raise Failure(self)
-        self.explanation = '%s.%s' % (expr.explanation, self.attrname)
-        # if the attribute comes from the instance, its value is interesting
-        source = ('hasattr(__exprinfo_expr, "__dict__") and '
-                  '%r in __exprinfo_expr.__dict__' % self.attrname)
-        try:
-            from_instance = frame.is_true(
-                frame.eval(source, __exprinfo_expr=expr.result))
-        except passthroughex:
-            raise
-        except:
-            from_instance = True
-        if from_instance:
-            r = frame.repr(self.result)
-            self.explanation = '%s\n{%s = %s\n}' % (r, r, self.explanation)
-
-# == Re-interpretation of full statements ==
-
-class Assert(Interpretable):
-    __view__ = ast.Assert
-
-    def run(self, frame):
-        test = Interpretable(self.test)
-        test.eval(frame)
-        # simplify 'assert False where False = ...'
-        if (test.explanation.startswith('False\n{False = ') and
-            test.explanation.endswith('\n}')):
-            test.explanation = test.explanation[15:-2]
-        # print the result as  'assert <explanation>'
-        self.result = test.result
-        self.explanation = 'assert ' + test.explanation
-        if not frame.is_true(test.result):
-            try:
-                raise BuiltinAssertionError
-            except passthroughex:
-                raise
-            except:
-                raise Failure(self)
-
-class Assign(Interpretable):
-    __view__ = ast.Assign
-
-    def run(self, frame):
-        expr = Interpretable(self.expr)
-        expr.eval(frame)
-        self.result = expr.result
-        self.explanation = '... = ' + expr.explanation
-        # fall-back-run the rest of the assignment
-        ass = ast.Assign(self.nodes, ast.Name('__exprinfo_expr'))
-        mod = ast.Module(None, ast.Stmt([ass]))
-        mod.filename = '<run>'
-        co = pycodegen.ModuleCodeGenerator(mod).getCode()
-        try:
-            frame.exec_(co, __exprinfo_expr=expr.result)
-        except passthroughex:
-            raise
-        except:
-            raise Failure(self)
-
-class Discard(Interpretable):
-    __view__ = ast.Discard
-
-    def run(self, frame):
-        expr = Interpretable(self.expr)
-        expr.eval(frame)
-        self.result = expr.result
-        self.explanation = expr.explanation
-
-class Stmt(Interpretable):
-    __view__ = ast.Stmt
-
-    def run(self, frame):
-        for stmt in self.nodes:
-            stmt = Interpretable(stmt)
-            stmt.run(frame)
-
-
-def report_failure(e):
-    explanation = e.node.nice_explanation()
-    if explanation:
-        explanation = ", in: " + explanation
-    else:
-        explanation = ""
-    sys.stdout.write("%s: %s%s\n" % (e.exc.__name__, e.value, explanation))
-
-def check(s, frame=None):
-    if frame is None:
-        frame = sys._getframe(1)
-        frame = py.code.Frame(frame)
-    expr = parse(s, 'eval')
-    assert isinstance(expr, ast.Expression)
-    node = Interpretable(expr.node)
-    try:
-        node.eval(frame)
-    except passthroughex:
-        raise
-    except Failure:
-        e = sys.exc_info()[1]
-        report_failure(e)
-    else:
-        if not frame.is_true(node.result):
-            sys.stderr.write("assertion failed: %s\n" % node.nice_explanation())
-
-
-###########################################################
-# API / Entry points
-# #########################################################
-
-def interpret(source, frame, should_fail=False):
-    module = Interpretable(parse(source, 'exec').node)
-    #print "got module", module
-    if isinstance(frame, py.std.types.FrameType):
-        frame = py.code.Frame(frame)
-    try:
-        module.run(frame)
-    except Failure:
-        e = sys.exc_info()[1]
-        return getfailure(e)
-    except passthroughex:
-        raise
-    except:
-        import traceback
-        traceback.print_exc()
-    if should_fail:
-        return ("(assertion failed, but when it was re-run for "
-                "printing intermediate values, it did not fail.  Suggestions: "
-                "compute assert expression before the assert or use --nomagic)")
-    else:
-        return None
-
-def getmsg(excinfo):
-    if isinstance(excinfo, tuple):
-        excinfo = py.code.ExceptionInfo(excinfo)
-    #frame, line = gettbline(tb)
-    #frame = py.code.Frame(frame)
-    #return interpret(line, frame)
-
-    tb = excinfo.traceback[-1]
-    source = str(tb.statement).strip()
-    x = interpret(source, tb.frame, should_fail=True)
-    if not isinstance(x, str):
-        raise TypeError("interpret returned non-string %r" % (x,))
-    return x
-
-def getfailure(e):
-    explanation = e.node.nice_explanation()
-    if str(e.value):
-        lines = explanation.split('\n')
-        lines[0] += "  << %s" % (e.value,)
-        explanation = '\n'.join(lines)
-    text = "%s: %s" % (e.exc.__name__, explanation)
-    if text.startswith('AssertionError: assert '):
-        text = text[16:]
-    return text
-
-def run(s, frame=None):
-    if frame is None:
-        frame = sys._getframe(1)
-        frame = py.code.Frame(frame)
-    module = Interpretable(parse(s, 'exec').node)
-    try:
-        module.run(frame)
-    except Failure:
-        e = sys.exc_info()[1]
-        report_failure(e)
-
-
-if __name__ == '__main__':
-    # example:
-    def f():
-        return 5
-    def g():
-        return 3
-    def h(x):
-        return 'never'
-    check("f() * g() == 5")
-    check("not f()")
-    check("not (f() and g() or 0)")
-    check("f() == g()")
-    i = 4
-    check("i == f()")
-    check("len(f()) == 0")
-    check("isinstance(2+3+4, float)")
-
-    run("x = i")
-    check("x == 5")
-
-    run("assert not f(), 'oops'")
-    run("a, b, c = 1, 2")
-    run("a, b, c = f()")
-
-    check("max([f(),g()]) == 4")
-    check("'hello'[g()] == 'h'")
-    run("'guk%d' % h(f())")

File py/_code/assertion.py

-import sys
-import py
-
-BuiltinAssertionError = py.builtin.builtins.AssertionError
-
-_reprcompare = None # if set, will be called by assert reinterp for comparison ops
-
-def _format_explanation(explanation):
-    """This formats an explanation
-
-    Normally all embedded newlines are escaped, however there are
-    three exceptions: \n{, \n} and \n~.  The first two are intended
-    cover nested explanations, see function and attribute explanations
-    for examples (.visit_Call(), visit_Attribute()).  The last one is
-    for when one explanation needs to span multiple lines, e.g. when
-    displaying diffs.
-    """
-    raw_lines = (explanation or '').split('\n')
-    # escape newlines not followed by {, } and ~
-    lines = [raw_lines[0]]
-    for l in raw_lines[1:]:
-        if l.startswith('{') or l.startswith('}') or l.startswith('~'):
-            lines.append(l)
-        else:
-            lines[-1] += '\\n' + l
-
-    result = lines[:1]
-    stack = [0]
-    stackcnt = [0]
-    for line in lines[1:]:
-        if line.startswith('{'):
-            if stackcnt[-1]:
-                s = 'and   '
-            else:
-                s = 'where '
-            stack.append(len(result))
-            stackcnt[-1] += 1
-            stackcnt.append(0)
-            result.append(' +' + '  '*(len(stack)-1) + s + line[1:])
-        elif line.startswith('}'):
-            assert line.startswith('}')
-            stack.pop()
-            stackcnt.pop()
-            result[stack[-1]] += line[1:]
-        else:
-            assert line.startswith('~')
-            result.append('  '*len(stack) + line[1:])
-    assert len(stack) == 1
-    return '\n'.join(result)
-
-
-class AssertionError(BuiltinAssertionError):
-    def __init__(self, *args):
-        BuiltinAssertionError.__init__(self, *args)
-        if args:
-            try:
-                self.msg = str(args[0])
-            except py.builtin._sysex:
-                raise
-            except:
-                self.msg = "<[broken __repr__] %s at %0xd>" %(
-                    args[0].__class__, id(args[0]))
-        else:
-            f = py.code.Frame(sys._getframe(1))
-            try:
-                source = f.code.fullsource
-                if source is not None:
-                    try:
-                        source = source.getstatement(f.lineno, assertion=True)
-                    except IndexError:
-                        source = None
-                    else:
-                        source = str(source.deindent()).strip()
-            except py.error.ENOENT:
-                source = None
-                # this can also occur during reinterpretation, when the
-                # co_filename is set to "<run>".
-            if source:
-                self.msg = reinterpret(source, f, should_fail=True)
-            else:
-                self.msg = "<could not determine information>"
-            if not self.args:
-                self.args = (self.msg,)
-
-if sys.version_info > (3, 0):
-    AssertionError.__module__ = "builtins"
-    reinterpret_old = "old reinterpretation not available for py3"
-else:
-    from py._code._assertionold import interpret as reinterpret_old
-if sys.version_info >= (2, 6) or (sys.platform.startswith("java")):
-    from py._code._assertionnew import interpret as reinterpret
-else:
-    reinterpret = reinterpret_old
-

File py/_code/code.py

-import py
-import sys, os.path
-
-builtin_repr = repr
-
-reprlib = py.builtin._tryimport('repr', 'reprlib')
-
-class Code(object):
-    """ wrapper around Python code objects """
-    def __init__(self, rawcode):
-        rawcode = py.code.getrawcode(rawcode)
-        self.raw = rawcode
-        try:
-            self.filename = rawcode.co_filename
-            self.firstlineno = rawcode.co_firstlineno - 1
-            self.name = rawcode.co_name
-        except AttributeError:
-            raise TypeError("not a code object: %r" %(rawcode,))
-
-    def __eq__(self, other):
-        return self.raw == other.raw
-
-    def __ne__(self, other):
-        return not self == other
-
-    def path(self):
-        """ return a path object pointing to source code"""
-        p = py.path.local(self.raw.co_filename)
-        if not p.check():
-            # XXX maybe try harder like the weird logic
-            # in the standard lib [linecache.updatecache] does?
-            p = self.raw.co_filename
-        return p
-
-    path = property(path, None, None, "path of this code object")
-
-    def fullsource(self):
-        """ return a py.code.Source object for the full source file of the code
-        """
-        from py._code import source
-        full, _ = source.findsource(self.raw)
-        return full
-    fullsource = property(fullsource, None, None,
-                          "full source containing this code object")
-
-    def source(self):
-        """ return a py.code.Source object for the code object's source only
-        """
-        # return source only for that part of code
-        return py.code.Source(self.raw)
-
-    def getargs(self):
-        """ return a tuple with the argument names for the code object
-        """
-        # handfull shortcut for getting args
-        raw = self.raw
-        return raw.co_varnames[:raw.co_argcount]
-
-class Frame(object):
-    """Wrapper around a Python frame holding f_locals and f_globals
-    in which expressions can be evaluated."""
-
-    def __init__(self, frame):
-        self.code = py.code.Code(frame.f_code)
-        self.lineno = frame.f_lineno - 1
-        self.f_globals = frame.f_globals
-        self.f_locals = frame.f_locals
-        self.raw = frame
-
-    def statement(self):
-        if self.code.fullsource is None:
-            return py.code.Source("")
-        return self.code.fullsource.getstatement(self.lineno)
-    statement = property(statement, None, None,
-                         "statement this frame is at")
-
-    def eval(self, code, **vars):
-        """ evaluate 'code' in the frame
-
-            'vars' are optional additional local variables
-
-            returns the result of the evaluation
-        """
-        f_locals = self.f_locals.copy()
-        f_locals.update(vars)
-        return eval(code, self.f_globals, f_locals)
-
-    def exec_(self, code, **vars):
-        """ exec 'code' in the frame
-
-            'vars' are optiona; additional local variables
-        """
-        f_locals = self.f_locals.copy()
-        f_locals.update(vars)
-        py.builtin.exec_(code, self.f_globals, f_locals )
-
-    def repr(self, object):
-        """ return a 'safe' (non-recursive, one-line) string repr for 'object'
-        """
-        return py.io.saferepr(object)
-
-    def is_true(self, object):
-        return object
-
-    def getargs(self):
-        """ return a list of tuples (name, value) for all arguments
-        """
-        retval = []
-        for arg in self.code.getargs():
-            try:
-                retval.append((arg, self.f_locals[arg]))
-            except KeyError:
-                pass     # this can occur when using Psyco
-        return retval
-
-class TracebackEntry(object):
-    """ a single entry in a traceback """
-
-    exprinfo = None
-
-    def __init__(self, rawentry):
-        self._rawentry = rawentry
-        self.frame = py.code.Frame(rawentry.tb_frame)
-        # Ugh. 2.4 and 2.5 differs here when encountering
-        # multi-line statements. Not sure about the solution, but
-        # should be portable
-        self.lineno = rawentry.tb_lineno - 1
-        self.relline = self.lineno - self.frame.code.firstlineno
-
-    def __repr__(self):
-        return "<TracebackEntry %s:%d>" %(self.frame.code.path, self.lineno+1)
-
-    def statement(self):
-        """ return a py.code.Source object for the current statement """
-        source = self.frame.code.fullsource
-        return source.getstatement(self.lineno)
-    statement = property(statement, None, None,
-                         "statement of this traceback entry.")
-
-    def path(self):
-        return self.frame.code.path
-    path = property(path, None, None, "path to the full source code")
-
-    def getlocals(self):
-        return self.frame.f_locals
-    locals = property(getlocals, None, None, "locals of underlaying frame")
-
-    def reinterpret(self):
-        """Reinterpret the failing statement and returns a detailed information
-           about what operations are performed."""
-        if self.exprinfo is None:
-            source = str(self.statement).strip()
-            x = py.code._reinterpret(source, self.frame, should_fail=True)
-            if not isinstance(x, str):
-                raise TypeError("interpret returned non-string %r" % (x,))
-            self.exprinfo = x
-        return self.exprinfo
-
-    def getfirstlinesource(self):
-        # on Jython this firstlineno can be -1 apparently
-        return max(self.frame.code.firstlineno, 0)
-
-    def getsource(self):
-        """ return failing source code. """
-        source = self.frame.code.fullsource
-        if source is None:
-            return None
-        start = self.getfirstlinesource()
-        end = self.lineno
-        try:
-            _, end = source.getstatementrange(end)
-        except (IndexError, ValueError):
-            end = self.lineno + 1
-        # heuristic to stop displaying source on e.g.
-        #   if something:  # assume this causes a NameError
-        #      # _this_ lines and the one
-               #        below we don't want from entry.getsource()
-        for i in range(self.lineno, end):
-            if source[i].rstrip().endswith(':'):
-                end = i + 1
-                break
-        return source[start:end]
-    source = property(getsource)
-
-    def ishidden(self):
-        """ return True if the current frame has a var __tracebackhide__
-            resolving to True
-
-            mostly for internal use
-        """
-        try:
-            return self.frame.eval("__tracebackhide__")
-        except py.builtin._sysex:
-            raise
-        except:
-            return False
-
-    def __str__(self):
-        try:
-            fn = str(self.path)
-        except py.error.Error:
-            fn = '???'
-        name = self.frame.code.name
-        try:
-            line = str(self.statement).lstrip()
-        except KeyboardInterrupt:
-            raise
-        except:
-            line = "???"
-        return "  File %r:%d in %s\n  %s\n" %(fn, self.lineno+1, name, line)
-
-    def name(self):
-        return self.frame.code.raw.co_name
-    name = property(name, None, None, "co_name of underlaying code")
-
-class Traceback(list):
-    """ Traceback objects encapsulate and offer higher level
-        access to Traceback entries.
-    """
-    Entry = TracebackEntry
-    def __init__(self, tb):
-        """ initialize from given python traceback object. """
-        if hasattr(tb, 'tb_next'):
-            def f(cur):
-                while cur is not None:
-                    yield self.Entry(cur)
-                    cur = cur.tb_next
-            list.__init__(self, f(tb))
-        else:
-            list.__init__(self, tb)
-
-    def cut(self, path=None, lineno=None, firstlineno=None, excludepath=None):
-        """ return a Traceback instance wrapping part of this Traceback
-
-            by provding any combination of path, lineno and firstlineno, the
-            first frame to start the to-be-returned traceback is determined
-
-            this allows cutting the first part of a Traceback instance e.g.
-            for formatting reasons (removing some uninteresting bits that deal
-            with handling of the exception/traceback)
-        """
-        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)):
-                return Traceback(x._rawentry)
-        return self
-
-    def __getitem__(self, key):
-        val = super(Traceback, self).__getitem__(key)
-        if isinstance(key, type(slice(0))):
-            val = self.__class__(val)
-        return val
-
-    def filter(self, fn=lambda x: not x.ishidden()):
-        """ return a Traceback instance with certain items removed
-
-            fn is a function that gets a single argument, a TracebackItem
-            instance, and should return True when the item should be added
-            to the Traceback, False when not
-
-            by default this removes all the TracebackItems which are hidden
-            (see ishidden() above)
-        """
-        return Traceback(filter(fn, self))
-
-    def getcrashentry(self):
-        """ return last non-hidden traceback entry that lead
-        to the exception of a traceback.
-        """
-        tb = self.filter()
-        if not tb:
-            tb = self
-        return tb[-1]
-
-    def recursionindex(self):
-        """ return the index of the frame/TracebackItem where recursion
-            originates if appropriate, None if no recursion occurred
-        """
-        cache = {}
-        for i, entry in enumerate(self):
-            # id for the code.raw is needed to work around
-            # the strange metaprogramming in the decorator lib from pypi
-            # which generates code objects that have hash/value equality
-            #XXX needs a test
-            key = entry.frame.code.path, id(entry.frame.code.raw), entry.lineno
-            #print "checking for recursion at", key
-            l = cache.setdefault(key, [])
-            if l:
-                f = entry.frame
-                loc = f.f_locals
-                for otherloc in l:
-                    if f.is_true(f.eval(co_equal,
-                        __recursioncache_locals_1=loc,
-                        __recursioncache_locals_2=otherloc)):
-                        return i
-            l.append(entry.frame.f_locals)
-        return None
-
-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 = ''
-    def __init__(self, tup=None, exprinfo=None):
-        # NB. all attributes are private!  Subclasses or other
-        #     ExceptionInfo-like classes may have different attributes.
-        if tup is None:
-            tup = sys.exc_info()
-            if exprinfo is None and isinstance(tup[1], AssertionError):
-                exprinfo = getattr(tup[1], 'msg', None)
-                if exprinfo is None:
-                    exprinfo = str(tup[1])
-                if exprinfo and exprinfo.startswith('assert '):
-                    self._striptext = 'AssertionError: '
-        self._excinfo = tup
-        self.type, self.value, tb = self._excinfo
-        self.typename = self.type.__name__
-        self.traceback = py.code.Traceback(tb)
-
-    def __repr__(self):
-        return "<ExceptionInfo %s tblen=%d>" % (self.typename, len(self.traceback))
-
-    def exconly(self, tryshort=False):
-        """ return the exception as a string
-
-            when 'tryshort' resolves to True, and the exception is a
-            py.code._AssertionError, only the actual exception part of
-            the exception representation is returned (so 'AssertionError: ' is
-            removed from the beginning)
-        """
-        lines = py.std.traceback.format_exception_only(self.type, self.value)
-        text = ''.join(lines)
-        text = text.rstrip()
-        if tryshort:
-            if text.startswith(self._striptext):
-                text = text[len(self._striptext):]
-        return text
-
-    def errisinstance(self, exc):
-        """ return True if the exception is an instance of exc """
-        return isinstance(self.value, exc)
-
-    def _getreprcrash(self):
-        exconly = self.exconly(tryshort=True)
-        entry = self.traceback.getcrashentry()
-        path, lineno = entry.path, entry.lineno
-        reprcrash = ReprFileLocation(path, lineno+1, exconly)
-        return reprcrash
-
-    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
-            tbfilter: hide entries (where __tracebackhide__ is true)
-
-            in case of style==native, tbfilter and showlocals is ignored.
-        """
-        if style == 'native':
-            return ReprExceptionInfo(ReprTracebackNative(
-                py.std.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):
-        entry = self.traceback[-1]
-        loc = ReprFileLocation(entry.path, entry.lineno + 1, self.exconly())
-        return str(loc)
-
-    def __unicode__(self):
-        entry = self.traceback[-1]
-        loc = ReprFileLocation(entry.path, entry.lineno + 1, self.exconly())
-        return unicode(loc)
-
-
-class FormattedExcinfo(object):
-    """ presenting information about failing Functions and Generators. """
-    # for traceback entries
-    flow_marker = ">"
-    fail_marker = "E"
-
-    def __init__(self, showlocals=False, style="long", abspath=True, tbfilter=True, funcargs=False):
-        self.showlocals = showlocals
-        self.style = style
-        self.tbfilter = tbfilter
-        self.funcargs = funcargs
-        self.abspath = abspath
-
-    def _getindent(self, source):
-        # figure out indent for given source
-        try:
-            s = str(source.getstatement(len(source)-1))
-        except KeyboardInterrupt:
-            raise
-        except:
-            try:
-                s = str(source[-1])
-            except KeyboardInterrupt:
-                raise
-            except:
-                return 0
-        return 4 + (len(s) - len(s.lstrip()))
-
-    def _getentrysource(self, entry):
-        source = entry.getsource()
-        if source is not None:
-            source = source.deindent()
-        return source
-
-    def _saferepr(self, obj):
-        return py.io.saferepr(obj)
-
-    def repr_args(self, entry):
-        if self.funcargs:
-            args = []
-            for argname, argvalue in entry.frame.getargs():
-                args.append((argname, self._saferepr(argvalue)))
-            return ReprFuncArgs(args)
-
-    def get_source(self, source, line_index=-1, excinfo=None, short=False):
-        """ return formatted and marked up source lines. """
-        lines = []
-        if source is None:
-            source = py.code.Source("???")
-            line_index = 0
-        if line_index < 0:
-            line_index += len(source)
-        for i in range(len(source)):
-            if i == line_index:
-                prefix = self.flow_marker + "   "
-            else:
-                if short:
-                    continue
-                prefix = "    "
-            line = prefix + source[i]
-            lines.append(line)
-        if excinfo is not None:
-            indent = self._getindent(source)
-            lines.extend(self.get_exconly(excinfo, indent=indent, markall=True))
-        return lines
-
-    def get_exconly(self, excinfo, indent=4, markall=False):
-        lines = []
-        indent = " " * indent
-        # get the real exception information out
-        exlines = excinfo.exconly(tryshort=True).split('\n')
-        failindent = self.fail_marker + indent[1:]
-        for line in exlines:
-            lines.append(failindent + line)
-            if not markall:
-                failindent = indent
-        return lines
-
-    def repr_locals(self, locals):
-        if self.showlocals:
-            lines = []
-            keys = [loc for loc in locals if loc[0] != "@"]
-            keys.sort()
-            for name in keys:
-                value = locals[name]
-                if name == '__builtins__':
-                    lines.append("__builtins__ = <builtins>")
-                else:
-                    # This formatting could all be handled by the
-                    # _repr() function, which is only reprlib.Repr in
-                    # disguise, so is very configurable.
-                    str_repr = self._saferepr(value)
-                    #if len(str_repr) < 70 or not isinstance(value,
-                    #                            (list, tuple, dict)):
-                    lines.append("%-10s = %s" %(name, str_repr))
-                    #else:
-                    #    self._line("%-10s =\\" % (name,))
-                    #    # XXX
-                    #    py.std.pprint.pprint(value, stream=self.excinfowriter)
-            return ReprLocals(lines)
-
-    def repr_traceback_entry(self, entry, excinfo=None):
-        # excinfo is not None if this is the last tb entry
-        source = self._getentrysource(entry)
-        if source is None:
-            source = py.code.Source("???")
-            line_index = 0
-        else:
-            # entry.getfirstlinesource() can be -1, should be 0 on jython
-            line_index = entry.lineno - max(entry.getfirstlinesource(), 0)
-
-        lines = []
-        if self.style in ("short", "long"):
-            short = self.style == "short"
-            reprargs = None
-            if not short:
-                reprargs = self.repr_args(entry)
-            s = self.get_source(source, line_index, excinfo, short=short)
-            lines.extend(s)
-            if short: