[pypy-svn] r26169 - in pypy/dist/pypy/rpython/rctypes: . test

arigo at codespeak.net arigo at codespeak.net
Sun Apr 23 10:40:52 CEST 2006


Author: arigo
Date: Sun Apr 23 10:40:51 2006
New Revision: 26169

Modified:
   pypy/dist/pypy/rpython/rctypes/afunc.py
   pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py
Log:
ctypes rules for calling functions with no 'argtypes' specification.
Needed for calling functions with a variable number of arguments.


Modified: pypy/dist/pypy/rpython/rctypes/afunc.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/afunc.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/afunc.py	Sun Apr 23 10:40:51 2006
@@ -1,4 +1,6 @@
 from pypy.annotation.model import SomeCTypesObject
+from pypy.annotation import model as annmodel
+from pypy.rpython.error import TyperError
 from pypy.rpython.extregistry import ExtRegistryEntry
 from pypy.rpython.lltypesystem import lltype
 
@@ -36,11 +38,28 @@
         cfuncptr = self.instance
         fnname = cfuncptr.__name__
 
+        def repr_for_ctype(ctype):
+            s = SomeCTypesObject(ctype, SomeCTypesObject.MEMORYALIAS)
+            return hop.rtyper.getrepr(s)
+
         args_r = []
-        for ctype in cfuncptr.argtypes:
-            s_arg = SomeCTypesObject(ctype, SomeCTypesObject.MEMORYALIAS)
-            r_arg = hop.rtyper.getrepr(s_arg)
-            args_r.append(r_arg)
+        if getattr(cfuncptr, 'argtypes', None) is not None:
+            for ctype in cfuncptr.argtypes:
+                args_r.append(repr_for_ctype(ctype))
+        else:
+            # unspecified argtypes: use ctypes rules for arguments
+            for s_arg, r_arg in zip(hop.args_s, hop.args_r):
+                if not isinstance(s_arg, SomeCTypesObject):
+                    # accept integers, strings, or None
+                    if isinstance(s_arg, annmodel.SomeInteger):
+                        r_arg = repr_for_ctype(c_long)
+                    elif (isinstance(s_arg, annmodel.SomeString)
+                          or s_arg == annmodel.s_None):
+                        r_arg = repr_for_ctype(c_char_p)
+                    else:
+                        raise TyperError("call with no argtypes: don't know "
+                                         "how to convert argument %r"%(s_arg,))
+                args_r.append(r_arg)
 
         vlist = hop.inputargs(*args_r)
         unwrapped_args_v = []

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py	Sun Apr 23 10:40:51 2006
@@ -14,7 +14,8 @@
 
 from ctypes import cdll, pythonapi, _FUNCFLAG_PYTHONAPI
 from ctypes import c_int, c_long, c_char_p, c_char, create_string_buffer
-from ctypes import POINTER, py_object, util
+from ctypes import POINTER, py_object, byref
+from pypy.rpython.rctypes.tool import util      # ctypes.util from 0.9.9.6
 
 # __________ the standard C library __________
 
@@ -49,6 +50,10 @@
 time_.restype = c_long    # should rather use ctypes_platform.getsimpletype()
 time_.argtypes = [POINTER(c_long)]
 
+ctime = mylib.ctime
+ctime.restype = c_char_p
+#ctimes.argtypes: omitted for this test
+
 
 def test_labs(n=6):
     assert labs(n) == abs(n)
@@ -85,6 +90,13 @@
     t3 = time.time()
     assert int(t1) <= t2 <= int(t3 + 1.0)
 
+def test_ctime():
+    import time
+    N = 99999999
+    s1 = time.ctime(N)
+    s2 = ctime(byref(c_long(N)))
+    assert s1.strip() == s2.strip()
+
 class Test_annotation:
     def test_annotate_labs(self):
         a = RPythonAnnotator()
@@ -202,3 +214,14 @@
         res = fn(17, 0)
         assert res == 34
         py.test.raises(OverflowError, 'fn(sys.maxint, 1)')
+
+    def test_compile_ctime(self):
+        import time
+        N = 123456789
+        def func(n):
+            return ctime(byref(c_long(n)))
+
+        fn = compile(func, [int])
+        s1 = time.ctime(N)
+        s2 = fn(N)
+        assert s1.strip() == s2.strip()



More information about the Pypy-commit mailing list