diff --git a/product/ERP5Type/ZopePatch.py b/product/ERP5Type/ZopePatch.py index d695af278469909f595cbf7f8e70afaf598c2ad4..6c943c7f4a7dbba4fd1f83e25790d52619ee563d 100644 --- a/product/ERP5Type/ZopePatch.py +++ b/product/ERP5Type/ZopePatch.py @@ -47,6 +47,8 @@ from Products.ERP5Type.patches import CMFCoreSkinnable from Products.ERP5Type.patches import CMFCoreSkinsTool from Products.ERP5Type.patches import OFSFolder from Products.ERP5Type.patches import HTTPRequest +from Products.ERP5Type.patches import Connection +from Products.ERP5Type.patches import copy_reg_patch # These symbols are required for backward compatibility from Products.ERP5Type.patches.PropertyManager import ERP5PropertyManager diff --git a/product/ERP5Type/patches/Connection.py b/product/ERP5Type/patches/Connection.py new file mode 100644 index 0000000000000000000000000000000000000000..7cc78557c8f768a2b5ed921e9a8d070f84c61a5f --- /dev/null +++ b/product/ERP5Type/patches/Connection.py @@ -0,0 +1,74 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# Copyright (c) 2007 Nexedi SA +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## + +"""This patch is for importing Business Templates generated by Zope 2.8 +into Zope 2.7. + +In Zope 2.7, the class of an object was represented by a tuple (module, name), +but this has been changed to just a class name itself. +""" + +try: + # This portion depends on ZODB, so the version test is based on + # the ZODB's structure. In ZODB 3.4 and later, the object serialization + # is segregated to serialize.py, while it is in Connection.py in ZODB 3.2. + from ZODB import serialize + del serialize +except ImportError: + from ZODB.Connection import Connection, StringIO, Unpickler, ExtensionKlass + + def __getitem__(self, oid, tt=type(())): + obj = self._cache.get(oid, None) + if obj is not None: + return obj + + __traceback_info__ = (oid) + p, serial = self._storage.load(oid, self._version) + __traceback_info__ = (oid, p) + file=StringIO(p) + unpickler=Unpickler(file) + unpickler.persistent_load=self._persistent_load + + object = unpickler.load() + + # <patch author="yo"> + if type(object) is tt: + klass, args = object + else: + klass = object + args = None + # </patch> + + if type(klass) is tt: + module, name = klass + klass=self._db._classFactory(self, module, name) + + if (args is None or + not args and not hasattr(klass,'__getinitargs__')): + object=klass.__basicnew__() + else: + object = klass(*args) + if klass is not ExtensionKlass: + object.__dict__.clear() + + object._p_oid=oid + object._p_jar=self + object._p_changed=None + object._p_serial=serial + + self._cache[oid] = object + return object + + Connection.__getitem__ = __getitem__ diff --git a/product/ERP5Type/patches/copy_reg_patch.py b/product/ERP5Type/patches/copy_reg_patch.py new file mode 100644 index 0000000000000000000000000000000000000000..ae7d16c55e4c08b3d6de7d61d66e03f480cdf9bd --- /dev/null +++ b/product/ERP5Type/patches/copy_reg_patch.py @@ -0,0 +1,62 @@ +############################################################################## +# +# Copyright (c) 2007 Nexedi SA and Contributors. All Rights Reserved. +# Yoshinori Okuji <yo@nexedi.com> +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsability of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# garantees and support are strongly adviced to contract a Free Software +# Service Company +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################## + +"""This is another patch for importing Business Templates generated by Zope 2.8 +into Zope 2.7. Also, look at Connection.py for the other part. + +In Zope 2.8 (i.e. ZODB 3.4), persistent objects are based on new-style class, +while Zope 2.7 (i.e. ZODB 3.2) uses old-style class only. To instantiate +objects in ZODB 3.4 and later, copy_reg.__newobj__ is utilized, which +supports only new-style class. On the other hand, ZODB 3.2 makes an empty +object by calling the class object with None. + +However, this is based on the analysis of some observation, and theoretically +not very certain. There might be an occasion where non-None arguments are +used to instantiate a ghost object. I am not sure. If this is not true, +we must patch __newobj__ differently. + +Note that this file is named copy_reg_patch instead of copy_reg by intention. +Otherwise, importing copy_reg results in importing itself. SO DO NOT RENAME +THIS FILE TO copy_reg.py. +""" + +try: + from ZODB import serialize + del serialize +except ImportError: + import copy_reg + + original_newobj = copy_reg.__newobj__ + def __newobj__(cls, *args): + # If this method is used for new-style class, call the original. + # Otherwise, just call the class object with None. + if issubclass(cls, object): + return original_newobj(cls, *args) + return cls(None) + + copy_reg.__newobj__ = __newobj__