Log message for revision 108726:
  First stab at breaking Results reference cycle based on feedback from Tres. 
The 'r' class declaration has been moved outside Results.__init__ into a class 
factory function. I don't know if this really breaks the reference cycle but am 
committing so others can review (all current tests are passing).

Changed:
  U   
Zope/branches/zeomega-2.11-memory-fixes/lib/python/Shared/DC/ZRDB/Results.py

-=-
Modified: 
Zope/branches/zeomega-2.11-memory-fixes/lib/python/Shared/DC/ZRDB/Results.py
===================================================================
--- 
Zope/branches/zeomega-2.11-memory-fixes/lib/python/Shared/DC/ZRDB/Results.py    
    2010-02-02 20:16:52 UTC (rev 108725)
+++ 
Zope/branches/zeomega-2.11-memory-fixes/lib/python/Shared/DC/ZRDB/Results.py    
    2010-02-02 22:53:53 UTC (rev 108726)
@@ -20,6 +20,46 @@
 
 class NoBrains: pass
 
+
+def record_cls_factory (data, schema, aliases, parent, brains, zbrains):
+    """Return a custom 'record' class inheriting from Record, Implicit,
+    brains, and zbrains).
+    """
+    # alternate implementation
+    # r = type('r', (Record, Implicit, brains, zbrains), {})
+    class r(Record, Implicit, brains, zbrains):
+        'Result record class'
+
+    # The Record class needs a __record_schema__ ...why?
+    r.__record_schema__=schema
+
+    # Every attribute in the Record class starting with '__' should
+    # take precedence over the same named attributes of the mixin.
+    for k in Record.__dict__.keys():
+        if k[:2]=='__':
+            setattr(r,k,getattr(Record,k))
+
+    # Add SQL Aliases
+    for k, v in aliases:
+        if not hasattr(r, k):
+            setattr(r, k, v)
+
+    # Use the init from the provided brains, if it has one;
+    # otherwise, create a default init which calls the
+    # Record base class __init__, and can accept params
+    # to allow additional custom initialization.
+    if hasattr(brains, '__init__'):
+        binit=brains.__init__
+        if hasattr(binit,'im_func'): binit=binit.im_func
+        def __init__(self, data, parent, binit=binit):
+            Record.__init__(self,data)
+            if parent is not None: self=self.__of__(parent)
+            binit(self)
+
+        setattr(r, '__init__', __init__)
+    return r
+
+
 class Results:
     """Class for providing a nice interface to DBI result data
     """
@@ -62,31 +102,9 @@
         # Create a record class to hold the records.
         names=tuple(names)
 
-        class r(Record, Implicit, brains, zbrains):
-            'Result record class'
+        self._class = record_cls_factory (data, schema, aliases, parent, 
brains,
+                                          zbrains)
 
-        r.__record_schema__=schema
-        for k in Record.__dict__.keys():
-            if k[:2]=='__':
-                setattr(r,k,getattr(Record,k))
-
-        # Add SQL Aliases
-        for k, v in aliases:
-            if not hasattr(r, k):
-                setattr(r, k, v)
-
-        if hasattr(brains, '__init__'):
-            binit=brains.__init__
-            if hasattr(binit,'im_func'): binit=binit.im_func
-            def __init__(self, data, parent, binit=binit):
-                Record.__init__(self,data)
-                if parent is not None: self=self.__of__(parent)
-                binit(self)
-
-            setattr(r, '__init__', __init__)
-
-        self._class=r
-
         # OK, we've read meta data, now get line indexes
 
     def _searchable_result_columns(self): return self.__items__

_______________________________________________
Zope-Checkins maillist  -  Zope-Checkins@zope.org
https://mail.zope.org/mailman/listinfo/zope-checkins

Reply via email to