[pypy-commit] pypy ffistruct: split the implementation/tests of W_FFIType and W_FuncPtr into two separate files
antocuni
noreply at buildbot.pypy.org
Tue Sep 6 18:04:39 CEST 2011
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: ffistruct
Changeset: r47109:edee74efbb9c
Date: 2011-09-05 16:47 +0200
http://bitbucket.org/pypy/pypy/changeset/edee74efbb9c/
Log: split the implementation/tests of W_FFIType and W_FuncPtr into two
separate files
diff --git a/pypy/module/_ffi/__init__.py b/pypy/module/_ffi/__init__.py
--- a/pypy/module/_ffi/__init__.py
+++ b/pypy/module/_ffi/__init__.py
@@ -1,13 +1,12 @@
from pypy.interpreter.mixedmodule import MixedModule
-from pypy.module._ffi import interp_ffi
class Module(MixedModule):
interpleveldefs = {
- 'CDLL': 'interp_ffi.W_CDLL',
- 'types': 'interp_ffi.W_types',
- 'FuncPtr': 'interp_ffi.W_FuncPtr',
- 'get_libc':'interp_ffi.get_libc',
+ 'types': 'interp_ffitype.W_types',
+ 'CDLL': 'interp_funcptr.W_CDLL',
+ 'FuncPtr': 'interp_funcptr.W_FuncPtr',
+ 'get_libc':'interp_funcptr.get_libc',
}
appleveldefs = {
diff --git a/pypy/module/_ffi/app_struct.py b/pypy/module/_ffi/app_struct.py
--- a/pypy/module/_ffi/app_struct.py
+++ b/pypy/module/_ffi/app_struct.py
@@ -5,6 +5,15 @@
self.ffitype = ffitype
self.offset = -1
+ ## def __get__(self, obj, cls=None):
+ ## if obj is None:
+ ## return self
+ ## return getfield(obj._buffer, self.ffitype, self.offset)
+
+ ## def __set__(self, obj, value):
+ ## setfield(obj._buffer, self.ffitype, self.offset, value)
+
+
class MetaStructure(type):
def __new__(cls, name, bases, dic):
diff --git a/pypy/module/_ffi/interp_ffitype.py b/pypy/module/_ffi/interp_ffitype.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_ffi/interp_ffitype.py
@@ -0,0 +1,156 @@
+from pypy.rlib import libffi
+from pypy.rlib.rarithmetic import intmask
+from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.gateway import interp2app
+
+class W_FFIType(Wrappable):
+
+ _immutable_fields_ = ['name', 'ffitype', 'w_datashape', 'w_pointer_to']
+
+ def __init__(self, name, ffitype, w_datashape=None, w_pointer_to=None):
+ self.name = name
+ self.ffitype = ffitype
+ self.w_datashape = w_datashape
+ self.w_pointer_to = w_pointer_to
+ if self.is_struct():
+ assert w_datashape is not None
+
+ def descr_deref_pointer(self, space):
+ if self.w_pointer_to is None:
+ return space.w_None
+ return self.w_pointer_to
+
+ def descr_sizeof(self, space):
+ return space.wrap(self.sizeof())
+
+ def sizeof(self):
+ return intmask(self.ffitype.c_size)
+
+ def repr(self, space):
+ return space.wrap(self.__repr__())
+
+ def __repr__(self):
+ return "<ffi type %s>" % self.name
+
+ def is_signed(self):
+ return (self is app_types.slong or
+ self is app_types.sint or
+ self is app_types.sshort or
+ self is app_types.sbyte or
+ self is app_types.slonglong)
+
+ def is_unsigned(self):
+ return (self is app_types.ulong or
+ self is app_types.uint or
+ self is app_types.ushort or
+ self is app_types.ubyte or
+ self is app_types.ulonglong)
+
+ def is_pointer(self):
+ return self.ffitype is libffi.types.pointer
+
+ def is_char(self):
+ return self is app_types.char
+
+ def is_unichar(self):
+ return self is app_types.unichar
+
+ def is_longlong(self):
+ return libffi.IS_32_BIT and (self is app_types.slonglong or
+ self is app_types.ulonglong)
+
+ def is_double(self):
+ return self is app_types.double
+
+ def is_singlefloat(self):
+ return self is app_types.float
+
+ def is_void(self):
+ return self is app_types.void
+
+ def is_struct(self):
+ return libffi.types.is_struct(self.ffitype)
+
+ def is_char_p(self):
+ return self is app_types.char_p
+
+ def is_unichar_p(self):
+ return self is app_types.unichar_p
+
+
+W_FFIType.typedef = TypeDef(
+ 'FFIType',
+ __repr__ = interp2app(W_FFIType.repr),
+ deref_pointer = interp2app(W_FFIType.descr_deref_pointer),
+ sizeof = interp2app(W_FFIType.descr_sizeof),
+ )
+
+
+def build_ffi_types():
+ types = [
+ # note: most of the type name directly come from the C equivalent,
+ # with the exception of bytes: in C, ubyte and char are equivalent,
+ # but for _ffi the first expects a number while the second a 1-length
+ # string
+ W_FFIType('slong', libffi.types.slong),
+ W_FFIType('sint', libffi.types.sint),
+ W_FFIType('sshort', libffi.types.sshort),
+ W_FFIType('sbyte', libffi.types.schar),
+ W_FFIType('slonglong', libffi.types.slonglong),
+ #
+ W_FFIType('ulong', libffi.types.ulong),
+ W_FFIType('uint', libffi.types.uint),
+ W_FFIType('ushort', libffi.types.ushort),
+ W_FFIType('ubyte', libffi.types.uchar),
+ W_FFIType('ulonglong', libffi.types.ulonglong),
+ #
+ W_FFIType('char', libffi.types.uchar),
+ W_FFIType('unichar', libffi.types.wchar_t),
+ #
+ W_FFIType('double', libffi.types.double),
+ W_FFIType('float', libffi.types.float),
+ W_FFIType('void', libffi.types.void),
+ W_FFIType('void_p', libffi.types.pointer),
+ #
+ # missing types:
+
+ ## 's' : ffi_type_pointer,
+ ## 'z' : ffi_type_pointer,
+ ## 'O' : ffi_type_pointer,
+ ## 'Z' : ffi_type_pointer,
+
+ ]
+ d = dict([(t.name, t) for t in types])
+ w_char = d['char']
+ w_unichar = d['unichar']
+ d['char_p'] = W_FFIType('char_p', libffi.types.pointer, w_pointer_to = w_char)
+ d['unichar_p'] = W_FFIType('unichar_p', libffi.types.pointer, w_pointer_to = w_unichar)
+ return d
+
+class app_types:
+ pass
+app_types.__dict__ = build_ffi_types()
+
+def descr_new_pointer(space, w_cls, w_pointer_to):
+ try:
+ return descr_new_pointer.cache[w_pointer_to]
+ except KeyError:
+ if w_pointer_to is app_types.char:
+ w_result = app_types.char_p
+ elif w_pointer_to is app_types.unichar:
+ w_result = app_types.unichar_p
+ else:
+ w_pointer_to = space.interp_w(W_FFIType, w_pointer_to)
+ name = '(pointer to %s)' % w_pointer_to.name
+ w_result = W_FFIType(name, libffi.types.pointer, w_pointer_to = w_pointer_to)
+ descr_new_pointer.cache[w_pointer_to] = w_result
+ return w_result
+descr_new_pointer.cache = {}
+
+class W_types(Wrappable):
+ pass
+W_types.typedef = TypeDef(
+ 'types',
+ Pointer = interp2app(descr_new_pointer, as_classmethod=True),
+ **app_types.__dict__)
diff --git a/pypy/module/_ffi/interp_ffi.py b/pypy/module/_ffi/interp_funcptr.py
rename from pypy/module/_ffi/interp_ffi.py
rename to pypy/module/_ffi/interp_funcptr.py
--- a/pypy/module/_ffi/interp_ffi.py
+++ b/pypy/module/_ffi/interp_funcptr.py
@@ -4,6 +4,7 @@
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.typedef import TypeDef
from pypy.module._rawffi.structure import W_StructureInstance, W_Structure
+from pypy.module._ffi.interp_ffitype import W_FFIType
#
from pypy.rpython.lltypesystem import lltype, rffi
#
@@ -13,157 +14,6 @@
from pypy.rlib.rarithmetic import intmask, r_uint
from pypy.rlib.objectmodel import we_are_translated
-class W_FFIType(Wrappable):
-
- _immutable_fields_ = ['name', 'ffitype', 'w_datashape', 'w_pointer_to']
-
- def __init__(self, name, ffitype, w_datashape=None, w_pointer_to=None):
- self.name = name
- self.ffitype = ffitype
- self.w_datashape = w_datashape
- self.w_pointer_to = w_pointer_to
- if self.is_struct():
- assert w_datashape is not None
-
- def descr_deref_pointer(self, space):
- if self.w_pointer_to is None:
- return space.w_None
- return self.w_pointer_to
-
- def descr_sizeof(self, space):
- return space.wrap(self.sizeof())
-
- def sizeof(self):
- return intmask(self.ffitype.c_size)
-
- def repr(self, space):
- return space.wrap(self.__repr__())
-
- def __repr__(self):
- return "<ffi type %s>" % self.name
-
- def is_signed(self):
- return (self is app_types.slong or
- self is app_types.sint or
- self is app_types.sshort or
- self is app_types.sbyte or
- self is app_types.slonglong)
-
- def is_unsigned(self):
- return (self is app_types.ulong or
- self is app_types.uint or
- self is app_types.ushort or
- self is app_types.ubyte or
- self is app_types.ulonglong)
-
- def is_pointer(self):
- return self.ffitype is libffi.types.pointer
-
- def is_char(self):
- return self is app_types.char
-
- def is_unichar(self):
- return self is app_types.unichar
-
- def is_longlong(self):
- return libffi.IS_32_BIT and (self is app_types.slonglong or
- self is app_types.ulonglong)
-
- def is_double(self):
- return self is app_types.double
-
- def is_singlefloat(self):
- return self is app_types.float
-
- def is_void(self):
- return self is app_types.void
-
- def is_struct(self):
- return libffi.types.is_struct(self.ffitype)
-
- def is_char_p(self):
- return self is app_types.char_p
-
- def is_unichar_p(self):
- return self is app_types.unichar_p
-
-
-W_FFIType.typedef = TypeDef(
- 'FFIType',
- __repr__ = interp2app(W_FFIType.repr),
- deref_pointer = interp2app(W_FFIType.descr_deref_pointer),
- sizeof = interp2app(W_FFIType.descr_sizeof),
- )
-
-
-def build_ffi_types():
- types = [
- # note: most of the type name directly come from the C equivalent,
- # with the exception of bytes: in C, ubyte and char are equivalent,
- # but for _ffi the first expects a number while the second a 1-length
- # string
- W_FFIType('slong', libffi.types.slong),
- W_FFIType('sint', libffi.types.sint),
- W_FFIType('sshort', libffi.types.sshort),
- W_FFIType('sbyte', libffi.types.schar),
- W_FFIType('slonglong', libffi.types.slonglong),
- #
- W_FFIType('ulong', libffi.types.ulong),
- W_FFIType('uint', libffi.types.uint),
- W_FFIType('ushort', libffi.types.ushort),
- W_FFIType('ubyte', libffi.types.uchar),
- W_FFIType('ulonglong', libffi.types.ulonglong),
- #
- W_FFIType('char', libffi.types.uchar),
- W_FFIType('unichar', libffi.types.wchar_t),
- #
- W_FFIType('double', libffi.types.double),
- W_FFIType('float', libffi.types.float),
- W_FFIType('void', libffi.types.void),
- W_FFIType('void_p', libffi.types.pointer),
- #
- # missing types:
-
- ## 's' : ffi_type_pointer,
- ## 'z' : ffi_type_pointer,
- ## 'O' : ffi_type_pointer,
- ## 'Z' : ffi_type_pointer,
-
- ]
- d = dict([(t.name, t) for t in types])
- w_char = d['char']
- w_unichar = d['unichar']
- d['char_p'] = W_FFIType('char_p', libffi.types.pointer, w_pointer_to = w_char)
- d['unichar_p'] = W_FFIType('unichar_p', libffi.types.pointer, w_pointer_to = w_unichar)
- return d
-
-class app_types:
- pass
-app_types.__dict__ = build_ffi_types()
-
-def descr_new_pointer(space, w_cls, w_pointer_to):
- try:
- return descr_new_pointer.cache[w_pointer_to]
- except KeyError:
- if w_pointer_to is app_types.char:
- w_result = app_types.char_p
- elif w_pointer_to is app_types.unichar:
- w_result = app_types.unichar_p
- else:
- w_pointer_to = space.interp_w(W_FFIType, w_pointer_to)
- name = '(pointer to %s)' % w_pointer_to.name
- w_result = W_FFIType(name, libffi.types.pointer, w_pointer_to = w_pointer_to)
- descr_new_pointer.cache[w_pointer_to] = w_result
- return w_result
-descr_new_pointer.cache = {}
-
-class W_types(Wrappable):
- pass
-W_types.typedef = TypeDef(
- 'types',
- Pointer = interp2app(descr_new_pointer, as_classmethod=True),
- **app_types.__dict__)
-
def unwrap_ffitype(space, w_argtype, allow_void=False):
res = w_argtype.ffitype
diff --git a/pypy/module/_ffi/test/test_ffitype.py b/pypy/module/_ffi/test/test_ffitype.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_ffi/test/test_ffitype.py
@@ -0,0 +1,37 @@
+from pypy.module._ffi.test.test_funcptr import BaseAppTestFFI
+
+class AppTestFFIType(BaseAppTestFFI):
+
+ def test_simple_types(self):
+ from _ffi import types
+ assert str(types.sint) == "<ffi type sint>"
+ assert str(types.uint) == "<ffi type uint>"
+
+ def test_sizeof(self):
+ from _ffi import types
+ assert types.sbyte.sizeof() == 1
+ assert types.sint.sizeof() == 4
+
+ def test_typed_pointer(self):
+ from _ffi import types
+ intptr = types.Pointer(types.sint) # create a typed pointer to sint
+ assert intptr.deref_pointer() is types.sint
+ assert str(intptr) == '<ffi type (pointer to sint)>'
+ assert types.sint.deref_pointer() is None
+ raises(TypeError, "types.Pointer(42)")
+
+ def test_pointer_identity(self):
+ from _ffi import types
+ x = types.Pointer(types.slong)
+ y = types.Pointer(types.slong)
+ z = types.Pointer(types.char)
+ assert x is y
+ assert x is not z
+
+ def test_char_p_cached(self):
+ from _ffi import types
+ x = types.Pointer(types.char)
+ assert x is types.char_p
+ x = types.Pointer(types.unichar)
+ assert x is types.unichar_p
+
diff --git a/pypy/module/_ffi/test/test__ffi.py b/pypy/module/_ffi/test/test_funcptr.py
rename from pypy/module/_ffi/test/test__ffi.py
rename to pypy/module/_ffi/test/test_funcptr.py
--- a/pypy/module/_ffi/test/test__ffi.py
+++ b/pypy/module/_ffi/test/test_funcptr.py
@@ -82,16 +82,6 @@
res = dll.getfunc('Py_IsInitialized', [], types.slong)()
assert res == 1
- def test_simple_types(self):
- from _ffi import types
- assert str(types.sint) == "<ffi type sint>"
- assert str(types.uint) == "<ffi type uint>"
-
- def test_sizeof(self):
- from _ffi import types
- assert types.sbyte.sizeof() == 1
- assert types.sint.sizeof() == 4
-
def test_callfunc(self):
from _ffi import CDLL, types
libm = CDLL(self.libm_name)
@@ -266,29 +256,6 @@
assert list(array) == list('foobar\00')
do_nothing.free_temp_buffers()
- def test_typed_pointer(self):
- from _ffi import types
- intptr = types.Pointer(types.sint) # create a typed pointer to sint
- assert intptr.deref_pointer() is types.sint
- assert str(intptr) == '<ffi type (pointer to sint)>'
- assert types.sint.deref_pointer() is None
- raises(TypeError, "types.Pointer(42)")
-
- def test_pointer_identity(self):
- from _ffi import types
- x = types.Pointer(types.slong)
- y = types.Pointer(types.slong)
- z = types.Pointer(types.char)
- assert x is y
- assert x is not z
-
- def test_char_p_cached(self):
- from _ffi import types
- x = types.Pointer(types.char)
- assert x is types.char_p
- x = types.Pointer(types.unichar)
- assert x is types.unichar_p
-
def test_typed_pointer_args(self):
"""
extern int dummy; // defined in test_void_result
diff --git a/pypy/module/_ffi/test/test_struct.py b/pypy/module/_ffi/test/test_struct.py
--- a/pypy/module/_ffi/test/test_struct.py
+++ b/pypy/module/_ffi/test/test_struct.py
@@ -1,4 +1,4 @@
-from pypy.module._ffi.test.test__ffi import BaseAppTestFFI
+from pypy.module._ffi.test.test_funcptr import BaseAppTestFFI
class AppTestStruct(BaseAppTestFFI):
More information about the pypy-commit
mailing list