[pypy-svn] r51617 - in pypy/dist/pypy/lib: _ctypes app_test/ctypes
fijal at codespeak.net
fijal at codespeak.net
Tue Feb 19 00:32:23 CET 2008
Author: fijal
Date: Tue Feb 19 00:32:21 2008
New Revision: 51617
Modified:
pypy/dist/pypy/lib/_ctypes/array.py
pypy/dist/pypy/lib/_ctypes/basics.py
pypy/dist/pypy/lib/_ctypes/structure.py
pypy/dist/pypy/lib/app_test/ctypes/test_structures.py
Log:
* A bit of simplification
* Forest of ifs what we support and what we don't in terms of args
for arrays
* Structure/Array inlining now shall work.
Modified: pypy/dist/pypy/lib/_ctypes/array.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/array.py (original)
+++ pypy/dist/pypy/lib/_ctypes/array.py Tue Feb 19 00:32:21 2008
@@ -3,6 +3,7 @@
from _ctypes.basics import _CData, cdata_from_address, _CDataMeta, sizeof,\
keepalive_key, store_reference, CArgObject
+from _ctypes.builtin import _string_at_addr, _wstring_at_addr
def _create_unicode(buffer, maxlength):
res = []
@@ -71,6 +72,12 @@
return self._type_._alignmentofinstances()
def _CData_output(self, resarray, base=None, index=-1):
+ # this seems to be a string if we're array of char, surprise!
+ from ctypes import c_char, c_wchar, c_char_p, c_wchar_p
+ if self._type_ is c_char:
+ return _rawffi.charp2string(resarray.buffer, self._length_)
+ if self._type_ is c_wchar:
+ xxx
res = self.__new__(self)
ffiarray = self._ffiarray.fromaddress(resarray.buffer, self._length_)
res._buffer = ffiarray
@@ -78,6 +85,22 @@
res._index = index
return res.__ctypes_from_outparam__()
+ def _CData_value(self, value):
+ # array accepts very strange parameters as part of structure
+ # or function argument...
+ from ctypes import c_char, c_wchar
+ if issubclass(self._type_, (c_char, c_wchar)):
+ if isinstance(value, basestring):
+ if len(value) > self._length_:
+ raise ValueError("Invalid length")
+ return self(*value)
+ else:
+ if isinstance(value, tuple):
+ if len(value) > self._length_:
+ raise RuntimeError("Invalid length")
+ return self(*value)
+ return _CDataMeta._CData_value(self, value)
+
def array_get_slice_params(self, index):
if index.step is not None:
raise TypeError("3 arg slices not supported (for no reason)")
@@ -158,6 +181,9 @@
def _get_buffer_for_param(self):
return CArgObject(self._buffer.byptr())
+ def _get_buffer_value(self):
+ return self._buffer.buffer
+
def __del__(self):
if self._needs_free:
self._buffer.free()
Modified: pypy/dist/pypy/lib/_ctypes/basics.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/basics.py (original)
+++ pypy/dist/pypy/lib/_ctypes/basics.py Tue Feb 19 00:32:21 2008
@@ -45,7 +45,7 @@
cobj = self.from_param(value)
# we don't care here if this stuff will live afterwards, as we're
# interested only in value anyway
- return cobj._get_buffer_for_param()._buffer[0]
+ return cobj._get_buffer_value()
def _CData_output(self, resarray, base=None, index=-1, needs_free=False):
assert isinstance(resarray, _rawffi.ArrayInstance)
@@ -99,6 +99,9 @@
def _get_buffer_for_param(self):
return self
+ def _get_buffer_value(self):
+ return self._buffer[0]
+
def sizeof(tp):
if not isinstance(tp, _CDataMeta):
if isinstance(tp, _CData):
Modified: pypy/dist/pypy/lib/_ctypes/structure.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/structure.py (original)
+++ pypy/dist/pypy/lib/_ctypes/structure.py Tue Feb 19 00:32:21 2008
@@ -141,6 +141,11 @@
def _alignmentofinstances(self):
return self._ffistruct.alignment
+ def _CData_value(self, value):
+ if isinstance(value, tuple):
+ return self(*value)
+ return _CDataMeta._CData_value(self, value)
+
def _CData_output(self, resarray, base=None, index=-1):
res = self.__new__(self)
ffistruct = self._ffistruct.fromaddress(resarray.buffer)
@@ -169,7 +174,13 @@
if getattr(value, '_objects', None):
key = keepalive_key(getattr(self.__class__, name).offset)
store_reference(self, key, value._objects)
- self._buffer.__setattr__(name, fieldtype._CData_value(value))
+ arg = fieldtype._CData_value(value)
+ if isinstance(fieldtype._ffishape, tuple):
+ from ctypes import memmove
+ dest = self._buffer.fieldaddress(name)
+ memmove(dest, arg._buffer.buffer, fieldtype._ffishape[0])
+ else:
+ self._buffer.__setattr__(name, arg)
def __getattribute__(self, name):
if name == '_fieldtypes':
@@ -185,6 +196,9 @@
def _get_buffer_for_param(self):
return CArgObject(self._buffer.byptr())
+ def _get_buffer_value(self):
+ return self._buffer.buffer
+
def __del__(self):
if self._needs_free:
self._buffer.free()
Modified: pypy/dist/pypy/lib/app_test/ctypes/test_structures.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/ctypes/test_structures.py (original)
+++ pypy/dist/pypy/lib/app_test/ctypes/test_structures.py Tue Feb 19 00:32:21 2008
@@ -161,7 +161,7 @@
# offset is always relative to the class...
def test_packed(self):
- py.test.skip("???")
+ py.test.skip("Custom alignment not supported")
class X(Structure):
_fields_ = [("a", c_byte),
("b", c_longlong)]
@@ -203,7 +203,6 @@
raises(ValueError, type(Structure), "X", (Structure,), d)
def test_initializers(self):
- py.test.skip("Structures with inlined arrays")
class Person(Structure):
_fields_ = [("name", c_char*6),
("age", c_int)]
@@ -235,7 +234,6 @@
raises(TypeError, setattr, POINT, "_fields_", [("x", 1), ("y", 2)])
def test_intarray_fields(self):
- py.test.skip("Structures with inlined arrays")
class SomeInts(Structure):
_fields_ = [("a", c_int * 4)]
@@ -247,7 +245,6 @@
raises(RuntimeError, SomeInts, (1, 2, 3, 4, 5))
def test_nested_initializers(self):
- py.test.skip("???")
# test initializing nested structures
class Phone(Structure):
_fields_ = [("areacode", c_char*6),
@@ -266,7 +263,7 @@
assert p.age == 5
def test_structures_with_wchar(self):
- py.test.skip("Inlined array")
+ py.test.skip("need unicode support on _rawffi level")
try:
c_wchar
except NameError:
@@ -287,7 +284,7 @@
raises(ValueError, PersonW, u"1234567890123")
def test_init_errors(self):
- py.test.skip("???")
+ py.test.skip("Very fragile errors")
class Phone(Structure):
_fields_ = [("areacode", c_char*6),
("number", c_char*12)]
@@ -334,7 +331,7 @@
## (AttributeError, "class must define a '_fields_' attribute"))
def test_abstract_class(self):
- py.test.skip("???")
+ py.test.skip("What is _abstract_?")
class X(Structure):
_abstract_ = "something"
# try 'X()'
@@ -405,7 +402,7 @@
def test_vice_versa(self):
- py.test.skip("???")
+ py.test.skip("I don't understand this test at all")
class First(Structure):
pass
class Second(Structure):
More information about the Pypy-commit
mailing list