[pypy-commit] pypy default: update to cffi/5aeca29219db

arigo pypy.commits at gmail.com
Tue Apr 2 10:26:42 EDT 2019


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r96404:67af7a9e5ca2
Date: 2019-04-02 16:25 +0200
http://bitbucket.org/pypy/pypy/changeset/67af7a9e5ca2/

Log:	update to cffi/5aeca29219db

diff --git a/extra_tests/cffi_tests/cffi0/backend_tests.py b/extra_tests/cffi_tests/cffi0/backend_tests.py
--- a/extra_tests/cffi_tests/cffi0/backend_tests.py
+++ b/extra_tests/cffi_tests/cffi0/backend_tests.py
@@ -1,5 +1,6 @@
 # Generated by pypy/tool/import_cffi.py
 import py
+import pytest
 import platform
 import sys, ctypes
 from cffi import FFI, CDefError, FFIError, VerificationMissing
@@ -113,10 +114,14 @@
         p[9] = 43
         assert p[0] == 42
         assert p[9] == 43
-        py.test.raises(IndexError, "p[10]")
-        py.test.raises(IndexError, "p[10] = 44")
-        py.test.raises(IndexError, "p[-1]")
-        py.test.raises(IndexError, "p[-1] = 44")
+        with pytest.raises(IndexError):
+            p[10]
+        with pytest.raises(IndexError):
+            p[10] = 44
+        with pytest.raises(IndexError):
+            p[-1]
+        with pytest.raises(IndexError):
+            p[-1] = 44
 
     def test_new_array_args(self):
         ffi = FFI(backend=self.Backend())
@@ -141,18 +146,21 @@
         ffi = FFI(backend=self.Backend())
         p = ffi.new("int[]", 10)     # a single integer is the length
         assert p[9] == 0
-        py.test.raises(IndexError, "p[10]")
+        with pytest.raises(IndexError):
+            p[10]
         #
         py.test.raises(TypeError, ffi.new, "int[]")
         #
         p = ffi.new("int[]", [-6, -7])    # a list is all the items, like C
         assert p[0] == -6
         assert p[1] == -7
-        py.test.raises(IndexError, "p[2]")
+        with pytest.raises(IndexError):
+            p[2]
         assert repr(p) == "<cdata 'int[]' owning %d bytes>" % (2*SIZE_OF_INT)
         #
         p = ffi.new("int[]", 0)
-        py.test.raises(IndexError, "p[0]")
+        with pytest.raises(IndexError):
+            p[0]
         py.test.raises(ValueError, ffi.new, "int[]", -1)
         assert repr(p) == "<cdata 'int[]' owning 0 bytes>"
 
@@ -260,7 +268,8 @@
         p[2][3] = 33
         assert p[0][0] == 10
         assert p[2][3] == 33
-        py.test.raises(IndexError, "p[1][-1]")
+        with pytest.raises(IndexError):
+            p[1][-1]
 
     def test_constructor_array_of_array(self):
         ffi = FFI(backend=self.Backend())
@@ -387,7 +396,8 @@
         n = ffi.new("int*", 99)
         p = ffi.new("int*[]", [n])
         assert p[0][0] == 99
-        py.test.raises(TypeError, "p[0] = None")
+        with pytest.raises(TypeError):
+            p[0] = None
         p[0] = ffi.NULL
         assert p[0] == ffi.NULL
 
@@ -423,13 +433,15 @@
         assert s.a == s.b == s.c == 0
         s.b = -23
         assert s.b == -23
-        py.test.raises(OverflowError, "s.b = 32768")
+        with pytest.raises(OverflowError):
+            s.b = 32768
         #
         s = ffi.new("struct foo*", [-2, -3])
         assert s.a == -2
         assert s.b == -3
         assert s.c == 0
-        py.test.raises((AttributeError, TypeError), "del s.a")
+        with pytest.raises((AttributeError, TypeError)):
+            del s.a
         assert repr(s) == "<cdata 'struct foo *' owning %d bytes>" % (
             SIZE_OF_INT + 2 * SIZE_OF_SHORT)
         #
@@ -451,8 +463,10 @@
         assert s[0].a == s[0].b == s[0].c == 0
         s[0].b = -23
         assert s[0].b == s.b == -23
-        py.test.raises(OverflowError, "s[0].b = -32769")
-        py.test.raises(IndexError, "s[1]")
+        with pytest.raises(OverflowError):
+            s[0].b = -32769
+        with pytest.raises(IndexError):
+            s[1]
 
     def test_struct_opaque(self):
         ffi = FFI(backend=self.Backend())
@@ -512,11 +526,13 @@
         u.b = -23
         assert u.b == -23
         assert u.a != 0
-        py.test.raises(OverflowError, "u.b = 32768")
+        with pytest.raises(OverflowError):
+            u.b = 32768
         #
         u = ffi.new("union foo*", [-2])
         assert u.a == -2
-        py.test.raises((AttributeError, TypeError), "del u.a")
+        with pytest.raises((AttributeError, TypeError)):
+            del u.a
         assert repr(u) == "<cdata 'union foo *' owning %d bytes>" % SIZE_OF_INT
 
     def test_union_opaque(self):
@@ -592,7 +608,8 @@
         p[3] = b'\x00'
         assert ffi.string(p) == b"hel"
         assert ffi.string(p, 2) == b"he"
-        py.test.raises(IndexError, "p[7] = b'X'")
+        with pytest.raises(IndexError):
+            p[7] = b'X'
         #
         a = ffi.new("char[]", b"hello\x00world")
         assert len(a) == 12
@@ -616,7 +633,8 @@
         p[3] = u+'\x00'
         assert ffi.string(p) == u+"hel"
         assert ffi.string(p, 123) == u+"hel"
-        py.test.raises(IndexError, "p[7] = u+'X'")
+        with pytest.raises(IndexError):
+            p[7] = u+'X'
         #
         a = ffi.new("wchar_t[]", u+"hello\x00world")
         assert len(a) == 12
@@ -634,7 +652,8 @@
         s = ffi.new("struct foo*", [t])
         assert type(s.name) not in (bytes, str, unicode)
         assert ffi.string(s.name) == b"testing"
-        py.test.raises(TypeError, "s.name = None")
+        with pytest.raises(TypeError):
+            s.name = None
         s.name = ffi.NULL
         assert s.name == ffi.NULL
 
@@ -658,18 +677,21 @@
         a = ffi.new("int[]", [10, 11, 12])
         p = ffi.new("void **", a)
         vp = p[0]
-        py.test.raises(TypeError, "vp[0]")
+        with pytest.raises(TypeError):
+            vp[0]
         py.test.raises(TypeError, ffi.new, "short **", a)
         #
         ffi.cdef("struct foo { void *p; int *q; short *r; };")
         s = ffi.new("struct foo *")
         s.p = a    # works
         s.q = a    # works
-        py.test.raises(TypeError, "s.r = a")    # fails
+        with pytest.raises(TypeError):
+            s.r = a    # fails
         b = ffi.cast("int *", a)
         s.p = b    # works
         s.q = b    # works
-        py.test.raises(TypeError, "s.r = b")    # fails
+        with pytest.raises(TypeError):
+            s.r = b    # fails
 
     def test_functionptr_simple(self):
         ffi = FFI(backend=self.Backend())
@@ -688,7 +710,8 @@
         q = ffi.new("int(**)(int)", p)
         assert repr(q) == "<cdata 'int(* *)(int)' owning %d bytes>" % (
             SIZE_OF_PTR)
-        py.test.raises(TypeError, "q(43)")
+        with pytest.raises(TypeError):
+            q(43)
         res = q[0](43)
         assert res == 44
         q = ffi.cast("int(*)(int)", p)
@@ -913,10 +936,14 @@
         assert s.e == 4294967295
         assert s[0].e == 4294967295
         s.e = s.e
-        py.test.raises(TypeError, "s.e = 'B'")
-        py.test.raises(TypeError, "s.e = '2'")
-        py.test.raises(TypeError, "s.e = '#2'")
-        py.test.raises(TypeError, "s.e = '#7'")
+        with pytest.raises(TypeError):
+            s.e = 'B'
+        with pytest.raises(TypeError):
+            s.e = '2'
+        with pytest.raises(TypeError):
+            s.e = '#2'
+        with pytest.raises(TypeError):
+            s.e = '#7'
 
     def test_enum_non_contiguous(self):
         ffi = FFI(backend=self.Backend())
@@ -951,11 +978,14 @@
         ffi = FFI(backend=self.Backend())
         ffi.cdef("struct foo { int a, b; };")
         s = ffi.new("struct foo[1]")
-        py.test.raises(AttributeError, 's.b')
-        py.test.raises(AttributeError, 's.b = 412')
+        with pytest.raises(AttributeError):
+            s.b
+        with pytest.raises(AttributeError):
+            s.b = 412
         s[0].b = 412
         assert s[0].b == 412
-        py.test.raises(IndexError, 's[1]')
+        with pytest.raises(IndexError):
+            s[1]
 
     def test_pointer_to_array(self):
         ffi = FFI(backend=self.Backend())
@@ -1012,17 +1042,23 @@
         assert ffi.sizeof("struct foo") == 8
         s = ffi.new("struct foo *")
         s.a = 511
-        py.test.raises(OverflowError, "s.a = 512")
-        py.test.raises(OverflowError, "s[0].a = 512")
+        with pytest.raises(OverflowError):
+            s.a = 512
+        with pytest.raises(OverflowError):
+            s[0].a = 512
         assert s.a == 511
         s.a = -512
-        py.test.raises(OverflowError, "s.a = -513")
-        py.test.raises(OverflowError, "s[0].a = -513")
+        with pytest.raises(OverflowError):
+            s.a = -513
+        with pytest.raises(OverflowError):
+            s[0].a = -513
         assert s.a == -512
         s.c = 3
         assert s.c == 3
-        py.test.raises(OverflowError, "s.c = 4")
-        py.test.raises(OverflowError, "s[0].c = 4")
+        with pytest.raises(OverflowError):
+            s.c = 4
+        with pytest.raises(OverflowError):
+            s[0].c = 4
         s.c = -4
         assert s.c == -4
 
@@ -1280,7 +1316,8 @@
         p = ffi.new("struct foo_s *", 10)     # a single integer is the length
         assert p.len == 0
         assert p.data[9] == 0
-        py.test.raises(IndexError, "p.data[10]")
+        with pytest.raises(IndexError):
+            p.data[10]
 
     def test_ffi_typeof_getcname(self):
         ffi = FFI(backend=self.Backend())
diff --git a/extra_tests/cffi_tests/cffi0/test_ffi_backend.py b/extra_tests/cffi_tests/cffi0/test_ffi_backend.py
--- a/extra_tests/cffi_tests/cffi0/test_ffi_backend.py
+++ b/extra_tests/cffi_tests/cffi0/test_ffi_backend.py
@@ -130,6 +130,36 @@
         alloc5 = ffi.new_allocator(myalloc5)
         py.test.raises(MemoryError, alloc5, "int[5]")
 
+    def test_new_struct_containing_struct_containing_array_varsize(self):
+        ffi = FFI(backend=self.Backend())
+        ffi.cdef("""
+            struct foo_s { int len[100]; short data[]; };
+            struct bar_s { int abc[100]; struct foo_s tail; };
+        """)
+        # loop to try to detect heap overwrites, if the size allocated
+        # is too small
+        for i in range(1, 501, 100):
+            p = ffi.new("struct bar_s *", [[10], [[20], [3,4,5,6,7,8,9] * i]])
+            assert p.abc[0] == 10
+            assert p.tail.len[0] == 20
+            assert p.tail.data[0] == 3
+            assert p.tail.data[6] == 9
+            assert p.tail.data[7 * i - 1] == 9
+
+    def test_bogus_struct_containing_struct_containing_array_varsize(self):
+        ffi = FFI(backend=self.Backend())
+        ffi.cdef("""
+            struct foo_s { signed char len; signed char data[]; };
+            struct bar_s { struct foo_s foo; int bcd; };
+        """)
+        p = ffi.new("struct bar_s *", [[123, [45, 56, 67, 78]], 9999999])
+        assert p.foo.len == 123
+        assert p.foo.data[0] == 45
+        assert p.foo.data[1] == 56
+        assert p.foo.data[2] == 67
+        assert p.bcd == 9999999
+        assert p.foo.data[3] != 78   # has been overwritten with 9999999
+
 
 class TestBitfield:
     def check(self, source, expected_ofs_y, expected_align, expected_size):
@@ -269,12 +299,15 @@
 
     def test_error_cases(self):
         ffi = FFI()
-        py.test.raises(TypeError,
-            'ffi.cdef("struct s1 { float x:1; };"); ffi.new("struct s1 *")')
-        py.test.raises(TypeError,
-            'ffi.cdef("struct s2 { char x:0; };"); ffi.new("struct s2 *")')
-        py.test.raises(TypeError,
-            'ffi.cdef("struct s3 { char x:9; };"); ffi.new("struct s3 *")')
+        ffi.cdef("struct s1 { float x:1; };")
+        with pytest.raises(TypeError):
+            ffi.new("struct s1 *")
+        ffi.cdef("struct s2 { char x:0; };")
+        with pytest.raises(TypeError):
+            ffi.new("struct s2 *")
+        ffi.cdef("struct s3 { char x:9; };")
+        with pytest.raises(TypeError):
+            ffi.new("struct s3 *")
 
     def test_struct_with_typedef(self):
         ffi = FFI()
diff --git a/extra_tests/cffi_tests/cffi0/test_function.py b/extra_tests/cffi_tests/cffi0/test_function.py
--- a/extra_tests/cffi_tests/cffi0/test_function.py
+++ b/extra_tests/cffi_tests/cffi0/test_function.py
@@ -1,5 +1,6 @@
 # Generated by pypy/tool/import_cffi.py
 import py
+import pytest
 from cffi import FFI, CDefError
 import math, os, sys
 import ctypes.util
@@ -91,7 +92,8 @@
         """)
         m = ffi.dlopen(lib_m)
         assert m.FOOBAR == 42
-        py.test.raises(NotImplementedError, "m.baz")
+        with pytest.raises(NotImplementedError):
+            m.baz
 
     def test_tlsalloc(self):
         if sys.platform != 'win32':
diff --git a/extra_tests/cffi_tests/cffi0/test_parsing.py b/extra_tests/cffi_tests/cffi0/test_parsing.py
--- a/extra_tests/cffi_tests/cffi0/test_parsing.py
+++ b/extra_tests/cffi_tests/cffi0/test_parsing.py
@@ -467,3 +467,40 @@
     e = py.test.raises(CDefError, ffi.cdef, 'void foo(void) {}')
     assert str(e.value) == ('<cdef source string>:1: unexpected <FuncDef>: '
                             'this construct is valid C but not valid in cdef()')
+
+def test_unsigned_int_suffix_for_constant():
+    ffi = FFI()
+    ffi.cdef("""enum e {
+                    bin_0=0b10,
+                    bin_1=0b10u,
+                    bin_2=0b10U,
+                    bin_3=0b10l,
+                    bin_4=0b10L,
+                    bin_5=0b10ll,
+                    bin_6=0b10LL,
+                    oct_0=010,
+                    oct_1=010u,
+                    oct_2=010U,
+                    oct_3=010l,
+                    oct_4=010L,
+                    oct_5=010ll,
+                    oct_6=010LL,
+                    dec_0=10,
+                    dec_1=10u,
+                    dec_2=10U,
+                    dec_3=10l,
+                    dec_4=10L,
+                    dec_5=10ll,
+                    dec_6=10LL,
+                    hex_0=0x10,
+                    hex_1=0x10u,
+                    hex_2=0x10U,
+                    hex_3=0x10l,
+                    hex_4=0x10L,
+                    hex_5=0x10ll,
+                    hex_6=0x10LL,};""")
+    needs_dlopen_none()
+    C = ffi.dlopen(None)
+    for base, expected_result in (('bin', 2), ('oct', 8), ('dec', 10), ('hex', 16)):
+        for index in range(7):
+            assert getattr(C, '{base}_{index}'.format(base=base, index=index)) == expected_result
diff --git a/extra_tests/cffi_tests/cffi0/test_verify.py b/extra_tests/cffi_tests/cffi0/test_verify.py
--- a/extra_tests/cffi_tests/cffi0/test_verify.py
+++ b/extra_tests/cffi_tests/cffi0/test_verify.py
@@ -1,5 +1,6 @@
 # Generated by pypy/tool/import_cffi.py
 import py, re
+import pytest
 import sys, os, math, weakref
 from cffi import FFI, VerificationError, VerificationMissing, model, FFIError
 from extra_tests.cffi_tests.support import *
@@ -21,7 +22,8 @@
         extra_compile_args.append('-Qunused-arguments')
     else:
         # assume a standard gcc
-        extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion']
+        extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion',
+                              '-Wno-unused-parameter']
 
     class FFI(FFI):
         def verify(self, *args, **kwds):
@@ -590,7 +592,8 @@
     assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int')
     s = ffi.new("struct foo_s *")
     assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int')
-    py.test.raises(IndexError, 's.a[17]')
+    with pytest.raises(IndexError):
+        s.a[17]
 
 def test_struct_array_c99_1():
     if sys.platform == 'win32':
@@ -648,7 +651,8 @@
     ffi.verify("struct foo_s { int a:2, b:3; };")
     s = ffi.new("struct foo_s *")
     s.b = 3
-    py.test.raises(OverflowError, "s.b = 4")
+    with pytest.raises(OverflowError):
+        s.b = 4
     assert s.b == 3
 
 def test_struct_with_bitfield_enum():
@@ -1464,8 +1468,10 @@
     p = ffi.new("struct foo_s *")
     p.x = 1
     assert p.x is True
-    py.test.raises(OverflowError, "p.x = -1")
-    py.test.raises(TypeError, "p.x = 0.0")
+    with pytest.raises(OverflowError):
+        p.x = -1
+    with pytest.raises(TypeError):
+        p.x = 0.0
     assert lib.foop(1) is False
     assert lib.foop(True) is False
     assert lib.foop(0) is True
@@ -1533,7 +1539,8 @@
                 }
             """ % (type, type))
             p = ffi.new("struct foo_s *")
-            py.test.raises(TypeError, "p.x = 0.0")
+            with pytest.raises(TypeError):
+                p.x = 0.0
             assert lib.foo(42) == 0
             assert lib.foo(0) == 1
             py.test.raises(TypeError, lib.foo, 0.0)
@@ -2099,6 +2106,11 @@
             raise errors[0][1]
 
 def test_errno_working_even_with_pypys_jit():
+    # NOTE: on some platforms, to work correctly, this test needs to be
+    # compiled with -pthread.  Otherwise, the accesses to errno done from f()
+    # are compiled by assuming this small library won't be used from multiple
+    # threads, which is wrong.  If you see failures _and_ if you pass your
+    # own CFLAGS environment variable, please make sure "-pthread" is in it.
     ffi = FFI()
     ffi.cdef("int f(int);")
     lib = ffi.verify("""
diff --git a/extra_tests/cffi_tests/cffi1/test_ffi_obj.py b/extra_tests/cffi_tests/cffi1/test_ffi_obj.py
--- a/extra_tests/cffi_tests/cffi1/test_ffi_obj.py
+++ b/extra_tests/cffi_tests/cffi1/test_ffi_obj.py
@@ -1,5 +1,6 @@
 # Generated by pypy/tool/import_cffi.py
 import py, sys
+import pytest
 import _cffi_backend as _cffi1_backend
 
 
@@ -86,9 +87,12 @@
 
 def test_ffi_no_attr():
     ffi = _cffi1_backend.FFI()
-    py.test.raises(AttributeError, "ffi.no_such_name")
-    py.test.raises(AttributeError, "ffi.no_such_name = 42")
-    py.test.raises(AttributeError, "del ffi.no_such_name")
+    with pytest.raises(AttributeError):
+        ffi.no_such_name
+    with pytest.raises(AttributeError):
+        ffi.no_such_name = 42
+    with pytest.raises(AttributeError):
+        del ffi.no_such_name
 
 def test_ffi_string():
     ffi = _cffi1_backend.FFI()
diff --git a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py
--- a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py
+++ b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py
@@ -1,5 +1,6 @@
 # Generated by pypy/tool/import_cffi.py
 import py
+import pytest
 import platform, imp
 import sys, os, ctypes
 import cffi
@@ -187,10 +188,14 @@
         p[9] = 43
         assert p[0] == 42
         assert p[9] == 43
-        py.test.raises(IndexError, "p[10]")
-        py.test.raises(IndexError, "p[10] = 44")
-        py.test.raises(IndexError, "p[-1]")
-        py.test.raises(IndexError, "p[-1] = 44")
+        with pytest.raises(IndexError):
+            p[10]
+        with pytest.raises(IndexError):
+            p[10] = 44
+        with pytest.raises(IndexError):
+            p[-1]
+        with pytest.raises(IndexError):
+            p[-1] = 44
 
     def test_new_array_args(self):
         # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}"
@@ -213,18 +218,21 @@
     def test_new_array_varsize(self):
         p = ffi.new("int[]", 10)     # a single integer is the length
         assert p[9] == 0
-        py.test.raises(IndexError, "p[10]")
+        with pytest.raises(IndexError):
+            p[10]
         #
         py.test.raises(TypeError, ffi.new, "int[]")
         #
         p = ffi.new("int[]", [-6, -7])    # a list is all the items, like C
         assert p[0] == -6
         assert p[1] == -7
-        py.test.raises(IndexError, "p[2]")
+        with pytest.raises(IndexError):
+            p[2]
         assert repr(p) == "<cdata 'int[]' owning %d bytes>" % (2*SIZE_OF_INT)
         #
         p = ffi.new("int[]", 0)
-        py.test.raises(IndexError, "p[0]")
+        with pytest.raises(IndexError):
+            p[0]
         py.test.raises(ValueError, ffi.new, "int[]", -1)
         assert repr(p) == "<cdata 'int[]' owning 0 bytes>"
 
@@ -325,7 +333,8 @@
         p[2][3] = 33
         assert p[0][0] == 10
         assert p[2][3] == 33
-        py.test.raises(IndexError, "p[1][-1]")
+        with pytest.raises(IndexError):
+            p[1][-1]
 
     def test_constructor_array_of_array(self):
         p = ffi.new("int[3][2]", [[10, 11], [12, 13], [14, 15]])
@@ -446,7 +455,8 @@
         n = ffi.new("int*", 99)
         p = ffi.new("int*[]", [n])
         assert p[0][0] == 99
-        py.test.raises(TypeError, "p[0] = None")
+        with pytest.raises(TypeError):
+            p[0] = None
         p[0] = ffi.NULL
         assert p[0] == ffi.NULL
 
@@ -479,13 +489,15 @@
         assert s.a == s.b == s.c == 0
         s.b = -23
         assert s.b == -23
-        py.test.raises(OverflowError, "s.b = 32768")
+        with pytest.raises(OverflowError):
+            s.b = 32768
         #
         s = ffi.new("struct simple*", [-2, -3])
         assert s.a == -2
         assert s.b == -3
         assert s.c == 0
-        py.test.raises((AttributeError, TypeError), "del s.a")
+        with pytest.raises((AttributeError, TypeError)):
+            del s.a
         assert repr(s) == "<cdata 'struct simple *' owning %d bytes>" % (
             SIZE_OF_INT + 2 * SIZE_OF_SHORT)
         #
@@ -503,8 +515,10 @@
         assert s[0].a == s[0].b == s[0].c == 0
         s[0].b = -23
         assert s[0].b == s.b == -23
-        py.test.raises(OverflowError, "s[0].b = -32769")
-        py.test.raises(IndexError, "s[1]")
+        with pytest.raises(OverflowError):
+            s[0].b = -32769
+        with pytest.raises(IndexError):
+            s[1]
 
     def test_struct_opaque(self):
         py.test.raises(ffi.error, ffi.new, "struct baz*")
@@ -556,11 +570,13 @@
         u.b = -23
         assert u.b == -23
         assert u.a != 0
-        py.test.raises(OverflowError, "u.b = 32768")
+        with pytest.raises(OverflowError):
+            u.b = 32768
         #
         u = ffi.new("union simple_u*", [-2])
         assert u.a == -2
-        py.test.raises((AttributeError, TypeError), "del u.a")
+        with pytest.raises((AttributeError, TypeError)):
+            del u.a
         assert repr(u) == "<cdata 'union simple_u *' owning %d bytes>" % (
             SIZE_OF_INT,)
 
@@ -626,7 +642,8 @@
         p[3] = b'\x00'
         assert ffi.string(p) == b"hel"
         assert ffi.string(p, 2) == b"he"
-        py.test.raises(IndexError, "p[7] = b'X'")
+        with pytest.raises(IndexError):
+            p[7] = b'X'
         #
         a = ffi.new("char[]", b"hello\x00world")
         assert len(a) == 12
@@ -649,7 +666,8 @@
         p[3] = u+'\x00'
         assert ffi.string(p) == u+"hel"
         assert ffi.string(p, 123) == u+"hel"
-        py.test.raises(IndexError, "p[7] = u+'X'")
+        with pytest.raises(IndexError):
+            p[7] = u+'X'
         #
         a = ffi.new("wchar_t[]", u+"hello\x00world")
         assert len(a) == 12
@@ -665,7 +683,8 @@
         s = ffi.new("struct string*", [t])
         assert type(s.name) not in (bytes, str, unicode)
         assert ffi.string(s.name) == b"testing"
-        py.test.raises(TypeError, "s.name = None")
+        with pytest.raises(TypeError):
+            s.name = None
         s.name = ffi.NULL
         assert s.name == ffi.NULL
 
@@ -686,17 +705,20 @@
         a = ffi.new("int[]", [10, 11, 12])
         p = ffi.new("void **", a)
         vp = p[0]
-        py.test.raises(TypeError, "vp[0]")
+        with pytest.raises(TypeError):
+            vp[0]
         py.test.raises(TypeError, ffi.new, "short **", a)
         #
         s = ffi.new("struct voidp *")
         s.p = a    # works
         s.q = a    # works
-        py.test.raises(TypeError, "s.r = a")    # fails
+        with pytest.raises(TypeError):
+            s.r = a    # fails
         b = ffi.cast("int *", a)
         s.p = b    # works
         s.q = b    # works
-        py.test.raises(TypeError, "s.r = b")    # fails
+        with pytest.raises(TypeError):
+            s.r = b    # fails
 
     def test_functionptr_simple(self):
         py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0)
@@ -714,7 +736,8 @@
         q = ffi.new("int(**)(int)", p)
         assert repr(q) == "<cdata 'int(* *)(int)' owning %d bytes>" % (
             SIZE_OF_PTR)
-        py.test.raises(TypeError, "q(43)")
+        with pytest.raises(TypeError):
+            q(43)
         res = q[0](43)
         assert res == 44
         q = ffi.cast("int(*)(int)", p)
@@ -923,10 +946,14 @@
         assert s.e in (4294967295, -1)     # two choices
         assert s[0].e in (4294967295, -1)
         s.e = s.e
-        py.test.raises(TypeError, "s.e = 'B3'")
-        py.test.raises(TypeError, "s.e = '2'")
-        py.test.raises(TypeError, "s.e = '#2'")
-        py.test.raises(TypeError, "s.e = '#7'")
+        with pytest.raises(TypeError):
+            s.e = 'B3'
+        with pytest.raises(TypeError):
+            s.e = '2'
+        with pytest.raises(TypeError):
+            s.e = '#2'
+        with pytest.raises(TypeError):
+            s.e = '#7'
 
     def test_enum_non_contiguous(self):
         # enum noncont { A4, B4=42, C4 };
@@ -948,11 +975,14 @@
 
     def test_array_of_struct(self):
         s = ffi.new("struct ab[1]")
-        py.test.raises(AttributeError, 's.b')
-        py.test.raises(AttributeError, 's.b = 412')
+        with pytest.raises(AttributeError):
+            s.b
+        with pytest.raises(AttributeError):
+            s.b = 412
         s[0].b = 412
         assert s[0].b == 412
-        py.test.raises(IndexError, 's[1]')
+        with pytest.raises(IndexError):
+            s[1]
 
     def test_pointer_to_array(self):
         p = ffi.new("int(**)[5]")
@@ -1001,17 +1031,23 @@
         assert ffi.sizeof("struct bitfield") == 8
         s = ffi.new("struct bitfield *")
         s.a = 511
-        py.test.raises(OverflowError, "s.a = 512")
-        py.test.raises(OverflowError, "s[0].a = 512")
+        with pytest.raises(OverflowError):
+            s.a = 512
+        with pytest.raises(OverflowError):
+            s[0].a = 512
         assert s.a == 511
         s.a = -512
-        py.test.raises(OverflowError, "s.a = -513")
-        py.test.raises(OverflowError, "s[0].a = -513")
+        with pytest.raises(OverflowError):
+            s.a = -513
+        with pytest.raises(OverflowError):
+            s[0].a = -513
         assert s.a == -512
         s.c = 3
         assert s.c == 3
-        py.test.raises(OverflowError, "s.c = 4")
-        py.test.raises(OverflowError, "s[0].c = 4")
+        with pytest.raises(OverflowError):
+            s.c = 4
+        with pytest.raises(OverflowError):
+            s[0].c = 4
         s.c = -4
         assert s.c == -4
 
@@ -1236,7 +1272,8 @@
         p = ffi.new("struct foo_s *", 10)     # a single integer is the length
         assert p.len == 0
         assert p.data[9] == 0
-        py.test.raises(IndexError, "p.data[10]")
+        with pytest.raises(IndexError):
+            p.data[10]
 
     def test_ffi_typeof_getcname(self):
         assert ffi.getctype("int") == "int"
@@ -1753,7 +1790,8 @@
         assert MYFOO == 42
         assert myfunc(43) == 44
         assert myvar == -5     # but can't be changed, so not very useful
-        py.test.raises(ImportError, "from _test_import_from_lib.lib import bar")
+        with pytest.raises(ImportError):
+            from _test_import_from_lib.lib import bar
         d = {}
         exec("from _test_import_from_lib.lib import *", d)
         assert (set(key for key in d if not key.startswith('_')) ==
diff --git a/extra_tests/cffi_tests/cffi1/test_recompiler.py b/extra_tests/cffi_tests/cffi1/test_recompiler.py
--- a/extra_tests/cffi_tests/cffi1/test_recompiler.py
+++ b/extra_tests/cffi_tests/cffi1/test_recompiler.py
@@ -1,6 +1,7 @@
 # Generated by pypy/tool/import_cffi.py
 
 import sys, os, py
+import pytest
 from cffi import FFI, VerificationError, FFIError, CDefError
 from cffi import recompiler
 from extra_tests.cffi_tests.udir import udir
@@ -189,20 +190,26 @@
     assert lib.a == -2
     lib.a = -2147483648
     assert lib.a == -2147483648
-    py.test.raises(OverflowError, "lib.a = 2147483648")
-    py.test.raises(OverflowError, "lib.a = -2147483649")
+    with pytest.raises(OverflowError):
+        lib.a = 2147483648
+    with pytest.raises(OverflowError):
+        lib.a = -2147483649
     lib.b = 525      # try with the first access being in setattr, too
     assert lib.b == 525
-    py.test.raises(AttributeError, "del lib.a")
-    py.test.raises(AttributeError, "del lib.c")
-    py.test.raises(AttributeError, "del lib.foobarbaz")
+    with pytest.raises(AttributeError):
+        del lib.a
+    with pytest.raises(AttributeError):
+        del lib.c
+    with pytest.raises(AttributeError):
+        del lib.foobarbaz
 
 def test_macro():
     ffi = FFI()
     ffi.cdef("#define FOOBAR ...")
     lib = verify(ffi, 'test_macro', "#define FOOBAR (-6912)")
     assert lib.FOOBAR == -6912
-    py.test.raises(AttributeError, "lib.FOOBAR = 2")
+    with pytest.raises(AttributeError):
+        lib.FOOBAR = 2
 
 def test_macro_check_value():
     # the value '-0x80000000' in C sources does not have a clear meaning
@@ -248,7 +255,8 @@
     ffi.cdef("static const int FOOBAR;")
     lib = verify(ffi, 'test_constant', "#define FOOBAR (-6912)")
     assert lib.FOOBAR == -6912
-    py.test.raises(AttributeError, "lib.FOOBAR = 2")
+    with pytest.raises(AttributeError):
+        lib.FOOBAR = 2
 
 def test_check_value_of_static_const():
     ffi = FFI()
@@ -264,7 +272,8 @@
     ffi.cdef("static const double FOOBAR;")
     lib = verify(ffi, 'test_constant_nonint', "#define FOOBAR (-6912.5)")
     assert lib.FOOBAR == -6912.5
-    py.test.raises(AttributeError, "lib.FOOBAR = 2")
+    with pytest.raises(AttributeError):
+        lib.FOOBAR = 2
 
 def test_constant_ptr():
     ffi = FFI()
@@ -316,8 +325,10 @@
     p = ffi.new("struct foo_s *", {'a': -32768, 'b': -2147483648})
     assert p.a == -32768
     assert p.b == -2147483648
-    py.test.raises(OverflowError, "p.a -= 1")
-    py.test.raises(OverflowError, "p.b -= 1")
+    with pytest.raises(OverflowError):
+        p.a -= 1
+    with pytest.raises(OverflowError):
+        p.b -= 1
     q = ffi.new("struct bar_s *", {'f': p})
     assert q.f == p
     #
@@ -388,8 +399,10 @@
     assert ffi.sizeof("struct foo_s") == (42 + 11) * 4
     p = ffi.new("struct foo_s *")
     assert p.a[41] == p.b[10] == 0
-    py.test.raises(IndexError, "p.a[42]")
-    py.test.raises(IndexError, "p.b[11]")
+    with pytest.raises(IndexError):
+        p.a[42]
+    with pytest.raises(IndexError):
+        p.b[11]
 
 def test_dotdotdot_global_array():
     ffi = FFI()
@@ -399,8 +412,10 @@
     assert ffi.sizeof(lib.aa) == 41 * 4
     assert ffi.sizeof(lib.bb) == 12 * 4
     assert lib.aa[40] == lib.bb[11] == 0
-    py.test.raises(IndexError, "lib.aa[41]")
-    py.test.raises(IndexError, "lib.bb[12]")
+    with pytest.raises(IndexError):
+        lib.aa[41]
+    with pytest.raises(IndexError):
+        lib.bb[12]
 
 def test_misdeclared_field_1():
     ffi = FFI()
@@ -1021,8 +1036,10 @@
     assert ffi.typeof(s.a) == ffi.typeof("int[5][8]")
     assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int')
     assert s.a[4][7] == 0
-    py.test.raises(IndexError, 's.a[4][8]')
-    py.test.raises(IndexError, 's.a[5][0]')
+    with pytest.raises(IndexError):
+        s.a[4][8]
+    with pytest.raises(IndexError):
+        s.a[5][0]
     assert ffi.typeof(s.a) == ffi.typeof("int[5][8]")
     assert ffi.typeof(s.a[0]) == ffi.typeof("int[8]")
 
@@ -1035,7 +1052,8 @@
     s = ffi.new("struct foo_s *")
     assert ffi.typeof(s.a) == ffi.typeof("int[][7]")
     assert s.a[4][6] == 0
-    py.test.raises(IndexError, 's.a[4][7]')
+    with pytest.raises(IndexError):
+        s.a[4][7]
     assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]")
 
 def test_global_var_array_2():
@@ -1044,8 +1062,10 @@
     lib = verify(ffi, 'test_global_var_array_2', 'int a[10][8];')
     lib.a[9][7] = 123456
     assert lib.a[9][7] == 123456
-    py.test.raises(IndexError, 'lib.a[0][8]')
-    py.test.raises(IndexError, 'lib.a[10][0]')
+    with pytest.raises(IndexError):
+        lib.a[0][8]
+    with pytest.raises(IndexError):
+        lib.a[10][0]
     assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]")
     assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]")
 
@@ -1055,7 +1075,8 @@
     lib = verify(ffi, 'test_global_var_array_3', 'int a[10][8];')
     lib.a[9][7] = 123456
     assert lib.a[9][7] == 123456
-    py.test.raises(IndexError, 'lib.a[0][8]')
+    with pytest.raises(IndexError):
+        lib.a[0][8]
     assert ffi.typeof(lib.a) == ffi.typeof("int(*)[8]")
     assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]")
 
@@ -1065,8 +1086,10 @@
     lib = verify(ffi, 'test_global_var_array_4', 'int a[10][8];')
     lib.a[9][7] = 123456
     assert lib.a[9][7] == 123456
-    py.test.raises(IndexError, 'lib.a[0][8]')
-    py.test.raises(IndexError, 'lib.a[10][8]')
+    with pytest.raises(IndexError):
+        lib.a[0][8]
+    with pytest.raises(IndexError):
+        lib.a[10][8]
     assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]")
     assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]")
 
@@ -1339,7 +1362,8 @@
         #define aaa 42
     """)
     assert lib.aaa == 42
-    py.test.raises(AttributeError, "lib.aaa = 43")
+    with pytest.raises(AttributeError):
+        lib.aaa = 43
 
 def test_win32_calling_convention_0():
     ffi = FFI()
diff --git a/extra_tests/cffi_tests/cffi1/test_verify1.py b/extra_tests/cffi_tests/cffi1/test_verify1.py
--- a/extra_tests/cffi_tests/cffi1/test_verify1.py
+++ b/extra_tests/cffi_tests/cffi1/test_verify1.py
@@ -1,5 +1,6 @@
 # Generated by pypy/tool/import_cffi.py
 import os, sys, math, py
+import pytest
 from cffi import FFI, FFIError, VerificationError, VerificationMissing, model
 from cffi import CDefError
 from cffi import recompiler
@@ -23,7 +24,8 @@
         extra_compile_args.append('-Qunused-arguments')
     else:
         # assume a standard gcc
-        extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion']
+        extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion',
+                              '-Wno-unused-parameter']
 
 class FFI(FFI):
     error = _cffi_backend.FFI.error
@@ -572,7 +574,8 @@
     assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int')
     s = ffi.new("struct foo_s *")
     assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int')
-    py.test.raises(IndexError, 's.a[17]')
+    with pytest.raises(IndexError):
+        s.a[17]
 
 def test_struct_array_c99_1():
     if sys.platform == 'win32':
@@ -630,7 +633,8 @@
     ffi.verify("struct foo_s { int a:2, b:3; };")
     s = ffi.new("struct foo_s *")
     s.b = 3
-    py.test.raises(OverflowError, "s.b = 4")
+    with pytest.raises(OverflowError):
+        s.b = 4
     assert s.b == 3
 
 def test_struct_with_bitfield_enum():
@@ -1434,8 +1438,10 @@
     p = ffi.new("struct foo_s *")
     p.x = 1
     assert p.x is True
-    py.test.raises(OverflowError, "p.x = -1")
-    py.test.raises(TypeError, "p.x = 0.0")
+    with pytest.raises(OverflowError):
+        p.x = -1
+    with pytest.raises(TypeError):
+        p.x = 0.0
     assert lib.foop(1) is False
     assert lib.foop(True) is False
     assert lib.foop(0) is True
@@ -1503,7 +1509,8 @@
                 }
             """ % (type, type))
             p = ffi.new("struct foo_s *")
-            py.test.raises(TypeError, "p.x = 0.0")
+            with pytest.raises(TypeError):
+                p.x = 0.0
             assert lib.foo(42) == 0
             assert lib.foo(0) == 1
             py.test.raises(TypeError, lib.foo, 0.0)
@@ -2194,7 +2201,8 @@
     ffi = FFI()
     ffi.cdef("#define FOO 123")
     lib = ffi.verify("#define FOO 124")     # used to complain
-    e = py.test.raises(ffi.error, "lib.FOO")
+    with pytest.raises(ffi.error) as e:
+        lib.FOO
     assert str(e.value) == ("the C compiler says 'FOO' is equal to 124 (0x7c),"
                             " but the cdef disagrees")
 
diff --git a/extra_tests/cffi_tests/embedding/test_basic.py b/extra_tests/cffi_tests/embedding/test_basic.py
--- a/extra_tests/cffi_tests/embedding/test_basic.py
+++ b/extra_tests/cffi_tests/embedding/test_basic.py
@@ -173,7 +173,8 @@
         result = popen.stdout.read()
         err = popen.wait()
         if err:
-            raise OSError("%r failed with exit code %r" % (name, err))
+            raise OSError("%r failed with exit code %r" % (
+                os.path.join(path, executable_name), err))
         return result
 
 
diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h
--- a/lib_pypy/cffi/_embedding.h
+++ b/lib_pypy/cffi/_embedding.h
@@ -169,8 +169,10 @@
     global_dict = PyDict_New();
     if (global_dict == NULL)
         goto error;
-    if (PyDict_SetItemString(global_dict, "__builtins__",
-                             PyThreadState_GET()->interp->builtins) < 0)
+    PyObject *builtins = PyEval_GetBuiltins();
+    if (builtins == NULL)
+        goto error;
+    if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0)
         goto error;
     x = PyEval_EvalCode(
 #if PY_MAJOR_VERSION < 3
@@ -263,23 +265,33 @@
        So we use a global variable as a simple spin lock.  This global
        variable must be from 'libpythonX.Y.so', not from this
        cffi-based extension module, because it must be shared from
-       different cffi-based extension modules.  We choose
+       different cffi-based extension modules.
+
+       In Python < 3.8, we choose
        _PyParser_TokenNames[0] as a completely arbitrary pointer value
        that is never written to.  The default is to point to the
        string "ENDMARKER".  We change it temporarily to point to the
        next character in that string.  (Yes, I know it's REALLY
        obscure.)
+
+       In Python >= 3.8, this string array is no longer writable, so
+       instead we pick PyCapsuleType.tp_version_tag.  We can't change
+       Python < 3.8 because someone might use a mixture of cffi
+       embedded modules, some of which were compiled before this file
+       changed.
     */
 
 #ifdef WITH_THREAD
+# if PY_VERSION_HEX < 0x03080000
     char *volatile *lock = (char *volatile *)_PyParser_TokenNames;
-    char *old_value;
+    char *old_value, *locked_value;
 
     while (1) {    /* spin loop */
         old_value = *lock;
+        locked_value = old_value + 1;
         if (old_value[0] == 'E') {
             assert(old_value[1] == 'N');
-            if (cffi_compare_and_swap(lock, old_value, old_value + 1))
+            if (cffi_compare_and_swap(lock, old_value, locked_value))
                 break;
         }
         else {
@@ -290,6 +302,27 @@
                this is only run at start-up anyway. */
         }
     }
+# else
+    int volatile *lock = (int volatile *)&PyCapsule_Type.tp_version_tag;
+    int old_value, locked_value;
+    assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG));
+
+    while (1) {    /* spin loop */
+        old_value = *lock;
+        locked_value = -42;
+        if (old_value == 0) {
+            if (cffi_compare_and_swap(lock, old_value, locked_value))
+                break;
+        }
+        else {
+            assert(old_value == locked_value);
+            /* should ideally do a spin loop instruction here, but
+               hard to do it portably and doesn't really matter I
+               think: PyEval_InitThreads() should be very fast, and
+               this is only run at start-up anyway. */
+        }
+    }
+# endif
 #endif
 
     /* call Py_InitializeEx() */
@@ -306,7 +339,7 @@
 
 #ifdef WITH_THREAD
     /* release the lock */
-    while (!cffi_compare_and_swap(lock, old_value + 1, old_value))
+    while (!cffi_compare_and_swap(lock, locked_value, old_value))
         ;
 #endif
 
diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py
--- a/lib_pypy/cffi/cparser.py
+++ b/lib_pypy/cffi/cparser.py
@@ -817,12 +817,20 @@
         # or positive/negative number
         if isinstance(exprnode, pycparser.c_ast.Constant):
             s = exprnode.value
-            if s.startswith('0'):
-                if s.startswith('0x') or s.startswith('0X'):
-                    return int(s, 16)
-                return int(s, 8)
-            elif '1' <= s[0] <= '9':
-                return int(s, 10)
+            if '0' <= s[0] <= '9':
+                s = s.rstrip('uUlL')
+                try:
+                    if s.startswith('0'):
+                        return int(s, 8)
+                    else:
+                        return int(s, 10)
+                except ValueError:
+                    if len(s) > 1:
+                        if s.lower()[0:2] == '0x':
+                            return int(s, 16)
+                        elif s.lower()[0:2] == '0b':
+                            return int(s, 2)
+                raise CDefError("invalid constant %r" % (s,))
             elif s[0] == "'" and s[-1] == "'" and (
                     len(s) == 3 or (len(s) == 4 and s[1] == "\\")):
                 return ord(s[-2])
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -304,8 +304,10 @@
     assert p[0] == 0
     p = newp(BPtr, 5000)
     assert p[0] == 5000
-    py.test.raises(IndexError, "p[1]")
-    py.test.raises(IndexError, "p[-1]")
+    with pytest.raises(IndexError):
+        p[1]
+    with pytest.raises(IndexError):
+        p[-1]
 
 def test_reading_pointer_to_float():
     BFloat = new_primitive_type("float")
@@ -433,7 +435,8 @@
 def test_invalid_indexing():
     p = new_primitive_type("int")
     x = cast(p, 42)
-    py.test.raises(TypeError, "x[0]")
+    with pytest.raises(TypeError):
+        x[0]
 
 def test_default_str():
     BChar = new_primitive_type("char")
@@ -526,13 +529,16 @@
     assert len(a) == LENGTH
     for i in range(LENGTH):
         assert a[i] == 0
-    py.test.raises(IndexError, "a[LENGTH]")
-    py.test.raises(IndexError, "a[-1]")
+    with pytest.raises(IndexError):
+        a[LENGTH]
+    with pytest.raises(IndexError):
+        a[-1]
     for i in range(LENGTH):
         a[i] = i * i + 1
     for i in range(LENGTH):
         assert a[i] == i * i + 1
-    e = py.test.raises(IndexError, "a[LENGTH+100] = 500")
+    with pytest.raises(IndexError) as e:
+        a[LENGTH+100] = 500
     assert ('(expected %d < %d)' % (LENGTH+100, LENGTH)) in str(e.value)
     py.test.raises(TypeError, int, a)
 
@@ -547,10 +553,14 @@
         a[i] -= i
     for i in range(42):
         assert a[i] == -i
-    py.test.raises(IndexError, "a[42]")
-    py.test.raises(IndexError, "a[-1]")
-    py.test.raises(IndexError, "a[42] = 123")
-    py.test.raises(IndexError, "a[-1] = 456")
+    with pytest.raises(IndexError):
+        a[42]
+    with pytest.raises(IndexError):
+        a[-1]
+    with pytest.raises(IndexError):
+        a[42] = 123
+    with pytest.raises(IndexError):
+        a[-1] = 456
 
 def test_array_of_unknown_length_instance_with_initializer():
     p = new_primitive_type("int")
@@ -598,10 +608,14 @@
     assert a == (p - 1)
     BPtr = new_pointer_type(new_primitive_type("short"))
     q = newp(BPtr, None)
-    py.test.raises(TypeError, "p - q")
-    py.test.raises(TypeError, "q - p")
-    py.test.raises(TypeError, "a - q")
-    e = py.test.raises(TypeError, "q - a")
+    with pytest.raises(TypeError):
+        p - q
+    with pytest.raises(TypeError):
+        q - p
+    with pytest.raises(TypeError):
+        a - q
+    with pytest.raises(TypeError) as e:
+        q - a
     assert str(e.value) == "cannot subtract cdata 'short *' and cdata 'int *'"
 
 def test_ptr_sub_unaligned():
@@ -614,8 +628,10 @@
             assert b - a == (bi - 1240) // size_of_int()
             assert a - b == (1240 - bi) // size_of_int()
         else:
-            py.test.raises(ValueError, "b - a")
-            py.test.raises(ValueError, "a - b")
+            with pytest.raises(ValueError):
+                b - a
+            with pytest.raises(ValueError):
+                a - b
 
 def test_cast_primitive_from_cdata():
     p = new_primitive_type("int")
@@ -766,10 +782,12 @@
     BStruct = new_struct_type("struct foo")
     BStructPtr = new_pointer_type(BStruct)
     p = cast(BStructPtr, 42)
-    e = py.test.raises(AttributeError, "p.a1")    # opaque
+    with pytest.raises(AttributeError) as e:
+        p.a1    # opaque
     assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: "
                             "cannot read fields")
-    e = py.test.raises(AttributeError, "p.a1 = 10")    # opaque
+    with pytest.raises(AttributeError) as e:
+        p.a1 = 10    # opaque
     assert str(e.value) == ("cdata 'struct foo *' points to an opaque type: "
                             "cannot write fields")
 
@@ -781,30 +799,41 @@
     s.a2 = 123
     assert s.a1 == 0
     assert s.a2 == 123
-    py.test.raises(OverflowError, "s.a1 = sys.maxsize+1")
+    with pytest.raises(OverflowError):
+        s.a1 = sys.maxsize+1
     assert s.a1 == 0
-    e = py.test.raises(AttributeError, "p.foobar")
+    with pytest.raises(AttributeError) as e:
+        p.foobar
     assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'"
-    e = py.test.raises(AttributeError, "p.foobar = 42")
+    with pytest.raises(AttributeError) as e:
+        p.foobar = 42
     assert str(e.value) == "cdata 'struct foo *' has no field 'foobar'"
-    e = py.test.raises(AttributeError, "s.foobar")
+    with pytest.raises(AttributeError) as e:
+        s.foobar
     assert str(e.value) == "cdata 'struct foo' has no field 'foobar'"
-    e = py.test.raises(AttributeError, "s.foobar = 42")
+    with pytest.raises(AttributeError) as e:
+        s.foobar = 42
     assert str(e.value) == "cdata 'struct foo' has no field 'foobar'"
     j = cast(BInt, 42)
-    e = py.test.raises(AttributeError, "j.foobar")
+    with pytest.raises(AttributeError) as e:
+        j.foobar
     assert str(e.value) == "cdata 'int' has no attribute 'foobar'"
-    e = py.test.raises(AttributeError, "j.foobar = 42")
+    with pytest.raises(AttributeError) as e:
+        j.foobar = 42
     assert str(e.value) == "cdata 'int' has no attribute 'foobar'"
     j = cast(new_pointer_type(BInt), 42)
-    e = py.test.raises(AttributeError, "j.foobar")
+    with pytest.raises(AttributeError) as e:
+        j.foobar
     assert str(e.value) == "cdata 'int *' has no attribute 'foobar'"
-    e = py.test.raises(AttributeError, "j.foobar = 42")
+    with pytest.raises(AttributeError) as e:
+        j.foobar = 42
     assert str(e.value) == "cdata 'int *' has no attribute 'foobar'"
     pp = newp(new_pointer_type(BStructPtr), p)
-    e = py.test.raises(AttributeError, "pp.a1")
+    with pytest.raises(AttributeError) as e:
+        pp.a1
     assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'"
-    e = py.test.raises(AttributeError, "pp.a1 = 42")
+    with pytest.raises(AttributeError) as e:
+        pp.a1 = 42
     assert str(e.value) == "cdata 'struct foo * *' has no attribute 'a1'"
 
 def test_union_instance():
@@ -1625,7 +1654,8 @@
     assert ("an integer is required" in msg or  # CPython
             "unsupported operand type for int(): 'NoneType'" in msg or  # old PyPys
             "expected integer, got NoneType object" in msg) # newer PyPys
-    py.test.raises(TypeError, 'p.a1 = "def"')
+    with pytest.raises(TypeError):
+        p.a1 = "def"
     if sys.version_info < (3,):
         BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,), BInt)
         assert string(cast(BEnum2, 5)) == 'abc'
@@ -1755,14 +1785,17 @@
     p.a1 = -1
     assert p.a1 == -1
     p.a1 = 0
-    py.test.raises(OverflowError, "p.a1 = 2")
+    with pytest.raises(OverflowError):
+        p.a1 = 2
     assert p.a1 == 0
     #
     p.a1 = -1
     p.a2 = 3
     p.a3 = -4
-    py.test.raises(OverflowError, "p.a3 = 4")
-    e = py.test.raises(OverflowError, "p.a3 = -5")
+    with pytest.raises(OverflowError):
+        p.a3 = 4
+    with pytest.raises(OverflowError) as e:
+        p.a3 = -5
     assert str(e.value) == ("value -5 outside the range allowed by the "
                             "bit field width: -4 <= x <= 3")
     assert p.a1 == -1 and p.a2 == 3 and p.a3 == -4
@@ -1771,7 +1804,8 @@
     # allows also setting the value "1" (it still gets read back as -1)
     p.a1 = 1
     assert p.a1 == -1
-    e = py.test.raises(OverflowError, "p.a1 = -2")
+    with pytest.raises(OverflowError) as e:
+        p.a1 = -2
     assert str(e.value) == ("value -2 outside the range allowed by the "
                             "bit field width: -1 <= x <= 1")
 
@@ -1831,14 +1865,17 @@
     assert string(a[2]) == b"."
     a[2] = b"12345"
     assert string(a[2]) == b"12345"
-    e = py.test.raises(IndexError, 'a[2] = b"123456"')
+    with pytest.raises(IndexError) as e:
+        a[2] = b"123456"
     assert 'char[5]' in str(e.value)
     assert 'got 6 characters' in str(e.value)
 
 def test_add_error():
     x = cast(new_primitive_type("int"), 42)
-    py.test.raises(TypeError, "x + 1")
-    py.test.raises(TypeError, "x - 1")
+    with pytest.raises(TypeError):
+        x + 1
+    with pytest.raises(TypeError):
+        x - 1
 
 def test_void_errors():
     py.test.raises(ValueError, alignof, new_void_type())
@@ -2170,8 +2207,10 @@
     s = newp(BStructPtr)
     s.a1 = u+'\x00'
     assert s.a1 == u+'\x00'
-    py.test.raises(TypeError, "s.a1 = b'a'")
-    py.test.raises(TypeError, "s.a1 = bytechr(0xFF)")
+    with pytest.raises(TypeError):
+        s.a1 = b'a'
+    with pytest.raises(TypeError):
+        s.a1 = bytechr(0xFF)
     s.a1 = u+'\u1234'
     assert s.a1 == u+'\u1234'
     if pyuni4:
@@ -2185,7 +2224,8 @@
             s.a1 = u+'\ud807\udf44'
             assert s.a1 == u+'\U00011f44'
     else:
-        py.test.raises(TypeError, "s.a1 = u+'\U00012345'")
+        with pytest.raises(TypeError):
+            s.a1 = u+'\U00012345'
     #
     BWCharArray = new_array_type(BWCharP, None)
     a = newp(BWCharArray, u+'hello \u1234 world')
@@ -2209,7 +2249,8 @@
         assert list(a) == expected
         got = [a[i] for i in range(4)]
         assert got == expected
-        py.test.raises(IndexError, 'a[4]')
+        with pytest.raises(IndexError):
+            a[4]
     #
     w = cast(BWChar, 'a')
     assert repr(w) == "<cdata '%s' %s'a'>" % (typename, mandatory_u_prefix)
@@ -2341,9 +2382,11 @@
 def test_cannot_dereference_void():
     BVoidP = new_pointer_type(new_void_type())
     p = cast(BVoidP, 123456)
-    py.test.raises(TypeError, "p[0]")
+    with pytest.raises(TypeError):
+        p[0]
     p = cast(BVoidP, 0)
-    py.test.raises((TypeError, RuntimeError), "p[0]")
+    with pytest.raises((TypeError, RuntimeError)):
+        p[0]
 
 def test_iter():
     BInt = new_primitive_type("int")
@@ -2366,12 +2409,12 @@
     assert (q == p) is False
     assert (q != p) is True
     if strict_compare:
-        py.test.raises(TypeError, "p < q")
-        py.test.raises(TypeError, "p <= q")
-        py.test.raises(TypeError, "q < p")
-        py.test.raises(TypeError, "q <= p")
-        py.test.raises(TypeError, "p > q")
-        py.test.raises(TypeError, "p >= q")
+        with pytest.raises(TypeError): p < q
+        with pytest.raises(TypeError): p <= q
+        with pytest.raises(TypeError): q < p
+        with pytest.raises(TypeError): q <= p
+        with pytest.raises(TypeError): p > q
+        with pytest.raises(TypeError): p >= q
     r = cast(BVoidP, p)
     assert (p <  r) is False
     assert (p <= r) is True
@@ -2417,7 +2460,8 @@
         try:
             expected = b"hi there\x00"[i]
         except IndexError:
-            py.test.raises(IndexError, "buf[i]")
+            with pytest.raises(IndexError):
+                buf[i]
         else:
             assert buf[i] == bitem2bchr(expected)
     # --mb_slice--
@@ -2444,15 +2488,18 @@
         try:
             expected[i] = bytechr(i & 0xff)
         except IndexError:
-            py.test.raises(IndexError, "buf[i] = bytechr(i & 0xff)")
+            with pytest.raises(IndexError):
+                buf[i] = bytechr(i & 0xff)
         else:
             buf[i] = bytechr(i & 0xff)
         assert list(buf) == expected
     # --mb_ass_slice--
     buf[:] = b"hi there\x00"
     assert list(buf) == list(c) == list(map(bitem2bchr, b"hi there\x00"))
-    py.test.raises(ValueError, 'buf[:] = b"shorter"')
-    py.test.raises(ValueError, 'buf[:] = b"this is much too long!"')
+    with pytest.raises(ValueError):
+        buf[:] = b"shorter"
+    with pytest.raises(ValueError):
+        buf[:] = b"this is much too long!"
     buf[4:2] = b""   # no effect, but should work
     assert buf[:] == b"hi there\x00"
     buf[:2] = b"HI"
@@ -2526,14 +2573,16 @@
     BChar = new_primitive_type("char")
     BCharP = new_pointer_type(BChar)
     x = newp(BCharP)
-    py.test.raises(TypeError, "del x[0]")
+    with pytest.raises(TypeError):
+        del x[0]
 
 def test_bug_delattr():
     BLong = new_primitive_type("long")
     BStruct = new_struct_type("struct foo")
     complete_struct_or_union(BStruct, [('a1', BLong, -1)])
     x = newp(new_pointer_type(BStruct))
-    py.test.raises(AttributeError, "del x.a1")
+    with pytest.raises(AttributeError):
+        del x.a1
 
 def test_variable_length_struct():
     py.test.skip("later")
@@ -2551,7 +2600,8 @@
     assert sizeof(x) == 6 * size_of_long()
     x[4] = 123
     assert x[4] == 123
-    py.test.raises(IndexError, "x[5]")
+    with pytest.raises(IndexError):
+        x[5]
     assert len(x.a2) == 5
     #
     py.test.raises(TypeError, newp, BStructP, [123])
@@ -2803,7 +2853,8 @@
     BCharP = new_pointer_type(new_primitive_type("char"))
     p = newp(BCharP, b'X')
     q = cast(BBoolP, p)
-    py.test.raises(ValueError, "q[0]")
+    with pytest.raises(ValueError):
+        q[0]
     py.test.raises(TypeError, newp, BBoolP, b'\x00')
     assert newp(BBoolP, 0)[0] is False
     assert newp(BBoolP, 1)[0] is True
@@ -3103,8 +3154,10 @@
     assert c[1] == 123
     assert c[3] == 456
     assert d[2] == 456
-    py.test.raises(IndexError, "d[3]")
-    py.test.raises(IndexError, "d[-1]")
+    with pytest.raises(IndexError):
+        d[3]
+    with pytest.raises(IndexError):
+        d[-1]
 
 def test_slice_ptr():
     BIntP = new_pointer_type(new_primitive_type("int"))
@@ -3122,7 +3175,8 @@
     c = newp(BIntArray, 5)
     c[0:5]
     assert len(c[5:5]) == 0
-    py.test.raises(IndexError, "c[-1:1]")
+    with pytest.raises(IndexError):
+        c[-1:1]
     cp = c + 0
     cp[-1:1]
 
@@ -3130,17 +3184,23 @@
     BIntP = new_pointer_type(new_primitive_type("int"))
     BIntArray = new_array_type(BIntP, None)
     c = newp(BIntArray, 5)
-    e = py.test.raises(IndexError, "c[:5]")
+    with pytest.raises(IndexError) as e:
+        c[:5]
     assert str(e.value) == "slice start must be specified"
-    e = py.test.raises(IndexError, "c[4:]")
+    with pytest.raises(IndexError) as e:
+        c[4:]
     assert str(e.value) == "slice stop must be specified"
-    e = py.test.raises(IndexError, "c[1:2:3]")
+    with pytest.raises(IndexError) as e:
+        c[1:2:3]
     assert str(e.value) == "slice with step not supported"
-    e = py.test.raises(IndexError, "c[1:2:1]")
+    with pytest.raises(IndexError) as e:
+        c[1:2:1]
     assert str(e.value) == "slice with step not supported"
-    e = py.test.raises(IndexError, "c[4:2]")
+    with pytest.raises(IndexError) as e:
+        c[4:2]
     assert str(e.value) == "slice start > stop"
-    e = py.test.raises(IndexError, "c[6:6]")
+    with pytest.raises(IndexError) as e:
+        c[6:6]
     assert str(e.value) == "index too large (expected 6 <= 5)"
 
 def test_setslice():
@@ -3154,9 +3214,11 @@
     assert list(c) == [0, 100, 300, 400, 0]
     cp[-1:1] = iter([500, 600])
     assert list(c) == [0, 100, 500, 600, 0]
-    py.test.raises(ValueError, "cp[-1:1] = [1000]")
+    with pytest.raises(ValueError):
+        cp[-1:1] = [1000]
     assert list(c) == [0, 100, 1000, 600, 0]
-    py.test.raises(ValueError, "cp[-1:1] = (700, 800, 900)")
+    with pytest.raises(ValueError):
+        cp[-1:1] = (700, 800, 900)
     assert list(c) == [0, 100, 700, 800, 0]
 
 def test_setslice_array():
@@ -3416,10 +3478,14 @@
     assert sizeof(q[0]) == sizeof(BStruct)
     #
     # error cases
-    py.test.raises(IndexError, "p.y[4]")
-    py.test.raises(TypeError, "p.y = cast(BIntP, 0)")
-    py.test.raises(TypeError, "p.y = 15")
-    py.test.raises(TypeError, "p.y = None")
+    with pytest.raises(IndexError):
+        p.y[4]
+    with pytest.raises(TypeError):
+        p.y = cast(BIntP, 0)
+    with pytest.raises(TypeError):
+        p.y = 15
+    with pytest.raises(TypeError):
+        p.y = None
     #
     # accepting this may be specified by the C99 standard,
     # or a GCC strangeness...
@@ -3524,8 +3590,10 @@
     p[2:5] = [b"*", b"Z", b"T"]
     p[1:3] = b"XY"
     assert list(p) == [b"f", b"X", b"Y", b"Z", b"T", b"r", b"\x00"]
-    py.test.raises(TypeError, "p[1:5] = u+'XYZT'")
-    py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]")
+    with pytest.raises(TypeError):
+        p[1:5] = u+'XYZT'
+    with pytest.raises(TypeError):
+        p[1:5] = [1, 2, 3, 4]
     #
     for typename in ["wchar_t", "char16_t", "char32_t"]:
         BUniChar = new_primitive_type(typename)
@@ -3534,8 +3602,10 @@
         p[2:5] = [u+"*", u+"Z", u+"T"]
         p[1:3] = u+"XY"
         assert list(p) == [u+"f", u+"X", u+"Y", u+"Z", u+"T", u+"r", u+"\x00"]
-        py.test.raises(TypeError, "p[1:5] = b'XYZT'")
-        py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]")
+        with pytest.raises(TypeError):
+            p[1:5] = b'XYZT'
+        with pytest.raises(TypeError):
+            p[1:5] = [1, 2, 3, 4]
 
 def test_void_p_arithmetic():
     BVoid = new_void_type()
@@ -3546,10 +3616,14 @@
     assert int(cast(BInt, p - (-42))) == 100042
     assert (p + 42) - p == 42
     q = cast(new_pointer_type(new_primitive_type("char")), 100000)
-    py.test.raises(TypeError, "p - q")
-    py.test.raises(TypeError, "q - p")
-    py.test.raises(TypeError, "p + cast(new_primitive_type('int'), 42)")
-    py.test.raises(TypeError, "p - cast(new_primitive_type('int'), 42)")
+    with pytest.raises(TypeError):
+        p - q
+    with pytest.raises(TypeError):
+        q - p
+    with pytest.raises(TypeError):
+        p + cast(new_primitive_type('int'), 42)
+    with pytest.raises(TypeError):
+        p - cast(new_primitive_type('int'), 42)
 
 def test_sizeof_sliced_array():
     BInt = new_primitive_type("int")
@@ -3764,8 +3838,10 @@
     assert p1[0] == lst[0]
     assert p1[1] == lst[1]
     assert p1[2] == lst[2]
-    py.test.raises(IndexError, "p1[3]")
-    py.test.raises(IndexError, "p1[-1]")
+    with pytest.raises(IndexError):
+        p1[3]
+    with pytest.raises(IndexError):
+        p1[-1]
     #
     py.test.raises(TypeError, from_buffer, BInt, bytestring)
     py.test.raises(TypeError, from_buffer, BIntP, bytestring)
@@ -3776,8 +3852,10 @@
     assert len(p2) == 2
     assert p2[0] == lst[0]
     assert p2[1] == lst[1]
-    py.test.raises(IndexError, "p2[2]")
-    py.test.raises(IndexError, "p2[-1]")
+    with pytest.raises(IndexError):
+        p2[2]
+    with pytest.raises(IndexError):
+        p2[-1]
     assert p2 == p1
     #
     BIntA4 = new_array_type(BIntP, 4)        # int[4]: too big
@@ -3793,7 +3871,8 @@
     assert typeof(p1) is BStructA
     assert p1[0].a1 == lst[0]
     assert p1[0].a2 == lst[1]
-    py.test.raises(IndexError, "p1[1]")
+    with pytest.raises(IndexError):
+        p1[1]
     #
     BEmptyStruct = new_struct_type("empty")
     complete_struct_or_union(BEmptyStruct, [], Ellipsis, 0)
@@ -3885,10 +3964,14 @@
     BInt = new_primitive_type("int")
     BIntPtr = new_pointer_type(BInt)
     p = cast(BIntPtr, 0)
-    py.test.raises(RuntimeError, "p[0]")
-    py.test.raises(RuntimeError, "p[0] = 42")
-    py.test.raises(RuntimeError, "p[42]")
-    py.test.raises(RuntimeError, "p[42] = -1")
+    with pytest.raises(RuntimeError):
+        p[0]
+    with pytest.raises(RuntimeError):
+        p[0] = 42
+    with pytest.raises(RuntimeError):
+        p[42]
+    with pytest.raises(RuntimeError):
+        p[42] = -1
 
 def test_mixup():
     BStruct1 = new_struct_type("foo")
@@ -3904,10 +3987,12 @@
     pp2 = newp(BStruct2PtrPtr)
     pp3 = newp(BStruct3PtrPtr)
     pp1[0] = pp1[0]
-    e = py.test.raises(TypeError, "pp3[0] = pp1[0]")
+    with pytest.raises(TypeError) as e:
+        pp3[0] = pp1[0]
     assert str(e.value).startswith("initializer for ctype 'bar *' must be a ")
     assert str(e.value).endswith(", not cdata 'foo *'")
-    e = py.test.raises(TypeError, "pp2[0] = pp1[0]")
+    with pytest.raises(TypeError) as e:
+        pp2[0] = pp1[0]
     assert str(e.value) == ("initializer for ctype 'foo *' appears indeed to "
                             "be 'foo *', but the types are different (check "
                             "that you are not e.g. mixing up different ffi "
@@ -4096,14 +4181,14 @@
         assert (a != b) is True
         assert (b != a) is True
         if strict_compare:
-            py.test.raises(TypeError, "a < b")
-            py.test.raises(TypeError, "a <= b")
-            py.test.raises(TypeError, "a > b")
-            py.test.raises(TypeError, "a >= b")
-            py.test.raises(TypeError, "b < a")
-            py.test.raises(TypeError, "b <= a")
-            py.test.raises(TypeError, "b > a")
-            py.test.raises(TypeError, "b >= a")
+            with pytest.raises(TypeError): a < b
+            with pytest.raises(TypeError): a <= b
+            with pytest.raises(TypeError): a > b
+            with pytest.raises(TypeError): a >= b
+            with pytest.raises(TypeError): b < a
+            with pytest.raises(TypeError): b <= a
+            with pytest.raises(TypeError): b > a
+            with pytest.raises(TypeError): b >= a
         elif a < b:
             assert_lt(a, b)
         else:
@@ -4149,7 +4234,8 @@
     BIntP = new_pointer_type(new_primitive_type("int"))
     p = newp(BIntP)
     p[0] = 42
-    py.test.raises(IndexError, "p[1]")
+    with pytest.raises(IndexError):
+        p[1]
     release(p)
     # here, reading p[0] might give garbage or segfault...
     release(p)   # no effect
@@ -4185,8 +4271,12 @@
 def test_explicit_release_badtype_contextmgr():
     BIntP = new_pointer_type(new_primitive_type("int"))
     p = cast(BIntP, 12345)
-    py.test.raises(ValueError, "with p: pass")
-    py.test.raises(ValueError, "with p: pass")
+    with pytest.raises(ValueError):
+        with p:
+            pass
+    with pytest.raises(ValueError):
+        with p:
+            pass
 
 def test_explicit_release_gc():
     BIntP = new_pointer_type(new_primitive_type("int"))
@@ -4246,7 +4336,8 @@
     BCharA = new_array_type(BCharP, None)
     a += b't' * 10
     p = from_buffer(BCharA, a)
-    py.test.raises(BufferError, "a += b'u' * 100")
+    with pytest.raises(BufferError):
+        a += b'u' * 100
     release(p)
     a += b'v' * 100
     release(p)   # no effect
diff --git a/pypy/module/_cffi_backend/test/test_c.py b/pypy/module/_cffi_backend/test/test_c.py
--- a/pypy/module/_cffi_backend/test/test_c.py
+++ b/pypy/module/_cffi_backend/test/test_c.py
@@ -124,6 +124,7 @@
     print >> f, '    class test:'
     print >> f, '        raises = staticmethod(raises)'
     print >> f, '        skip = staticmethod(skip)'
+    print >> f, 'pytest = py.test'
     print >> f, backend_test_c.read()
 
 
diff --git a/pypy/tool/pytest/appsupport.py b/pypy/tool/pytest/appsupport.py
--- a/pypy/tool/pytest/appsupport.py
+++ b/pypy/tool/pytest/appsupport.py
@@ -1,7 +1,7 @@
 from inspect import CO_VARARGS, CO_VARKEYWORDS
 
 import py
-from pypy.interpreter import gateway, pycode
+from pypy.interpreter import gateway, pycode, typedef, baseobjspace
 from pypy.interpreter.error import OperationError, oefmt
 
 try:
@@ -227,8 +227,42 @@
     finally:
         frame.last_exception = old
 
-def pypyraises(space, w_ExpectedException, w_expr, __args__):
+
+class W_RaisesContextManager(baseobjspace.W_Root):
+    # Note: this is here because of _cffi_backend/test/test_c.py
+    def __init__(self, space, w_ExpectedException):
+        self.space = space
+        self.w_ExpectedException = w_ExpectedException
+
+    def enter(self):
+        return self
+
+    def exit(self, w_exc_type, w_exc_value, w_traceback):
+        space = self.space
+        if space.is_none(w_exc_type):
+            self.report_error("no exception")
+        if not space.exception_match(w_exc_type, self.w_ExpectedException):
+            self.report_error(space.text_w(space.repr(w_exc_type)))
+        self.w_value = w_exc_value   # for the 'value' app-level attribute
+        return space.w_True     # suppress the exception
+
+    def report_error(self, got):
+        space = self.space
+        raise oefmt(space.w_AssertionError,
+                    "raises() expected %s, but got %s",
+                    space.text_w(space.repr(self.w_ExpectedException)),
+                    got)
+
+W_RaisesContextManager.typedef = typedef.TypeDef("RaisesContextManager",
+    __enter__ = gateway.interp2app_temp(W_RaisesContextManager.enter),
+    __exit__ = gateway.interp2app_temp(W_RaisesContextManager.exit),
+    value = typedef.interp_attrproperty_w('w_value', cls=W_RaisesContextManager)
+    )
+
+def pypyraises(space, w_ExpectedException, w_expr=None, __args__=None):
     """A built-in function providing the equivalent of py.test.raises()."""
+    if w_expr is None:
+        return W_RaisesContextManager(space, w_ExpectedException)
     args_w, kwds_w = __args__.unpack()
     if space.isinstance_w(w_expr, space.w_text):
         if args_w:


More information about the pypy-commit mailing list