From 9071fb3cb4de7d70cb47cdeeb07e667da98f04be Mon Sep 17 00:00:00 2001 From: Nicolas Dumazet <nicolas.dumazet@nexedi.com> Date: Tue, 2 Nov 2010 05:45:48 +0000 Subject: [PATCH] weed out the not-so-pretty ExtensionClass.__init__ trick Exploring Zope code finally revealed what we needed in the code, to allow removing the "trick". It's a "trick" because we have no real reason to call again the __init__ method of a metaclass: it's nicer to understand what we need to do and to do it explicitely. In this case, the __get__ slot was missing after the __bases__ assignement (bases are recomputed and as a result __get__ is null'ed), and there is a method exposed in Zope's ExtensionClass to do exactly this and only this. The InitializeClass calls are included because ExtensionClass.__init__ calls __class_init__, which sets correctly roles and security on the class. git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@39752 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5Type/dynamic/lazy_class.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/product/ERP5Type/dynamic/lazy_class.py b/product/ERP5Type/dynamic/lazy_class.py index 5232d903cb..d958a7ad78 100644 --- a/product/ERP5Type/dynamic/lazy_class.py +++ b/product/ERP5Type/dynamic/lazy_class.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- import sys +from Products.ERP5Type.Globals import InitializeClass from Products.ERP5Type.Base import Base as ERP5Base -from ExtensionClass import Base as ExtensionBase +from ExtensionClass import ExtensionClass, pmc_init_of from ZODB.broken import Broken, PersistentBroken from zLOG import LOG, ERROR, BLATHER @@ -12,8 +13,6 @@ ERP5BaseBroken = type('ERP5BaseBroken', (Broken, ERP5Base), dict(x for x in PersistentBroken.__dict__.iteritems() if x[0] not in ('__dict__', '__module__', '__weakref__'))) -ExtensionClass = type(ExtensionBase) - class PortalTypeMetaClass(ExtensionClass): """ Meta class that will be used by portal type classes @@ -40,9 +39,18 @@ class PortalTypeMetaClass(ExtensionClass): return metacls.subclass_register.get(cls, []) def InitializePortalTypeClass(klass): - ExtensionClass.__init__(klass, klass) + # First, fill the __get__ slot of the class + # that has been null'ed after resetting its __bases__ + # This descriptor is the magic allowing __of__ and our + # _aq_dynamic trick + pmc_init_of(klass) + # Then, call __class_init__ on the class for security + InitializeClass(klass) + + # And we need to do the same thing on subclasses for klass in PortalTypeMetaClass.getSubclassList(klass): - ExtensionClass.__init__(klass, klass) + pmc_init_of(klass) + InitializeClass(klass) def generateLazyPortalTypeClass(portal_type_name, portal_type_class_loader): -- 2.30.9