[pypy-commit] pypy exc-later: Propagate exception annotations from functions to their callers (work in progress)
rlamy
noreply at buildbot.pypy.org
Sun Nov 22 13:00:06 EST 2015
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: exc-later
Changeset: r80835:ec9ba2968c66
Date: 2015-11-22 18:00 +0000
http://bitbucket.org/pypy/pypy/changeset/ec9ba2968c66/
Log: Propagate exception annotations from functions to their callers
(work in progress)
diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py
--- a/rpython/annotator/annrpython.py
+++ b/rpython/annotator/annrpython.py
@@ -7,12 +7,12 @@
from rpython.tool.pairtype import pair
from rpython.tool.error import (format_blocked_annotation_error,
gather_error, source_lines)
-from rpython.flowspace.model import Variable, Constant, checkgraph
+from rpython.flowspace.model import Variable, Constant, checkgraph, FunctionGraph
from rpython.translator import simplify, transform
from rpython.annotator import model as annmodel, signature
from rpython.annotator.model import (
- typeof, s_ImpossibleValue, SomeInstance)
-from rpython.annotator.bookkeeper import Bookkeeper
+ unionof, typeof, s_ImpossibleValue, SomeInstance, SomePBC)
+from rpython.annotator.bookkeeper import Bookkeeper, simple_args
from rpython.rtyper.normalizecalls import perform_normalizations
import py
@@ -265,6 +265,7 @@
# points to this func which triggers a reflow whenever the
# return block of this graph has been analysed.
callpositions = self.notify.setdefault(graph.returnblock, {})
+ callpositions2 = self.notify.setdefault(graph.exceptblock, {})
if whence is not None:
if callable(whence):
def callback():
@@ -272,6 +273,7 @@
else:
callback = whence
callpositions[callback] = True
+ callpositions2[callback] = True
# generalize the function's input arguments
self.addpendingblock(graph, graph.startblock, inputcells)
@@ -607,6 +609,24 @@
"""
Return the annotation for all exceptions that `operation` may raise.
"""
+ from rpython.flowspace.operation import SimpleCall
+ if isinstance(operation, SimpleCall):
+ s_func = self.annotation(operation.args[0])
+ if (isinstance(s_func, SomePBC) and
+ hasattr(s_func.getKind(), 'get_graph')): # exclude ClassDesc
+ args_s = [self.annotation(v) for v in operation.args[1:]]
+ argspec = simple_args(args_s)
+ exceptions_s = []
+ for desc in s_func.descriptions:
+ with self.bookkeeper.at_position(None):
+ graph = desc.get_graph(argspec, operation)
+ if not isinstance(graph, FunctionGraph):
+ break
+ s_exc = graph.exceptblock.inputargs[1].annotation
+ if s_exc is not None:
+ exceptions_s.append(s_exc)
+ else:
+ return unionof(*exceptions_s)
can_only_throw = operation.get_can_only_throw(self)
if can_only_throw is None:
return SomeInstance(self.bookkeeper.getuniqueclassdef(Exception))
More information about the pypy-commit
mailing list