[pypy-commit] pypy kill-someobject: fix test_error, a bit by improving error messages
fijal
noreply at buildbot.pypy.org
Tue Oct 9 17:58:07 CEST 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: kill-someobject
Changeset: r57954:01e86a93b033
Date: 2012-10-09 17:56 +0200
http://bitbucket.org/pypy/pypy/changeset/01e86a93b033/
Log: fix test_error, a bit by improving error messages
diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py
--- a/pypy/annotation/annrpython.py
+++ b/pypy/annotation/annrpython.py
@@ -1,9 +1,8 @@
-import sys
import types
-from pypy.tool.ansi_print import ansi_log, raise_nicer_exception
+from pypy.tool.ansi_print import ansi_log
from pypy.tool.pairtype import pair
from pypy.tool.error import (format_blocked_annotation_error,
- format_someobject_error, AnnotatorError)
+ AnnotatorError, gather_error)
from pypy.objspace.flow.model import (Variable, Constant, FunctionGraph,
c_last_exception, checkgraph)
from pypy.translator import simplify, transform
@@ -38,7 +37,7 @@
self.links_followed = {} # set of links that have ever been followed
self.notify = {} # {block: {positions-to-reflow-from-when-done}}
self.fixed_graphs = {} # set of graphs not to annotate again
- self.blocked_blocks = {} # set of {blocked_block: graph}
+ self.blocked_blocks = {} # set of {blocked_block: (graph, index)}
# --- the following information is recorded for debugging ---
self.blocked_graphs = {} # set of graphs that have blocked blocks
# --- end of debugging information ---
@@ -341,7 +340,7 @@
self.flowin(graph, block)
except BlockedInference, e:
self.annotated[block] = False # failed, hopefully temporarily
- self.blocked_blocks[block] = graph
+ self.blocked_blocks[block] = (graph, e.opindex)
except Exception, e:
# hack for debug tools only
if not hasattr(e, '__annotator_block'):
@@ -360,7 +359,7 @@
self.pendingblocks[block] = graph
assert block in self.annotated
self.annotated[block] = False # must re-flow
- self.blocked_blocks[block] = graph
+ self.blocked_blocks[block] = (graph, None)
def bindinputargs(self, graph, block, inputcells):
# Create the initial bindings for the input args of a block.
@@ -368,7 +367,7 @@
for a, cell in zip(block.inputargs, inputcells):
self.setbinding(a, cell)
self.annotated[block] = False # must flowin.
- self.blocked_blocks[block] = graph
+ self.blocked_blocks[block] = (graph, None)
def mergeinputargs(self, graph, block, inputcells):
# Merge the new 'cells' with each of the block's existing input
@@ -397,7 +396,7 @@
for i in range(len(block.operations)):
try:
self.bookkeeper.enter((graph, block, i))
- self.consider_op(block.operations[i])
+ self.consider_op(block, i)
finally:
self.bookkeeper.leave()
@@ -573,7 +572,8 @@
#___ creating the annotations based on operations ______
- def consider_op(self, op):
+ def consider_op(self, block, opindex):
+ op = block.operations[opindex]
argcells = [self.binding(a) for a in op.args]
consider_meth = getattr(self,'consider_op_'+op.opname,
None)
@@ -588,16 +588,17 @@
# boom -- in the assert of setbinding()
for arg in argcells:
if isinstance(arg, annmodel.SomeImpossibleValue):
- raise BlockedInference(self, op)
+ raise BlockedInference(self, op, opindex)
try:
resultcell = consider_meth(*argcells)
- except Exception:
+ except Exception, e:
graph = self.bookkeeper.position_key[0]
- raise_nicer_exception(op, str(graph))
+ e.args = e.args + (gather_error(self, graph, block, opindex),)
+ raise
if resultcell is None:
resultcell = self.noreturnvalue(op)
elif resultcell == annmodel.s_ImpossibleValue:
- raise BlockedInference(self, op) # the operation cannot succeed
+ raise BlockedInference(self, op, opindex) # the operation cannot succeed
assert isinstance(resultcell, annmodel.SomeObject)
assert isinstance(op.result, Variable)
self.setbinding(op.result, resultcell) # bind resultcell to op.result
@@ -648,13 +649,14 @@
"""This exception signals the type inference engine that the situation
is currently blocked, and that it should try to progress elsewhere."""
- def __init__(self, annotator, op):
+ def __init__(self, annotator, op, opindex):
self.annotator = annotator
try:
self.break_at = annotator.bookkeeper.position_key
except AttributeError:
self.break_at = None
self.op = op
+ self.opindex = opindex
def __repr__(self):
if not self.break_at:
diff --git a/pypy/tool/ansi_print.py b/pypy/tool/ansi_print.py
--- a/pypy/tool/ansi_print.py
+++ b/pypy/tool/ansi_print.py
@@ -72,23 +72,3 @@
file=self.file, newline=newline, flush=flush)
ansi_log = AnsiLog()
-
-# ____________________________________________________________
-# Nice helper
-
-def raise_nicer_exception(*extraargs):
- cls, e, tb = sys.exc_info()
- str_e = str(e)
- class ExcSubclass(cls):
- def __str__(self):
- lines = [str_e]
- for extra in extraargs:
- lines.append('\t.. %r' % (extra,))
- return '\n'.join(lines)
- ExcSubclass.__name__ = cls.__name__ + "'"
- ExcSubclass.__module__ = cls.__module__
- try:
- e.__class__ = ExcSubclass
- except TypeError: # doesn't work any more on 2.5 :-(
- pass
- raise ExcSubclass, e, tb
diff --git a/pypy/tool/error.py b/pypy/tool/error.py
--- a/pypy/tool/error.py
+++ b/pypy/tool/error.py
@@ -2,8 +2,8 @@
""" error handling features, just a way of displaying errors
"""
-from pypy.tool.ansi_print import ansi_log, raise_nicer_exception
-from pypy.objspace.flow.model import Constant, Variable
+from pypy.tool.ansi_print import ansi_log
+from pypy.objspace.flow.model import Variable
import sys
import py
@@ -15,7 +15,6 @@
SHOW_DEFAULT_LINES_OF_CODE = 0
from pypy.interpreter.pytraceback import offset2lineno
-import traceback
def source_lines1(graph, block, operindex=None, offset=None, long=False, \
show_lines_of_code=SHOW_DEFAULT_LINES_OF_CODE):
@@ -71,29 +70,16 @@
class NoSuchAttrError(Exception):
pass
-def gather_error(annotator, block, graph):
- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+def gather_error(annotator, graph, block, operindex):
msg = [""]
- msg.append('-+' * 30)
- from pypy.annotation import model
- msg.append("Blocked block -- operation cannot succeed")
- if model.DEBUG:
- _, _, operindex = annotator.why_not_annotated[block][1].break_at
- else:
- # guess the blocked operation by the fact that its return value is
- # not annotated
- for operindex in range(len(block.operations)):
- if block.operations[operindex].result not in annotator.bindings:
- break
- else:
- operindex = None
if operindex is not None:
oper = block.operations[operindex]
- msg.append(" " + str(oper))
+ if oper.opname == 'simple_call':
+ format_simple_call(annotator, oper, msg)
else:
oper = None
- msg.append(" (inconsistency - the block is fully annotated??)")
+ msg.append(" " + str(oper))
msg += source_lines(graph, block, operindex, long=True)
if oper is not None:
if SHOW_ANNOTATIONS:
@@ -104,17 +90,17 @@
msg.append(" " + str(arg) + " = " + str(annotator.binding(arg)))
except KeyError:
pass
- if model.DEBUG and SHOW_TRACEBACK:
- msg.extend(traceback.format_exception(*annotator.why_not_annotated[block]))
return "\n".join(msg)
def format_blocked_annotation_error(annotator, blocked_blocks):
text = []
- for block, graph in blocked_blocks.items():
- text.append(gather_error(annotator, block, graph))
+ for block, (graph, index) in blocked_blocks.items():
+ text.append('-+' * 30)
+ text.append("Blocked block -- operation cannot succeed")
+ text.append(gather_error(annotator, graph, block, index))
return '\n'.join(text)
-def format_simple_call(annotator, oper, what, msg):
+def format_simple_call(annotator, oper, msg):
msg.append("Simple call of incompatible family:")
try:
descs = annotator.bindings[oper.args[0]].descriptions
@@ -147,32 +133,6 @@
msg.append(" %s" % (r,))
msg.append("")
-def format_someobject_error(annotator, position_key, what, s_value, called_from_graph, binding=""):
- XXXXXXXXXXXXXXXXXXXXXX
- #block = getattr(annotator, 'flowin_block', None) or block
- msg = ["annotation of %r degenerated to SomeObject()" % (what,)]
- if position_key is not None:
- graph, block, operindex = position_key
- if operindex is not None:
- oper = block.operations[operindex]
- if oper.opname == 'simple_call':
- format_simple_call(annotator, oper, what, msg)
- else:
- msg.append(str(oper))
- else:
- msg.append("at the start of the block with input arguments:")
- for v in block.inputargs:
- s_v = annotator.binding(v, "(no annotation)")
- msg.append("%8s: %s" % (v, s_v))
- msg.append('')
- msg += source_lines(graph, block, operindex, long=True)
-
- if called_from_graph is not None:
- msg.append(".. called from %r" % (called_from_graph,))
- msg.append("Previous annotation:")
- msg.append(" " + str(binding))
- return "\n".join(msg)
-
def debug(drv, use_pdb=True):
# XXX unify some code with pypy.translator.goal.translate
from pypy.translator.tool.pdbplus import PdbPlusShow
diff --git a/pypy/tool/test/test_error.py b/pypy/tool/test/test_error.py
--- a/pypy/tool/test/test_error.py
+++ b/pypy/tool/test/test_error.py
@@ -4,6 +4,7 @@
from pypy.translator.translator import TranslationContext
from pypy.tool.error import AnnotatorError
+from pypy.annotation.model import UnionError
import py
@@ -37,7 +38,7 @@
a = 9
return a
- py.test.raises(AnnotatorError, compile_function, someobject_degeneration, [int])
+ py.test.raises(UnionError, compile_function, someobject_degeneration, [int])
def test_someobject2():
def someobject_deg(n):
@@ -47,12 +48,12 @@
return AAA()
return a
- py.test.raises(AnnotatorError, compile_function, someobject_deg, [int])
+ py.test.raises(UnionError, compile_function, someobject_deg, [int])
def test_eval_someobject():
exec("def f(n):\n if n == 2:\n return 'a'\n else:\n return 3")
- py.test.raises(AnnotatorError, compile_function, f, [int])
+ py.test.raises(UnionError, compile_function, f, [int])
def test_someobject_from_call():
def one(x):
@@ -70,6 +71,6 @@
try:
compile_function(fn, [int])
- except AnnotatorError, e:
- assert 'function one' in e.args[0]
- assert 'function two' in e.args[0]
+ except UnionError, e:
+ assert 'function one' in e.args[2]
+ assert 'function two' in e.args[2]
More information about the pypy-commit
mailing list