[pypy-commit] pypy apptest-file: hg merge default

rlamy pypy.commits at gmail.com
Thu Jan 31 11:44:23 EST 2019


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: apptest-file
Changeset: r95759:d25403a13858
Date: 2019-01-31 16:10 +0000
http://bitbucket.org/pypy/pypy/changeset/d25403a13858/

Log:	hg merge default

diff too long, truncating to 2000 out of 15681 lines

diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -30,7 +30,7 @@
     DEALINGS IN THE SOFTWARE.
 
 
-PyPy Copyright holders 2003-2018
+PyPy Copyright holders 2003-2019
 --------------------------------
 
 Except when otherwise stated (look for LICENSE files or information at
@@ -40,16 +40,16 @@
   Armin Rigo
   Maciej Fijalkowski
   Carl Friedrich Bolz-Tereick
+  Antonio Cuni
   Amaury Forgeot d'Arc
-  Antonio Cuni
   Matti Picus
   Samuele Pedroni
   Ronan Lamy
   Alex Gaynor
   Philip Jenvey
+  Richard Plangger
   Brian Kearns
-  Richard Plangger
-  Michael Hudson
+  Michael Hudson-Doyle
   Manuel Jacob
   David Schneider
   Holger Krekel
@@ -59,8 +59,8 @@
   Anders Chrigstrom
   Wim Lavrijsen
   Eric van Riet Paap
+  Remi Meier
   Richard Emslie
-  Remi Meier
   Alexander Schremmer
   Dan Villiom Podlaski Christiansen
   Lukas Diekmann
@@ -70,10 +70,10 @@
   Niklaus Haldimann
   Camillo Bruni
   Laura Creighton
-  Romain Guillebert
   Toon Verwaest
   Leonardo Santagada
   Seo Sanghyeon
+  Romain Guillebert
   Ronny Pfannschmidt
   Justin Peel
   Raffael Tfirst
@@ -114,12 +114,12 @@
   Squeaky
   Edd Barrett
   Timo Paulssen
+  Laurence Tratt
   Marius Gedminas
   Nicolas Truessel
   Alexandre Fayolle
   Simon Burton
   Martin Matusiak
-  Laurence Tratt
   Wenzhu Man
   Konstantin Lopuhin
   John Witulski
@@ -134,8 +134,9 @@
   Jean-Philippe St. Pierre
   Guido van Rossum
   Pavel Vinogradov
+  Stefan Beyer
+  William Leslie
   Paweł Piotr Przeradowski
-  William Leslie
   marky1991
   Ilya Osadchiy
   Tobias Oberstein
@@ -144,10 +145,10 @@
   Taavi Burns
   Adrian Kuhn
   tav
+  Stian Andreassen
   Georg Brandl
   Joannah Nanjekye
   Bert Freudenberg
-  Stian Andreassen
   Wanja Saatkamp
   Mike Blume
   Gerald Klix
@@ -163,6 +164,7 @@
   Vasily Kuznetsov
   Preston Timmons
   David Ripton
+  Pieter Zieschang
   Dusty Phillips
   Lukas Renggli
   Guenter Jantzen
@@ -176,6 +178,7 @@
   Andrew Durdin
   Ben Young
   Michael Schneider
+  Yusuke Tsutsumi
   Nicholas Riley
   Jason Chu
   Igor Trindade Oliveira
@@ -187,7 +190,6 @@
   Mariano Anaya
   anatoly techtonik
   Karl Bartel
-  Stefan Beyer
   Gabriel Lavoie
   Jared Grubb
   Alecsandru Patrascu
@@ -198,7 +200,6 @@
   Victor Stinner
   Andrews Medina
   Aaron Iles
-  p_zieschang at yahoo.de
   Toby Watson
   Daniel Patrick
   Stuart Williams
@@ -210,6 +211,7 @@
   Mikael Schönenberg
   Stanislaw Halik
   Mihnea Saracin
+  Matt Jackson
   Berkin Ilbeyi
   Gasper Zejn
   Faye Zhao
@@ -217,12 +219,14 @@
   Anders Qvist
   Corbin Simpson
   Chirag Jadwani
+  Pauli Virtanen
   Jonathan David Riehl
   Beatrice During
   Alex Perry
   Robert Zaremba
   Alan McIntyre
   Alexander Sedov
+  David C Ellis
   Vaibhav Sood
   Reuben Cummings
   Attila Gobi
@@ -242,7 +246,6 @@
   Arjun Naik
   Aaron Gallagher
   Alexis Daboville
-  Pieter Zieschang
   Karl Ramm
   Lukas Vacek
   Omer Katz
@@ -270,12 +273,15 @@
   Catalin Gabriel Manciu
   Jacob Oscarson
   Ryan Gonzalez
+  Antoine Dupre
   Kristjan Valur Jonsson
   Lucio Torre
   Richard Lancaster
   Dan Buch
   Lene Wagner
   Tomo Cocoa
+  Miro Hrončok
+  Anthony Sottile
   David Lievens
   Neil Blakey-Milner
   Henrik Vendelbo
@@ -290,10 +296,12 @@
   Bobby Impollonia
   Roberto De Ioris
   Jeong YunWon
+  andrewjlawrence
   Christopher Armstrong
   Aaron Tubbs
   Vasantha Ganesh K
   Jason Michalski
+  Radu Ciorba
   Markus Holtermann
   Andrew Thompson
   Yusei Tahara
@@ -301,28 +309,26 @@
   Fabio Niephaus
   Akira Li
   Gustavo Niemeyer
-  Rafał Gałczyński
+  Nate Bragg
   Lucas Stadler
   roberto at goyle
+  Carl Bordum Hansen
   Matt Bogosian
   Yury V. Zaytsev
   florinpapa
   Anders Sigfridsson
-  Matt Jackson
   Nikolay Zinov
   rafalgalczynski at gmail.com
   Joshua Gilbert
   Anna Katrina Dominguez
   Kim Jin Su
   Amber Brown
-  Miro Hrončok
-  Anthony Sottile
-  Nate Bragg
+  Andrew Stepanov
+  Rafał Gałczyński
   Ben Darnell
   Juan Francisco Cantero Hurtado
   Godefroid Chappelle
   Julian Berman
-  Michael Hudson-Doyle
   Stephan Busemann
   Dan Colish
   timo
@@ -332,6 +338,7 @@
   halgari
   Jim Baker
   Chris Lambacher
+  John Aldis
   coolbutuseless at gmail.com
   Mike Bayer
   Rodrigo Araújo
@@ -340,6 +347,7 @@
   OlivierBlanvillain
   Jonas Pfannschmidt
   Zearin
+  Johan Forsberg
   Andrey Churin
   Dan Crosta
   reubano at gmail.com
@@ -349,8 +357,9 @@
   Steve Papanik
   Eli Stevens
   Boglarka Vezer
-  gabrielg
+  gabrielg at ec2-54-146-239-158.compute-1.amazonaws.com
   PavloKapyshin
+  Hervé Beraud
   Tomer Chachamu
   Christopher Groskopf
   Asmo Soinio
@@ -364,7 +373,6 @@
   Michael Chermside
   Anna Ravencroft
   remarkablerocket
-  Pauli Virtanen
   Petre Vijiac
   Berker Peksag
   Christian Muirhead
@@ -384,12 +392,13 @@
   Zooko Wilcox-O Hearn
   James Lan
   jiaaro
+  Evgenii Gorinov
   Markus Unterwaditzer
   Kristoffer Kleine
   Graham Markall
   Dan Loewenherz
   werat
-  Andrew Stepanov
+  Filip Salomonsson
   Niclas Olofsson
   Chris Pressey
   Tobias Diaz
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
@@ -325,8 +325,31 @@
         a = array.array('H', [10000, 20000, 30000])
         c = ffi.from_buffer(a)
         assert ffi.typeof(c) is ffi.typeof("char[]")
+        assert len(c) == 6
         ffi.cast("unsigned short *", c)[1] += 500
         assert list(a) == [10000, 20500, 30000]
+        assert c == ffi.from_buffer("char[]", a, True)
+        assert c == ffi.from_buffer(a, require_writable=True)
+        #
+        c = ffi.from_buffer("unsigned short[]", a)
+        assert len(c) == 3
+        assert c[1] == 20500
+        #
+        p = ffi.from_buffer(b"abcd")
+        assert p[2] == b"c"
+        #
+        assert p == ffi.from_buffer(b"abcd", require_writable=False)
+        py.test.raises((TypeError, BufferError), ffi.from_buffer,
+                                                 "char[]", b"abcd", True)
+        py.test.raises((TypeError, BufferError), ffi.from_buffer, b"abcd",
+                                                 require_writable=True)
+
+    def test_release(self):
+        ffi = FFI()
+        p = ffi.new("int[]", 123)
+        ffi.release(p)
+        # here, reading p[0] might give garbage or segfault...
+        ffi.release(p)   # no effect
 
     def test_memmove(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
@@ -46,14 +46,15 @@
         assert x != math.sin(1.23)    # rounding effects
         assert abs(x - math.sin(1.23)) < 1E-6
 
-    def test_lround_no_return_value(self):
+    def test_getenv_no_return_value(self):
         # check that 'void'-returning functions work too
         ffi = FFI(backend=self.Backend())
         ffi.cdef("""
-            void lround(double x);
+            void getenv(char *);
         """)
-        m = ffi.dlopen(lib_m)
-        x = m.lround(1.23)
+        needs_dlopen_none()
+        m = ffi.dlopen(None)
+        x = m.getenv(b"FOO")
         assert x is None
 
     def test_dlopen_filename(self):
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
@@ -239,11 +239,33 @@
 def test_ffi_from_buffer():
     import array
     ffi = _cffi1_backend.FFI()
-    a = array.array('H', [10000, 20000, 30000])
+    a = array.array('H', [10000, 20000, 30000, 40000])
     c = ffi.from_buffer(a)
     assert ffi.typeof(c) is ffi.typeof("char[]")
+    assert len(c) == 8
     ffi.cast("unsigned short *", c)[1] += 500
-    assert list(a) == [10000, 20500, 30000]
+    assert list(a) == [10000, 20500, 30000, 40000]
+    py.test.raises(TypeError, ffi.from_buffer, a, True)
+    assert c == ffi.from_buffer("char[]", a, True)
+    assert c == ffi.from_buffer(a, require_writable=True)
+    #
+    c = ffi.from_buffer("unsigned short[]", a)
+    assert len(c) == 4
+    assert c[1] == 20500
+    #
+    c = ffi.from_buffer("unsigned short[2][2]", a)
+    assert len(c) == 2
+    assert len(c[0]) == 2
+    assert c[0][1] == 20500
+    #
+    p = ffi.from_buffer(b"abcd")
+    assert p[2] == b"c"
+    #
+    assert p == ffi.from_buffer(b"abcd", require_writable=False)
+    py.test.raises((TypeError, BufferError), ffi.from_buffer,
+                                             "char[]", b"abcd", True)
+    py.test.raises((TypeError, BufferError), ffi.from_buffer, b"abcd",
+                                             require_writable=True)
 
 def test_memmove():
     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
@@ -1457,6 +1457,35 @@
         import gc; gc.collect(); gc.collect(); gc.collect()
         assert seen == [3]
 
+    def test_release(self):
+        p = ffi.new("int[]", 123)
+        ffi.release(p)
+        # here, reading p[0] might give garbage or segfault...
+        ffi.release(p)   # no effect
+
+    def test_release_new_allocator(self):
+        seen = []
+        def myalloc(size):
+            seen.append(size)
+            return ffi.new("char[]", b"X" * size)
+        def myfree(raw):
+            seen.append(raw)
+        alloc2 = ffi.new_allocator(alloc=myalloc, free=myfree)
+        p = alloc2("int[]", 15)
+        assert seen == [15 * 4]
+        ffi.release(p)
+        assert seen == [15 * 4, p]
+        ffi.release(p)    # no effect
+        assert seen == [15 * 4, p]
+        #
+        del seen[:]
+        p = alloc2("struct ab *")
+        assert seen == [2 * 4]
+        ffi.release(p)
+        assert seen == [2 * 4, p]
+        ffi.release(p)    # no effect
+        assert seen == [2 * 4, p]
+
     def test_CData_CType(self):
         assert isinstance(ffi.cast("int", 0), ffi.CData)
         assert isinstance(ffi.new("int *"), ffi.CData)
@@ -1647,14 +1676,6 @@
         py.test.raises(TypeError, len, q.a)
         py.test.raises(TypeError, list, q.a)
 
-    def test_from_buffer(self):
-        import array
-        a = array.array('H', [10000, 20000, 30000])
-        c = ffi.from_buffer(a)
-        assert ffi.typeof(c) is ffi.typeof("char[]")
-        ffi.cast("unsigned short *", c)[1] += 500
-        assert list(a) == [10000, 20500, 30000]
-
     def test_all_primitives(self):
         assert set(PRIMITIVE_TO_INDEX) == set([
             "char",
diff --git a/extra_tests/cffi_tests/cffi1/test_parse_c_type.py b/extra_tests/cffi_tests/cffi1/test_parse_c_type.py
--- a/extra_tests/cffi_tests/cffi1/test_parse_c_type.py
+++ b/extra_tests/cffi_tests/cffi1/test_parse_c_type.py
@@ -4,7 +4,12 @@
 from cffi import cffi_opcode
 
 if '__pypy__' in sys.builtin_module_names:
-    py.test.skip("not available on pypy", allow_module_level=True)
+    try:
+        # pytest >= 4.0
+        py.test.skip("not available on pypy", allow_module_level=True)
+    except TypeError:
+        # older pytest
+        py.test.skip("not available on pypy")
 
 cffi_dir = os.path.dirname(cffi_opcode.__file__)
 
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
@@ -5,7 +5,7 @@
 from cffi import recompiler
 from extra_tests.cffi_tests.udir import udir
 from extra_tests.cffi_tests.support import u, long
-from extra_tests.cffi_tests.support import FdWriteCapture, StdErrCapture
+from extra_tests.cffi_tests.support import FdWriteCapture, StdErrCapture, _verify
 
 try:
     import importlib
@@ -36,7 +36,7 @@
         # add '-Werror' to the existing 'extra_compile_args' flags
         kwds['extra_compile_args'] = (kwds.get('extra_compile_args', []) +
                                       ['-Werror'])
-    return recompiler._verify(ffi, module_name, source, *args, **kwds)
+    return _verify(ffi, module_name, source, *args, **kwds)
 
 def test_set_source_no_slashes():
     ffi = FFI()
@@ -1539,15 +1539,18 @@
     assert (pt.x, pt.y) == (99*500*999, -99*500*999)
 
 def test_extern_python_1():
+    import warnings
     ffi = FFI()
-    ffi.cdef("""
+    with warnings.catch_warnings(record=True) as log:
+        ffi.cdef("""
         extern "Python" {
             int bar(int, int);
             void baz(int, int);
             int bok(void);
             void boz(void);
         }
-    """)
+        """)
+    assert len(log) == 0, "got a warning: %r" % (log,)
     lib = verify(ffi, 'test_extern_python_1', """
         static void baz(int, int);   /* forward */
     """)
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
@@ -4,6 +4,7 @@
 from cffi import CDefError
 from cffi import recompiler
 from extra_tests.cffi_tests.support import *
+from extra_tests.cffi_tests.support import _verify
 import _cffi_backend
 
 lib_m = ['m']
@@ -38,9 +39,8 @@
         except AttributeError:
             pass
         self.set_source(module_name, preamble)
-        return recompiler._verify(self, module_name, preamble, *args,
-                                  extra_compile_args=self._extra_compile_args,
-                                  **kwds)
+        return _verify(self, module_name, preamble, *args,
+                       extra_compile_args=self._extra_compile_args, **kwds)
 
 class FFI_warnings_not_error(FFI):
     _extra_compile_args = []
diff --git a/extra_tests/cffi_tests/support.py b/extra_tests/cffi_tests/support.py
--- a/extra_tests/cffi_tests/support.py
+++ b/extra_tests/cffi_tests/support.py
@@ -62,3 +62,28 @@
 
     def getvalue(self):
         return self._value
+
+def _verify(ffi, module_name, preamble, *args, **kwds):
+    import imp
+    from cffi.recompiler import recompile
+    from .udir import udir
+    assert module_name not in sys.modules, "module name conflict: %r" % (
+        module_name,)
+    kwds.setdefault('tmpdir', str(udir))
+    outputfilename = recompile(ffi, module_name, preamble, *args, **kwds)
+    module = imp.load_dynamic(module_name, outputfilename)
+    #
+    # hack hack hack: copy all *bound methods* from module.ffi back to the
+    # ffi instance.  Then calls like ffi.new() will invoke module.ffi.new().
+    for name in dir(module.ffi):
+        if not name.startswith('_'):
+            attr = getattr(module.ffi, name)
+            if attr is not getattr(ffi, name, object()):
+                setattr(ffi, name, attr)
+    def typeof_disabled(*args, **kwds):
+        raise NotImplementedError
+    ffi._typeof = typeof_disabled
+    for name in dir(ffi):
+        if not name.startswith('_') and not hasattr(module.ffi, name):
+            setattr(ffi, name, NotImplemented)
+    return module.lib
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/__init__.py b/extra_tests/ctypes_tests/__init__.py
rename from pypy/module/test_lib_pypy/ctypes_tests/__init__.py
rename to extra_tests/ctypes_tests/__init__.py
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/_ctypes_test.c b/extra_tests/ctypes_tests/_ctypes_test.c
rename from pypy/module/test_lib_pypy/ctypes_tests/_ctypes_test.c
rename to extra_tests/ctypes_tests/_ctypes_test.c
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/conftest.py b/extra_tests/ctypes_tests/conftest.py
rename from pypy/module/test_lib_pypy/ctypes_tests/conftest.py
rename to extra_tests/ctypes_tests/conftest.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/conftest.py
+++ b/extra_tests/ctypes_tests/conftest.py
@@ -3,10 +3,6 @@
 import sys
 import os
 
-def pytest_ignore_collect(path):
-    if '__pypy__' not in sys.builtin_module_names:
-        return True
-
 # XXX: copied from pypy/tool/cpyext/extbuild.py
 if os.name != 'nt':
     so_ext = 'so'
@@ -85,8 +81,7 @@
     return outputfilename
 # end copy
 
-def compile_so_file():
-    udir = pytest.ensuretemp('_ctypes_test')
+def compile_so_file(udir):
     cfile = py.path.local(__file__).dirpath().join("_ctypes_test.c")
 
     if sys.platform == 'win32':
@@ -96,8 +91,12 @@
 
     return c_compile([cfile], str(udir / '_ctypes_test'), libraries=libraries)
 
-# we need to run after the "tmpdir" plugin which installs pytest.ensuretemp
- at pytest.mark.trylast
-def pytest_configure(config):
-    global sofile
-    sofile = compile_so_file()
+ at pytest.fixture(scope='session')
+def sofile(tmpdir_factory):
+    udir = tmpdir_factory.mktemp('_ctypes_test')
+    return str(compile_so_file(udir))
+
+ at pytest.fixture
+def dll(sofile):
+    from ctypes import CDLL
+    return CDLL(str(sofile))
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/support.py b/extra_tests/ctypes_tests/support.py
rename from pypy/module/test_lib_pypy/ctypes_tests/support.py
rename to extra_tests/ctypes_tests/support.py
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_anon.py b/extra_tests/ctypes_tests/test_anon.py
rename from pypy/module/test_lib_pypy/ctypes_tests/test_anon.py
rename to extra_tests/ctypes_tests/test_anon.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_anon.py
+++ b/extra_tests/ctypes_tests/test_anon.py
@@ -1,86 +1,55 @@
 import pytest
 from ctypes import *
-from .support import BaseCTypesTestChecker
 
-class TestAnon(BaseCTypesTestChecker):
+ at pytest.mark.pypy_only
+def test_nested():
+    class ANON_S(Structure):
+        _fields_ = [("a", c_int)]
 
-    def test_anon(self):
-        class ANON(Union):
-            _fields_ = [("a", c_int),
-                        ("b", c_int)]
+    class ANON_U(Union):
+        _fields_ = [("_", ANON_S),
+                    ("b", c_int)]
+        _anonymous_ = ["_"]
 
-        class Y(Structure):
-            _fields_ = [("x", c_int),
-                        ("_", ANON),
-                        ("y", c_int)]
-            _anonymous_ = ["_"]
+    class Y(Structure):
+        _fields_ = [("x", c_int),
+                    ("_", ANON_U),
+                    ("y", c_int)]
+        _anonymous_ = ["_"]
 
-        assert Y.a.offset == sizeof(c_int)
-        assert Y.b.offset == sizeof(c_int)
+    assert Y.x.offset == 0
+    assert Y.a.offset == sizeof(c_int)
+    assert Y.b.offset == sizeof(c_int)
+    assert Y._.offset == sizeof(c_int)
+    assert Y.y.offset == sizeof(c_int) * 2
 
-        assert ANON.a.offset == 0
-        assert ANON.b.offset == 0
+    assert Y._names_ == ['x', 'a', 'b', 'y']
 
-    def test_anon_nonseq(self):
-        # TypeError: _anonymous_ must be a sequence
-        with pytest.raises(TypeError):
-            type(Structure)(
-                "Name", (Structure,), {"_fields_": [], "_anonymous_": 42})
+def test_anonymous_fields_on_instance():
+    # this is about the *instance-level* access of anonymous fields,
+    # which you'd guess is the most common, but used not to work
+    # (issue #2230)
 
-    def test_anon_nonmember(self):
-        # AttributeError: type object 'Name' has no attribute 'x'
-        with pytest.raises(AttributeError):
-            type(Structure)(
-                "Name", (Structure,), {"_fields_": [], "_anonymous_": ["x"]})
+    class B(Structure):
+        _fields_ = [("x", c_int), ("y", c_int), ("z", c_int)]
+    class A(Structure):
+        _anonymous_ = ["b"]
+        _fields_ = [("b", B)]
 
-    def test_nested(self):
-        class ANON_S(Structure):
-            _fields_ = [("a", c_int)]
+    a = A()
+    a.x = 5
+    assert a.x == 5
+    assert a.b.x == 5
+    a.b.x += 1
+    assert a.x == 6
 
-        class ANON_U(Union):
-            _fields_ = [("_", ANON_S),
-                        ("b", c_int)]
-            _anonymous_ = ["_"]
+    class C(Structure):
+        _anonymous_ = ["a"]
+        _fields_ = [("v", c_int), ("a", A)]
 
-        class Y(Structure):
-            _fields_ = [("x", c_int),
-                        ("_", ANON_U),
-                        ("y", c_int)]
-            _anonymous_ = ["_"]
-
-        assert Y.x.offset == 0
-        assert Y.a.offset == sizeof(c_int)
-        assert Y.b.offset == sizeof(c_int)
-        assert Y._.offset == sizeof(c_int)
-        assert Y.y.offset == sizeof(c_int) * 2
-
-        assert Y._names_ == ['x', 'a', 'b', 'y']
-
-    def test_anonymous_fields_on_instance(self):
-        # this is about the *instance-level* access of anonymous fields,
-        # which you'd guess is the most common, but used not to work
-        # (issue #2230)
-
-        class B(Structure):
-            _fields_ = [("x", c_int), ("y", c_int), ("z", c_int)]
-        class A(Structure):
-            _anonymous_ = ["b"]
-            _fields_ = [("b", B)]
-
-        a = A()
-        a.x = 5
-        assert a.x == 5
-        assert a.b.x == 5
-        a.b.x += 1
-        assert a.x == 6
-
-        class C(Structure):
-            _anonymous_ = ["a"]
-            _fields_ = [("v", c_int), ("a", A)]
-
-        c = C()
-        c.v = 3
-        c.y = -8
-        assert c.v == 3
-        assert c.y == c.a.y == c.a.b.y == -8
-        assert not hasattr(c, 'b')
+    c = C()
+    c.v = 3
+    c.y = -8
+    assert c.v == 3
+    assert c.y == c.a.y == c.a.b.y == -8
+    assert not hasattr(c, 'b')
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_array.py b/extra_tests/ctypes_tests/test_array.py
rename from pypy/module/test_lib_pypy/ctypes_tests/test_array.py
rename to extra_tests/ctypes_tests/test_array.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_array.py
+++ b/extra_tests/ctypes_tests/test_array.py
@@ -1,177 +1,64 @@
 import pytest
 from ctypes import *
-from .support import BaseCTypesTestChecker
 
-formats = "bBhHiIlLqQfd"
+def test_slice():
+    values = list(range(5))
+    numarray = c_int * 5
 
-formats = c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, \
-          c_long, c_ulonglong, c_float, c_double
+    na = numarray(*(c_int(x) for x in values))
 
-class TestArray(BaseCTypesTestChecker):
-    def test_simple(self):
-        # create classes holding simple numeric types, and check
-        # various properties.
+    assert list(na[0:0]) == []
+    assert list(na[:])   == values
+    assert list(na[:10]) == values
 
-        init = range(15, 25)
+def test_init_again():
+    sz = (c_char * 3)()
+    addr1 = addressof(sz)
+    sz.__init__(*b"foo")
+    addr2 = addressof(sz)
+    assert addr1 == addr2
 
-        for fmt in formats:
-            alen = len(init)
-            int_array = ARRAY(fmt, alen)
+def test_array_of_structures():
+    class X(Structure):
+        _fields_ = [('x', c_int), ('y', c_int)]
 
-            ia = int_array(*init)
-            # length of instance ok?
-            assert len(ia) == alen
+    Y = X * 2
+    y = Y()
+    x = X()
+    x.y = 3
+    y[1] = x
+    assert y[1].y == 3
 
-            # slot values ok?
-            values = [ia[i] for i in range(len(init))]
-            assert values == init
+def test_output_simple():
+    A = c_char * 10
+    TP = POINTER(A)
+    x = TP(A())
+    assert x[0] != b''
 
-            # change the items
-            from operator import setitem
-            new_values = range(42, 42+alen)
-            [setitem(ia, n, new_values[n]) for n in range(alen)]
-            values = [ia[i] for i in range(len(init))]
-            assert values == new_values
+    A = c_wchar * 10
+    TP = POINTER(A)
+    x = TP(A())
+    assert x[0] != b''
 
-            # are the items initialized to 0?
-            ia = int_array()
-            values = [ia[i] for i in range(len(init))]
-            assert values == [0] * len(init)
+def test_output_simple_array():
+    A = c_char * 10
+    AA = A * 10
+    aa = AA()
+    assert aa[0] != b''
 
-            # Too many in itializers should be caught
-            with pytest.raises(IndexError):
-                int_array(*range(alen*2))
+def test_output_complex_test():
+    class Car(Structure):
+        _fields_ = [("brand", c_char * 10),
+                    ("speed", c_float),
+                    ("owner", c_char * 10)]
 
-        CharArray = ARRAY(c_char, 3)
+    assert isinstance(Car(b"abcdefghi", 42.0, b"12345").brand, bytes)
+    assert Car(b"abcdefghi", 42.0, b"12345").brand == b"abcdefghi"
+    assert Car(b"abcdefghio", 42.0, b"12345").brand == b"abcdefghio"
+    with pytest.raises(ValueError):
+        Car(b"abcdefghiop", 42.0, b"12345")
 
-        ca = CharArray("a", "b", "c")
-
-        # Should this work? It doesn't:
-        # CharArray("abc")
-        with pytest.raises(TypeError):
-            CharArray("abc")
-
-        assert ca[0] == "a"
-        assert ca[1] == "b"
-        assert ca[2] == "c"
-        assert ca[-3] == "a"
-        assert ca[-2] == "b"
-        assert ca[-1] == "c"
-
-        assert len(ca) == 3
-
-        # slicing is now supported, but not extended slicing (3-argument)!
-        from operator import getslice, delitem
-        with pytest.raises(TypeError):
-            getslice(ca, 0, 1, -1)
-
-        # cannot delete items
-        with pytest.raises(TypeError):
-            delitem(ca, 0)
-
-    def test_numeric_arrays(self):
-
-        alen = 5
-
-        numarray = ARRAY(c_int, alen)
-
-        na = numarray()
-        values = [na[i] for i in range(alen)]
-        assert values == [0] * alen
-
-        na = numarray(*[c_int()] * alen)
-        values = [na[i] for i in range(alen)]
-        assert values == [0]*alen
-
-        na = numarray(1, 2, 3, 4, 5)
-        values = [i for i in na]
-        assert values == [1, 2, 3, 4, 5]
-
-        na = numarray(*map(c_int, (1, 2, 3, 4, 5)))
-        values = [i for i in na]
-        assert values == [1, 2, 3, 4, 5]
-
-    def test_slice(self):
-        values = range(5)
-        numarray = c_int * 5
-
-        na = numarray(*(c_int(x) for x in values))
-
-        assert list(na[0:0]) == []
-        assert list(na[:])   == values
-        assert list(na[:10]) == values
-
-    def test_classcache(self):
-        assert not ARRAY(c_int, 3) is ARRAY(c_int, 4)
-        assert ARRAY(c_int, 3) is ARRAY(c_int, 3)
-
-    def test_from_address(self):
-        # Failed with 0.9.8, reported by JUrner
-        p = create_string_buffer("foo")
-        sz = (c_char * 3).from_address(addressof(p))
-        assert sz[:] == "foo"
-        assert sz.value == "foo"
-
-    def test_init_again(self):
-        sz = (c_char * 3)()
-        addr1 = addressof(sz)
-        sz.__init__(*"foo")
-        addr2 = addressof(sz)
-        assert addr1 == addr2
-
-    try:
-        create_unicode_buffer
-    except NameError:
-        pass
-    else:
-        def test_from_addressW(self):
-            p = create_unicode_buffer("foo")
-            sz = (c_wchar * 3).from_address(addressof(p))
-            assert sz[:] == "foo"
-            assert sz.value == "foo"
-
-class TestSophisticatedThings(BaseCTypesTestChecker):
-    def test_array_of_structures(self):
-        class X(Structure):
-            _fields_ = [('x', c_int), ('y', c_int)]
-
-        Y = X * 2
-        y = Y()
-        x = X()
-        x.y = 3
-        y[1] = x
-        assert y[1].y == 3
-
-    def test_output_simple(self):
-        A = c_char * 10
-        TP = POINTER(A)
-        x = TP(A())
-        assert x[0] != ''
-
-        A = c_wchar * 10
-        TP = POINTER(A)
-        x = TP(A())
-        assert x[0] != ''
-
-    def test_output_simple_array(self):
-        A = c_char * 10
-        AA = A * 10
-        aa = AA()
-        assert aa[0] != ''
-
-    def test_output_complex_test(self):
-        class Car(Structure):
-            _fields_ = [("brand", c_char * 10),
-                        ("speed", c_float),
-                        ("owner", c_char * 10)]
-
-        assert isinstance(Car("abcdefghi", 42.0, "12345").brand, bytes)
-        assert Car("abcdefghi", 42.0, "12345").brand == "abcdefghi"
-        assert Car("abcdefghio", 42.0, "12345").brand == "abcdefghio"
-        with pytest.raises(ValueError):
-            Car("abcdefghiop", 42.0, "12345")
-
-        A = Car._fields_[2][1]
-        TP = POINTER(A)
-        x = TP(A())
-        assert x[0] != ''
+    A = Car._fields_[2][1]
+    TP = POINTER(A)
+    x = TP(A())
+    assert x[0] != b''
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_base.py b/extra_tests/ctypes_tests/test_base.py
rename from pypy/module/test_lib_pypy/ctypes_tests/test_base.py
rename to extra_tests/ctypes_tests/test_base.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_base.py
+++ b/extra_tests/ctypes_tests/test_base.py
@@ -1,26 +1,24 @@
-from .support import WhiteBoxTests
-
+import pytest
 from ctypes import *
 
-# WhiteBoxTests
+pytestmark = pytest.mark.pypy_only
 
-class TestCTypesBase(WhiteBoxTests):
-    def test_pointer(self):
-        p = pointer(pointer(c_int(2)))
-        x = p[0]
-        assert x._base is p
+def test_pointer():
+    p = pointer(pointer(c_int(2)))
+    x = p[0]
+    assert x._base is p
 
-    def test_structure(self):
-        class X(Structure):
-            _fields_ = [('x', POINTER(c_int)),
-                        ('y', POINTER(c_int))]
+def test_structure():
+    class X(Structure):
+        _fields_ = [('x', POINTER(c_int)),
+                    ('y', POINTER(c_int))]
 
-        x = X()
-        assert x.y._base is x
-        assert x.y._index == 1
+    x = X()
+    assert x.y._base is x
+    assert x.y._index == 1
 
-    def test_array(self):
-        X = POINTER(c_int) * 24
-        x = X()
-        assert x[16]._base is x
-        assert x[16]._index == 16
+def test_array():
+    X = POINTER(c_int) * 24
+    x = X()
+    assert x[16]._base is x
+    assert x[16]._index == 16
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_bitfields.py b/extra_tests/ctypes_tests/test_bitfields.py
rename from pypy/module/test_lib_pypy/ctypes_tests/test_bitfields.py
rename to extra_tests/ctypes_tests/test_bitfields.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_bitfields.py
+++ b/extra_tests/ctypes_tests/test_bitfields.py
@@ -1,249 +1,19 @@
 import pytest
 from ctypes import *
-from .support import BaseCTypesTestChecker
-import os
 
-import ctypes
 
-signed_int_types = (c_byte, c_short, c_int, c_long, c_longlong)
-unsigned_int_types = (c_ubyte, c_ushort, c_uint, c_ulong, c_ulonglong)
-int_types = unsigned_int_types + signed_int_types
+def test_set_fields_attr():
+    class A(Structure):
+        pass
+    A._fields_ = [("a", c_byte), ("b", c_ubyte)]
 
+def test_set_fields_attr_bitfields():
+    class A(Structure):
+        pass
+    A._fields_ = [("a", POINTER(A)), ("b", c_ubyte, 4)]
 
-def setup_module(mod):
-    import conftest
-    _ctypes_test = str(conftest.sofile)
-    func = CDLL(_ctypes_test).unpack_bitfields
-    func.argtypes = POINTER(BITS), c_char
-    mod.func = func
-
-
-class BITS(Structure):
-    _fields_ = [("A", c_int, 1),
-                ("B", c_int, 2),
-                ("C", c_int, 3),
-                ("D", c_int, 4),
-                ("E", c_int, 5),
-                ("F", c_int, 6),
-                ("G", c_int, 7),
-                ("H", c_int, 8),
-                ("I", c_int, 9),
-
-                ("M", c_short, 1),
-                ("N", c_short, 2),
-                ("O", c_short, 3),
-                ("P", c_short, 4),
-                ("Q", c_short, 5),
-                ("R", c_short, 6),
-                ("S", c_short, 7)]
-
-
-class TestC:
-    def test_ints(self):
-        for i in range(512):
-            for name in "ABCDEFGHI":
-                b = BITS()
-                setattr(b, name, i)
-                assert (name, i, getattr(b, name)) == (name, i, func(byref(b), name))
-
-    def test_shorts(self):
-        for i in range(256):
-            for name in "MNOPQRS":
-                b = BITS()
-                setattr(b, name, i)
-                assert (name, i, getattr(b, name)) == (name, i, func(byref(b), name))
-
-
-class TestBitField:
-    def test_longlong(self):
-        class X(Structure):
-            _fields_ = [("a", c_longlong, 1),
-                        ("b", c_longlong, 62),
-                        ("c", c_longlong, 1)]
-
-        assert sizeof(X) == sizeof(c_longlong)
-        x = X()
-        x.a, x.b, x.c = -1, 7, -1
-        assert (x.a, x.b, x.c) == (-1, 7, -1)
-
-        x = X()
-        x.a, x.b, x.c = -1, -7, -1
-        assert (x.a, x.b, x.c) == (-1, -7, -1)
-
-    def test_ulonglong(self):
-        class X(Structure):
-            _fields_ = [("a", c_ulonglong, 1),
-                        ("b", c_ulonglong, 62),
-                        ("c", c_ulonglong, 1)]
-
-        assert sizeof(X) == sizeof(c_longlong)
-        x = X()
-        assert (x.a, x.b, x.c) == (0, 0, 0)
-        x.a, x.b, x.c = 7, 2305843009213693953, 7
-        assert (x.a, x.b, x.c) == (1, 2305843009213693953, 1)
-
-    def test_signed(self):
-        for c_typ in signed_int_types:
-            class X(Structure):
-                _fields_ = [("dummy", c_typ),
-                            ("a", c_typ, 3),
-                            ("b", c_typ, 3),
-                            ("c", c_typ, 1)]
-            assert sizeof(X) == sizeof(c_typ)*2
-
-            x = X()
-            assert (c_typ, x.a, x.b, x.c) == (c_typ, 0, 0, 0)
-            x.a = -1
-            assert (c_typ, x.a, x.b, x.c) == (c_typ, -1, 0, 0)
-            x.a, x.b = 0, -1
-            assert (c_typ, x.a, x.b, x.c) == (c_typ, 0, -1, 0)
-
-    def test_unsigned(self):
-        for c_typ in unsigned_int_types:
-            class X(Structure):
-                _fields_ = [("a", c_typ, 3),
-                            ("b", c_typ, 3),
-                            ("c", c_typ, 1)]
-            assert sizeof(X) == sizeof(c_typ)
-
-            x = X()
-            assert (c_typ, x.a, x.b, x.c) == (c_typ, 0, 0, 0)
-            x.a = -1
-            assert (c_typ, x.a, x.b, x.c) == (c_typ, 7, 0, 0)
-            x.a, x.b = 0, -1
-            assert (c_typ, x.a, x.b, x.c) == (c_typ, 0, 7, 0)
-
-    def fail_fields(self, *fields):
-        return self.get_except(type(Structure), "X", (),
-                               {"_fields_": fields})
-
-    def test_nonint_types(self):
-        # bit fields are not allowed on non-integer types.
-        result = self.fail_fields(("a", c_char_p, 1))
-        assert result == (TypeError, 'bit fields not allowed for type c_char_p')
-
-        result = self.fail_fields(("a", c_void_p, 1))
-        assert result == (TypeError, 'bit fields not allowed for type c_void_p')
-
-        if c_int != c_long:
-            result = self.fail_fields(("a", POINTER(c_int), 1))
-            assert result == (TypeError, 'bit fields not allowed for type LP_c_int')
-
-        result = self.fail_fields(("a", c_char, 1))
-        assert result == (TypeError, 'bit fields not allowed for type c_char')
-
-        try:
-            c_wchar
-        except NameError:
-            pass
-        else:
-            result = self.fail_fields(("a", c_wchar, 1))
-            assert result == (TypeError, 'bit fields not allowed for type c_wchar')
-
-        class Dummy(Structure):
-            _fields_ = []
-
-        result = self.fail_fields(("a", Dummy, 1))
-        assert result == (TypeError, 'bit fields not allowed for type Dummy')
-
-    def test_single_bitfield_size(self):
-        for c_typ in int_types:
-            result = self.fail_fields(("a", c_typ, -1))
-            assert result == (ValueError, 'number of bits invalid for bit field')
-
-            result = self.fail_fields(("a", c_typ, 0))
-            assert result == (ValueError, 'number of bits invalid for bit field')
-
-            class X(Structure):
-                _fields_ = [("a", c_typ, 1)]
-            assert sizeof(X) == sizeof(c_typ)
-
-            class X(Structure):
-                _fields_ = [("a", c_typ, sizeof(c_typ)*8)]
-            assert sizeof(X) == sizeof(c_typ)
-
-            result = self.fail_fields(("a", c_typ, sizeof(c_typ)*8 + 1))
-            assert result == (ValueError, 'number of bits invalid for bit field')
-
-    def test_multi_bitfields_size(self):
-        class X(Structure):
-            _fields_ = [("a", c_short, 1),
-                        ("b", c_short, 14),
-                        ("c", c_short, 1)]
-        assert sizeof(X) == sizeof(c_short)
-
-        class X(Structure):
-            _fields_ = [("a", c_short, 1),
-                        ("a1", c_short),
-                        ("b", c_short, 14),
-                        ("c", c_short, 1)]
-        assert sizeof(X) == sizeof(c_short)*3
-        assert X.a.offset == 0
-        assert X.a1.offset == sizeof(c_short)
-        assert X.b.offset == sizeof(c_short)*2
-        assert X.c.offset == sizeof(c_short)*2
-
-        class X(Structure):
-            _fields_ = [("a", c_short, 3),
-                        ("b", c_short, 14),
-                        ("c", c_short, 14)]
-        assert sizeof(X) == sizeof(c_short)*3
-        assert X.a.offset == sizeof(c_short)*0
-        assert X.b.offset == sizeof(c_short)*1
-        assert X.c.offset == sizeof(c_short)*2
-
-    def get_except(self, func, *args, **kw):
-        try:
-            func(*args, **kw)
-        except Exception as detail:
-            import traceback
-            traceback.print_exc()
-            return detail.__class__, str(detail)
-
-    def test_mixed_1(self):
-        class X(Structure):
-            _fields_ = [("a", c_byte, 4),
-                        ("b", c_int, 4)]
-        if os.name in ("nt", "ce"):
-            assert sizeof(X) == sizeof(c_int)*2
-        else:
-            assert sizeof(X) == sizeof(c_int)
-
-    def test_mixed_2(self):
-        class X(Structure):
-            _fields_ = [("a", c_byte, 4),
-                        ("b", c_int, 32)]
-        assert sizeof(X) == sizeof(c_int)*2
-
-    def test_mixed_3(self):
-        class X(Structure):
-            _fields_ = [("a", c_byte, 4),
-                        ("b", c_ubyte, 4)]
-        assert sizeof(X) == sizeof(c_byte)
-
-    def test_anon_bitfields(self):
-        # anonymous bit-fields gave a strange error message
-        class X(Structure):
-            _fields_ = [("a", c_byte, 4),
-                        ("b", c_ubyte, 4)]
-        class Y(Structure):
-            _anonymous_ = ["_"]
-            _fields_ = [("_", X)]
-
-    def test_set_fields_attr(self):
-        class A(Structure):
-            pass
-        A._fields_ = [("a", c_byte),
-                      ("b", c_ubyte)]
-
-    def test_set_fields_attr_bitfields(self):
-        class A(Structure):
-            pass
-        A._fields_ = [("a", POINTER(A)),
-                      ("b", c_ubyte, 4)]
-
-    def test_set_fields_cycle_fails(self):
-        class A(Structure):
-            pass
-        with pytest.raises(AttributeError):
-            A._fields_ = [("a", A)]
+def test_set_fields_cycle_fails():
+    class A(Structure):
+        pass
+    with pytest.raises(AttributeError):
+        A._fields_ = [("a", A)]
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_buffers.py b/extra_tests/ctypes_tests/test_buffers.py
rename from pypy/module/test_lib_pypy/ctypes_tests/test_buffers.py
rename to extra_tests/ctypes_tests/test_buffers.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_buffers.py
+++ b/extra_tests/ctypes_tests/test_buffers.py
@@ -1,76 +1,38 @@
 from ctypes import *
-from .support import BaseCTypesTestChecker
 
-class TestStringBuffer(BaseCTypesTestChecker):
+def test_buffer():
+    b = create_string_buffer(32)
+    assert len(b) == 32
+    assert sizeof(b) == 32 * sizeof(c_char)
+    assert type(b[0]) is str
 
-    def test_buffer(self):
-        b = create_string_buffer(32)
-        assert len(b) == 32
-        assert sizeof(b) == 32 * sizeof(c_char)
-        assert type(b[0]) is str
+    b = create_string_buffer(33L)
+    assert len(b) == 33
+    assert sizeof(b) == 33 * sizeof(c_char)
+    assert type(b[0]) is str
 
-        b = create_string_buffer(33L)
-        assert len(b) == 33
-        assert sizeof(b) == 33 * sizeof(c_char)
-        assert type(b[0]) is str
+    b = create_string_buffer(b"abc")
+    assert len(b) == 4 # trailing nul char
+    assert sizeof(b) == 4 * sizeof(c_char)
+    assert type(b[0]) is str
+    assert b[0] == b"a"
+    assert b[:] == b"abc\0"
 
-        b = create_string_buffer("abc")
-        assert len(b) == 4 # trailing nul char
-        assert sizeof(b) == 4 * sizeof(c_char)
-        assert type(b[0]) is str
-        assert b[0] == "a"
-        assert b[:] == "abc\0"
+def test_from_buffer():
+    b1 = bytearray(b"abcde")
+    b = (c_char * 5).from_buffer(b1)
+    assert b[2] == b"c"
+    #
+    b1 = bytearray(b"abcd")
+    b = c_int.from_buffer(b1)
+    assert b.value in (1684234849,   # little endian
+                        1633837924)   # big endian
 
-    def test_string_conversion(self):
-        b = create_string_buffer(u"abc")
-        assert len(b) == 4 # trailing nul char
-        assert sizeof(b) == 4 * sizeof(c_char)
-        assert type(b[0]) is str
-        assert b[0] == "a"
-        assert b[:] == "abc\0"
-
-    def test_from_buffer(self):
-        b1 = bytearray("abcde")
-        b = (c_char * 5).from_buffer(b1)
-        assert b[2] == "c"
-        #
-        b1 = bytearray("abcd")
-        b = c_int.from_buffer(b1)
-        assert b.value in (1684234849,   # little endian
-                           1633837924)   # big endian
-
-    def test_from_buffer_keepalive(self):
-        # Issue #2878
-        b1 = bytearray("ab")
-        array = (c_uint16 * 32)()
-        array[6] = c_uint16.from_buffer(b1)
-        # this is also what we get on CPython.  I don't think it makes
-        # sense because the array contains just a copy of the number.
-        assert array._objects == {'6': b1}
-
-    try:
-        c_wchar
-    except NameError:
-        pass
-    else:
-        def test_unicode_buffer(self):
-            b = create_unicode_buffer(32)
-            assert len(b) == 32
-            assert sizeof(b) == 32 * sizeof(c_wchar)
-            assert type(b[0]) is unicode
-
-            b = create_unicode_buffer(u"abc")
-            assert len(b) == 4 # trailing nul char
-            assert sizeof(b) == 4 * sizeof(c_wchar)
-            assert type(b[0]) is unicode
-            assert b[0] == u"a"
-            assert b[:] == "abc\0"
-
-        def test_unicode_conversion(self):
-            b = create_unicode_buffer("abc")
-            assert len(b) == 4 # trailing nul char
-            assert sizeof(b) == 4 * sizeof(c_wchar)
-            assert type(b[0]) is unicode
-            assert b[0] == u"a"
-            assert b[:] == "abc\0"
-
+def test_from_buffer_keepalive():
+    # Issue #2878
+    b1 = bytearray(b"ab")
+    array = (c_uint16 * 32)()
+    array[6] = c_uint16.from_buffer(b1)
+    # this is also what we get on CPython.  I don't think it makes
+    # sense because the array contains just a copy of the number.
+    assert array._objects == {'6': b1}
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_callback_traceback.py b/extra_tests/ctypes_tests/test_callback_traceback.py
rename from pypy/module/test_lib_pypy/ctypes_tests/test_callback_traceback.py
rename to extra_tests/ctypes_tests/test_callback_traceback.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_callback_traceback.py
+++ b/extra_tests/ctypes_tests/test_callback_traceback.py
@@ -1,80 +1,35 @@
 # derived from test_random_things.py
-import py
+import pytest
+
 from ctypes import *
-import sys
 
-def callback_func(arg):
-    42 / arg
-    raise ValueError(arg)
+_rawffi = pytest.importorskip('_rawffi')
 
-class TestCallbackTraceback:
-    # When an exception is raised in a ctypes callback function, the C
-    # code prints a traceback.
+#
+# This test makes sure the exception types *and* the exception
+# value is printed correctly.
+
+ at pytest.mark.skipif("sys.flags.inspect")
+def test_SystemExit(monkeypatch, capsys):
+    """
+    When an exception is raised in a ctypes callback function, the C
+    code prints a traceback. When SystemExit is raised, the interpreter
+    normally exits immediately.
+    """
+    def callback_func(arg):
+        raise SystemExit(42)
+    def custom_exit(value):
+        raise Exception("<<<exit(%r)>>>" % (value,))
+    monkeypatch.setattr(_rawffi, 'exit', custom_exit)
+    cb = CFUNCTYPE(c_int, c_int)(callback_func)
+    cb2 = cast(cast(cb, c_void_p), CFUNCTYPE(c_int, c_int))
+    out, err = capsys.readouterr()
+    assert not err
+    cb2(0)
+    out, err = capsys.readouterr()
+    assert err.splitlines()[-1] == "Exception: <<<exit(42)>>>"
     #
-    # This test makes sure the exception types *and* the exception
-    # value is printed correctly.
-    #
-    # Changed in 0.9.3: No longer is '(in callback)' prepended to the
-    # error message - instead a additional frame for the C code is
-    # created, then a full traceback printed.  When SystemExit is
-    # raised in a callback function, the interpreter exits.
-
-    def capture_stderr(self, func, *args, **kw):
-        # helper - call function 'func', and return the captured stderr
-        import StringIO
-        old_stderr = sys.stderr
-        logger = sys.stderr = StringIO.StringIO()
-        try:
-            func(*args, **kw)
-        finally:
-            sys.stderr = old_stderr
-        return logger.getvalue()
-
-    def test_ValueError(self):
-        cb = CFUNCTYPE(c_int, c_int)(callback_func)
-        out = self.capture_stderr(cb, 42)
-        assert out.splitlines()[-1] == (
-                             "ValueError: 42")
-
-    def test_IntegerDivisionError(self):
-        cb = CFUNCTYPE(c_int, c_int)(callback_func)
-        out = self.capture_stderr(cb, 0)
-        assert out.splitlines()[-1][:19] == (
-                             "ZeroDivisionError: ")
-
-    def test_FloatDivisionError(self):
-        cb = CFUNCTYPE(c_int, c_double)(callback_func)
-        out = self.capture_stderr(cb, 0.0)
-        assert out.splitlines()[-1][:19] == (
-                             "ZeroDivisionError: ")
-
-    def test_TypeErrorDivisionError(self):
-        cb = CFUNCTYPE(c_int, c_char_p)(callback_func)
-        out = self.capture_stderr(cb, "spam")
-        assert out.splitlines()[-1].startswith(
-                             "TypeError: "
-                             "unsupported operand type(s) for")
-
-    def test_SystemExit(self):
-        import _rawffi
-        if sys.flags.inspect:
-            skip("requires sys.flags.inspect == 0")
-        def callback_func(arg):
-            raise SystemExit(42)
-        def custom_exit(value):
-            raise Exception("<<<exit(%r)>>>" % (value,))
-        original_exit = _rawffi.exit
-        try:
-            _rawffi.exit = custom_exit
-            #
-            cb = CFUNCTYPE(c_int, c_int)(callback_func)
-            cb2 = cast(cast(cb, c_void_p), CFUNCTYPE(c_int, c_int))
-            out = self.capture_stderr(cb2, 0)
-            assert out.splitlines()[-1] == "Exception: <<<exit(42)>>>"
-            #
-            cb = CFUNCTYPE(c_int, c_int)(callback_func)
-            out = self.capture_stderr(cb, 0)
-            assert out.splitlines()[-1] == "Exception: <<<exit(42)>>>"
-            #
-        finally:
-            _rawffi.exit = original_exit
+    cb = CFUNCTYPE(c_int, c_int)(callback_func)
+    cb(0)
+    out, err = capsys.readouterr()
+    assert err.splitlines()[-1] == "Exception: <<<exit(42)>>>"
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_callbacks.py b/extra_tests/ctypes_tests/test_callbacks.py
rename from pypy/module/test_lib_pypy/ctypes_tests/test_callbacks.py
rename to extra_tests/ctypes_tests/test_callbacks.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_callbacks.py
+++ b/extra_tests/ctypes_tests/test_callbacks.py
@@ -1,283 +1,194 @@
+import pytest
+
+import math
 from ctypes import *
-import pytest
 from .support import BaseCTypesTestChecker
 
-class TestCallbacks(BaseCTypesTestChecker):
-    functype = CFUNCTYPE
-
-##    def tearDown(self):
-##        import gc
-##        gc.collect()
-
-    def callback(self, *args):
-        self.got_args = args
-        return args[-1]
-
-    def check_type(self, typ, arg):
-        unwrapped_types = {
-            c_float: (float,),
-            c_double: (float,),
-            c_char: (str,),
-            c_char_p: (str,),
-            c_uint: (int, long),
-            c_ulong: (int, long),
-            }
-
-        PROTO = self.functype.im_func(typ, typ)
-        cfunc = PROTO(self.callback)
-        result = cfunc(arg)
-        if typ == c_float:
-            assert abs(result - arg) < 0.000001
-        else:
-            assert self.got_args == (arg,)
-            assert result == arg
-
-        result2 = cfunc(typ(arg))
-        assert type(result2) in unwrapped_types.get(typ, (int, long))
-
-        PROTO = self.functype.im_func(typ, c_byte, typ)
-        result = PROTO(self.callback)(-3, arg)
-        if typ == c_float:
-            assert abs(result - arg) < 0.000001
-        else:
-            assert self.got_args == (-3, arg)
-            assert result == arg
-
-    ################
-
-    def test_byte(self):
-        self.check_type(c_byte, 42)
-        self.check_type(c_byte, -42)
-
-    def test_ubyte(self):
-        self.check_type(c_ubyte, 42)
-
-    def test_short(self):
-        self.check_type(c_short, 42)
-        self.check_type(c_short, -42)
-
-    def test_ushort(self):
-        self.check_type(c_ushort, 42)
-
-    def test_int(self):
-        self.check_type(c_int, 42)
-        self.check_type(c_int, -42)
-
-    def test_uint(self):
-        self.check_type(c_uint, 42)
-
-    def test_long(self):
-        self.check_type(c_long, 42)
-        self.check_type(c_long, -42)
-
-    def test_ulong(self):
-        self.check_type(c_ulong, 42)
-
-    def test_longlong(self):
-        self.check_type(c_longlong, 42)
-        self.check_type(c_longlong, -42)
-
-    def test_ulonglong(self):
-        self.check_type(c_ulonglong, 42)
-
-    def test_float(self):
-        # only almost equal: double -> float -> double
-        import math
-        self.check_type(c_float, math.e)
-        self.check_type(c_float, -math.e)
-
-    def test_double(self):
-        self.check_type(c_double, 3.14)
-        self.check_type(c_double, -3.14)
-
-    def test_char(self):
-        self.check_type(c_char, "x")
-        self.check_type(c_char, "a")
-
-    # disabled: would now (correctly) raise a RuntimeWarning about
-    # a memory leak.  A callback function cannot return a non-integral
-    # C type without causing a memory leak.
-##    def test_char_p(self):
-##        self.check_type(c_char_p, "abc")
-##        self.check_type(c_char_p, "def")
-
-
-    @pytest.mark.xfail(
-        reason="we are less strict about callback return type sanity")
-    def test_unsupported_restype_1(self):
-        # Only "fundamental" result types are supported for callback
-        # functions, the type must have a non-NULL stgdict->setfunc.
-        # POINTER(c_double), for example, is not supported.
-
-        prototype = self.functype.im_func(POINTER(c_double))
-        # The type is checked when the prototype is called
-        with pytest.raises(TypeError):
-            prototype(lambda: None)
-
+functypes = [CFUNCTYPE]
 try:
-    WINFUNCTYPE
+    functypes.append(WINFUNCTYPE)
 except NameError:
     pass
-else:
-    class TestStdcallCallbacks(TestCallbacks):
-        functype = WINFUNCTYPE
 
-################################################################
 
-class TestSampleCallbacks(BaseCTypesTestChecker):
+def callback(*args):
+    callback.got_args = args
+    return args[-1]
 
-    def test_integrate(self):
-        # Derived from some then non-working code, posted by David Foster
-        import conftest
-        _ctypes_test = str(conftest.sofile)
-        dll = CDLL(_ctypes_test)
+unwrapped_types = {
+    c_float: (float,),
+    c_double: (float,),
+    c_char: (str,),
+    c_char_p: (str,),
+    c_uint: (int, long),
+    c_ulong: (int, long),
+    }
 
-        # The function prototype called by 'integrate': double func(double);
-        CALLBACK = CFUNCTYPE(c_double, c_double)
+ at pytest.mark.parametrize("typ, arg", [
+    (c_byte, 42),
+    (c_byte, -42),
+    (c_ubyte, 42),
+    (c_short, 42),
+    (c_short, -42),
+    (c_ushort, 42),
+    (c_int, 42),
+    (c_int, -42),
+    (c_uint, 42),
+    (c_long, 42),
+    (c_long, -42),
+    (c_ulong, 42),
+    (c_longlong, 42),
+    (c_longlong, -42),
+    (c_ulonglong, 42),
+    (c_float, math.e),  # only almost equal: double -> float -> double
+    (c_float, -math.e),
+    (c_double, 3.14),
+    (c_double, -3.14),
+    (c_char, b"x"),
+    (c_char, b"a"),
+])
+ at pytest.mark.parametrize('functype', functypes)
+def test_types(typ, arg, functype):
+    PROTO = functype(typ, typ)
+    cfunc = PROTO(callback)
+    result = cfunc(arg)
+    if typ == c_float:
+        assert abs(result - arg) < 0.000001
+    else:
+        assert callback.got_args == (arg,)
+        assert result == arg
 
-        # The integrate function itself, exposed from the _ctypes_test dll
-        integrate = dll.integrate
-        integrate.argtypes = (c_double, c_double, CALLBACK, c_long)
-        integrate.restype = c_double
+    result2 = cfunc(typ(arg))
+    assert type(result2) in unwrapped_types.get(typ, (int, long))
 
-        def func(x):
-            print 'calculating x**2 of',x
-            return x**2
+    PROTO = functype(typ, c_byte, typ)
+    result = PROTO(callback)(-3, arg)
+    if typ == c_float:
+        assert abs(result - arg) < 0.000001
+    else:
+        assert callback.got_args == (-3, arg)
+        assert result == arg
 
-        result = integrate(0.0, 1.0, CALLBACK(func), 10)
-        diff = abs(result - 1./3.)
+ at pytest.mark.parametrize('functype', functypes)
+def test_unsupported_restype_1(functype):
+    # Only "fundamental" result types are supported for callback
+    # functions, the type must have a non-NULL stgdict->setfunc.
+    # POINTER(c_double), for example, is not supported.
 
-        assert diff < 0.01, "%s not less than 0.01" % diff
+    prototype = functype(POINTER(c_double))
+    # The type is checked when the prototype is called
+    with pytest.raises(TypeError):
+        prototype(lambda: None)
 
-################################################################
 
-class TestMoreCallbacks(BaseCTypesTestChecker):
+def test_callback_with_struct_argument():
+    class RECT(Structure):
+        _fields_ = [("left", c_int), ("top", c_int),
+                    ("right", c_int), ("bottom", c_int)]
 
-    def test_callback_with_struct_argument(self):
-        class RECT(Structure):
-            _fields_ = [("left", c_int), ("top", c_int),
-                        ("right", c_int), ("bottom", c_int)]
+    proto = CFUNCTYPE(c_int, RECT)
 
-        proto = CFUNCTYPE(c_int, RECT)
-        def callback(point):
-            point.left *= -1
-            return point.left+point.top+point.right+point.bottom
+    def callback(point):
+        point.left *= -1
+        return point.left + point.top + point.right + point.bottom
 
-        cbp = proto(callback)
+    cbp = proto(callback)
+    rect = RECT(-1000, 100, 10, 1)
+    res = cbp(rect)
+    assert res == 1111
+    assert rect.left == -1000   # must not have been changed!
 
-        rect = RECT(-1000,100,10,1)
+def test_callback_from_c_with_struct_argument(dll):
+    class RECT(Structure):
+        _fields_ = [("left", c_long), ("top", c_long),
+                    ("right", c_long), ("bottom", c_long)]
 
-        res = cbp(rect)
+    proto = CFUNCTYPE(c_int, RECT)
 
-        assert res == 1111
-        assert rect.left == -1000   # must not have been changed!
+    def callback(point):
+        return point.left + point.top + point.right + point.bottom
 
-    def test_callback_from_c_with_struct_argument(self):
-        import conftest
-        _ctypes_test = str(conftest.sofile)
-        dll = CDLL(_ctypes_test)
+    cbp = proto(callback)
+    rect = RECT(1000, 100, 10, 1)
 
-        class RECT(Structure):
-            _fields_ = [("left", c_long), ("top", c_long),
-                        ("right", c_long), ("bottom", c_long)]
+    call_callback_with_rect = dll.call_callback_with_rect
+    call_callback_with_rect.restype = c_int
+    call_callback_with_rect.argtypes = [proto, RECT]
+    res = call_callback_with_rect(cbp, rect)
+    assert res == 1111
 
-        proto = CFUNCTYPE(c_int, RECT)
-        def callback(point):
-            return point.left+point.top+point.right+point.bottom
+def test_callback_unsupported_return_struct():
+    class RECT(Structure):
+        _fields_ = [("left", c_int), ("top", c_int),
+                    ("right", c_int), ("bottom", c_int)]
 
-        cbp = proto(callback)
-        rect = RECT(1000,100,10,1)
+    proto = CFUNCTYPE(RECT, c_int)
+    with pytest.raises(TypeError):
+        proto(lambda r: 0)
 
-        call_callback_with_rect = dll.call_callback_with_rect
-        call_callback_with_rect.restype = c_int
-        call_callback_with_rect.argtypes = [proto, RECT]
-        res = call_callback_with_rect(cbp, rect)
-        assert res == 1111
 
-    def test_callback_unsupported_return_struct(self):
-        class RECT(Structure):
-            _fields_ = [("left", c_int), ("top", c_int),
-                        ("right", c_int), ("bottom", c_int)]
+def test_qsort(dll):
+    PI = POINTER(c_int)
+    A = c_int*5
+    a = A()
+    for i in range(5):
+        a[i] = 5-i
 
-        proto = CFUNCTYPE(RECT, c_int)
-        with pytest.raises(TypeError):
-            proto(lambda r: 0)
+    assert a[0] == 5 # sanity
 
+    def comp(a, b):
+        a = a.contents.value
+        b = b.contents.value
+        return cmp(a,b)
+    qs = dll.my_qsort
+    qs.restype = None
+    CMP = CFUNCTYPE(c_int, PI, PI)
+    qs.argtypes = (PI, c_size_t, c_size_t, CMP)
 
-    def test_qsort(self):
-        import conftest
-        _ctypes_test = str(conftest.sofile)
-        dll = CDLL(_ctypes_test)
+    qs(cast(a, PI), 5, sizeof(c_int), CMP(comp))
 
-        PI = POINTER(c_int)
-        A = c_int*5
-        a = A()
-        for i in range(5):
-            a[i] = 5-i
+    res = list(a)
 
-        assert a[0] == 5 # sanity
+    assert res == [1,2,3,4,5]
 
-        def comp(a, b):
-            a = a.contents.value
-            b = b.contents.value
-            return cmp(a,b)
-        qs = dll.my_qsort
-        qs.restype = None
-        CMP = CFUNCTYPE(c_int, PI, PI)
-        qs.argtypes = (PI, c_size_t, c_size_t, CMP)
+def test_pyobject_as_opaque(dll):
+    def callback(arg):
+        return arg()
 
-        qs(cast(a, PI), 5, sizeof(c_int), CMP(comp))
+    CTP = CFUNCTYPE(c_int, py_object)
+    cfunc = dll._testfunc_callback_opaque
+    cfunc.argtypes = [CTP, py_object]
+    cfunc.restype = c_int
+    res = cfunc(CTP(callback), lambda : 3)
+    assert res == 3
 
-        res = list(a)
+def test_callback_void(capsys, dll):
+    def callback():
+        pass
 
-        assert res == [1,2,3,4,5]
+    CTP = CFUNCTYPE(None)
+    cfunc = dll._testfunc_callback_void
+    cfunc.argtypes = [CTP]
+    cfunc.restype = int
+    cfunc(CTP(callback))
+    out, err = capsys.readouterr()
+    assert (out, err) == ("", "")
 
-    def test_pyobject_as_opaque(self):
-        import conftest
-        _ctypes_test = str(conftest.sofile)
-        dll = CDLL(_ctypes_test)
 
-        def callback(arg):
-            return arg()
+def test_callback_pyobject():
+    def callback(obj):
+        return obj
 
-        CTP = CFUNCTYPE(c_int, py_object)
-        cfunc = dll._testfunc_callback_opaque
-        cfunc.argtypes = [CTP, py_object]
-        cfunc.restype = c_int
-        res = cfunc(CTP(callback), lambda : 3)
-        assert res == 3
+    FUNC = CFUNCTYPE(py_object, py_object)
+    cfunc = FUNC(callback)
+    param = c_int(42)
+    assert cfunc(param) is param
 
-    def test_callback_void(self, capsys):
-        import conftest
-        _ctypes_test = str(conftest.sofile)
-        dll = CDLL(_ctypes_test)
-
-        def callback():
-            pass
-
-        CTP = CFUNCTYPE(None)
-        cfunc = dll._testfunc_callback_void
-        cfunc.argtypes = [CTP]
-        cfunc.restype = int
-        cfunc(CTP(callback))
-        out, err = capsys.readouterr()
-        assert (out, err) == ("", "")
-
-
-    def test_callback_pyobject(self):
-        def callback(obj):
-            return obj
-
-        FUNC = CFUNCTYPE(py_object, py_object)
-        cfunc = FUNC(callback)
-        param = c_int(42)
-        assert cfunc(param) is param
-
-    def test_raise_argumenterror(self):
-        def callback(x):
-            pass
-        FUNC = CFUNCTYPE(None, c_void_p)
-        cfunc = FUNC(callback)
-        param = c_uint(42)
-        with pytest.raises(ArgumentError):
-            cfunc(param)
+def test_raise_argumenterror():
+    def callback(x):
+        pass
+    FUNC = CFUNCTYPE(None, c_void_p)
+    cfunc = FUNC(callback)
+    param = c_uint(42)
+    with pytest.raises(ArgumentError):
+        cfunc(param)
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_cast.py b/extra_tests/ctypes_tests/test_cast.py
rename from pypy/module/test_lib_pypy/ctypes_tests/test_cast.py
rename to extra_tests/ctypes_tests/test_cast.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_cast.py
+++ b/extra_tests/ctypes_tests/test_cast.py
@@ -1,106 +1,30 @@
+import pytest
+
 from ctypes import *
-import sys, py
-from .support import BaseCTypesTestChecker
 
-def setup_module(mod):
-    import conftest
-    mod.lib = CDLL(str(conftest.sofile))
+def test_cast_functype(dll):
+    # make sure we can cast function type
+    my_sqrt = dll.my_sqrt
+    saved_objects = my_sqrt._objects.copy()
+    sqrt = cast(cast(my_sqrt, c_void_p), CFUNCTYPE(c_double, c_double))
+    assert sqrt(4.0) == 2.0
+    assert not cast(0, CFUNCTYPE(c_int))
+    #
+    assert sqrt._objects is my_sqrt._objects   # on CPython too
+    my_sqrt._objects.clear()
+    my_sqrt._objects.update(saved_objects)
 
-class TestCast(BaseCTypesTestChecker):
+def test_cast_argumenterror():
+    param = c_uint(42)
+    with pytest.raises(ArgumentError):
+        cast(param, c_void_p)
 
-    def test_array2pointer(self):
-        array = (c_int * 3)(42, 17, 2)
-
-        # casting an array to a pointer works.
-        ptr = cast(array, POINTER(c_int))
-        assert [ptr[i] for i in range(3)] == [42, 17, 2]
-
-        if 2*sizeof(c_short) == sizeof(c_int):
-            ptr = cast(array, POINTER(c_short))
-            if sys.byteorder == "little":
-                assert [ptr[i] for i in range(6)] == (
-                                     [42, 0, 17, 0, 2, 0])
-            else:
-                assert [ptr[i] for i in range(6)] == (
-                                     [0, 42, 0, 17, 0, 2])
-
-    def test_address2pointer(self):
-        array = (c_int * 3)(42, 17, 2)
-
-        address = addressof(array)
-        ptr = cast(c_void_p(address), POINTER(c_int))
-        assert [ptr[i] for i in range(3)] == [42, 17, 2]
-
-        ptr = cast(address, POINTER(c_int))
-        assert [ptr[i] for i in range(3)] == [42, 17, 2]


More information about the pypy-commit mailing list