[pypy-svn] pypy default: try to print relevant information when the loop does not match
antocuni
commits-noreply at bitbucket.org
Mon Mar 14 14:55:47 CET 2011
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch:
Changeset: r42607:09dbc4efa036
Date: 2011-03-14 14:45 +0100
http://bitbucket.org/pypy/pypy/changeset/09dbc4efa036/
Log: try to print relevant information when the loop does not match
diff --git a/pypy/module/pypyjit/test_pypy_c/model.py b/pypy/module/pypyjit/test_pypy_c/model.py
--- a/pypy/module/pypyjit/test_pypy_c/model.py
+++ b/pypy/module/pypyjit/test_pypy_c/model.py
@@ -1,4 +1,5 @@
import py
+import sys
import re
import os.path
from pypy.tool.jitlogparser.parser import SimpleParser, Function, TraceForOpcode
@@ -132,12 +133,15 @@
for op in self._ops_for_chunk(chunk, include_debug_merge_points):
yield op
- def print_ops(self, id=None, **kwds):
+ def format_ops(self, id=None, **kwds):
if id is None:
ops = self.allops()
else:
ops = self.ops_by_id(id, **kwds)
- print '\n'.join(map(str, ops))
+ return '\n'.join(map(str, ops))
+
+ def print_ops(self, *args, **kwds):
+ print self.format_ops(*args, **kwds)
def ops_by_id(self, id, include_debug_merge_points=False, opcode=None):
opcode_name = opcode
@@ -151,7 +155,7 @@
def match(self, expected_src):
ops = list(self.allops())
- matcher = OpMatcher(ops)
+ matcher = OpMatcher(ops, src=self.format_ops())
return matcher.match(expected_src)
def match_by_id(self, id, expected_src):
@@ -160,12 +164,36 @@
return matcher.match(expected_src)
class InvalidMatch(Exception):
- pass
+
+ def __init__(self, message, frame):
+ Exception.__init__(self, message)
+ # copied and adapted from pytest's magic AssertionError
+ f = py.code.Frame(frame)
+ try:
+ source = f.code.fullsource
+ if source is not None:
+ try:
+ source = source.getstatement(f.lineno)
+ except IndexError:
+ source = None
+ else:
+ source = str(source.deindent()).strip()
+ except py.error.ENOENT:
+ source = None
+ if source and source.startswith('self._assert('):
+ # transform self._assert(x, 'foo') into assert x, 'foo'
+ source = source.replace('self._assert(', 'assert ')
+ source = source[:-1] # remove the trailing ')'
+ self.msg = py.code._reinterpret(source, f, should_fail=True)
+ else:
+ self.msg = "<could not determine information>"
+
class OpMatcher(object):
- def __init__(self, ops):
+ def __init__(self, ops, src=None):
self.ops = ops
+ self.src = src
self.alpha_map = {}
@classmethod
@@ -195,9 +223,7 @@
args = args[:-1]
args = args.split(',')
args = map(str.strip, args)
- if args == ['']:
- args = []
- if args and args[-1].startswith('descr='):
+ if args[-1].startswith('descr='):
descr = args.pop()
descr = descr[len('descr='):]
else:
@@ -236,7 +262,7 @@
def _assert(self, cond, message):
if not cond:
- raise InvalidMatch(message)
+ raise InvalidMatch(message, frame=sys._getframe(1))
def match_op(self, op, (exp_opname, exp_res, exp_args, exp_descr)):
self._assert(op.name == exp_opname, "operation mismatch")
@@ -302,8 +328,18 @@
expected_ops = self.parse_ops(expected_src)
try:
self.match_loop(expected_ops)
- except InvalidMatch:
+ except InvalidMatch, e:
#raise # uncomment this and use py.test --pdb for better debugging
+ print '@' * 40
+ print "Loops don't match"
+ print "================="
+ print e.msg
+ print
+ print "Got:"
+ print py.code.Source(self.src).deindent().indent()
+ print
+ print "Expected:"
+ print py.code.Source(expected_src).deindent().indent()
return False
else:
return True
diff --git a/pypy/module/pypyjit/test_pypy_c/test_model.py b/pypy/module/pypyjit/test_pypy_c/test_model.py
--- a/pypy/module/pypyjit/test_pypy_c/test_model.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_model.py
@@ -98,7 +98,7 @@
def match(self, src1, src2):
from pypy.tool.jitlogparser.parser import SimpleParser
loop = SimpleParser.parse_from_input(src1)
- matcher = OpMatcher(loop.operations)
+ matcher = OpMatcher(loop.operations, src=src1)
return matcher.match(src2)
def test_match_var(self):
More information about the Pypy-commit
mailing list