[pypy-commit] pypy default: Flow space: "raise x" now explicitly asserts that x is not a None
arigo
pypy.commits at gmail.com
Fri Dec 16 07:56:27 EST 2016
Author: Armin Rigo <arigo at 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
More information about the pypy-commit
mailing list