Armin Rigo avatar Armin Rigo committed da1d30f

In-progress: tweaks to support the case of the same StructType being
instantiated on multiple ffi's (and then returning the same backend
object).

Comments (0)

Files changed (1)

 import weakref
 
-class BaseType(object):
+class BaseTypeByIdentity(object):
 
     def get_c_name(self, replace_with='', context='a C file'):
         result = self._get_c_name(replace_with)
     def __repr__(self):
         return '<%s>' % (self._get_c_name(''),)
 
+    def _get_items(self):
+        return [(name, getattr(self, name)) for name in self._attrs_]
+
+
+class BaseType(BaseTypeByIdentity):
+
     def __eq__(self, other):
         return (self.__class__ == other.__class__ and
                 self._get_items() == other._get_items())
     def __ne__(self, other):
         return not self == other
 
-    def _get_items(self):
-        return [(name, getattr(self, name)) for name in self._attrs_]
-
     def __hash__(self):
         return hash((self.__class__, tuple(self._get_items())))
 
         return global_cache(self, ffi, 'new_array_type', BPtrItem, self.length)
 
 
-class StructOrUnionOrEnum(BaseType):
+class StructOrUnionOrEnum(BaseTypeByIdentity):
     _attrs_ = ('name',)
     forcename = None
 
     def build_backend_type(self, ffi, finishlist):
         self.check_not_partial()
         finishlist.append(self)
-        return ffi._backend.new_struct_type(self.name)
+        return global_cache(self, ffi, 'new_struct_type', self.name, key=self)
 
 
 class UnionType(StructOrUnion):
 
     def build_backend_type(self, ffi, finishlist):
         finishlist.append(self)
-        return ffi._backend.new_union_type(self.name)
+        return global_cache(self, ffi, 'new_union_type', self.name, key=self)
 
 
 class EnumType(StructOrUnionOrEnum):
 
     def build_backend_type(self, ffi, finishlist):
         self.check_not_partial()
-        return ffi._backend.new_enum_type(self.name, self.enumerators,
-                                          self.enumvalues)
+        return global_cache(self, ffi, 'new_enum_type', self.name,
+                            self.enumerators, self.enumvalues, key=self)
 
 
 def unknown_type(name, structname=None):
 
 file_type = unknown_type('FILE', '_IO_FILE')
 
-def global_cache(srctype, ffi, funcname, *args):
-    key = (funcname, args)
+def global_cache(srctype, ffi, funcname, *args, **kwds):
+    key = kwds.pop('key', (funcname, args))
+    assert not kwds
     try:
         return ffi._backend.__typecache[key]
     except KeyError:
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.