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