[pypy-svn] r51046 - in pypy/dist/pypy/lib: _ctypes app_test/ctypes
fijal at codespeak.net
fijal at codespeak.net
Fri Jan 25 20:26:32 CET 2008
Author: fijal
Date: Fri Jan 25 20:26:31 2008
New Revision: 51046
Added:
pypy/dist/pypy/lib/app_test/ctypes/test_cast.py (contents, props changed)
Modified:
pypy/dist/pypy/lib/_ctypes/pointer.py
pypy/dist/pypy/lib/_ctypes/primitive.py
Log:
* Casting from integers
* get/setvalue for c_wchar_p
* allow setitem on pointers on further indices (cpython allows that)
Modified: pypy/dist/pypy/lib/_ctypes/pointer.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/pointer.py (original)
+++ pypy/dist/pypy/lib/_ctypes/pointer.py Fri Jan 25 20:26:31 2008
@@ -95,8 +95,6 @@
return self._type_._CData_output(self._subarray(index))
def __setitem__(self, index, value):
- if index != 0:
- raise IndexError
self._subarray(index)[0] = self._type_._CData_input(value)[0]
def __nonzero__(self):
@@ -114,6 +112,10 @@
ptr._buffer = tp._ffiarray(1)
ptr._buffer[0] = obj._buffer
return ptr
+ if isinstance(obj, (int, long)):
+ result = tp()
+ result._buffer[0] = obj
+ return result
if not (isinstance(obj, _CData) and type(obj)._is_pointer_like()):
raise TypeError("cast() argument 1 must be a pointer, not %s"
% (type(obj),))
Modified: pypy/dist/pypy/lib/_ctypes/primitive.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/primitive.py (original)
+++ pypy/dist/pypy/lib/_ctypes/primitive.py Fri Jan 25 20:26:31 2008
@@ -76,6 +76,25 @@
value = 0
self._buffer[0] = value
result.value = property(_getvalue, _setvalue)
+ elif tp == 'Z':
+ # c_wchar_p
+ from _ctypes import Array, _Pointer, _wstring_at_addr
+ def _getvalue(self):
+ addr = self._buffer[0]
+ if addr == 0:
+ return None
+ else:
+ return _wstring_at_addr(addr)
+
+ def _setvalue(self, value):
+ if isinstance(value, str):
+ array = _rawffi.Array('u')(len(value)+1, value)
+ value = array.buffer
+ # XXX free 'array' later
+ elif value is None:
+ value = 0
+ self._buffer[0] = value
+ result.value = property(_getvalue, _setvalue)
elif tp == 'P':
# c_void_p
Added: pypy/dist/pypy/lib/app_test/ctypes/test_cast.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/lib/app_test/ctypes/test_cast.py Fri Jan 25 20:26:31 2008
@@ -0,0 +1,75 @@
+from ctypes import *
+import sys, py
+
+class TestCast:
+
+ 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]
+
+ def test_p2a_objects(self):
+ py.test.skip("keepalive logic")
+ array = (c_char_p * 5)()
+ assert array._objects == None
+ array[0] = "foo bar"
+ assert array._objects == {'0': "foo bar"}
+
+ p = cast(array, POINTER(c_char_p))
+ # array and p share a common _objects attribute
+ assert p._objects is array._objects
+ assert array._objects == {'0': "foo bar", id(array): array}
+ p[0] = "spam spam"
+ assert p._objects == {'0': "spam spam", id(array): array}
+ assert array._objects is p._objects
+ p[1] = "foo bar"
+ assert p._objects == {'1': 'foo bar', '0': "spam spam", id(array): array}
+ assert array._objects is p._objects
+
+ def test_other(self):
+ p = cast((c_int * 4)(1, 2, 3, 4), POINTER(c_int))
+ assert p[:4] == [1,2, 3, 4]
+ c_int()
+ assert p[:4] == [1, 2, 3, 4]
+ p[2] = 96
+ assert p[:4] == [1, 2, 96, 4]
+ c_int()
+ assert p[:4] == [1, 2, 96, 4]
+
+ def test_char_p(self):
+ # This didn't work: bad argument to internal function
+ s = c_char_p("hiho")
+ assert cast(cast(s, c_void_p), c_char_p).value == (
+ "hiho")
+
+ try:
+ c_wchar_p
+ except NameError:
+ pass
+ else:
+ def test_wchar_p(self):
+ py.test.skip("XXX reenable")
+ s = c_wchar_p("hiho")
+ assert cast(cast(s, c_void_p), c_wchar_p).value == (
+ "hiho")
More information about the Pypy-commit
mailing list