Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r1202:760ec4641128
Date: 2013-03-28 14:59 +0100
http://bitbucket.org/cffi/cffi/changeset/760ec4641128/

Log:    A bit hackish, but solves exactly issue #71:
        ffi.typeof(builtin_function).

diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -137,8 +137,13 @@
         """
         if isinstance(cdecl, basestring):
             return self._typeof(cdecl)
-        else:
+        if isinstance(cdecl, self.CData):
             return self._backend.typeof(cdecl)
+        if isinstance(cdecl, types.BuiltinFunctionType):
+            res = _builtin_function_type(cdecl)
+            if res is not None:
+                return res
+        raise TypeError(type(cdecl))
 
     def sizeof(self, cdecl):
         """Return the size in bytes of the argument.  It can be a
@@ -415,3 +420,17 @@
             pass
     library = FFILibrary()
     return library, library.__dict__
+
+def _builtin_function_type(func):
+    # a hack to make at least ffi.typeof(builtin_function) work,
+    # if the builtin function was obtained by 'vengine_cpy'.
+    import sys
+    try:
+        module = sys.modules[func.__module__]
+        ffi = module._cffi_original_ffi
+        types_of_builtin_funcs = module._cffi_types_of_builtin_funcs
+        tp = types_of_builtin_funcs[func]
+    except (KeyError, AttributeError, TypeError):
+        return None
+    else:
+        return ffi._get_cached_btype(tp)
diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py
--- a/cffi/vengine_cpy.py
+++ b/cffi/vengine_cpy.py
@@ -10,6 +10,7 @@
         self.verifier = verifier
         self.ffi = verifier.ffi
         self._struct_pending_verification = {}
+        self._types_of_builtin_functions = {}
 
     def patch_extension_kwds(self, kwds):
         pass
@@ -149,6 +150,8 @@
         # functions from the module to the 'library' object, and setting
         # up the FFILibrary class with properties for the global C variables.
         self._load(module, 'loaded', library=library)
+        module._cffi_original_ffi = self.ffi
+        module._cffi_types_of_builtin_funcs = self._types_of_builtin_functions
         return library
 
     def _get_declarations(self):
@@ -384,7 +387,9 @@
     def _loaded_cpy_function(self, tp, name, module, library):
         if tp.ellipsis:
             return
-        setattr(library, name, getattr(module, name))
+        func = getattr(module, name)
+        setattr(library, name, func)
+        self._types_of_builtin_functions[func] = tp
 
     # ----------
     # named structs
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -1582,3 +1582,11 @@
     py.test.raises(TypeError, lib.seeme2, None)
     py.test.raises(TypeError, lib.seeme1, 0.0)
     py.test.raises(TypeError, lib.seeme2, 0.0)
+
+def test_typeof_function():
+    ffi = FFI()
+    ffi.cdef("int foo(int, char);")
+    lib = ffi.verify("int foo(int x, char y) { return 42; }")
+    ctype = ffi.typeof(lib.foo)
+    assert len(ctype.args) == 2
+    assert ctype.result == ffi.typeof("int")
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to