[pypy-svn] r52872 - in pypy/dist/pypy/lib: _ctypes app_test/ctypes

pedronis at codespeak.net pedronis at codespeak.net
Sun Mar 23 15:30:49 CET 2008


Author: pedronis
Date: Sun Mar 23 15:30:48 2008
New Revision: 52872

Modified:
   pypy/dist/pypy/lib/_ctypes/array.py
   pypy/dist/pypy/lib/_ctypes/basics.py
   pypy/dist/pypy/lib/_ctypes/pointer.py
   pypy/dist/pypy/lib/_ctypes/primitive.py
   pypy/dist/pypy/lib/_ctypes/structure.py
   pypy/dist/pypy/lib/_ctypes/union.py
   pypy/dist/pypy/lib/app_test/ctypes/test_keepalive.py
   pypy/dist/pypy/lib/app_test/ctypes/test_keeprefs.py
Log:
make test_keeprefs pass except for where the behavior is really differrent (we copy string contents),
all a bit obscure



Modified: pypy/dist/pypy/lib/_ctypes/array.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/array.py	(original)
+++ pypy/dist/pypy/lib/_ctypes/array.py	Sun Mar 23 15:30:48 2008
@@ -2,7 +2,8 @@
 import _rawffi
 
 from _ctypes.basics import _CData, cdata_from_address, _CDataMeta, sizeof
-from _ctypes.basics import keepalive_key, store_reference, CArgObject
+from _ctypes.basics import keepalive_key, store_reference, ensure_objects
+from _ctypes.basics import CArgObject
 from _ctypes.builtin import _string_at_addr, _wstring_at_addr
 
 def _create_unicode(buffer, maxlength):
@@ -133,7 +134,6 @@
 
     def __init__(self, *args):
         self._buffer = self._ffiarray(self._length_, autofree=True)
-        self._objects = {}
         for i, arg in enumerate(args):
             self[i] = arg
 
@@ -160,7 +160,7 @@
             self._slice_setitem(index, value)
             return
         index = self._fix_index(index)
-        if getattr(value, '_objects', None) is not None:
+        if ensure_objects(value) is not None:
             store_reference(self, index, value._objects)
         arg = self._type_._CData_value(value)
         if self._type_._fficompositesize is None:

Modified: pypy/dist/pypy/lib/_ctypes/basics.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/basics.py	(original)
+++ pypy/dist/pypy/lib/_ctypes/basics.py	Sun Mar 23 15:30:48 2008
@@ -4,18 +4,24 @@
 
 keepalive_key = str # XXX fix this when provided with test
 
+def ensure_objects(where):
+    try:
+        ensure = where._ensure_objects
+    except AttributeError:
+        return None
+    return ensure()
+
 def store_reference(where, base_key, target):
-    #self.__dict__['_objects'][key] = value._objects
-    if '_objects' in where.__dict__:
+    if '_index' not in where.__dict__:
         # shortcut
-        where.__dict__['_objects'][str(base_key)] = target
+        where._ensure_objects()[str(base_key)] = target
         return
     key = [base_key]
-    while not '_objects' in where.__dict__:
+    while '_index' in where.__dict__:
         key.append(where.__dict__['_index'])
         where = where.__dict__['_base']
     real_key = ":".join([str(i) for i in key])
-    where.__dict__['_objects'][real_key] = target
+    where._ensure_objects()[real_key] = target
 
 class ArgumentError(Exception):
     pass
@@ -95,6 +101,13 @@
     def __init__(self, *args, **kwds):
         raise TypeError("%s has no type" % (type(self),))
 
+    def _ensure_objects(self):
+        if '_objects' not in self.__dict__:
+            if '_index' in self.__dict__:
+                return None
+            self.__dict__['_objects'] = {}
+        return self._objects
+
     def __ctypes_from_outparam__(self):
         return self
 

Modified: pypy/dist/pypy/lib/_ctypes/pointer.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/pointer.py	(original)
+++ pypy/dist/pypy/lib/_ctypes/pointer.py	Sun Mar 23 15:30:48 2008
@@ -58,8 +58,6 @@
             self._buffer = ffiarray(1, autofree=True)
             if value is not None:
                 self.contents = value
-            else:
-                self._objects = {}
         self._ffiarray = ffiarray
         self.__init__ = __init__
         self._type_ = TP
@@ -80,7 +78,7 @@
             raise TypeError("expected %s instead of %s" % (
                 self._type_.__name__, type(value).__name__))
         self._objects = {keepalive_key(1):value}
-        if getattr(value, '_objects', None) is not None:
+        if value._ensure_objects() is not None:
             self._objects[keepalive_key(0)] = value._objects
         value = value._buffer
         self._buffer[0] = value

Modified: pypy/dist/pypy/lib/_ctypes/primitive.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/primitive.py	(original)
+++ pypy/dist/pypy/lib/_ctypes/primitive.py	Sun Mar 23 15:30:48 2008
@@ -83,7 +83,7 @@
                     if isinstance(value, unicode):
                         value = value.encode(ConvMode.encoding,
                                              ConvMode.errors)
-                    self._objects = value
+                    #self._objects = value
                     array = _rawffi.Array('c')(len(value)+1, value)
                     value = array.buffer
                     self._objects = {'0': CArgObject(array)}
@@ -106,7 +106,7 @@
                     if isinstance(value, str):
                         value = value.decode(ConvMode.encoding,
                                              ConvMode.errors)
-                    self._objects = value
+                    #self._objects = value
                     array = _rawffi.Array('u')(len(value)+1, value)
                     value = array.buffer
                     self._objects = {'0': CArgObject(array)}
@@ -212,6 +212,9 @@
         if value is not DEFAULT_VALUE:
             self.value = value
 
+    def _ensure_objects(self):
+        return None
+
     def _getvalue(self):
         return self._buffer[0]
 

Modified: pypy/dist/pypy/lib/_ctypes/structure.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/structure.py	(original)
+++ pypy/dist/pypy/lib/_ctypes/structure.py	Sun Mar 23 15:30:48 2008
@@ -1,7 +1,7 @@
 
 import _rawffi
 from _ctypes.basics import _CData, _CDataMeta, keepalive_key,\
-     store_reference, CArgObject
+     store_reference, ensure_objects, CArgObject
 import inspect
 
 def round_up(size, alignment):
@@ -115,7 +115,6 @@
             if not hasattr(self, '_ffistruct'):
                 raise TypeError("Cannot instantiate structure, has no _fields_")
             self.__dict__['_buffer'] = self._ffistruct(autofree=True)
-            self.__dict__['_objects'] = {}
             if len(args) > len(self._names):
                 raise TypeError("too many arguments")
             for name, arg in zip(self._names, args):
@@ -181,7 +180,7 @@
             fieldtype = self._fieldtypes[name].ctype
         except KeyError:
             raise AttributeError(name)
-        if getattr(value, '_objects', None) is not None:
+        if ensure_objects(value) is not None:
             key = keepalive_key(getattr(self.__class__, name).num)
             store_reference(self, key, value._objects)
         arg = fieldtype._CData_value(value)

Modified: pypy/dist/pypy/lib/_ctypes/union.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/union.py	(original)
+++ pypy/dist/pypy/lib/_ctypes/union.py	Sun Mar 23 15:30:48 2008
@@ -2,6 +2,7 @@
 
 import _rawffi
 from _ctypes.basics import _CData, _CDataMeta, store_reference, keepalive_key
+from _ctypes.basics import ensure_objects
 from _ctypes.structure import round_up, names_and_fields, struct_getattr,\
      struct_setattr
 import inspect
@@ -99,7 +100,7 @@
             fieldtype = self._fieldtypes[name].ctype
         except KeyError:
             raise AttributeError(name)
-        if getattr(value, '_objects', None) is not None:
+        if ensure_objects(value) is not None:
             key = keepalive_key(getattr(self.__class__, name).num)
             store_reference(self, key, value._objects)
         arg = fieldtype._CData_value(value)

Modified: pypy/dist/pypy/lib/app_test/ctypes/test_keepalive.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/ctypes/test_keepalive.py	(original)
+++ pypy/dist/pypy/lib/app_test/ctypes/test_keepalive.py	Sun Mar 23 15:30:48 2008
@@ -19,6 +19,19 @@
         assert p._objects == {'1':l}
         assert a._objects == {'3':{'1':l}}
 
+    def test_simple_structure_and_pointer(self):
+        class X(Structure):
+            _fields_ = [('x', POINTER(c_int))]
+
+        x = X()
+        p = POINTER(c_int)()
+        assert x._objects is None
+        assert p._objects is None
+        x.x = p
+        assert p._objects == {}
+        assert len(x._objects) == 1
+        assert x._objects['0'] is p._objects
+        
     def test_structure_with_pointers(self):
         class X(Structure):
             _fields_ = [('x', POINTER(c_int)),

Modified: pypy/dist/pypy/lib/app_test/ctypes/test_keeprefs.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/ctypes/test_keeprefs.py	(original)
+++ pypy/dist/pypy/lib/app_test/ctypes/test_keeprefs.py	Sun Mar 23 15:30:48 2008
@@ -1,8 +1,6 @@
 import py
 from ctypes import *
 
-py.test.skip("tests implementation details")
-
 class TestSimple:
     def test_cint(self):
         x = c_int()
@@ -13,6 +11,7 @@
         assert x._objects == None
 
     def test_ccharp(self):
+        py.test.skip("we make copies of strings")
         x = c_char_p()
         assert x._objects == None
         x.value = "abc"
@@ -33,6 +32,7 @@
         assert x._objects == None
 
     def test_ccharp_struct(self):
+        py.test.skip("we make copies of strings")        
         class X(Structure):
             _fields_ = [("a", c_char_p),
                         ("b", c_char_p)]



More information about the Pypy-commit mailing list