[pypy-commit] cffi default: Speed up.

arigo noreply at buildbot.pypy.org
Mon Jul 30 17:53:32 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r748:d4a718449054
Date: 2012-07-30 17:53 +0200
http://bitbucket.org/cffi/cffi/changeset/d4a718449054/

Log:	Speed up.

diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -259,41 +259,43 @@
     #
     backend = ffi._backend
     backendlib = backend.load_library(path)
-    function_cache = {}
+    #
+    def make_accessor(name):
+        key = 'function ' + name
+        if key in ffi._parser._declarations:
+            tp = ffi._parser._declarations[key]
+            BType = ffi._get_cached_btype(tp)
+            value = backendlib.load_function(BType, name)
+            library.__dict__[name] = value
+            return
+        #
+        key = 'variable ' + name
+        if key in ffi._parser._declarations:
+            tp = ffi._parser._declarations[key]
+            BType = ffi._get_cached_btype(tp)
+            read_variable = backendlib.read_variable
+            write_variable = backendlib.write_variable
+            setattr(FFILibrary, name, property(
+                lambda self: read_variable(BType, name),
+                lambda self, value: write_variable(BType, name, value)))
+            return
+        #
+        raise AttributeError(name)
     #
     class FFILibrary(object):
-        def __getattribute__(self, name):
+        def __getattr__(self, name):
+            make_accessor(name)
+            return getattr(self, name)
+        def __setattr__(self, name, value):
             try:
-                return function_cache[name]
-            except KeyError:
-                pass
-            #
-            key = 'function ' + name
-            if key in ffi._parser._declarations:
-                tp = ffi._parser._declarations[key]
-                BType = ffi._get_cached_btype(tp)
-                value = backendlib.load_function(BType, name)
-                function_cache[name] = value
-                return value
-            #
-            key = 'variable ' + name
-            if key in ffi._parser._declarations:
-                tp = ffi._parser._declarations[key]
-                BType = ffi._get_cached_btype(tp)
-                return backendlib.read_variable(BType, name)
-            #
-            raise AttributeError(name)
-
-        def __setattr__(self, name, value):
-            key = 'variable ' + name
-            if key in ffi._parser._declarations:
-                tp = ffi._parser._declarations[key]
-                BType = ffi._get_cached_btype(tp)
-                backendlib.write_variable(BType, name, value)
-                return
-            #
-            raise AttributeError(name)
+                property = getattr(self.__class__, name)
+            except AttributeError:
+                make_accessor(name)
+                setattr(self, name, value)
+            else:
+                property.__set__(self, value)
     #
     if libname is not None:
         FFILibrary.__name__ = 'FFILibrary_%s' % libname
-    return FFILibrary(), function_cache
+    library = FFILibrary()
+    return library, library.__dict__


More information about the pypy-commit mailing list