[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