[Erp5-report] r40345 arnaud.fontaine - in /erp5/trunk/products/ERP5Type: Tool/ dynamic/ mix...

nobody at svn.erp5.org nobody at svn.erp5.org
Thu Nov 18 05:35:17 CET 2010


Author: arnaud.fontaine
Date: Thu Nov 18 05:35:16 2010
New Revision: 40345

URL: http://svn.erp5.org?rev=40345&view=rev
Log:
Fix infinite recursion on ZODB Property Sheets accessors generation
and define only one accessor holder module (ZODB Property Sheets)


Modified:
    erp5/trunk/products/ERP5Type/Tool/PropertySheetTool.py
    erp5/trunk/products/ERP5Type/dynamic/portal_type_class.py
    erp5/trunk/products/ERP5Type/mixin/constraint.py
    erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py

Modified: erp5/trunk/products/ERP5Type/Tool/PropertySheetTool.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/Tool/PropertySheetTool.py?rev=40345&r1=40344&r2=40345&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/Tool/PropertySheetTool.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/Tool/PropertySheetTool.py [utf8] Thu Nov 18 05:35:16 2010
@@ -266,7 +266,7 @@ class PropertySheetTool(BaseTool):
     return self._createCommonPropertySheetAccessorHolder(
       property_holder,
       property_sheet.getId(),
-      'erp5.zodb_accessor_holder')
+      'erp5.accessor_holder')
 
   security.declareProtected(Permissions.ManagePortal,
                             'getPropertyAvailablePermissionList')

Modified: erp5/trunk/products/ERP5Type/dynamic/portal_type_class.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/dynamic/portal_type_class.py?rev=40345&r1=40344&r2=40345&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/dynamic/portal_type_class.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/dynamic/portal_type_class.py [utf8] Thu Nov 18 05:35:16 2010
@@ -37,7 +37,6 @@ from Products.ERP5Type.Base import _aq_r
 from Products.ERP5Type.Globals import InitializeClass
 from Products.ERP5Type.Utils import setDefaultClassProperties
 from Products.ERP5Type import document_class_registry, mixin_class_registry
-from Products.ERP5Type import PropertySheet as FilesystemPropertySheet
 
 from zope.interface import classImplements
 from zLOG import LOG, ERROR, INFO
@@ -66,6 +65,9 @@ def _fillAccessorHolderList(accessor_hol
   could be coming either from the filesystem or ZODB)
   """
   for property_sheet_name in property_sheet_name_set:
+    # LOG("ERP5Type.dynamic", INFO,
+    #     "Getting accessor holder for " + property_sheet_name)
+
     try:
       # Get the already generated accessor holder
       accessor_holder_list.append(getattr(accessor_holder_module,
@@ -79,19 +81,31 @@ def _fillAccessorHolderList(accessor_hol
                                               property_sheet_name))
 
       except AttributeError:
-        # Not too critical
         LOG("ERP5Type.dynamic", ERROR,
             "Ignoring missing Property Sheet " + property_sheet_name)
 
-      else:
-        setattr(accessor_holder_module, property_sheet_name,
-                accessor_holder_class)
-
-        accessor_holder_list.append(accessor_holder_class)
-
-        LOG("ERP5Type.dynamic", INFO,
-            "Created accessor holder for %s in %s" % (property_sheet_name,
-                                                      accessor_holder_module))
+        raise
+
+      accessor_holder_list.append(accessor_holder_class)
+
+      setattr(accessor_holder_module, property_sheet_name,
+              accessor_holder_class)
+
+    #   LOG("ERP5Type.dynamic", INFO,
+    #       "Created accessor holder for %s in %s" % (property_sheet_name,
+    #                                                 accessor_holder_module))
+
+    # LOG("ERP5Type.dynamic", INFO,
+    #     "Got accessor holder for " + property_sheet_name)
+
+# Loading Cache Factory portal type would generate the accessor holder
+# for Cache Factory, itself defined with Standard Property thus
+# loading the portal type Standard Property, itself defined with
+# Standard Property and so on...
+#
+# NOTE: only the outer Property Sheets is stored in the accessor
+# holder module
+property_sheet_generating_portal_type_set = set()
 
 # 'Types Tool' is required to access 'site.portal_types' and the
 # former requires 'Base Type'. Thus, 'generating' is meaningful to
@@ -120,6 +134,8 @@ def generatePortalTypeClass(portal_type_
   from Products.ERP5.ERP5Site import getSite
   site = getSite()
 
+  # LOG("ERP5Type.dynamic", INFO, "Loading portal type " + portal_type_name)
+
   global core_portal_type_class_dict
 
   if portal_type_name in core_portal_type_class_dict:
@@ -132,6 +148,9 @@ def generatePortalTypeClass(portal_type_
       klass = _importClass(document_class_registry.get(
         core_portal_type_class_dict[portal_type_name]['type_class']))
 
+      # LOG("ERP5Type.dynamic", INFO,
+      #     "Loaded portal type %s (INNER)" % portal_type_name)
+
       # Don't do anything else, just allow to load fully the outer
       # portal type class
       return ((klass,), [], {})
@@ -184,44 +203,57 @@ def generatePortalTypeClass(portal_type_
 
   klass = _importClass(type_class_path)
 
-  accessor_holder_list = []
+  global property_sheet_generating_portal_type_set
 
-  ## Disabled because there will be no commit of
-  ## type_zodb_property_sheet, only use for testing ATM
+  accessor_holder_list = []
 
-  # import erp5
+  if portal_type_name not in property_sheet_generating_portal_type_set:
+    # LOG("ERP5Type.dynamic", INFO,
+    #     "Filling accessor holder list for portal_type " + portal_type_name)
+
+    property_sheet_generating_portal_type_set.add(portal_type_name)
+
+    property_sheet_set = set()
+
+    #### Waiting for Yoshinori's advice before enabling this code
+    # if portal_type is not None:
+    #   # Get the Property Sheets defined on the portal_type
+    #   property_sheet_set.update(portal_type.getTypeZodbPropertySheetList() \
+    #                             or ())
+
+    #### The Property Sheets specified in the property_sheets
+    #### attribute of a Document are only filesystem-based, thus for
+    #### now it has to be done in the Portal Types themselves
+    # # Get the Property Sheets defined on the document and its bases
+    # # recursively
+    # from Products.ERP5Type.Base import getClassPropertyList
+    # for property_sheet in getClassPropertyList(klass):
+    #   if isinstance(property_sheet, basestring):
+    #     property_sheet_name = property_sheet
+    #   # FIXME: The Property Sheets of a document should be given as a
+    #   # string from now on, but to avoid changing all the code now, we
+    #   # just get the class name of the filesystem Property Sheet
+    #   else:
+    #     property_sheet_name = property_sheet.__name__
+
+    #   property_sheet_set.add(property_sheet_name)
+
+    import erp5
+
+    if property_sheet_set:
+      # Initialize ZODB Property Sheets accessor holders
+      _fillAccessorHolderList(
+        accessor_holder_list,
+        site.portal_property_sheets.createZodbPropertySheetAccessorHolder,
+        property_sheet_set,
+        erp5.accessor_holder,
+        site.portal_property_sheets)
 
-  # # Initialize filesystem Property Sheets accessor holders
-  # _fillAccessorHolderList(
-  #   accessor_holder_list,
-  #   site.portal_property_sheets.createFilesystemPropertySheetAccessorHolder,
-  #   set(portal_type.getTypePropertySheetList() or ()),
-  #   erp5.filesystem_accessor_holder,
-  #   FilesystemPropertySheet)
-
-  # # Initialize ZODB Property Sheets accessor holders
-  # _fillAccessorHolderList(
-  #   accessor_holder_list,
-  #   site.portal_property_sheets.createZodbPropertySheetAccessorHolder,
-  #   set(portal_type.getTypeZodbPropertySheetList() or ()),
-  #   erp5.zodb_accessor_holder,
-  #   site.portal_property_sheets)
-
-  # # XXX: for now, we have PropertySheet classes defined in
-  # #      property_sheets attribute of Document, but there will be only
-  # #      string at the end
-  # from Products.ERP5Type.Base import getClassPropertyList
-  # _fillAccessorHolderList(
-  #   accessor_holder_list,
-  #   site.portal_property_sheets.createFilesystemPropertySheetAccessorHolder,
-  #   [ property_sheet.__name__ for property_sheet in \
-  #     getClassPropertyList(klass) ],
-  #   erp5.filesystem_accessor_holder,
-  #   FilesystemPropertySheet)
+    property_sheet_generating_portal_type_set.remove(portal_type_name)
 
   # LOG("ERP5Type.dynamic", INFO,
-  #     "%s: accessor_holder_list: %s" % (portal_type_name,
-  #                                       accessor_holder_list))
+  #     "Filled accessor holder list for portal_type %s (%s)" % \
+  #     (portal_type_name, accessor_holder_list))
 
   mixin_path_list = []
   if mixin_list:
@@ -244,8 +276,8 @@ def generatePortalTypeClass(portal_type_
   #        % (portal_type_name, repr(baseclasses)))
 
   return (tuple(baseclasses),
-         interface_class_list,
-         dict(portal_type=portal_type_name))
+          interface_class_list,
+          dict(portal_type=portal_type_name))
 
 from lazy_class import generateLazyPortalTypeClass
 def initializeDynamicModules():
@@ -259,23 +291,15 @@ def initializeDynamicModules():
       holds document classes that have no physical import path,
       for example classes created through ClassTool that are in
       $INSTANCE_HOME/Document
-    erp5.zodb_accessor_holder
+    erp5.accessor_holder
       holds accessors of ZODB Property Sheets
-    erp5.filesystem_accessor_holder
-      holds accessors of filesystem Property Sheets
-
-  XXX: there should be only one accessor_holder once the code is
-       stable and all the Property Sheets have been migrated
   """
   erp5 = ModuleType("erp5")
   sys.modules["erp5"] = erp5
   erp5.document = ModuleType("erp5.document")
   sys.modules["erp5.document"] = erp5.document
-
-  erp5.zodb_accessor_holder = ModuleType("erp5.zodb_accessor_holder")
-  sys.modules["erp5.zodb_accessor_holder"] = erp5.zodb_accessor_holder
-  erp5.filesystem_accessor_holder = ModuleType("erp5.filesystem_accessor_holder")
-  sys.modules["erp5.filesystem_accessor_holder"] = erp5.filesystem_accessor_holder
+  erp5.accessor_holder = ModuleType("erp5.accessor_holder")
+  sys.modules["erp5.accessor_holder"] = erp5.accessor_holder
 
   portal_type_container = registerDynamicModule('erp5.portal_type',
                                                 generateLazyPortalTypeClass)
@@ -317,18 +341,6 @@ def initializeDynamicModules():
   erp5.temp_portal_type = registerDynamicModule('erp5.temp_portal_type',
                                                 loadTempPortalTypeClass)
 
-def _clearAccessorHolderModule(module):
-  """
-  Clear the given accessor holder module (either for filesystem or
-  ZODB)
-
-  XXX: Merge into synchronizeDynamicModules as soon as we get rid of
-       these two accessor holder modules
-  """
-  for property_sheet_id in module.__dict__.keys():
-    if not property_sheet_id.startswith('__'):
-      delattr(module, property_sheet_id)
-
 last_sync = 0
 def synchronizeDynamicModules(context, force=False):
   """
@@ -364,10 +376,9 @@ def synchronizeDynamicModules(context, f
     klass.restoreGhostState()
 
   # Clear accessor holders of ZODB Property Sheets
-  _clearAccessorHolderModule(erp5.zodb_accessor_holder)
-
-  # Clear accessor holders of filesystem Property Sheets
-  _clearAccessorHolderModule(erp5.filesystem_accessor_holder)
+  for property_sheet_id in erp5.accessor_holder.__dict__.keys():
+    if not property_sheet_id.startswith('__'):
+      delattr(erp5.accessor_holder, property_sheet_id)
 
   # Necessary because accessors are wrapped in WorkflowMethod by
   # _aq_dynamic (performed in createAccessorHolder)

Modified: erp5/trunk/products/ERP5Type/mixin/constraint.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/mixin/constraint.py?rev=40345&r1=40344&r2=40345&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/mixin/constraint.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/mixin/constraint.py [utf8] Thu Nov 18 05:35:16 2010
@@ -96,4 +96,4 @@ class ConstraintMixin(Predicate):
 
     XXX: remove as soon as the code is stable
     """
-    return self.asContext().aq_base
+    return self.asContext()

Modified: erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py?rev=40345&r1=40344&r2=40345&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py [utf8] Thu Nov 18 05:35:16 2010
@@ -462,14 +462,14 @@ class TestZodbPropertySheet(ERP5TypeTest
 
       # The accessor holder will be generated once the new Person will
       # be created as Person type has test Property Sheet
-      self.failIfHasAttribute(erp5.zodb_accessor_holder, 'TestMigration')
+      self.failIfHasAttribute(erp5.accessor_holder, 'TestMigration')
 
       new_person = portal.person_module.newContent(
         id='testAssignZodbPropertySheet', portal_type='Person')
 
-      self.assertHasAttribute(erp5.zodb_accessor_holder, 'TestMigration')
+      self.assertHasAttribute(erp5.accessor_holder, 'TestMigration')
 
-      self.assertTrue(erp5.zodb_accessor_holder.TestMigration in \
+      self.assertTrue(erp5.accessor_holder.TestMigration in \
                       erp5.portal_type.Person.mro())
 
       # Check that the accessors have been properly created for all
@@ -523,7 +523,7 @@ class TestZodbPropertySheet(ERP5TypeTest
       # workflow and the ID of the interaction and where the value is
       # a boolean stating whether the transition method has already
       # been called before.  Thus, the next statement may not reset
-      # erp5.zodb_accessor_holder as loading Person portal type calls
+      # erp5.accessor_holder as loading Person portal type calls
       # '_setType*'
       transaction.commit()
 
@@ -546,7 +546,7 @@ class TestZodbPropertySheet(ERP5TypeTest
         id='testAssignZodbPropertySheet', portal_type='Person')
 
       self.failIfHasAttribute(new_person, 'getTestStandardPropertyAssign')
-      self.failIfHasAttribute(erp5.zodb_accessor_holder, 'TestMigration')
+      self.failIfHasAttribute(erp5.accessor_holder, 'TestMigration')
 
     finally:
       if new_person is not None:
@@ -555,15 +555,15 @@ class TestZodbPropertySheet(ERP5TypeTest
   def _checkAddPropertyToZodbPropertySheet(self,
                                           new_property_function,
                                           added_accessor_name):
-    import erp5.zodb_accessor_holder
+    import erp5.accessor_holder
 
-    self.failIfHasAttribute(erp5.zodb_accessor_holder, 'TestMigration')
+    self.failIfHasAttribute(erp5.accessor_holder, 'TestMigration')
 
     new_property_function('add')
     self._forceTestAccessorHolderGeneration()
 
-    self.assertHasAttribute(erp5.zodb_accessor_holder, 'TestMigration')
-    self.assertHasAttribute(erp5.zodb_accessor_holder.TestMigration,
+    self.assertHasAttribute(erp5.accessor_holder, 'TestMigration')
+    self.assertHasAttribute(erp5.accessor_holder.TestMigration,
                             added_accessor_name)
 
   def testAddStandardPropertyToZodbPropertySheet(self):
@@ -606,15 +606,15 @@ class TestZodbPropertySheet(ERP5TypeTest
                                              change_setter_func,
                                              new_value,
                                              changed_accessor_name):
-    import erp5.zodb_accessor_holder
+    import erp5.accessor_holder
 
-    self.failIfHasAttribute(erp5.zodb_accessor_holder, 'TestMigration')
+    self.failIfHasAttribute(erp5.accessor_holder, 'TestMigration')
 
     change_setter_func(new_value)
     self._forceTestAccessorHolderGeneration()
 
-    self.assertHasAttribute(erp5.zodb_accessor_holder, 'TestMigration')
-    self.assertHasAttribute(erp5.zodb_accessor_holder.TestMigration,
+    self.assertHasAttribute(erp5.accessor_holder, 'TestMigration')
+    self.assertHasAttribute(erp5.accessor_holder.TestMigration,
                             changed_accessor_name)
 
   def testChangeStandardPropertyOfZodbPropertySheet(self):
@@ -666,17 +666,17 @@ class TestZodbPropertySheet(ERP5TypeTest
     Delete the given property from the test Property Sheet and check
     whether its corresponding accessor is not there anymore
     """
-    import erp5.zodb_accessor_holder
+    import erp5.accessor_holder
 
-    self.failIfHasAttribute(erp5.zodb_accessor_holder, 'TestMigration')
+    self.failIfHasAttribute(erp5.accessor_holder, 'TestMigration')
 
     # Delete the property and force re-generation of TestMigration
     # accessor holder
     self.test_property_sheet.deleteContent(property_id)
     self._forceTestAccessorHolderGeneration()
 
-    self.assertHasAttribute(erp5.zodb_accessor_holder, 'TestMigration')
-    self.failIfHasAttribute(erp5.zodb_accessor_holder.TestMigration,
+    self.assertHasAttribute(erp5.accessor_holder, 'TestMigration')
+    self.failIfHasAttribute(erp5.accessor_holder.TestMigration,
                             accessor_name)
 
   def testDeleteStandardPropertyFromZodbPropertySheet(self):




More information about the Erp5-report mailing list