[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