move the old assertion reinterpreting implementation to _assertionold.py
Also, seperate out some common code from the two. --HG-- branch : trunk
This commit is contained in:
		
							parent
							
								
									130046d245
								
							
						
					
					
						commit
						e596d9df13
					
				|  | @ -133,7 +133,7 @@ initpkg(__name__, | |||
|     'code.getrawcode'        : ('./code/code.py', 'getrawcode'), | ||||
|     'code.patch_builtins'    : ('./code/code.py', 'patch_builtins'), | ||||
|     'code.unpatch_builtins'  : ('./code/code.py', 'unpatch_builtins'), | ||||
|     'code._AssertionError'   : ('./code/_assertion.py', 'AssertionError'), | ||||
|     'code._AssertionError'   : ('./code/assertion.py', 'AssertionError'), | ||||
| 
 | ||||
|     # backports and additions of builtins | ||||
|     'builtin.__doc__'        : ('./builtin/__init__.py', '__doc__'), | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ import sys | |||
| import ast | ||||
| 
 | ||||
| import py | ||||
| from py.__.code._assertion import _format_explanation, BuiltinAssertionError | ||||
| from py.__.code.assertion import _format_explanation, BuiltinAssertionError | ||||
| 
 | ||||
| 
 | ||||
| class Failure(Exception): | ||||
|  | @ -40,6 +40,8 @@ def getfailure(failure): | |||
|     value = failure.cause[1] | ||||
|     if str(value): | ||||
|         lines = explanation.splitlines() | ||||
|         if not lines: | ||||
|             lines.append("") | ||||
|         lines[0] += " << {0}".format(value) | ||||
|         explanation = "\n".join(lines) | ||||
|     text = "{0}: {1}".format(failure.cause[0].__name__, explanation) | ||||
|  | @ -97,7 +99,7 @@ class DebugInterpreter(ast.NodeVisitor): | |||
|             mod = ast.Module([node]) | ||||
|             co = self._compile(mod, "exec") | ||||
|             try: | ||||
|                 frame.exec_(co) | ||||
|                 self.frame.exec_(co) | ||||
|             except Exception: | ||||
|                 raise Failure() | ||||
|             return None, None | ||||
|  | @ -107,6 +109,9 @@ class DebugInterpreter(ast.NodeVisitor): | |||
|     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) | ||||
|  | @ -175,8 +180,8 @@ class DebugInterpreter(ast.NodeVisitor): | |||
|         left_explanation, left_result = self.visit(binop.left) | ||||
|         right_explanation, right_result = self.visit(binop.right) | ||||
|         symbol = operator_map[binop.op.__class__] | ||||
|         explanation = "{0} {1} {2}".format(left_explanation, symbol, | ||||
|                                            right_explanation) | ||||
|         explanation = "({0} {1} {2})".format(left_explanation, symbol, | ||||
|                                              right_explanation) | ||||
|         source = "__exprinfo_left {0} __exprinfo_right".format(symbol) | ||||
|         co = self._compile(source) | ||||
|         try: | ||||
|  |  | |||
|  | @ -1,8 +1,7 @@ | |||
| import py | ||||
| import sys, inspect | ||||
| from compiler import parse, ast, pycodegen | ||||
| import __builtin__ as cpy_builtin | ||||
| BuiltinAssertionError = cpy_builtin.AssertionError | ||||
| from py.__.code.assertion import BuiltinAssertionError, _format_explanation | ||||
| 
 | ||||
| passthroughex = (KeyboardInterrupt, SystemExit, MemoryError) | ||||
| 
 | ||||
|  | @ -97,42 +96,6 @@ def enumsubclasses(cls): | |||
|     yield cls | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| def _format_explanation(explanation): | ||||
|     # uck!  See CallFunc for where \n{ and \n} escape sequences are used | ||||
|     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('}'): | ||||
|             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:]) | ||||
|         else: | ||||
|             assert line.startswith('}') | ||||
|             stack.pop() | ||||
|             stackcnt.pop() | ||||
|             result[stack[-1]] += line[1:] | ||||
|     assert len(stack) == 1 | ||||
|     return '\n'.join(result) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| class Interpretable(View): | ||||
|     """A parse tree node with a few extra methods.""" | ||||
|     explanation = None | ||||
|  | @ -566,39 +529,6 @@ def run(s, frame=None): | |||
|         report_failure(e) | ||||
| 
 | ||||
| 
 | ||||
| class AssertionError(BuiltinAssertionError): | ||||
|     def __init__(self, *args): | ||||
|         BuiltinAssertionError.__init__(self, *args) | ||||
|         if args:  | ||||
|             try: | ||||
|                 self.msg = str(args[0]) | ||||
|             except (KeyboardInterrupt, SystemExit): | ||||
|                 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.statement | ||||
|                 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: | ||||
|                 if sys.version_info >= (2, 6): | ||||
|                     from py.__.code._assertionnew import interpret as do_interp | ||||
|                 else: | ||||
|                     do_interp = interpret | ||||
|                 self.msg = do_interp(source, f, should_fail=True) | ||||
|                 if not self.args: | ||||
|                     self.args = (self.msg,) | ||||
|             else: | ||||
|                 self.msg = None | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     # example: | ||||
|     def f(): | ||||
|  | @ -0,0 +1,76 @@ | |||
| try: | ||||
|     import __builtin__ as builtins | ||||
| except ImportError: | ||||
|     import builtins | ||||
| import sys | ||||
| import py | ||||
| 
 | ||||
| BuiltinAssertionError = builtins.AssertionError | ||||
| 
 | ||||
| 
 | ||||
| def _format_explanation(explanation): | ||||
|     # uck!  See CallFunc for where \n{ and \n} escape sequences are used | ||||
|     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('}'): | ||||
|             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:]) | ||||
|         else: | ||||
|             assert line.startswith('}') | ||||
|             stack.pop() | ||||
|             stackcnt.pop() | ||||
|             result[stack[-1]] += line[1:] | ||||
|     assert len(stack) == 1 | ||||
|     return '\n'.join(result) | ||||
| 
 | ||||
| 
 | ||||
| if sys.version_info >= (2, 6): | ||||
|     from py.__.code._assertionnew import interpret | ||||
| else: | ||||
|     from py.__.code._assertionold import interpret | ||||
| 
 | ||||
| 
 | ||||
| class AssertionError(BuiltinAssertionError): | ||||
| 
 | ||||
|     def __init__(self, *args): | ||||
|         BuiltinAssertionError.__init__(self, *args) | ||||
|         if args: | ||||
|             try: | ||||
|                 self.msg = str(args[0]) | ||||
|             except (KeyboardInterrupt, SystemExit): | ||||
|                 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.statement | ||||
|                 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 = interpret(source, f, should_fail=True) | ||||
|                 if not self.args: | ||||
|                     self.args = (self.msg,) | ||||
|             else: | ||||
|                 self.msg = None | ||||
|  | @ -197,9 +197,9 @@ class TracebackEntry(object): | |||
|         """Reinterpret the failing statement and returns a detailed information | ||||
|            about what operations are performed.""" | ||||
|         if self.exprinfo is None: | ||||
|             from py.__.code import _assertion  | ||||
|             from py.__.code import assertion  | ||||
|             source = str(self.statement).strip() | ||||
|             x = _assertion.interpret(source, self.frame, should_fail=True) | ||||
|             x = assertion.interpret(source, self.frame, should_fail=True) | ||||
|             if not isinstance(x, str): | ||||
|                 raise TypeError("interpret returned non-string %r" % (x,)) | ||||
|             self.exprinfo = x  | ||||
|  | @ -739,10 +739,10 @@ oldbuiltins = {} | |||
| def patch_builtins(assertion=True, compile=True): | ||||
|     """ put compile and AssertionError builtins to Python's builtins. """ | ||||
|     if assertion: | ||||
|         from py.__.code import _assertion | ||||
|         from py.__.code import assertion | ||||
|         l = oldbuiltins.setdefault('AssertionError', []) | ||||
|         l.append(py.builtin.builtins.AssertionError) | ||||
|         py.builtin.builtins.AssertionError = _assertion.AssertionError | ||||
|         py.builtin.builtins.AssertionError = assertion.AssertionError | ||||
|     if compile:  | ||||
|         l = oldbuiltins.setdefault('compile', []) | ||||
|         l.append(py.builtin.builtins.compile) | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| import py | ||||
| from py.__.code._assertion import View | ||||
| from py.__.code._assertionold import View | ||||
| def exvalue(): | ||||
|     return py.std.sys.exc_info()[1] | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue