[pypy-svn] r61772 - in pypy/trunk/pypy/lib: _ctypes app_test/ctypes_tests

afa at codespeak.net afa at codespeak.net
Thu Feb 12 11:14:28 CET 2009


Author: afa
Date: Thu Feb 12 11:14:28 2009
New Revision: 61772

Modified:
   pypy/trunk/pypy/lib/_ctypes/primitive.py
   pypy/trunk/pypy/lib/app_test/ctypes_tests/test_parameters.py
Log:
Don't ignore the from_param() defined in subclasses
One more test passes


Modified: pypy/trunk/pypy/lib/_ctypes/primitive.py
==============================================================================
--- pypy/trunk/pypy/lib/_ctypes/primitive.py	(original)
+++ pypy/trunk/pypy/lib/_ctypes/primitive.py	Thu Feb 12 11:14:28 2009
@@ -7,6 +7,8 @@
 from _ctypes.basics import _CData, _CDataMeta, cdata_from_address,\
      CArgObject
 from _ctypes.builtin import ConvMode
+from _ctypes.array import Array
+from _ctypes.pointer import _Pointer
 
 class NULL(object):
     pass
@@ -54,17 +56,43 @@
 
 pyobj_container = GlobalPyobjContainer()
 
-def generic_xxx_p_from_param(self, value):
+def generic_xxx_p_from_param(cls, value):
     from _ctypes import Array, _Pointer
     if value is None:
-        return self(None)
+        return cls(None)
     if isinstance(value, basestring):
-        return self(value)
+        return cls(value)
     if isinstance(value, _SimpleCData) and \
            type(value)._type_ in 'zZP':
         return value
     return None # eventually raise
 
+def from_param_char_p(cls, value):
+    "used by c_char_p and c_wchar_p subclasses"
+    res = generic_xxx_p_from_param(cls, value)
+    if res is not None:
+        return res
+    if isinstance(value, (Array, _Pointer)):
+        from ctypes import c_char, c_byte, c_wchar
+        if type(value)._type_ in [c_char, c_byte, c_wchar]:
+            return value
+
+def from_param_void_p(cls, value):
+    "used by c_void_p subclasses"
+    res = generic_xxx_p_from_param(cls, value)
+    if res is not None:
+        return res
+    if isinstance(value, Array):
+        return value
+    if isinstance(value, _Pointer):
+        return cls.from_address(value._buffer.buffer)
+
+FROM_PARAM_BY_TYPE = {
+    'z': from_param_char_p,
+    'Z': from_param_char_p,
+    'P': from_param_void_p,
+    }
+
 class SimpleType(_CDataMeta):
     def __new__(self, name, bases, dct):
         try:
@@ -154,33 +182,6 @@
                 self._buffer[0] = value
             result.value = property(_getvalue, _setvalue)            
         
-        if tp in 'zZ':
-            from _ctypes import Array, _Pointer
-            # c_char_p
-            def from_param(self, value):
-                res = generic_xxx_p_from_param(self, value)
-                if res is not None:
-                    return res
-                if isinstance(value, (Array, _Pointer)):
-                    from ctypes import c_char, c_byte, c_wchar
-                    if type(value)._type_ in [c_char, c_byte, c_wchar]:
-                        return value
-                return SimpleType.from_param(self, value)
-            result.from_param = classmethod(from_param)
-        elif tp == 'P':
-            from _ctypes import Array, _Pointer
-            # c_void_p
-            def from_param(self, value):
-                res = generic_xxx_p_from_param(self, value)
-                if res is not None:
-                    return res
-                if isinstance(value, Array):
-                    return value
-                if isinstance(value, _Pointer):
-                    return self.from_address(value._buffer.buffer)
-                return SimpleType.from_param(self, value)
-            result.from_param = classmethod(from_param)
-
         elif tp == 'u':
             def _setvalue(self, val):
                 if isinstance(val, str):
@@ -215,6 +216,12 @@
     from_address = cdata_from_address
 
     def from_param(self, value):
+        from_param_f = FROM_PARAM_BY_TYPE.get(self._type_)
+        if from_param_f:
+            res = from_param_f(self, value)
+            if res is not None:
+                return res
+            
         if isinstance(value, self):
             return value
         try:

Modified: pypy/trunk/pypy/lib/app_test/ctypes_tests/test_parameters.py
==============================================================================
--- pypy/trunk/pypy/lib/app_test/ctypes_tests/test_parameters.py	(original)
+++ pypy/trunk/pypy/lib/app_test/ctypes_tests/test_parameters.py	Thu Feb 12 11:14:28 2009
@@ -22,7 +22,6 @@
 
 
     def test_subclasses(self):
-        py.test.skip("subclassing semantics not implemented")
         from ctypes import c_void_p, c_char_p
         # ctypes 0.9.5 and before did overwrite from_param in SimpleType_new
         class CVOIDP(c_void_p):



More information about the Pypy-commit mailing list