From 13b0fb9a5680f948f8fcefea99c8500fbbec924b Mon Sep 17 00:00:00 2001 From: Julien Muchembled <jm@nexedi.com> Date: Sun, 17 Jan 2010 22:20:23 +0000 Subject: [PATCH] Fix support of BT containing instances of classes defined by the BT itself. This fixes [28422] and testBPMEvaluation (PicklingError exceptions). This reverts useless [30411]. It also allows to revert [31213]. git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@31791 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5/Document/BusinessTemplate.py | 25 +++++++++++++++++----- product/ERP5Type/tests/ERP5TypeTestCase.py | 3 +-- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/product/ERP5/Document/BusinessTemplate.py b/product/ERP5/Document/BusinessTemplate.py index 8f967b25bf..07d4a70935 100644 --- a/product/ERP5/Document/BusinessTemplate.py +++ b/product/ERP5/Document/BusinessTemplate.py @@ -5611,15 +5611,22 @@ Business Template is a set of definitions, such as skins, portal types and categ # Create temporary modules/classes for classes defined by this BT. # This is required if the BT contains instances of one of these classes. module_id_list = [] + instance_oid_list = [] for template_type in ('Constraint', 'Document', 'PropertySheet'): for template_id in getattr(self, 'getTemplate%sIdList' % template_type)(): module_id = 'Products.ERP5Type.%s.%s' % (template_type, template_id) - if module_id not in sys.modules: - module_id_list.append(module_id) - sys.modules[module_id] = module = imp.new_module(module_id) - module.SimpleItem = SimpleItem.SimpleItem - exec "class %s(SimpleItem): pass" % template_id in module.__dict__ + module_id_list.append(module_id) + # Always redefine the module, so that 'instance_oid_list' contains + # the full list of oid to remove from pickle cache. + sys.modules[module_id] = module = imp.new_module(module_id) + module.SimpleItem = SimpleItem.SimpleItem + module.instance_oid_list = instance_oid_list + exec """class %s(SimpleItem): + def __setstate__(self, state): + instance_oid_list.append(self._p_oid) + return SimpleItem.__setstate__(self, state)""" % template_id \ + in module.__dict__ for item_name in self._item_name_list: getattr(self, item_name).importFile(bta) @@ -5628,6 +5635,14 @@ Business Template is a set of definitions, such as skins, portal types and categ # (during the installation). for module_id in module_id_list: del sys.modules[module_id] + # Remove from pickle cache all objects whose classes are temporary + # (= defined by this BT). This forces to reload these objects on next + # access, with the correct classes. + # Invalidation is forced using __delitem__ instead of invalidate. + if instance_oid_list: + pickle_cache = self.getPortalObject()._p_jar._cache + for oid in instance_oid_list: + del pickle_cache[oid] def getItemsList(self): """Return list of items in business template diff --git a/product/ERP5Type/tests/ERP5TypeTestCase.py b/product/ERP5Type/tests/ERP5TypeTestCase.py index 1aa8c14a84..004defcfc1 100644 --- a/product/ERP5Type/tests/ERP5TypeTestCase.py +++ b/product/ERP5Type/tests/ERP5TypeTestCase.py @@ -11,7 +11,7 @@ import base64 import errno import md5 import os -#import random # XXX +import random import re import socket import sys @@ -753,7 +753,6 @@ class ERP5TypeTestCase(backportUnittest.TestCase, PortalTestCase): """Starts an HTTP ZServer thread.""" from Testing.ZopeTestCase import threadutils, utils if utils._Z2HOST is None: - import random randint = random.Random(hash(os.environ['INSTANCE_HOME'])).randint def zserverRunner(): try: -- 2.30.9