Commit b4d37a31 authored by 's avatar

- removed metaclass (AFAICS it is obsolete)

parent 3aea68c0
......@@ -73,6 +73,8 @@ Features Added
Restructuring
+++++++++++++
- Five: Removed obsolete metaclass.
- Five: Refactored ``browser:view`` and ``browser:page`` directives.
This makes their implementation more similar to that in ``zope.browserpage``
and adds allowed_interface support for the ``browser:view`` directive.
......
......@@ -8,9 +8,5 @@ Five contains source code derived from:
- Zope, copyright (C) 2001-2005 by Zope Corporation.
- metaclass.py is derived from PEAK, copyright (C) 1996-2004 by
Phillip J. Eby and Tyler C. Sarna. PEAK may be used under the same
terms as Zope.
- TrustedExecutables. Dieter Mauer kindly allow licensing this under the
ZPL 2.1.
......@@ -51,7 +51,6 @@ from Products.Five.browser.resource import ImageResourceFactory
from Products.Five.browser.resource import PageTemplateResourceFactory
from Products.Five.browser.resource import DirectoryResourceFactory
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from Products.Five.metaclass import makeClass
def _configure_z2security(_context, new_class, required):
_context.action(
......@@ -131,7 +130,7 @@ def page(_context, name, permission, for_=Interface,
})
cdict['__name__'] = name
cdict['__page_attribute__'] = attribute
new_class = makeClass(class_.__name__, (class_, simple), cdict)
new_class = type(class_.__name__, (class_, simple,), cdict)
if attribute != "__call__":
# in case the attribute does not provide a docstring,
......@@ -273,7 +272,7 @@ class view(zope.browserpage.metaconfigure.view):
cname = "GeneratedClass"
cdict['__name__'] = name
newclass = makeClass(cname, bases, cdict)
newclass = type(cname, bases, cdict)
for n in ('',):
required[n] = permission
......@@ -331,7 +330,7 @@ def resource(_context, name, layer=IDefaultBrowserLayer, permission='zope.Public
factory_info['count'] += 1
res_factory = factory_info['factory']
class_name = '%s%s' % (factory_info['prefix'], factory_info['count'])
new_class = makeClass(class_name, (res_factory.resource,), {})
new_class = type(class_name, (res_factory.resource,), {})
factory = res_factory(name, res, resource_factory=new_class)
_context.action(
......@@ -380,9 +379,9 @@ def resourceDirectory(_context, name, directory, layer=IDefaultBrowserLayer,
factory_info['count'] += 1
class_name = '%s%s' % (factory_info['prefix'], factory_info['count'])
factory_name = '%s%s' % (factory.__name__, factory_info['count'])
f_resource = makeClass(class_name, (factory.resource,), {})
f_cache[factory] = makeClass(factory_name, (factory,),
{'resource':f_resource})
f_resource = type(class_name, (factory.resource,), {})
f_cache[factory] = type(factory_name, (factory,),
{'resource': f_resource})
for ext, factory in resource_factories.items():
resource_factories[ext] = f_cache[factory]
default_factory = resource_factories['default']
......@@ -394,7 +393,7 @@ def resourceDirectory(_context, name, directory, layer=IDefaultBrowserLayer,
factory_info = _rd_map.get(DirectoryResourceFactory)
factory_info['count'] += 1
class_name = '%s%s' % (factory_info['prefix'], factory_info['count'])
dir_factory = makeClass(class_name, (resource,), cdict)
dir_factory = type(class_name, (resource,), cdict)
factory = DirectoryResourceFactory(name, directory,
resource_factory=dir_factory)
......@@ -454,7 +453,7 @@ def SimpleViewClass(src, offering=None, used_for=None, bases=(), name=u''):
bases += (ViewMixinForTemplates,)
class_ = makeClass("SimpleViewClass from %s" % src, bases, cdict)
class_ = type("SimpleViewClass from %s" % src, bases, cdict)
if used_for is not None:
class_.__used_for__ = used_for
......
......@@ -21,7 +21,7 @@ views still works (the printed output is the aq_chain of the view):
>>> browser.open('http://localhost/test_folder_1_/attributes')
>>> print browser.contents
[<Products.Five.metaclass.LegacyAttributes object at ...>,
[<Products.Five.browser.metaconfigure.LegacyAttributes object at ...>,
<Folder at /test_folder_1_>,
<Application at >,
<ZPublisher.BaseRequest.RequestContainer object at ...>]
......@@ -30,7 +30,7 @@ The same goes for browser views that just mix in Acquisition.Explicit:
>>> browser.open('http://localhost/test_folder_1_/explicitattributes')
>>> print browser.contents
[<Products.Five.metaclass.ExplicitLegacyAttributes object at ...>,
[<Products.Five.browser.metaconfigure.ExplicitLegacyAttributes object at ...>,
<Folder at /test_folder_1_>,
<Application at >,
<ZPublisher.BaseRequest.RequestContainer object at ...>]
......
......@@ -77,14 +77,14 @@ it shouldn't modify existing ones:
Make sure new-style classes work fine as view classes:
>>> self.folder.unrestrictedTraverse('testoid/@@new_style_class')
<Products.Five.metaclass.NewStyleClass ...>
<Products.Five.browser.metaconfigure.NewStyleClass ...>
At one point browser classes with no attribute and no template
values specified wasn't getting BrowserView mixed in. Lets make
sure it is now:
>>> self.folder.unrestrictedTraverse('testoid/@@new_style_class2')
<Products.Five.metaclass.NewStyleClass ...>
<Products.Five.browser.metaconfigure.NewStyleClass ...>
Both browser:view and browser:page are ILocation providers, so make sure they
have a __name__ attribute:
......
##############################################################################
#
# Copyright (c) 2004, 2005 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
# metaclass taken from PEAK.
# Martijn doesn't pretend to understand this.
from weakref import WeakValueDictionary
from types import ClassType
def makeClass(name,bases,dict):
"""makeClass(name, bases, dict) - enhanced class creation
"""
# Create either a "classic" Python class, an ExtensionClass, or a new-style
# class with autogenerated metaclass, based on the nature of the base
# classes involved
name = str(name) # De-unicode
metaclasses = [getattr(b,'__class__',type(b)) for b in bases]
if dict.has_key('__metaclass__'):
metaclasses.insert(0,dict['__metaclass__'])
if dict.has_key('__metaclasses__'):
metaclasses[0:0] = list(dict['__metaclasses__'])
metaclasses = normalizeBases(metaclasses)
if metaclasses:
# If we have metaclasses, it's not a classic class, so derive a
# single metaclass, and ask it to create the class.
if len(metaclasses)==1:
metaclass = metaclasses[0]
else:
metaclass = derivedMeta(metaclasses)
return metaclass(name,bases,dict)
# No metaclasses, it's a classic class, so use 'new.classobj'
from new import classobj; return classobj(name,bases,dict)
def normalizeBases(allBases):
return minimalBases([b for b in allBases if b is not makeClass])
def minimalBases(classes):
"""Reduce a list of base classes to its ordered minimum equivalent"""
classes = [c for c in classes if c is not ClassType]
candidates = []
for m in classes:
for n in classes:
if issubclass(n,m) and m is not n:
break
else:
# m has no subclasses in 'classes'
if m in candidates:
candidates.remove(m) # ensure that we're later in the list
candidates.append(m)
return candidates
metaReg = WeakValueDictionary()
def derivedMeta(metaclasses):
metaclasses = tuple(metaclasses)
derived = metaReg.get(metaclasses)
if derived is None:
normalized = tuple(normalizeBases(metaclasses))
derived = metaReg.get(normalized)
if derived is None:
if len(normalized)==1:
derived = normalized[0]
else:
derived = metaFromBases(normalized)(
'_'.join([n.__name__ for n in normalized]),
metaclasses, {}
)
try: metaReg[normalized] = derived
except TypeError: pass # Some metatypes can't be weakref'd
try: metaReg[metaclasses] = derived
except TypeError: pass
return derived
def metaFromBases(bases):
meta = tuple([getattr(b,'__class__',type(b)) for b in bases])
if meta==bases: raise TypeError("Incompatible root metatypes",bases)
return derivedMeta(meta)
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