[pypy-svn] r50353 - in pypy/branch/applevel-ctypes2/pypy/module/_ffi: . test
fijal at codespeak.net
fijal at codespeak.net
Sat Jan 5 13:10:36 CET 2008
Author: fijal
Date: Sat Jan 5 13:10:35 2008
New Revision: 50353
Modified:
pypy/branch/applevel-ctypes2/pypy/module/_ffi/__init__.py
pypy/branch/applevel-ctypes2/pypy/module/_ffi/app_ffi.py
pypy/branch/applevel-ctypes2/pypy/module/_ffi/interp_ffi.py
pypy/branch/applevel-ctypes2/pypy/module/_ffi/structure.py
pypy/branch/applevel-ctypes2/pypy/module/_ffi/test/test__ffi.py
Log:
Merge _ffi from branch applevel-ctypes here
Modified: pypy/branch/applevel-ctypes2/pypy/module/_ffi/__init__.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_ffi/__init__.py (original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_ffi/__init__.py Sat Jan 5 13:10:35 2008
@@ -12,6 +12,7 @@
interpleveldefs = {
'CDLL' : 'interp_ffi.W_CDLL',
'FuncPtr' : 'interp_ffi.W_FuncPtr',
+ 'Structure' : 'structure.W_Structure',
'StructureInstance' : 'structure.W_StructureInstance',
'ArrayInstance' : 'array.W_ArrayInstance',
'_get_type' : 'interp_ffi._w_get_type',
@@ -19,7 +20,5 @@
}
appleveldefs = {
- 'Structure' : 'app_ffi.Structure',
'Array' : 'app_ffi.Array',
- #'StructureInstance' : 'app_ffi.StructureInstance',
}
Modified: pypy/branch/applevel-ctypes2/pypy/module/_ffi/app_ffi.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_ffi/app_ffi.py (original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_ffi/app_ffi.py Sat Jan 5 13:10:35 2008
@@ -1,24 +1,5 @@
# NOT_RPYTHON
-class Structure(object):
- def check_fields(self, fields):
- import _ffi
- for name, letter in fields:
- _ffi._get_type(letter)
-
- def __init__(self, fields):
- self.check_fields(fields)
- self.fields = fields
-
- def __call__(self, *args, **kwds):
- from _ffi import StructureInstance
- if args:
- if len(args) > 1:
- raise TypeError("Can give at most one non-keyword argument")
- if kwds:
- raise TypeError("Keyword arguments not allowed when passing address argument")
- return StructureInstance(self, args[0], None)
- return StructureInstance(self, None, kwds)
class Array(object):
def __init__(self, of):
Modified: pypy/branch/applevel-ctypes2/pypy/module/_ffi/interp_ffi.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_ffi/interp_ffi.py (original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_ffi/interp_ffi.py Sat Jan 5 13:10:35 2008
@@ -124,14 +124,14 @@
__new__ = interp2app(descr_new_cdll),
ptr = interp2app(W_CDLL.ptr),
__doc__ = """ C Dynamically loaded library
-use CDLL(libname) to create handle to C library (argument is processed the
-same way as dlopen processes it). On such library call:
+use CDLL(libname) to create a handle to a C library (the argument is processed
+the same way as dlopen processes it). On such a library you can call:
lib.ptr(func_name, argtype_list, restype)
where argtype_list is a list of single characters and restype is a single
-character. Character meanings are more or less the same as in struct module,
-except that s has trailing \x00 added, while p is considered a raw buffer.
-"""
+character. The character meanings are more or less the same as in the struct
+module, except that s has trailing \x00 added, while p is considered a raw
+buffer."""
)
def pack_pointer(space, add_arg, argdesc, w_arg, push_func):
Modified: pypy/branch/applevel-ctypes2/pypy/module/_ffi/structure.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_ffi/structure.py (original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_ffi/structure.py Sat Jan 5 13:10:35 2008
@@ -3,9 +3,9 @@
to app-level with apropriate interface
"""
-from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable,\
- Arguments
-from pypy.interpreter.gateway import interp2app
+from pypy.interpreter.baseobjspace import W_Root, Wrappable
+from pypy.interpreter.gateway import interp2app, ObjSpace
+from pypy.interpreter.argument import Arguments
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.interpreter.error import OperationError, wrap_oserror
@@ -13,7 +13,7 @@
# the other one is in rlib/libffi, we should refactor it to reuse the same
# logic, I'll not touch it by now, and refactor it later
from pypy.module.struct.nativefmttable import native_fmttable as struct_native_fmttable
-from pypy.module._ffi.interp_ffi import wrap_value, unwrap_value, _get_type
+from pypy.module._ffi.interp_ffi import wrap_value, unwrap_value, _get_type, TYPEMAP
native_fmttable = {}
for key, value in struct_native_fmttable.items():
@@ -45,55 +45,98 @@
size += field_desc['size']
return size, pos
+
+class W_Structure(Wrappable):
+ def __init__(self, space, w_fields):
+ fields = unpack_fields(space, w_fields)
+ name_to_offset = {}
+ for i in range(len(fields)):
+ name, letter = fields[i]
+ if letter not in TYPEMAP:
+ raise OperationError(space.w_ValueError, space.wrap(
+ "Unkown type letter %s" % (letter,)))
+ if name in name_to_offset:
+ raise OperationError(space.w_ValueError, space.wrap(
+ "duplicate field name %s" % (name, )))
+ name_to_offset[name] = i
+ size, pos = size_and_pos(fields)
+ self.size = size
+ self.ll_positions = pos
+ self.fields = fields
+ self.name_to_offset = name_to_offset
+
+ def descr_call(self, space, __args__):
+ args_w, kwargs_w = __args__.unpack()
+ if args_w:
+ if len(args_w) > 1:
+ raise OperationError(
+ space.w_TypeError,
+ space.wrap("Can give at most one non-keyword argument"))
+ if kwargs_w:
+ raise OperationError(
+ space.w_TypeError,
+ space.wrap("Keyword arguments not allowed when passing address argument"))
+ return space.wrap(W_StructureInstance(space, self, args_w[0], None))
+ return space.wrap(W_StructureInstance(space, self, None, kwargs_w))
+
+def descr_new_structure(space, w_type, w_fields):
+ return space.wrap(W_Structure(space, w_fields))
+
+W_Structure.typedef = TypeDef(
+ 'Structure',
+ __new__ = interp2app(descr_new_structure),
+ __call__ = interp2app(W_Structure.descr_call,
+ unwrap_spec=['self', ObjSpace, Arguments]),
+)
+W_Structure.typedef.acceptable_as_base_class = False
+
def push_field(self, num, value):
- ptr = rffi.ptradd(self.ll_buffer, self.ll_positions[num])
+ ptr = rffi.ptradd(self.ll_buffer, self.shape.ll_positions[num])
TP = lltype.typeOf(value)
T = lltype.Ptr(rffi.CArray(TP))
rffi.cast(T, ptr)[0] = value
push_field._annspecialcase_ = 'specialize:argtype(2)'
def cast_pos(self, i, ll_t):
- pos = rffi.ptradd(self.ll_buffer, self.ll_positions[i])
+ pos = rffi.ptradd(self.ll_buffer, self.shape.ll_positions[i])
TP = lltype.Ptr(rffi.CArray(ll_t))
return rffi.cast(TP, pos)[0]
cast_pos._annspecialcase_ = 'specialize:arg(2)'
class W_StructureInstance(Wrappable):
- def __init__(self, space, w_shape, w_address, w_fieldinits):
+ def __init__(self, space, shape, w_address, fieldinits_w):
self.free_afterwards = False
- w_fields = space.getattr(w_shape, space.wrap('fields'))
- fields = unpack_fields(space, w_fields)
- size, pos = size_and_pos(fields)
- self.fields = fields
- if space.is_true(w_address):
+ self.shape = shape
+ if w_address is not None:
self.ll_buffer = rffi.cast(rffi.VOIDP, space.int_w(w_address))
else:
self.free_afterwards = True
- self.ll_buffer = lltype.malloc(rffi.VOIDP.TO, size, flavor='raw',
+ self.ll_buffer = lltype.malloc(rffi.VOIDP.TO, shape.size, flavor='raw',
zero=True)
- self.ll_positions = pos
- if space.is_true(w_fieldinits):
- for w_field in space.unpackiterable(w_fieldinits):
- w_value = space.getitem(w_fieldinits, w_field)
- self.setattr(space, space.str_w(w_field), w_value)
+ if fieldinits_w:
+ self.fieldinits_w = fieldinits_w
+ for field, w_value in fieldinits_w.iteritems():
+ self.setattr(space, field, w_value)
+ else:
+ self.fieldinits_w = None
+
+ def getindex(self, space, attr):
+ try:
+ return self.shape.name_to_offset[attr]
+ except KeyError:
+ raise OperationError(space.w_AttributeError, space.wrap(
+ "C Structure has no attribute %s" % attr))
def getattr(self, space, attr):
- if attr.startswith('tm'):
- pass
- for i in range(len(self.fields)):
- name, c = self.fields[i]
- if name == attr:
- return wrap_value(space, cast_pos, self, i, c)
- raise OperationError(space.w_AttributeError, space.wrap(
- "C Structure has no attribute %s" % attr))
+ i = self.getindex(space, attr)
+ _, c = self.shape.fields[i]
+ return wrap_value(space, cast_pos, self, i, c)
getattr.unwrap_spec = ['self', ObjSpace, str]
def setattr(self, space, attr, w_value):
- for i in range(len(self.fields)):
- name, c = self.fields[i]
- if name == attr:
- unwrap_value(space, push_field, self, i, c, w_value, None)
- return
+ i = self.getindex(space, attr)
+ _, c = self.shape.fields[i]
+ unwrap_value(space, push_field, self, i, c, w_value, None)
setattr.unwrap_spec = ['self', ObjSpace, str, W_Root]
def __del__(self):
@@ -103,13 +146,11 @@
def getbuffer(space, self):
return space.wrap(rffi.cast(rffi.INT, self.ll_buffer))
-def descr_new_structure_instance(space, w_type, w_shape, w_adr, w_fieldinits):
- return W_StructureInstance(space, w_shape, w_adr, w_fieldinits)
-
W_StructureInstance.typedef = TypeDef(
'StructureInstance',
- __new__ = interp2app(descr_new_structure_instance),
__getattr__ = interp2app(W_StructureInstance.getattr),
__setattr__ = interp2app(W_StructureInstance.setattr),
buffer = GetSetProperty(W_StructureInstance.getbuffer),
)
+W_StructureInstance.typedef.acceptable_as_base_class = False
+
Modified: pypy/branch/applevel-ctypes2/pypy/module/_ffi/test/test__ffi.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_ffi/test/test__ffi.py (original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_ffi/test/test__ffi.py Sat Jan 5 13:10:35 2008
@@ -212,7 +212,6 @@
X = _ffi.Structure([('x1', 'i'), ('x2', 'h'), ('x3', 'c'), ('next', 'P')])
x = X(next=X(next=None, x3='x'), x1=1, x2=2, x3='x')
assert X(x.next).x3 == 'x'
- assert inner(x) == 'x'
create_double_struct = lib.ptr("create_double_struct", [], 'P')
x = create_double_struct()
assert X(X(x).next).x2 == 3
@@ -258,9 +257,7 @@
raises(ValueError, "lib.ptr('get_char', ['x'], None)")
raises(ValueError, "lib.ptr('get_char', [], 'x')")
raises(ValueError, "_ffi.Structure(['x1', 'xx'])")
- S = _ffi.Structure([('x1', 'i')])
- S.fields[0] = ('x1', 'xx')
- raises(ValueError, "S()")
+ raises(ValueError, _ffi.Structure, [('x1', 'xx')])
raises(ValueError, "_ffi.Array('xx')")
A = _ffi.Array('i')
A.of = 'xx'
@@ -305,3 +302,14 @@
_ffi.CallbackPtr(compare, ['i', 'i'], 'i'))
res = [ll_to_sort[i] for i in range(len(to_sort))]
assert res == sorted(to_sort)
+
+ def test_setattr_struct(self):
+ import _ffi
+ X = _ffi.Structure([('value1', 'i'), ('value2', 'i')])
+ x = X(value1=1, value2=2)
+ assert x.value1 == 1
+ assert x.value2 == 2
+ x.value1 = 3
+ assert x.value1 == 3
+ raises(AttributeError, "x.foo")
+ raises(AttributeError, "x.foo = 1")
More information about the Pypy-commit
mailing list