[pypy-commit] pypy default: try to produce better error messages for the scary
cfbolz
noreply at buildbot.pypy.org
Wed Jun 27 15:54:45 CEST 2012
Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch:
Changeset: r55861:86204e97633f
Date: 2012-06-27 11:34 +0200
http://bitbucket.org/pypy/pypy/changeset/86204e97633f/
Log: try to produce better error messages for the scary "assert nshapes
== 1, "XXX call table too complex"
diff --git a/pypy/rpython/normalizecalls.py b/pypy/rpython/normalizecalls.py
--- a/pypy/rpython/normalizecalls.py
+++ b/pypy/rpython/normalizecalls.py
@@ -39,7 +39,8 @@
row)
if did_something:
assert not callfamily.normalized, "change in call family normalisation"
- assert nshapes == 1, "XXX call table too complex"
+ if nshapes != 1:
+ raise_call_table_too_complex_error(callfamily, annotator)
while True:
progress = False
for shape, table in callfamily.calltables.items():
@@ -50,6 +51,38 @@
return # done
assert not callfamily.normalized, "change in call family normalisation"
+def raise_call_table_too_complex_error(callfamily, annotator):
+ msg = []
+ items = callfamily.calltables.items()
+ for i, (shape1, table1) in enumerate(items):
+ for shape2, table2 in items[i + 1:]:
+ if shape1 == shape2:
+ continue
+ row1 = table1[0]
+ row2 = table2[0]
+ problematic_function_graphs = set(row1.values()).union(set(row2.values()))
+ pfg = [str(graph) for graph in problematic_function_graphs]
+ pfg.sort()
+ msg.append("the following functions:")
+ msg.append(" %s" % ("\n ".join(pfg), ))
+ msg.append("are called with inconsistent numbers of arguments")
+ if shape1[0] != shape2[0]:
+ msg.append("sometimes with %s arguments, sometimes with %s" % (shape1[0], shape2[0]))
+ else:
+ pass # XXX better message in this case
+ callers = []
+ msg.append("the callers of these functions are:")
+ for tag, (caller, callee) in annotator.translator.callgraph.iteritems():
+ if callee not in problematic_function_graphs:
+ continue
+ if str(caller) in callers:
+ continue
+ callers.append(str(caller))
+ callers.sort()
+ for caller in callers:
+ msg.append(" %s" % (caller, ))
+ raise TyperError("\n".join(msg))
+
def normalize_calltable_row_signature(annotator, shape, row):
graphs = row.values()
assert graphs, "no graph??"
diff --git a/pypy/rpython/test/test_normalizecalls.py b/pypy/rpython/test/test_normalizecalls.py
--- a/pypy/rpython/test/test_normalizecalls.py
+++ b/pypy/rpython/test/test_normalizecalls.py
@@ -2,6 +2,7 @@
from pypy.annotation import model as annmodel
from pypy.translator.translator import TranslationContext, graphof
from pypy.rpython.llinterp import LLInterpreter
+from pypy.rpython.error import TyperError
from pypy.rpython.test.test_llinterp import interpret
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.normalizecalls import TotalOrderSymbolic, MAX
@@ -158,6 +159,39 @@
res = llinterp.eval_graph(graphof(translator, dummyfn), [2])
assert res == -2
+ def test_methods_with_defaults(self):
+ class Base:
+ def fn(self):
+ raise NotImplementedError
+ class Sub1(Base):
+ def fn(self, x=1):
+ return 1 + x
+ class Sub2(Base):
+ def fn(self):
+ return -2
+ def otherfunc(x):
+ return x.fn()
+ def dummyfn(n):
+ if n == 1:
+ x = Sub1()
+ n = x.fn(2)
+ else:
+ x = Sub2()
+ return otherfunc(x) + x.fn()
+
+ excinfo = py.test.raises(TyperError, "self.rtype(dummyfn, [int], int)")
+ msg = """the following functions:
+ .+Base.fn
+ .+Sub1.fn
+ .+Sub2.fn
+are called with inconsistent numbers of arguments
+sometimes with 2 arguments, sometimes with 1
+the callers of these functions are:
+ .+otherfunc
+ .+dummyfn"""
+ import re
+ assert re.match(msg, excinfo.value.args[0])
+
class PBase:
def fn(self):
More information about the pypy-commit
mailing list