Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r89096:2fbea2e90463 Date: 2016-12-16 13:40 +0100 http://bitbucket.org/pypy/pypy/changeset/2fbea2e90463/
Log: Flow space: "raise x" now explicitly asserts that x is not a None diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py --- a/rpython/annotator/annrpython.py +++ b/rpython/annotator/annrpython.py @@ -231,6 +231,12 @@ v = graph.getreturnvar() if v.annotation is None: self.setbinding(v, s_ImpossibleValue) + v = graph.exceptblock.inputargs[1] + if v.annotation is not None and v.annotation.can_be_none(): + raise annmodel.AnnotatorError( + "%r is found by annotation to possibly raise None, " + "but the None was not suppressed by the flow space" % + (graph,)) def validate(self): """Check that the annotation results are valid""" diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -484,6 +484,9 @@ def __init__(self, classdefs): self.classdefs = classdefs + def can_be_none(self): + return False + def as_SomeInstance(self): return unionof(*[SomeInstance(cdef) for cdef in self.classdefs]) 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 @@ -4652,6 +4652,17 @@ assert ('string formatting requires a constant string/unicode' in str(e.value)) + def test_cannot_raise_none(self): + def f(x): + s = None + if x > 5: + s = ValueError() + raise s + a = self.RPythonAnnotator() + a.build_types(f, [int]) + s_exc = a.binding(graphof(a, f).exceptblock.inputargs[1]) + assert not s_exc.can_be_none() + 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 @@ -597,6 +597,8 @@ Returns an FSException object whose w_value is an instance of w_type. """ + from rpython.rlib.debug import ll_assert_not_none + w_is_type = op.isinstance(w_arg1, const(type)).eval(self) if self.guessbool(w_is_type): # this is for all cases of the form (Class, something) @@ -618,6 +620,7 @@ "separate value") raise Raise(const(exc)) w_value = w_arg1 + w_value = op.simple_call(const(ll_assert_not_none), w_value).eval(self) w_type = op.type(w_value).eval(self) return FSException(w_type, w_value) diff --git a/rpython/rlib/debug.py b/rpython/rlib/debug.py --- a/rpython/rlib/debug.py +++ b/rpython/rlib/debug.py @@ -11,7 +11,8 @@ # Expose these here (public interface) from rpython.rtyper.debug import ( - ll_assert, FatalError, fatalerror, fatalerror_notb, debug_print_traceback) + ll_assert, FatalError, fatalerror, fatalerror_notb, debug_print_traceback, + ll_assert_not_none) class DebugLog(list): diff --git a/rpython/rtyper/debug.py b/rpython/rtyper/debug.py --- a/rpython/rtyper/debug.py +++ b/rpython/rtyper/debug.py @@ -20,6 +20,26 @@ hop.exception_cannot_occur() hop.genop('debug_assert', vlist) +def ll_assert_not_none(x): + """assert x is not None""" + assert x, "ll_assert_not_none(%r)" % (x,) + return x + +class Entry(ExtRegistryEntry): + _about_ = ll_assert_not_none + + def compute_result_annotation(self, s_x): + return s_x.nonnoneify() + + def specialize_call(self, hop): + [v0] = hop.inputargs(hop.args_r[0]) + assert isinstance(v0.concretetype, lltype.Ptr) + v1 = hop.genop('ptr_nonzero', [v0], resulttype=lltype.Bool) + hop.exception_cannot_occur() + cmsg = hop.inputconst(lltype.Void, "ll_assert_not_none failed") + hop.genop('debug_assert', [v1, cmsg]) + return v0 + class FatalError(Exception): pass _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit