Commit b230c4e3 authored by Arnaud Fontaine's avatar Arnaud Fontaine

py3: Make metaclass with ExtensionClass work on both python2 and python3.

parent 4420bce7
...@@ -550,6 +550,45 @@ def checkPythonSourceCode(source_code_str, portal_type=None): ...@@ -550,6 +550,45 @@ def checkPythonSourceCode(source_code_str, portal_type=None):
#LOG('Utils', INFO, 'Checking time (pylint): %.2f' % (time.time() - started)) #LOG('Utils', INFO, 'Checking time (pylint): %.2f' % (time.time() - started))
return message_list return message_list
#####################################################
# Python 2-3 compat
#####################################################
def with_metaclass(meta, *bases):
"""
Function from jinja2/_compat.py. License: BSD (copy/paste here for
ExtensionClass)
Use it like this::
class BaseForm(object):
pass
class FormType(type):
pass
class Form(with_metaclass(FormType, BaseForm)):
pass
This requires a bit of explanation: the basic idea is to make a
dummy metaclass for one level of class instantiation that replaces
itself with the actual metaclass. Because of internal type checks
we also need to make sure that we downgrade the custom metaclass
for one level to something closer to type (that's why __call__ and
__init__ comes back from type etc.).
This has the advantage over six.with_metaclass of not introducing
dummy classes into the final MRO.
"""
class metaclass(meta):
__call__ = type.__call__
__init__ = type.__init__
def __new__(cls, name, this_bases, d):
if this_bases is None:
import ExtensionClass
return ExtensionClass.ExtensionClass.__new__(cls, name, (), d)
return meta(name, bases, d)
return metaclass('temporary_class', None, {})
##################################################### #####################################################
# Globals initialization # Globals initialization
##################################################### #####################################################
......
...@@ -122,7 +122,8 @@ class RecordablePropertyMetaClass(ExtensionClass): ...@@ -122,7 +122,8 @@ class RecordablePropertyMetaClass(ExtensionClass):
# ghosting/unghosting Portal Types # ghosting/unghosting Portal Types
return ExtensionClass.__new__(ExtensionClass, name, bases, dictionary) return ExtensionClass.__new__(ExtensionClass, name, bases, dictionary)
class ComponentMixin(PropertyRecordableMixin, Base): from Products.ERP5Type.Utils import with_metaclass
class ComponentMixin(with_metaclass(RecordablePropertyMetaClass, type('NewBase', (PropertyRecordableMixin, Base), {}))):
""" """
Mixin used for all ZODB Components. Most of the code is generic, thus actual Mixin used for all ZODB Components. Most of the code is generic, thus actual
ZODB Components should have almost nothing to defined... ZODB Components should have almost nothing to defined...
...@@ -145,8 +146,6 @@ class ComponentMixin(PropertyRecordableMixin, Base): ...@@ -145,8 +146,6 @@ class ComponentMixin(PropertyRecordableMixin, Base):
state, checkConsistency() is called to check id, reference, version and state, checkConsistency() is called to check id, reference, version and
errors/warnings messages (set when the Component is modified). errors/warnings messages (set when the Component is modified).
""" """
__metaclass__ = RecordablePropertyMetaClass
isPortalContent = 1 isPortalContent = 1
isRADContent = 1 isRADContent = 1
isDelivery = ConstantGetter('isDelivery', value=True) isDelivery = ConstantGetter('isDelivery', value=True)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment