[Erp5-report] r39879 nicolas.dumazet - in /erp5/trunk/products/ERP5Type: dynamic/ tests/
nobody at svn.erp5.org
nobody at svn.erp5.org
Thu Nov 4 08:03:17 CET 2010
Author: nicolas.dumazet
Date: Thu Nov 4 08:03:16 2010
New Revision: 39879
URL: http://svn.erp5.org?rev=39879&view=rev
Log:
add support for interfaces on Portal Type classes.
You can now add and remove interfaces to Portal Types on the fly.
Modified:
erp5/trunk/products/ERP5Type/dynamic/lazy_class.py
erp5/trunk/products/ERP5Type/dynamic/portal_type_class.py
erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py
Modified: erp5/trunk/products/ERP5Type/dynamic/lazy_class.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/dynamic/lazy_class.py?rev=39879&r1=39878&r2=39879&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/dynamic/lazy_class.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/dynamic/lazy_class.py [utf8] Thu Nov 4 08:03:16 2010
@@ -1,9 +1,12 @@
# -*- coding: utf-8 -*-
import sys
+
from Products.ERP5Type.Globals import InitializeClass
from Products.ERP5Type.Base import Base as ERP5Base
from ExtensionClass import ExtensionClass, pmc_init_of
+
+from zope.interface import classImplements
from ZODB.broken import Broken, PersistentBroken
from zLOG import LOG, WARNING, BLATHER
@@ -120,22 +123,28 @@ class PortalTypeMetaClass(ExtensionClass
portal_type = klass.__name__
try:
- baseclasses, attributes = generatePortalTypeClass(portal_type)
+ class_definition = generatePortalTypeClass(portal_type)
except AttributeError:
LOG("ERP5Type.Dynamic", WARNING,
"Could not access Portal Type Object for type %r"
% portal_type, error=sys.exc_info())
- baseclasses = (ERP5BaseBroken, )
- attributes = {}
+ base_list = (ERP5BaseBroken, )
+ attribute_dict = {}
+ interface_list = []
+ else:
+ base_list, interface_list, attribute_dict = class_definition
+
# save the old bases to be able to restore a ghost state later
klass.__ghostbase__ = klass.__bases__
- klass.__bases__ = baseclasses
+ klass.__bases__ = base_list
- for key, value in attributes.iteritems():
+ for key, value in attribute_dict.iteritems():
setattr(klass, key, value)
klass.resetAcquisitionAndSecurity()
+ for interface in interface_list:
+ classImplements(klass, interface)
def generateLazyPortalTypeClass(portal_type_name):
return PortalTypeMetaClass(portal_type_name, (GhostPortalType,), {})
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=39879&r1=39878&r2=39879&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 4 08:03:16 2010
@@ -29,7 +29,6 @@
import sys
import inspect
-
from types import ModuleType
from dynamic_module import registerDynamicModule
@@ -39,6 +38,8 @@ from Products.ERP5Type.Globals import In
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
def _importClass(classpath):
@@ -175,11 +176,19 @@ def generatePortalTypeClass(portal_type_
baseclasses = [klass] + accessor_holder_list + mixin_class_list
+ interface_class_list = []
+ if interface_list:
+ from Products.ERP5Type import interfaces
+ interface_class_list = [getattr(interfaces, name)
+ for name in interface_list]
+
#LOG("ERP5Type.dynamic", INFO,
# "Portal type %s loaded with bases %s" \
# % (portal_type_name, repr(baseclasses)))
- return tuple(baseclasses), dict(portal_type=portal_type_name)
+ return (tuple(baseclasses),
+ interface_class_list,
+ dict(portal_type=portal_type_name))
from lazy_class import generateLazyPortalTypeClass
def initializeDynamicModules():
Modified: erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py?rev=39879&r1=39878&r2=39879&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py [utf8] Thu Nov 4 08:03:16 2010
@@ -35,6 +35,8 @@ from Products.ERP5Type.dynamic.portal_ty
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.backportUnittest import expectedFailure, skip
+from zope.interface import Interface, implementedBy
+
class TestPortalTypeClass(ERP5TypeTestCase):
def getBusinessTemplateList(self):
return 'erp5_base',
@@ -205,6 +207,40 @@ class TestPortalTypeClass(ERP5TypeTestCa
self.assertEquals(accessor(), 'foobar')
self.assertEquals(temp.__class__.__module__, 'erp5.temp_portal_type')
+ def testInterfaces(self):
+ types_tool = self.portal.portal_types
+
+ # a new interface
+ class IForTest(Interface):
+ pass
+ from Products.ERP5Type import interfaces
+ interfaces.IForTest = IForTest
+
+
+ # one new type
+ dummy_type = types_tool.newContent('InterfaceTestType',
+ 'Base Type')
+ # implementing IForTest
+ dummy_type.edit(type_class='Person',
+ type_interface_list=['IForTest',],)
+ transaction.commit()
+
+ from erp5.portal_type import InterfaceTestType
+
+ # it's necessary to load the class
+ # to have a correct list of interfaces
+ implemented_by = list(implementedBy(InterfaceTestType))
+ self.failIf(IForTest in implemented_by)
+ InterfaceTestType.loadClass()
+
+ implemented_by = list(implementedBy(InterfaceTestType))
+ self.assertTrue(IForTest in implemented_by,
+ 'IForTest not in %s' % implemented_by)
+
+ InterfaceTestType.restoreGhostState()
+ implemented_by = list(implementedBy(InterfaceTestType))
+ self.failIf(IForTest in implemented_by)
+
class TestZodbPropertySheet(ERP5TypeTestCase):
"""
XXX: WORK IN PROGRESS
More information about the Erp5-report
mailing list