Author: Armin Rigo <[email protected]>
Branch:
Changeset: r2983:09cc68d4b9cf
Date: 2017-06-19 10:55 +0200
http://bitbucket.org/cffi/cffi/changeset/09cc68d4b9cf/
Log: Some test fixes for Python 3 on Windows
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -61,6 +61,10 @@
path = None
else:
path = ctypes.util.find_library(name)
+ if path is None and name == 'c':
+ assert sys.platform == 'win32'
+ assert sys.version_info >= (3,)
+ py.test.skip("dlopen(None) cannot work on Windows with Python 3")
return load_library(path, flags)
def test_load_library():
diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -765,7 +765,7 @@
if sys.platform != "win32":
return backend.load_library(None, flags)
name = "c" # Windows: load_library(None) fails, but this works
- # (backward compatibility hack only)
+ # on Python 2 (backward compatibility hack only)
first_error = None
if '.' in name or '/' in name or os.sep in name:
try:
@@ -775,6 +775,9 @@
import ctypes.util
path = ctypes.util.find_library(name)
if path is None:
+ if name == "c" and sys.platform == "win32" and sys.version_info >=
(3,):
+ raise OSError("dlopen(None) cannot work on Windows for Python 3 "
+ "(see http://bugs.python.org/issue23606)")
msg = ("ctypes.util.find_library() did not manage "
"to locate a library called %r" % (name,))
if first_error is not None:
diff --git a/doc/source/cdef.rst b/doc/source/cdef.rst
--- a/doc/source/cdef.rst
+++ b/doc/source/cdef.rst
@@ -306,7 +306,10 @@
contain a full path or not (in which case it is searched in standard
locations, as described in ``man dlopen``), with extensions or not.
Alternatively, if ``libpath`` is None, it returns the standard C library
-(which can be used to access the functions of glibc, on Linux).
+(which can be used to access the functions of glibc, on Linux). Note
+that ``libpath`` `cannot be None`__ on Windows with Python 3.
+
+.. __: http://bugs.python.org/issue23606
Let me state it again: this gives ABI-level access to the library, so
you need to have all types declared manually exactly as they were
diff --git a/testing/cffi0/backend_tests.py b/testing/cffi0/backend_tests.py
--- a/testing/cffi0/backend_tests.py
+++ b/testing/cffi0/backend_tests.py
@@ -10,6 +10,10 @@
SIZE_OF_PTR = ctypes.sizeof(ctypes.c_void_p)
SIZE_OF_WCHAR = ctypes.sizeof(ctypes.c_wchar)
+def needs_dlopen_none():
+ if sys.platform == 'win32' and sys.version_info >= (3,):
+ py.test.skip("dlopen(None) cannot work on Windows for Python 3")
+
class BackendTests:
@@ -354,7 +358,6 @@
#
p = ffi.new("wchar_t[]", u+'\U00023456')
if SIZE_OF_WCHAR == 2:
- assert sys.maxunicode == 0xffff
assert len(p) == 3
assert p[0] == u+'\ud84d'
assert p[1] == u+'\udc56'
@@ -937,6 +940,7 @@
def test_enum_partial(self):
ffi = FFI(backend=self.Backend())
ffi.cdef(r"enum foo {A, ...}; enum bar { B, C };")
+ needs_dlopen_none()
lib = ffi.dlopen(None)
assert lib.B == 0
py.test.raises(VerificationMissing, getattr, lib, "A")
@@ -1844,6 +1848,7 @@
#define DOT_UL 1000UL
enum foo {AA, BB=DOT, CC};
""")
+ needs_dlopen_none()
lib = ffi.dlopen(None)
assert ffi.string(ffi.cast("enum foo", 100)) == "BB"
assert lib.DOT_0 == 0
@@ -1873,6 +1878,7 @@
ffi = FFI()
ffi.include(ffi1)
ffi.cdef("enum { EE2, EE3 };")
+ needs_dlopen_none()
lib = ffi.dlopen(None)
assert lib.EE1 == 0
assert lib.EE2 == 0
diff --git a/testing/cffi0/test_function.py b/testing/cffi0/test_function.py
--- a/testing/cffi0/test_function.py
+++ b/testing/cffi0/test_function.py
@@ -5,6 +5,7 @@
from cffi.backend_ctypes import CTypesBackend
from testing.udir import udir
from testing.support import FdWriteCapture
+from .backend_tests import needs_dlopen_none
try:
from StringIO import StringIO
@@ -111,6 +112,7 @@
int fputs(const char *, void *);
void *stderr;
""")
+ needs_dlopen_none()
ffi.C = ffi.dlopen(None)
ffi.C.fputs # fetch before capturing, for easier debugging
with FdWriteCapture() as fd:
@@ -127,6 +129,7 @@
int fputs(char *, void *);
void *stderr;
""")
+ needs_dlopen_none()
ffi.C = ffi.dlopen(None)
ffi.C.fputs # fetch before capturing, for easier debugging
with FdWriteCapture() as fd:
@@ -143,6 +146,7 @@
int fprintf(void *, const char *format, ...);
void *stderr;
""")
+ needs_dlopen_none()
ffi.C = ffi.dlopen(None)
with FdWriteCapture() as fd:
ffi.C.fprintf(ffi.C.stderr, b"hello with no arguments\n")
@@ -169,6 +173,7 @@
ffi.cdef("""
int printf(const char *format, ...);
""")
+ needs_dlopen_none()
ffi.C = ffi.dlopen(None)
e = py.test.raises(TypeError, ffi.C.printf, b"hello %d\n", 42)
assert str(e.value) == ("argument 2 passed in the variadic part "
@@ -179,6 +184,7 @@
ffi.cdef("""
int puts(const char *);
""")
+ needs_dlopen_none()
ffi.C = ffi.dlopen(None)
fptr = ffi.C.puts
assert ffi.typeof(fptr) == ffi.typeof("int(*)(const char*)")
@@ -202,6 +208,7 @@
int fputs(const char *, void *);
void *stderr;
""")
+ needs_dlopen_none()
ffi.C = ffi.dlopen(None)
fptr = ffi.cast("int(*)(const char *txt, void *)", ffi.C.fputs)
assert fptr == ffi.C.fputs
@@ -235,6 +242,7 @@
ffi.cdef("""
int strlen(char[]);
""")
+ needs_dlopen_none()
ffi.C = ffi.dlopen(None)
p = ffi.new("char[]", b"hello")
res = ffi.C.strlen(p)
@@ -247,6 +255,7 @@
ffi.cdef("""
void *stdout;
""")
+ needs_dlopen_none()
C = ffi.dlopen(None)
pout = C.stdout
C.stdout = ffi.NULL
@@ -259,6 +268,7 @@
ffi.cdef("""
char *strchr(const char *s, int c);
""")
+ needs_dlopen_none()
ffi.C = ffi.dlopen(None)
p = ffi.new("char[]", b"hello world!")
q = ffi.C.strchr(p, ord('w'))
@@ -275,6 +285,7 @@
struct in_addr { unsigned int s_addr; };
char *inet_ntoa(struct in_addr in);
""")
+ needs_dlopen_none()
ffi.C = ffi.dlopen(None)
ina = ffi.new("struct in_addr *", [0x04040404])
a = ffi.C.inet_ntoa(ina[0])
@@ -296,6 +307,7 @@
filename = str(udir.join('fputs_custom_FILE'))
ffi = FFI(backend=self.Backend())
ffi.cdef("int fputs(const char *, FILE *);")
+ needs_dlopen_none()
C = ffi.dlopen(None)
with open(filename, 'wb') as f:
f.write(b'[')
@@ -311,6 +323,7 @@
ffi = FFI(backend=self.Backend())
ffi.cdef("""enum foo_e { AA, BB, CC=5, DD };
typedef enum { EE=-5, FF } some_enum_t;""")
+ needs_dlopen_none()
lib = ffi.dlopen(None)
assert lib.AA == 0
assert lib.BB == 1
@@ -322,6 +335,7 @@
def test_void_star_accepts_string(self):
ffi = FFI(backend=self.Backend())
ffi.cdef("""int strlen(const void *);""")
+ needs_dlopen_none()
lib = ffi.dlopen(None)
res = lib.strlen(b"hello")
assert res == 5
@@ -331,6 +345,7 @@
py.test.skip("not supported by the ctypes backend")
ffi = FFI(backend=self.Backend())
ffi.cdef("""int strlen(signed char *);""")
+ needs_dlopen_none()
lib = ffi.dlopen(None)
res = lib.strlen(b"hello")
assert res == 5
@@ -340,6 +355,7 @@
py.test.skip("not supported by the ctypes backend")
ffi = FFI(backend=self.Backend())
ffi.cdef("""int strlen(unsigned char *);""")
+ needs_dlopen_none()
lib = ffi.dlopen(None)
res = lib.strlen(b"hello")
assert res == 5
diff --git a/testing/cffi0/test_parsing.py b/testing/cffi0/test_parsing.py
--- a/testing/cffi0/test_parsing.py
+++ b/testing/cffi0/test_parsing.py
@@ -1,5 +1,7 @@
import py, sys, re
from cffi import FFI, FFIError, CDefError, VerificationError
+from .backend_tests import needs_dlopen_none
+
class FakeBackend(object):
@@ -90,6 +92,7 @@
def test_pipe():
ffi = FFI(backend=FakeBackend())
ffi.cdef("int pipe(int pipefd[2]);")
+ needs_dlopen_none()
C = ffi.dlopen(None)
func = C.pipe
assert func.name == 'pipe'
@@ -98,6 +101,7 @@
def test_vararg():
ffi = FFI(backend=FakeBackend())
ffi.cdef("short foo(int, ...);")
+ needs_dlopen_none()
C = ffi.dlopen(None)
func = C.foo
assert func.name == 'foo'
@@ -108,6 +112,7 @@
ffi.cdef("""
int foo(void);
""")
+ needs_dlopen_none()
C = ffi.dlopen(None)
assert C.foo.BType == '<func (), <int>, False>'
@@ -118,6 +123,7 @@
typedef UInt UIntReally;
UInt foo(void);
""")
+ needs_dlopen_none()
C = ffi.dlopen(None)
assert str(ffi.typeof("UIntReally")) == '<unsigned int>'
assert C.foo.BType == '<func (), <unsigned int>, False>'
@@ -128,6 +134,7 @@
typedef struct { int a, b; } foo_t, *foo_p;
int foo(foo_p[]);
""")
+ needs_dlopen_none()
C = ffi.dlopen(None)
assert str(ffi.typeof("foo_t")) == '<int>a, <int>b'
assert str(ffi.typeof("foo_p")) == '<pointer to <int>a, <int>b>'
@@ -217,6 +224,7 @@
def test_override():
ffi = FFI(backend=FakeBackend())
+ needs_dlopen_none()
C = ffi.dlopen(None)
ffi.cdef("int foo(void);")
py.test.raises(FFIError, ffi.cdef, "long foo(void);")
@@ -403,6 +411,7 @@
ffi.cdef("""
enum Enum { POS = +1, TWO = 2, NIL = 0, NEG = -1, OP = (POS+TWO)-1};
""")
+ needs_dlopen_none()
C = ffi.dlopen(None)
assert C.POS == 1
assert C.TWO == 2
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit