[pypy-commit] pypy assert-rewrite: Create an assert_() function that can exactly replace asserts in RPython and doesn't trigger pytest's assertion rewriting

rlamy pypy.commits at gmail.com
Sun Nov 27 13:31:45 EST 2016


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: assert-rewrite
Changeset: r88681:da4b23a03b40
Date: 2016-11-27 18:28 +0000
http://bitbucket.org/pypy/pypy/changeset/da4b23a03b40/

Log:	Create an assert_() function that can exactly replace asserts in
	RPython and doesn't trigger pytest's assertion rewriting

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
@@ -18,6 +18,7 @@
 from rpython.rlib.rarithmetic import r_uint, base_int, r_longlong, r_ulonglong
 from rpython.rlib.rarithmetic import r_singlefloat
 from rpython.rlib import objectmodel
+from rpython.rlib.objectmodel import assert_
 from rpython.flowspace.flowcontext import FlowingError
 from rpython.flowspace.operation import op
 
@@ -858,7 +859,7 @@
         class C(B):
             pass
         def f(x):
-            assert type(x) is C
+            assert_(type(x) is C)
             return x
         a = self.RPythonAnnotator()
         s = a.build_types(f, [B])
@@ -894,10 +895,10 @@
         assert isinstance(s, annmodel.SomeString)
 
     def test_ann_assert(self):
-        def assert_(x):
-            assert x,"XXX"
-        a = self.RPythonAnnotator()
-        s = a.build_types(assert_, [int])
+        def my_assert(x):
+            assert_(x, "XXX")
+        a = self.RPythonAnnotator()
+        s = a.build_types(my_assert, [int])
         assert s.const is None
 
     def test_string_and_none(self):
@@ -1059,7 +1060,7 @@
             if a:
                 c = a
             else:
-                assert b >= 0
+                assert_(b >= 0)
                 c = b
             return c
         a = self.RPythonAnnotator()
@@ -1214,7 +1215,7 @@
 
         def alloc(cls):
             i = inst(cls)
-            assert isinstance(i, cls)
+            assert_(isinstance(i, cls))
             return i
         alloc._annspecialcase_ = "specialize:arg(0)"
 
@@ -1250,9 +1251,9 @@
 
         def alloc(cls, cls2):
             i = cls()
-            assert isinstance(i, cls)
+            assert_(isinstance(i, cls))
             j = cls2()
-            assert isinstance(j, cls2)
+            assert_(isinstance(j, cls2))
             return i
 
         def f():
@@ -1360,7 +1361,7 @@
         class T(object):
             pass
         def g(l):
-            assert isinstance(l, list)
+            assert_(isinstance(l, list))
             return l
         def f():
             l = [T()]
diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -759,7 +759,6 @@
         w_value = self.peekvalue()
         if self.guessbool(op.bool(w_value).eval(self)):
             return target
-            return target
         self.popvalue()
 
     def JUMP_IF_NOT_DEBUG(self, target):
diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py
--- a/rpython/rlib/objectmodel.py
+++ b/rpython/rlib/objectmodel.py
@@ -14,7 +14,7 @@
 from rpython.tool.sourcetools import rpython_wrapper, func_with_new_name
 from rpython.rtyper.extregistry import ExtRegistryEntry
 from rpython.flowspace.specialcase import register_flow_sc
-from rpython.flowspace.model import Constant
+from rpython.flowspace.model import Constant, const
 
 # specialize is a decorator factory for attaching _annspecialcase_
 # attributes to functions: for example
@@ -230,6 +230,34 @@
     func._not_rpython_ = True
     return func
 
+def assert_(condition, msg=None):
+    """
+    A function version of the assert statement.
+
+    The RPython toolchain interprets it in exactly the same way as the
+    statement version. This is useful in tests to prevent py.test assertion
+    rewriting from modifying the bytecode of RPython functions.
+    """
+    if msg is None:
+        assert condition
+    else:
+        assert condition, msg
+
+ at register_flow_sc(assert_)
+def sc_assert(ctx, *args_w):
+    from rpython.flowspace.operation import op
+    from rpython.flowspace.flowcontext import Raise, FlowingError
+    if len(args_w) == 2:
+        w_condition, w_msg = args_w
+    elif len(args_w) == 1:
+        w_condition, = args_w
+        w_msg = const(None)
+    else:
+        raise FlowingError(
+            "assert_() requires 1 or 2 arguments, %s given" % len(args_w))
+    if not ctx.guessbool(op.bool(w_condition).eval(ctx)):
+        raise Raise(ctx.exc_from_raise(const(AssertionError), w_msg))
+
 
 # ____________________________________________________________
 


More information about the pypy-commit mailing list