Author: Romain Guillebert <[email protected]>
Branch:
Changeset: r66379:c240d50f3830
Date: 2013-08-28 13:37 +0100
http://bitbucket.org/pypy/pypy/changeset/c240d50f3830/
Log: Merge heads
diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py
--- a/rpython/annotator/annrpython.py
+++ b/rpython/annotator/annrpython.py
@@ -5,7 +5,7 @@
from rpython.tool.ansi_print import ansi_log
from rpython.tool.pairtype import pair
from rpython.tool.error import (format_blocked_annotation_error,
- AnnotatorError, gather_error, ErrorWrapper)
+ AnnotatorError, gather_error, ErrorWrapper,
source_lines)
from rpython.flowspace.model import (Variable, Constant, FunctionGraph,
c_last_exception, checkgraph)
from rpython.translator import simplify, transform
@@ -383,8 +383,8 @@
try:
unions = [annmodel.unionof(c1,c2) for c1, c2 in
zip(oldcells,inputcells)]
except annmodel.UnionError, e:
- e.args = e.args + (
- ErrorWrapper(gather_error(self, graph, block, None)),)
+ # Add source code to the UnionError
+ e.source = '\n'.join(source_lines(graph, block, None, long=True))
raise
# if the merged cells changed, we must redo the analysis
if unions != oldcells:
diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py
--- a/rpython/annotator/binaryop.py
+++ b/rpython/annotator/binaryop.py
@@ -243,14 +243,16 @@
if t2 is int:
if int2.nonneg == False:
- raise UnionError, "Merging %s and a possibly negative int
is not allowed" % t1
+ raise UnionError(int1, int2, "RPython cannot prove that
these " + \
+ "integers are of the same signedness")
knowntype = t1
elif t1 is int:
if int1.nonneg == False:
- raise UnionError, "Merging %s and a possibly negative int
is not allowed" % t2
+ raise UnionError(int1, int2, "RPython cannot prove that
these " + \
+ "integers are of the same signedness")
knowntype = t2
else:
- raise UnionError, "Merging these types (%s, %s) is not
supported" % (t1, t2)
+ raise UnionError(int1, int2)
return SomeInteger(nonneg=int1.nonneg and int2.nonneg,
knowntype=knowntype)
@@ -551,9 +553,9 @@
def union((tup1, tup2)):
if len(tup1.items) != len(tup2.items):
- raise UnionError("cannot take the union of a tuple of length %d "
- "and a tuple of length %d" % (len(tup1.items),
- len(tup2.items)))
+ raise UnionError(tup1, tup2, "RPython cannot unify tuples of "
+ "different length: %d versus %d" % \
+ (len(tup1.items), len(tup2.items)))
else:
unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)]
return SomeTuple(items = unions)
@@ -726,7 +728,8 @@
else:
basedef = ins1.classdef.commonbase(ins2.classdef)
if basedef is None:
- raise UnionError(ins1, ins2)
+ raise UnionError(ins1, ins2, "RPython cannot unify instances "
+ "with no common base class")
flags = ins1.flags
if flags:
flags = flags.copy()
@@ -768,7 +771,8 @@
def union((iter1, iter2)):
s_cont = unionof(iter1.s_container, iter2.s_container)
if iter1.variant != iter2.variant:
- raise UnionError("merging incompatible iterators variants")
+ raise UnionError(iter1, iter2,
+ "RPython cannot unify incompatible iterator variants")
return SomeIterator(s_cont, *iter1.variant)
@@ -778,8 +782,7 @@
if (bltn1.analyser != bltn2.analyser or
bltn1.methodname != bltn2.methodname or
bltn1.s_self is None or bltn2.s_self is None):
- raise UnionError("cannot merge two different builtin functions "
- "or methods:\n %r\n %r" % (bltn1, bltn2))
+ raise UnionError(bltn1, bltn2)
s_self = unionof(bltn1.s_self, bltn2.s_self)
return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname)
@@ -976,8 +979,8 @@
class __extend__(pairtype(SomeAddress, SomeObject)):
def union((s_addr, s_obj)):
- raise UnionError, "union of address and anything else makes no sense"
+ raise UnionError(s_addr, s_obj)
class __extend__(pairtype(SomeObject, SomeAddress)):
def union((s_obj, s_addr)):
- raise UnionError, "union of address and anything else makes no sense"
+ raise UnionError(s_obj, s_addr)
diff --git a/rpython/annotator/listdef.py b/rpython/annotator/listdef.py
--- a/rpython/annotator/listdef.py
+++ b/rpython/annotator/listdef.py
@@ -58,7 +58,7 @@
def merge(self, other):
if self is not other:
if getattr(TLS, 'no_side_effects_in_union', 0):
- raise UnionError("merging list/dict items")
+ raise UnionError(self, other)
if other.dont_change_any_more:
if self.dont_change_any_more:
diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py
--- a/rpython/annotator/model.py
+++ b/rpython/annotator/model.py
@@ -680,6 +680,33 @@
"""Signals an suspicious attempt at taking the union of
deeply incompatible SomeXxx instances."""
+ def __init__(self, s_obj1, s_obj2, msg=None):
+ """
+ This exception expresses the fact that s_obj1 and s_obj2 cannot be
unified.
+ The msg paramter is appended to a generic message. This can be used to
+ give the user a little more information.
+ """
+ self.s_obj1 = s_obj1
+ self.s_obj2 = s_obj2
+ self.msg = msg
+ self.source = None
+
+ def __str__(self):
+ s = "\n\n"
+
+ if self.msg is not None:
+ s += "%s\n\n" % self.msg
+
+ s += "Offending annotations:\n"
+ s += "%s\n%s\n\n" % (self.s_obj1, self.s_obj2)
+
+ if self.source is not None:
+ s += self.source
+
+ return s
+
+ def __repr__(self):
+ return str(self)
def unionof(*somevalues):
"The most precise SomeValue instance that contains all the values."
diff --git a/rpython/annotator/test/test_annrpython.py
b/rpython/annotator/test/test_annrpython.py
--- a/rpython/annotator/test/test_annrpython.py
+++ b/rpython/annotator/test/test_annrpython.py
@@ -4023,6 +4023,81 @@
a = self.RPythonAnnotator()
assert not a.build_types(fn, [int]).nonneg
+ def test_unionerror_attrs(self):
+ def f(x):
+ if x < 10:
+ return 1
+ else:
+ return "bbb"
+ a = self.RPythonAnnotator()
+
+ with py.test.raises(annmodel.UnionError) as exc:
+ a.build_types(f, [int])
+
+ the_exc = exc.value
+ s_objs = set([type(the_exc.s_obj1), type(the_exc.s_obj2)])
+
+ assert s_objs == set([annmodel.SomeInteger, annmodel.SomeString])
+ assert the_exc.msg == None # Check that this is a generic UnionError
+
+ def test_unionerror_tuple_size(self):
+ def f(x):
+ if x < 10:
+ return (1, )
+ else:
+ return (1, 2)
+ a = self.RPythonAnnotator()
+
+ with py.test.raises(annmodel.UnionError) as exc:
+ a.build_types(f, [int])
+
+ assert exc.value.msg == "RPython cannot unify tuples of different
length: 2 versus 1"
+
+ def test_unionerror_signedness(self):
+ def f(x):
+ if x < 10:
+ return r_uint(99)
+ else:
+ return -1
+ a = self.RPythonAnnotator()
+
+ with py.test.raises(annmodel.UnionError) as exc:
+ a.build_types(f, [int])
+
+ assert exc.value.msg == ("RPython cannot prove that these integers are
of "
+ "the same signedness")
+
+ def test_unionerror_instance(self):
+ class A(object): pass
+ class B(object): pass
+
+ def f(x):
+ if x < 10:
+ return A()
+ else:
+ return B()
+ a = self.RPythonAnnotator()
+
+ with py.test.raises(annmodel.UnionError) as exc:
+ a.build_types(f, [int])
+
+ assert exc.value.msg == ("RPython cannot unify instances with no
common base class")
+
+ def test_unionerror_iters(self):
+
+ def f(x):
+ d = { 1 : "a", 2 : "b" }
+ if x < 10:
+ return d.iterkeys()
+ else:
+ return d.itervalues()
+ a = self.RPythonAnnotator()
+
+ with py.test.raises(annmodel.UnionError) as exc:
+ a.build_types(f, [int])
+
+ assert exc.value.msg == ("RPython cannot unify incompatible iterator
variants")
+
def g(n):
return [0, 1, 2, n]
diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -24,8 +24,9 @@
self.frame = frame
def __str__(self):
- msg = ['-+' * 30]
+ msg = ["\n"]
msg += map(str, self.args)
+ msg += [""]
msg += source_lines(self.frame.graph, None,
offset=self.frame.last_instr)
return "\n".join(msg)
@@ -293,7 +294,7 @@
_unsupported_ops = [
('BINARY_POWER', "a ** b"),
- ('BUILD_CLASS', 'creating new classes'),
+ ('BUILD_CLASS', 'defining classes inside functions'),
('EXEC_STMT', 'exec statement'),
('STOP_CODE', '???'),
('STORE_NAME', 'modifying globals'),
diff --git a/rpython/tool/error.py b/rpython/tool/error.py
--- a/rpython/tool/error.py
+++ b/rpython/tool/error.py
@@ -90,7 +90,7 @@
format_simple_call(annotator, oper, msg)
else:
oper = None
- msg.append(" " + str(oper))
+ msg.append(" %s\n" % str(oper))
msg += source_lines(graph, block, operindex, long=True)
if oper is not None:
if SHOW_ANNOTATIONS:
@@ -106,7 +106,7 @@
def format_blocked_annotation_error(annotator, blocked_blocks):
text = []
for block, (graph, index) in blocked_blocks.items():
- text.append('-+' * 30)
+ text.append('\n')
text.append("Blocked block -- operation cannot succeed")
text.append(gather_error(annotator, graph, block, index))
return '\n'.join(text)
diff --git a/rpython/translator/goal/translate.py
b/rpython/translator/goal/translate.py
--- a/rpython/translator/goal/translate.py
+++ b/rpython/translator/goal/translate.py
@@ -246,17 +246,19 @@
tb = None
if got_error:
import traceback
- errmsg = ["Error:\n"]
+ stacktrace_errmsg = ["Error:\n"]
exc, val, tb = sys.exc_info()
- errmsg.extend([" %s" % line for line in
traceback.format_exception(exc, val, tb)])
+ stacktrace_errmsg.extend([" %s" % line for line in
traceback.format_tb(tb)])
+ summary_errmsg = traceback.format_exception_only(exc, val)
block = getattr(val, '__annotator_block', None)
if block:
class FileLike:
def write(self, s):
- errmsg.append(" %s" % s)
- errmsg.append("Processing block:\n")
+ summary_errmsg.append(" %s" % s)
+ summary_errmsg.append("Processing block:\n")
t.about(block, FileLike())
- log.ERROR(''.join(errmsg))
+ log.info(''.join(stacktrace_errmsg))
+ log.ERROR(''.join(summary_errmsg))
else:
log.event('Done.')
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit