[pypy-svn] r70437 - in pypy/trunk/pypy/lib: _ctypes app_test/ctypes_tests
afa at codespeak.net
afa at codespeak.net
Thu Jan 7 18:50:23 CET 2010
Author: afa
Date: Thu Jan 7 18:50:21 2010
New Revision: 70437
Modified:
pypy/trunk/pypy/lib/_ctypes/array.py
pypy/trunk/pypy/lib/_ctypes/primitive.py
pypy/trunk/pypy/lib/_ctypes/structure.py
pypy/trunk/pypy/lib/_ctypes/union.py
pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py
Log:
Fix a keepalive problem in ctypes:
When setting a struct member, the structure did not track keepalives
if the value needs to be converted.
Modified: pypy/trunk/pypy/lib/_ctypes/array.py
==============================================================================
--- pypy/trunk/pypy/lib/_ctypes/array.py (original)
+++ pypy/trunk/pypy/lib/_ctypes/array.py Thu Jan 7 18:50:21 2010
@@ -90,7 +90,7 @@
def _CData_retval(self, resbuffer):
raise NotImplementedError
- def _CData_value(self, value):
+ def from_param(self, value):
# array accepts very strange parameters as part of structure
# or function argument...
from ctypes import c_char, c_wchar
@@ -104,7 +104,7 @@
if len(value) > self._length_:
raise RuntimeError("Invalid length")
value = self(*value)
- return _CDataMeta._CData_value(self, value)
+ return _CDataMeta.from_param(self, value)
def array_get_slice_params(self, index):
if index.step is not None:
Modified: pypy/trunk/pypy/lib/_ctypes/primitive.py
==============================================================================
--- pypy/trunk/pypy/lib/_ctypes/primitive.py (original)
+++ pypy/trunk/pypy/lib/_ctypes/primitive.py Thu Jan 7 18:50:21 2010
@@ -290,6 +290,8 @@
self.value = value
def _ensure_objects(self):
+ if self._type_ in 'zZ':
+ return self._objects
return None
def _getvalue(self):
Modified: pypy/trunk/pypy/lib/_ctypes/structure.py
==============================================================================
--- pypy/trunk/pypy/lib/_ctypes/structure.py (original)
+++ pypy/trunk/pypy/lib/_ctypes/structure.py Thu Jan 7 18:50:21 2010
@@ -130,10 +130,10 @@
def _alignmentofinstances(self):
return self._ffistruct.alignment
- def _CData_value(self, value):
+ def from_param(self, value):
if isinstance(value, tuple):
value = self(*value)
- return _CDataMeta._CData_value(self, value)
+ return _CDataMeta.from_param(self, value)
def _CData_output(self, resarray, base=None, index=-1):
res = self.__new__(self)
@@ -183,10 +183,11 @@
fieldtype = self._fieldtypes[name].ctype
except KeyError:
return _CData.__setattr__(self, name, value)
- if ensure_objects(value) is not None:
+ cobj = fieldtype.from_param(value)
+ if ensure_objects(cobj) is not None:
key = keepalive_key(getattr(self.__class__, name).num)
- store_reference(self, key, value._objects)
- arg = fieldtype._CData_value(value)
+ store_reference(self, key, cobj._objects)
+ arg = cobj._get_buffer_value()
if fieldtype._fficompositesize is not None:
from ctypes import memmove
dest = self._buffer.fieldaddress(name)
Modified: pypy/trunk/pypy/lib/_ctypes/union.py
==============================================================================
--- pypy/trunk/pypy/lib/_ctypes/union.py (original)
+++ pypy/trunk/pypy/lib/_ctypes/union.py Thu Jan 7 18:50:21 2010
@@ -99,10 +99,11 @@
fieldtype = self._fieldtypes[name].ctype
except KeyError:
raise AttributeError(name)
- if ensure_objects(value) is not None:
+ cobj = fieldtype.from_param(value)
+ if ensure_objects(cobj) is not None:
key = keepalive_key(getattr(self.__class__, name).num)
- store_reference(self, key, value._objects)
- arg = fieldtype._CData_value(value)
+ store_reference(self, key, cobj._objects)
+ arg = cobj._get_buffer_value()
if fieldtype._fficompositesize is not None:
from ctypes import memmove
dest = self._buffer.buffer
Modified: pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py
==============================================================================
--- pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py (original)
+++ pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py Thu Jan 7 18:50:21 2010
@@ -221,6 +221,11 @@
('dptr', c_char_p),
('dsize', c_int),
]
+ class union(Union):
+ _fields_ = [
+ ('dptr', c_char_p),
+ ('dsize', c_int),
+ ]
for wrap in [False, True]:
n = 2
xs = "hello" * n
@@ -235,3 +240,15 @@
print 'dat._objects =', repr(dat._objects)
assert dat.dptr == "hellohello"
assert dat._objects.keys() == ['0']
+
+ xs = "hello" * n
+ if wrap:
+ xs = c_char_p(xs)
+ dat = union()
+ dat.dptr = xs
+ del xs
+ import gc; gc.collect()
+ print 'dat.dptr =', repr(dat.dptr)
+ print 'dat._objects =', repr(dat._objects)
+ assert dat.dptr == "hellohello"
+ assert dat._objects.keys() == ['0']
More information about the Pypy-commit
mailing list