[pypy-svn] r50633 - pypy/branch/applevel-ctypes2/pypy/lib/_ctypes

arigo at codespeak.net arigo at codespeak.net
Tue Jan 15 16:41:30 CET 2008


Author: arigo
Date: Tue Jan 15 16:41:30 2008
New Revision: 50633

Modified:
   pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/__init__.py
   pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/array.py
   pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/basics.py
   pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/function.py
   pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/pointer.py
   pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/primitive.py
   pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/structure.py
Log:
(fijal, arigo)
As usual - rewrite some core logic once again, and more tests pass.


Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/__init__.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/__init__.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/__init__.py	Tue Jan 15 16:41:30 2008
@@ -2,11 +2,10 @@
 from _ctypes.dummy import ArgumentError
 from _ctypes.dummy import resize
 from _ctypes.dummy import _memmove_addr, _memset_addr, _string_at_addr
-from _ctypes.dummy import _cast_addr
 
 from _ctypes.basics import _CData, sizeof, alignment, byref, addressof
 from _ctypes.primitive import _SimpleCData
-from _ctypes.pointer import _Pointer
+from _ctypes.pointer import _Pointer, _cast_addr
 from _ctypes.function import CFuncPtr
 from _ctypes.dll import dlopen
 from _ctypes.structure import Structure

Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/array.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/array.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/array.py	Tue Jan 15 16:41:30 2008
@@ -35,9 +35,6 @@
             res._ffiarray = None
         return res
 
-    def _CData_input(self, value):
-        return self.from_param(value)._buffer.byptr()
-
     from_address = cdata_from_address
 
 class Array(_CData):
@@ -95,6 +92,9 @@
     def __len__(self):
         return self._length_
 
+    def _get_buffer_for_param(self):
+        return self._buffer.byptr()
+
 ARRAY_CACHE = {}
 
 def create_array_type(base, length):

Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/basics.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/basics.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/basics.py	Tue Jan 15 16:41:30 2008
@@ -19,7 +19,8 @@
         array of length 1 containing the same value according to the
         type 'self'.
         """
-        return self.from_param(value)._buffer
+        cobj = self.from_param(value)
+        return cobj._get_buffer_for_param()
 
     def _CData_output(self, resarray):
         """Used when data exits ctypes and goes into user code.
@@ -34,6 +35,9 @@
         from _ctypes.array import create_array_type
         return create_array_type(self, other)
 
+    def _is_pointer_like(self):
+        return False
+
 class _CData(object):
     """ The most basic object for all ctypes types
     """
@@ -45,6 +49,9 @@
     def __ctypes_from_outparam__(self):
         return self
 
+    def _get_buffer_for_param(self):
+        return self._buffer
+
 #class CArgObject(object):
 #    def __init__(self, letter, raw_value, _type):
 #        self.ffiletter = letter

Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/function.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/function.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/function.py	Tue Jan 15 16:41:30 2008
@@ -1,4 +1,5 @@
 
+import types
 from _ctypes.basics import _CData, _CDataMeta
 
 class CFuncPtrType(_CDataMeta):
@@ -27,10 +28,15 @@
         if isinstance(address_or_name_and_dll, tuple):
             self.name, self.dll = address_or_name_and_dll
         else:
+            self.address = address_or_name_and_dll
             self.name = None
 
     def __call__(self, *args):
         if self.name is None:
+            if isinstance(self.address, types.FunctionType):
+                # special hack to support to way a few functions like
+                # ctypes.cast() are implemented in ctypes/__init__.py
+                return self.address(*args)
             raise NotImplementedError("Creation of function pointer to pure addresses is not implemented")
         argtypes = self._argtypes_
         if argtypes is None:

Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/pointer.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/pointer.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/pointer.py	Tue Jan 15 16:41:30 2008
@@ -21,12 +21,12 @@
             setattr(obj, k, v)
         if '_type_' in typedict:
             ffiarray = _rawffi.Array('P')
-            def __init__(self, value=0):
+            def __init__(self, value=None):
                 self._buffer = ffiarray(1)
                 self.contents = value
             obj._ffiarray = ffiarray
         else:
-            def __init__(self, value=0):
+            def __init__(self, value=None):
                 raise TypeError("%s has no type" % obj)
         obj.__init__ = __init__
         return obj
@@ -47,19 +47,30 @@
     def _sizeofinstances(self):
         return _rawffi.sizeof('P')
 
+    def _is_pointer_like(self):
+        return True
+
     from_address = cdata_from_address
 
 class _Pointer(_CData):
     __metaclass__ = PointerType
 
     def getcontents(self):
-        return self._type_.from_address(self._buffer[0])
+        addr = self._buffer[0]
+        if addr == 0:
+            return None
+        else:
+            return self._type_.from_address(addr)
 
     def setcontents(self, value):
-        if not isinstance(value, self._type_):
-            raise TypeError("expected %s instead of %s" % (
-                self._type_.__name__, type(value).__name__))
-        self._buffer[0] = value._buffer
+        if value is not None:
+            if not isinstance(value, self._type_):
+                raise TypeError("expected %s instead of %s" % (
+                    self._type_.__name__, type(value).__name__))
+            value = value._buffer
+        else:
+            value = 0
+        self._buffer[0] = value
 
     def _subarray(self, index=0):
         """Return a _rawffi array of length 1 whose address is the same as
@@ -77,3 +88,15 @@
         self._subarray(index)[0] = self._type_._CData_input(value)[0]
 
     contents = property(getcontents, setcontents)
+
+
+def _cast_addr(obj, _, tp):
+    if not (isinstance(obj, _CData) and type(obj)._is_pointer_like()):
+        raise TypeError("cast() argument 1 must be a pointer, not %s"
+                        % (type(obj),))
+    if not (isinstance(tp, _CDataMeta) and tp._is_pointer_like()):
+        raise TypeError("cast() argument 2 must be a pointer type, not %s"
+                        % (tp,))
+    result = tp()
+    result._buffer[0] = obj._buffer[0]
+    return result

Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/primitive.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/primitive.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/primitive.py	Tue Jan 15 16:41:30 2008
@@ -64,9 +64,10 @@
                 if isinstance(value, self):
                     return value
                 if isinstance(value, (Array, _Pointer)):
-                    if type(value)._type_ == 'c':
+                    from ctypes import c_char
+                    if type(value)._type_ == c_char:
                         return value
-                return _SimpleCData.from_param(self, value)
+                return SimpleType.from_param(self, value)
             result.from_param = classmethod(from_param)
 
         return result
@@ -84,6 +85,9 @@
     def _sizeofinstances(self):
         return _rawffi.sizeof(self._type_)
 
+    def _is_pointer_like(self):
+        return self._type_ in "sPzUZXO"
+
 class _SimpleCData(_CData):
     __metaclass__ = SimpleType
     _type_ = 'i'

Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/structure.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/structure.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/structure.py	Tue Jan 15 16:41:30 2008
@@ -28,9 +28,6 @@
 
         return res
 
-    def _CData_input(self, value):
-        return self.from_param(value)._buffer.byptr()
-
     def from_address(self, address):
         instance = self.__new__(self)
         instance.__dict__['_buffer'] = self._ffistruct.fromaddress(address)
@@ -61,3 +58,6 @@
         except KeyError:
             raise AttributeError(name)
         return fieldtype._CData_output(self._subarray(fieldtype, name))
+
+    def _get_buffer_for_param(self):
+        return self._buffer.byptr()



More information about the Pypy-commit mailing list