[z3-checkins] r18095 - in z3/Five/branch/zope31: . browser browser/tests doc form form/tests skin/tests tests

faassen at codespeak.net faassen at codespeak.net
Mon Oct 3 10:46:43 CEST 2005


Author: faassen
Date: Mon Oct  3 10:46:36 2005
New Revision: 18095

Added:
   z3/Five/branch/zope31/doc/zope31goals.txt
Modified:
   z3/Five/branch/zope31/browser/configure.zcml
   z3/Five/branch/zope31/browser/meta.zcml
   z3/Five/branch/zope31/browser/metaconfigure.py
   z3/Five/branch/zope31/browser/resource.py
   z3/Five/branch/zope31/browser/tests/pages.txt
   z3/Five/branch/zope31/browser/tests/pages_ftest.txt
   z3/Five/branch/zope31/browser/tests/resource.txt
   z3/Five/branch/zope31/browser/tests/resource_ftest.txt
   z3/Five/branch/zope31/browser/tests/test_absoluteurl.py
   z3/Five/branch/zope31/browser/tests/test_defaultview.py
   z3/Five/branch/zope31/browser/tests/test_i18n.py
   z3/Five/branch/zope31/browser/tests/test_menu.py
   z3/Five/branch/zope31/browser/tests/test_recurse.py
   z3/Five/branch/zope31/browser/tests/test_traversable.py
   z3/Five/branch/zope31/form/__init__.py
   z3/Five/branch/zope31/form/metaconfigure.py
   z3/Five/branch/zope31/form/tests/forms.txt
   z3/Five/branch/zope31/form/tests/test_forms.py
   z3/Five/branch/zope31/meta.zcml
   z3/Five/branch/zope31/metaconfigure.py
   z3/Five/branch/zope31/services.zcml
   z3/Five/branch/zope31/skin/tests/test_standardmacros.py
   z3/Five/branch/zope31/tests/boilerplate.py
   z3/Five/branch/zope31/tests/event.txt
   z3/Five/branch/zope31/tests/test_directives.py
   z3/Five/branch/zope31/tests/test_i18n.py
   z3/Five/branch/zope31/tests/test_security.py
   z3/Five/branch/zope31/tests/test_size.py
   z3/Five/branch/zope31/tests/test_viewable.py
   z3/Five/branch/zope31/traversable.py
   z3/Five/branch/zope31/viewable.py
Log:
Check this in. None of this works yet; the tests don't pass. The
attempt is to:

* make Five work with Zope 3.1+

* make Five be less code by reusing more of Zope 3.1

A nice side effect is that it gives a bit of a roadmap for Zope 2;
it evolves towards Zope 3 if it makes some of this Five code disappear.



Modified: z3/Five/branch/zope31/browser/configure.zcml
==============================================================================
--- z3/Five/branch/zope31/browser/configure.zcml	(original)
+++ z3/Five/branch/zope31/browser/configure.zcml	Mon Oct  3 10:46:36 2005
@@ -1,6 +1,7 @@
 <configure xmlns="http://namespaces.zope.org/zope"
            xmlns:browser="http://namespaces.zope.org/browser">
 
+<!--
   <serviceType
       id="BrowserMenu"
       interface="zope.app.publisher.interfaces.browser.IBrowserMenuService"
@@ -11,6 +12,7 @@
       permission="zope.Public"
       component="zope.app.publisher.browser.globalbrowsermenuservice.globalBrowserMenuService"
       />
+-->
 
   <browser:defaultView name="index.html" />
 

Modified: z3/Five/branch/zope31/browser/meta.zcml
==============================================================================
--- z3/Five/branch/zope31/browser/meta.zcml	(original)
+++ z3/Five/branch/zope31/browser/meta.zcml	Mon Oct  3 10:46:36 2005
@@ -25,7 +25,7 @@
     <meta:directive
         name="defaultView"
         schema="zope.app.publisher.browser.metadirectives.IDefaultViewDirective"
-        handler=".metaconfigure.defaultView"
+        handler="zope.app.publisher.browser.metaconfigure.defaultView"
         />
 
     <meta:directive
@@ -47,6 +47,7 @@
 
     </meta:complexDirective>
 
+<!--
     <meta:directive
         name="resource"
         schema="zope.app.publisher.browser.metadirectives.IResourceDirective"
@@ -58,23 +59,24 @@
         schema="zope.app.publisher.browser.metadirectives.IResourceDirectoryDirective"
         handler=".metaconfigure.resourceDirectory"
         />
+-->
 
     <meta:directive
         name="menu"
         schema="zope.app.publisher.browser.metadirectives.IMenuDirective"
-        handler="zope.app.publisher.browser.globalbrowsermenuservice.menuDirective"
+        handler="zope.app.publisher.browser.menumeta.menuDirective"
         />
 
     <meta:directive
         name="menuItem"
         schema="zope.app.publisher.browser.metadirectives.IMenuItemDirective"
-        handler="zope.app.publisher.browser.globalbrowsermenuservice.menuItemDirective"
+        handler="zope.app.publisher.browser.menumeta.menuItemDirective"
         />
 
     <meta:complexDirective
         name="menuItems"
         schema="zope.app.publisher.browser.metadirectives.IMenuItemsDirective"
-        handler="zope.app.publisher.browser.globalbrowsermenuservice.menuItemsDirective"
+        handler="zope.app.publisher.browser.menumeta.menuItemsDirective"
         >
 
       <meta:subdirective

Modified: z3/Five/branch/zope31/browser/metaconfigure.py
==============================================================================
--- z3/Five/branch/zope31/browser/metaconfigure.py	(original)
+++ z3/Five/branch/zope31/browser/metaconfigure.py	Mon Oct  3 10:46:36 2005
@@ -20,122 +20,70 @@
 """
 import os
 
-from zope.interface import Interface
-from zope.component import getGlobalService, ComponentLookupError
+from zope.component import ComponentLookupError
 from zope.configuration.exceptions import ConfigurationError
-from zope.component.servicenames import Presentation
-from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.browser import IBrowserRequest,\
+     IDefaultBrowserLayer
+
+from zope.app.component.metaconfigure import handler
+
 from zope.app.publisher.browser.viewmeta import pages as zope_app_pages
 from zope.app.publisher.browser.viewmeta import view as zope_app_view
-from zope.app.publisher.browser.viewmeta import providesCallable
-from zope.app.publisher.browser.globalbrowsermenuservice import\
-     menuItemDirective
-from zope.app.component.metaconfigure import handler
-from zope.app.component.interface import provideInterface
-from zope.app.container.interfaces import IAdding
+from zope.app.publisher.browser.viewmeta import page as zope_app_page
 
-from Products.Five.browser import BrowserView
-from Products.Five.browser.resource import FileResourceFactory, ImageResourceFactory
+from Products.Five.browser.pagetemplatefile import ZopeTwoPageTemplateFile
+from Products.Five.browser.resource import FileResourceFactory,\
+     ImageResourceFactory
 from Products.Five.browser.resource import PageTemplateResourceFactory
 from Products.Five.browser.resource import DirectoryResourceFactory
-from Products.Five.browser.pagetemplatefile import ZopeTwoPageTemplateFile
-from Products.Five.metaclass import makeClass
-from Products.Five.security import getSecurityInfo, protectClass, \
+from Products.Five.security import getSecurityInfo, protectClass,\
     protectName, initializeClass
 
-import ExtensionClass
+def getNewClass(_context):
+    # now we retrieve the last action from the _context, as we need to do
+    # some extra things to what's there
+    last_action = _context.actions[-1]
+    args = last_action[2]
+    #import pdb; pdb.set_trace()
+    directive, (for_, layer), dummy, name, new_class, context_info = args
+    return new_class
 
 def page(_context, name, permission, for_,
-         layer='default', template=None, class_=None,
+         layer=IDefaultBrowserLayer, template=None, class_=None,
          allowed_interface=None, allowed_attributes=None,
-         attribute='__call__', menu=None, title=None,
-         ):
-
-    try:
-        s = getGlobalService(Presentation)
-    except ComponentLookupError, err:
-        pass
+         attribute='__call__', menu=None, title=None):
+    zope_app_page(_context, name, permission, for_,
+                  layer, template, class_, allowed_interface,
+                  allowed_attributes, attribute, menu, title)
+    new_class = getNewClass(_context)
 
-    _handle_menu(_context, menu, title, [for_], name, permission)
-
-    if not (class_ or template):
-        raise ConfigurationError("Must specify a class or template")
+    # we may need to replace the new class's index with Five's page template
+    # version
+    if template:
+        new_class.index = ZopeTwoPageTemplateFile(new_class.index.filename)
+        
+    # in case the attribute does not provide a docstring,
+    # ZPublisher refuses to publish it. So, as a workaround,
+    # we provide a stub docstring
+    func = getattr(new_class, attribute)
+    if not func.__doc__:
+        # cannot test for MethodType/UnboundMethod here
+        # because of ExtensionClass
+        # XXX should be able to do this now, but don't know what was
+        # meant
+        if hasattr(func, 'im_func'):
+            # you can only set a docstring on functions, not
+            # on method objects
+            func = func.im_func
+        func.__doc__ = "Stub docstring to make ZPublisher work"
+    
+    # Zope 2 security
     if allowed_attributes is None:
         allowed_attributes = []
     if allowed_interface is not None:
         for interface in allowed_interface:
             attrs = [n for n, d in interface.namesAndDescriptions(1)]
             allowed_attributes.extend(attrs)
-
-    if attribute != '__call__':
-        if template:
-            raise ConfigurationError(
-                "Attribute and template cannot be used together.")
-
-        if not class_:
-            raise ConfigurationError(
-                "A class must be provided if attribute is used")
-
-    if template:
-        template = os.path.abspath(str(_context.path(template)))
-        if not os.path.isfile(template):
-            raise ConfigurationError("No such file", template)
-
-    if class_:
-        # new-style classes do not work with Five. As we want to import
-        # packages from z3 directly, we ignore new-style classes for now.
-        if type(class_) == type:
-            return
-        if attribute != '__call__':
-            if not hasattr(class_, attribute):
-                raise ConfigurationError(
-                    "The provided class doesn't have the specified attribute "
-                    )
-        cdict = getSecurityInfo(class_)
-        if template:
-            new_class = makeClassForTemplate(template, bases=(class_, ),
-                                             cdict=cdict)
-        elif attribute != "__call__":
-            # we're supposed to make a page for an attribute (read:
-            # method) and it's not __call__.  We thus need to create a
-            # new class using our mixin for attributes.
-            cdict.update({'__page_attribute__': attribute})
-            new_class = makeClass(class_.__name__,
-                                  (class_, ViewMixinForAttributes),
-                                  cdict)
-
-            # in case the attribute does not provide a docstring,
-            # ZPublisher refuses to publish it.  So, as a workaround,
-            # we provide a stub docstring
-            func = getattr(new_class, attribute)
-            if not func.__doc__:
-                # cannot test for MethodType/UnboundMethod here
-                # because of ExtensionClass
-                if hasattr(func, 'im_func'):
-                    # you can only set a docstring on functions, not
-                    # on method objects
-                    func = func.im_func
-                func.__doc__ = "Stub docstring to make ZPublisher work"
-        else:
-            # we could use the class verbatim here, but we'll execute
-            # some security declarations on it so we really shouldn't
-            # modify the original.  So, instead we make a new class
-            # with just one base class -- the original
-            new_class = makeClass(class_.__name__, (class_,), cdict)
-
-    else:
-        # template
-        new_class = makeClassForTemplate(template)
-
-    _handle_for(_context, for_)
-
-    _context.action(
-        discriminator = ('view', for_, name, IBrowserRequest, layer),
-        callable = handler,
-        args = (Presentation, 'provideAdapter',
-                IBrowserRequest, new_class, name, [for_], Interface, layer,
-                _context.info),
-        )
     _context.action(
         discriminator = ('five:protectClass', new_class),
         callable = protectClass,
@@ -165,307 +113,135 @@
                     menu=menu, title=title,
                     **(self.opts))
 
-def defaultView(_context, name, for_=None):
-
-    type = IBrowserRequest
-
-    _context.action(
-        discriminator = ('defaultViewName', for_, type, name),
-        callable = handler,
-        args = (Presentation,
-                'setDefaultViewName', for_, type, name),
-        )
-
-    _handle_for(_context, for_)
-
 # view (named view with pages)
 
 class view(zope_app_view):
 
     def __call__(self):
-        (_context, name, for_, permission, layer, class_,
-         allowed_interface, allowed_attributes) = self.args
-
-        required = {}
-
-        cdict = {}
-        pages = {}
-
+        super(view, self).__call__()
+        _context = self.args[0]
+        new_class = getNewClass(_context)
+        # override Z3 templates with Five templates
         for pname, attribute, template in self.pages:
-            try:
-                s = getGlobalService(Presentation)
-            except ComponentLookupError, err:
-                pass
-
             if template:
-                cdict[pname] = ZopeTwoPageTemplateFile(template)
-                if attribute and attribute != name:
-                    cdict[attribute] = cdict[pname]
-            else:
-                if not hasattr(class_, attribute):
-                    raise ConfigurationError("Undefined attribute",
-                                             attribute)
-
-            attribute = attribute or pname
-            required[pname] = permission
-
-            pages[pname] = attribute
-
-        # This should go away, but noone seems to remember what to do. :-(
-        if hasattr(class_, 'publishTraverse'):
-
-            def publishTraverse(self, request, name,
-                                pages=pages, getattr=getattr):
-
-                if name in pages:
-                    return getattr(self, pages[name])
-                view = zapi.queryView(self, name, request)
-                if view is not None:
-                    return view
-
-                m = class_.publishTraverse.__get__(self)
-                return m(request, name)
-
-        else:
-            def publishTraverse(self, request, name,
-                                pages=pages, getattr=getattr):
-
-                if name in pages:
-                    return getattr(self, pages[name])
-                view = zapi.queryView(self, name, request)
-                if view is not None:
-                    return view
-
-                raise NotFoundError(self, name, request)
-
-        cdict['publishTraverse'] = publishTraverse
-
-        if not hasattr(class_, 'browserDefault'):
-            if self.default or self.pages:
-                default = self.default or self.pages[0][0]
-                cdict['browserDefault'] = (
-                    lambda self, request, default=default:
-                    (self, (default, ))
-                    )
-            elif providesCallable(class_):
-                cdict['browserDefault'] = (
-                    lambda self, request: (self, ())
-                    )
-
-        if class_ is not None:
-            bases = (class_, ViewMixinForTemplates)
-        else:
-            bases = (ViewMixinForTemplates)
-
-        try:
-            cname = str(name)
-        except:
-            cname = "GeneratedClass"
-            
-        newclass = makeClass(cname, bases, cdict)
-        
-        _handle_for(_context, for_)
-
-        if self.provides is not None:
-            _context.action(
-                discriminator = None,
-                callable = provideInterface,
-                args = ('', self.provides)
-                )
-
-        _context.action(
-            discriminator = ('view', for_, name, IBrowserRequest, layer,
-                             self.provides),
-            callable = handler,
-            args = (Presentation, 'provideAdapter',
-                    IBrowserRequest, newclass, name, [for_],  self.provides,
-                    layer, _context.info),
-            )
-
-def _handle_for(_context, for_):
-    if for_ is not None:
-        _context.action(
-            discriminator = None,
-            callable = provideInterface,
-            args = ('', for_)
-            )
-
-def _handle_menu(_context, menu, title, for_, name, permission):
-    if menu or title:
-        if not (menu and title):
-            raise ConfigurationError(
-                "If either menu or title are specified, they must "
-                "both be specified.")
-
-        if len(for_) != 1:
-            raise ConfigurationError(
-                "Menus can be specified only for single-view, not for "
-                "multi-views.")
-
-        return menuItemDirective(
-            _context, menu, for_[0], '@@' + str(name), title,
-            permission=permission)
-
-    return []
-
-_factory_map = {'image':{'prefix':'ImageResource',
-                         'count':0,
-                         'factory':ImageResourceFactory},
-                'file':{'prefix':'FileResource',
-                        'count':0,
-                        'factory':FileResourceFactory},
-                'template':{'prefix':'PageTemplateResource',
-                            'count':0,
-                            'factory':PageTemplateResourceFactory}
-                }
-
-def resource(_context, name, layer='default', permission='zope.Public',
-             file=None, image=None, template=None):
-
-    if ((file and image) or (file and template) or
-        (image and template) or not (file or image or template)):
-        raise ConfigurationError(
-            "Must use exactly one of file or image or template"
-            "attributes for resource directives"
-            )
-
-    res = file or image or template
-    res_type = ((file and 'file') or
-                 (image and 'image') or
-                 (template and 'template'))
-    factory_info = _factory_map.get(res_type)
-    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,), {})
-    factory = res_factory(name, res, resource_factory=new_class)
-
-    _context.action(
-        discriminator = ('resource', name, IBrowserRequest, layer),
-        callable = handler,
-        args = (Presentation, 'provideResource',
-                name, IBrowserRequest, factory, layer),
-        )
-    _context.action(
-        discriminator = ('five:protectClass', new_class),
-        callable = protectClass,
-        args = (new_class, permission)
-        )
-    _context.action(
-        discriminator = ('five:initialize:class', new_class),
-        callable = initializeClass,
-        args = (new_class,)
-        )
-
-_rd_map = {ImageResourceFactory:{'prefix':'DirContainedImageResource',
-                                 'count':0},
-           FileResourceFactory:{'prefix':'DirContainedFileResource',
-                                'count':0},
-           PageTemplateResourceFactory:{'prefix':'DirContainedPTResource',
-                                        'count':0},
-           DirectoryResourceFactory:{'prefix':'DirectoryResource',
-                                     'count':0}
-           }
-
-def resourceDirectory(_context, name, directory, layer='default',
-                      permission='zope.Public'):
-
-    if not os.path.isdir(directory):
-        raise ConfigurationError(
-            "Directory %s does not exist" % directory
-            )
-
-    resource = DirectoryResourceFactory.resource
-    f_cache = {}
-    resource_factories = dict(resource.resource_factories)
-    resource_factories['default'] = resource.default_factory
-    for ext, factory in resource_factories.items():
-        if f_cache.get(factory) is not None:
-            continue
-        factory_info = _rd_map.get(factory)
-        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})
-    for ext, factory in resource_factories.items():
-        resource_factories[ext] = f_cache[factory]
-    default_factory = resource_factories['default']
-    del resource_factories['default']
-
-    cdict = {'resource_factories':resource_factories,
-             'default_factory':default_factory}
-
-    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)
-    factory = DirectoryResourceFactory(name, directory,
-                                       resource_factory=dir_factory)
-
-    new_classes = [dir_factory,
-                   ] + [f.resource for f in f_cache.values()]
-
-    _context.action(
-        discriminator = ('resource', name, IBrowserRequest, layer),
-        callable = handler,
-        args = (Presentation, 'provideResource',
-                name, IBrowserRequest, factory, layer),
-        )
-    for new_class in new_classes:
-        _context.action(
-            discriminator = ('five:protectClass', new_class),
-            callable = protectClass,
-            args = (new_class, permission)
-            )
-        _context.action(
-            discriminator = ('five:initialize:class', new_class),
-            callable = initializeClass,
-            args = (new_class,)
-            )
-
-#
-# mixin classes / class factories
-#
-
-class ViewMixinForAttributes(BrowserView):
-
-    # we have an attribute that we can simply tell ZPublisher to go to
-    def __browser_default__(self, request):
-        return self, (self.__page_attribute__,)
-
-    # this is technically not needed because ZPublisher finds our
-    # attribute through __browser_default__; but we also want to be
-    # able to call pages from python modules, PythonScripts or ZPT
-    def __call__(self, *args, **kw):
-        attr = self.__page_attribute__
-        meth = getattr(self, attr)
-        return meth(*args, **kw)
-
-class ViewMixinForTemplates(BrowserView):
-
-    # short cut to get to macros more easily
-    def __getitem__(self, name):
-        if name == 'macros':
-            return self.index.macros
-        return self.index.macros[name]
-
-    # make the template publishable
-    def __call__(self, *args, **kw):
-        return self.index(self, *args, **kw)
-
-def makeClassForTemplate(filename, globals=None, used_for=None,
-                         bases=(), cdict=None):
-    # XXX needs to deal with security from the bases?
-    if cdict is None:
-        cdict = {}
-    cdict.update({'index': ZopeTwoPageTemplateFile(filename, globals)})
-    bases += (ViewMixinForTemplates,)
-    class_ = makeClass("SimpleViewClass from %s" % filename, bases, cdict)
-
-    if used_for is not None:
-        class_.__used_for__ = used_for
-
-    return class_
+                new_class.pname = ZopeTwoPageTemplateFile(template)
+        # XXX probably need to do more patching to make it a ZPublisher
+        # compliant view class
+
+## _factory_map = {'image':{'prefix':'ImageResource',
+##                          'count':0,
+##                          'factory':ImageResourceFactory},
+##                 'file':{'prefix':'FileResource',
+##                         'count':0,
+##                         'factory':FileResourceFactory},
+##                 'template':{'prefix':'PageTemplateResource',
+##                             'count':0,
+##                             'factory':PageTemplateResourceFactory}
+##                 }
+
+## def resource(_context, name, layer='default', permission='zope.Public',
+##              file=None, image=None, template=None):
+
+##     if ((file and image) or (file and template) or
+##         (image and template) or not (file or image or template)):
+##         raise ConfigurationError(
+##             "Must use exactly one of file or image or template"
+##             "attributes for resource directives"
+##             )
+
+##     res = file or image or template
+##     res_type = ((file and 'file') or
+##                  (image and 'image') or
+##                  (template and 'template'))
+##     factory_info = _factory_map.get(res_type)
+##     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,), {})
+##     factory = res_factory(name, res, resource_factory=new_class)
+
+##     _context.action(
+##         discriminator = ('resource', name, IBrowserRequest, layer),
+##         callable = handler,
+##         args = (Presentation, 'provideResource',
+##                 name, IBrowserRequest, factory, layer),
+##         )
+##     _context.action(
+##         discriminator = ('five:protectClass', new_class),
+##         callable = protectClass,
+##         args = (new_class, permission)
+##         )
+##     _context.action(
+##         discriminator = ('five:initialize:class', new_class),
+##         callable = initializeClass,
+##         args = (new_class,)
+##         )
+
+## _rd_map = {ImageResourceFactory:{'prefix':'DirContainedImageResource',
+##                                  'count':0},
+##            FileResourceFactory:{'prefix':'DirContainedFileResource',
+##                                 'count':0},
+##            PageTemplateResourceFactory:{'prefix':'DirContainedPTResource',
+##                                         'count':0},
+##            DirectoryResourceFactory:{'prefix':'DirectoryResource',
+##                                      'count':0}
+##            }
+
+## def resourceDirectory(_context, name, directory, layer='default',
+##                       permission='zope.Public'):
+
+##     if not os.path.isdir(directory):
+##         raise ConfigurationError(
+##             "Directory %s does not exist" % directory
+##             )
+
+##     resource = DirectoryResourceFactory.resource
+##     f_cache = {}
+##     resource_factories = dict(resource.resource_factories)
+##     resource_factories['default'] = resource.default_factory
+##     for ext, factory in resource_factories.items():
+##         if f_cache.get(factory) is not None:
+##             continue
+##         factory_info = _rd_map.get(factory)
+##         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})
+##     for ext, factory in resource_factories.items():
+##         resource_factories[ext] = f_cache[factory]
+##     default_factory = resource_factories['default']
+##     del resource_factories['default']
+
+##     cdict = {'resource_factories':resource_factories,
+##              'default_factory':default_factory}
+
+##     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)
+##     factory = DirectoryResourceFactory(name, directory,
+##                                        resource_factory=dir_factory)
+
+##     new_classes = [dir_factory,
+##                    ] + [f.resource for f in f_cache.values()]
+
+##     _context.action(
+##         discriminator = ('resource', name, IBrowserRequest, layer),
+##         callable = handler,
+##         args = (Presentation, 'provideResource',
+##                 name, IBrowserRequest, factory, layer),
+##         )
+##     for new_class in new_classes:
+##         _context.action(
+##             discriminator = ('five:protectClass', new_class),
+##             callable = protectClass,
+##             args = (new_class, permission)
+##             )
+##         _context.action(
+##             discriminator = ('five:initialize:class', new_class),
+##             callable = initializeClass,
+##             args = (new_class,)
+##             )
 

Modified: z3/Five/branch/zope31/browser/resource.py
==============================================================================
--- z3/Five/branch/zope31/browser/resource.py	(original)
+++ z3/Five/branch/zope31/browser/resource.py	Mon Oct  3 10:46:36 2005
@@ -22,7 +22,6 @@
 from ComputedAttribute import ComputedAttribute
 from OFS.Traversable import Traversable as OFSTraversable
 
-from zope.exceptions import NotFoundError
 from zope.interface import implements
 from zope.component.interfaces import IResource
 from zope.component import getViewProviding
@@ -213,7 +212,7 @@
         filename = os.path.join(path, name)
         if not os.path.isfile(filename):
             if default is _marker:
-                raise NotFoundError(name)
+                raise KeyError(name)
             return default
         ext = name.split('.')[-1]
         factory = self.resource_factories.get(ext, self.default_factory)

Modified: z3/Five/branch/zope31/browser/tests/pages.txt
==============================================================================
--- z3/Five/branch/zope31/browser/tests/pages.txt	(original)
+++ z3/Five/branch/zope31/browser/tests/pages.txt	Mon Oct  3 10:46:36 2005
@@ -283,5 +283,5 @@
 Clean up
 --------
 
-  >>> from zope.app.tests.placelesssetup import tearDown
+  >>> from zope.app.testing.placelesssetup import tearDown
   >>> tearDown()

Modified: z3/Five/branch/zope31/browser/tests/pages_ftest.txt
==============================================================================
--- z3/Five/branch/zope31/browser/tests/pages_ftest.txt	(original)
+++ z3/Five/branch/zope31/browser/tests/pages_ftest.txt	Mon Oct  3 10:46:36 2005
@@ -125,5 +125,5 @@
 Clean up
 --------
 
-  >>> from zope.app.tests.placelesssetup import tearDown
+  >>> from zope.app.testing.placelesssetup import tearDown
   >>> tearDown()

Modified: z3/Five/branch/zope31/browser/tests/resource.txt
==============================================================================
--- z3/Five/branch/zope31/browser/tests/resource.txt	(original)
+++ z3/Five/branch/zope31/browser/tests/resource.txt	Mon Oct  3 10:46:36 2005
@@ -112,5 +112,5 @@
 Clean up
 --------
 
-  >>> from zope.app.tests.placelesssetup import tearDown
+  >>> from zope.app.testing.placelesssetup import tearDown
   >>> tearDown()

Modified: z3/Five/branch/zope31/browser/tests/resource_ftest.txt
==============================================================================
--- z3/Five/branch/zope31/browser/tests/resource_ftest.txt	(original)
+++ z3/Five/branch/zope31/browser/tests/resource_ftest.txt	Mon Oct  3 10:46:36 2005
@@ -69,5 +69,5 @@
 Clean up
 --------
 
-  >>> from zope.app.tests.placelesssetup import tearDown
+  >>> from zope.app.testing.placelesssetup import tearDown
   >>> tearDown()

Modified: z3/Five/branch/zope31/browser/tests/test_absoluteurl.py
==============================================================================
--- z3/Five/branch/zope31/browser/tests/test_absoluteurl.py	(original)
+++ z3/Five/branch/zope31/browser/tests/test_absoluteurl.py	Mon Oct  3 10:46:36 2005
@@ -86,7 +86,7 @@
 
     Clean up:
 
-      >>> from zope.app.tests.placelesssetup import tearDown
+      >>> from zope.app.testing.placelesssetup import tearDown
       >>> tearDown()
     """
 

Modified: z3/Five/branch/zope31/browser/tests/test_defaultview.py
==============================================================================
--- z3/Five/branch/zope31/browser/tests/test_defaultview.py	(original)
+++ z3/Five/branch/zope31/browser/tests/test_defaultview.py	Mon Oct  3 10:46:36 2005
@@ -79,7 +79,7 @@
 
     Clean up:
 
-      >>> from zope.app.tests.placelesssetup import tearDown
+      >>> from zope.app.testing.placelesssetup import tearDown
       >>> tearDown()
     """
 

Modified: z3/Five/branch/zope31/browser/tests/test_i18n.py
==============================================================================
--- z3/Five/branch/zope31/browser/tests/test_i18n.py	(original)
+++ z3/Five/branch/zope31/browser/tests/test_i18n.py	Mon Oct  3 10:46:36 2005
@@ -80,7 +80,7 @@
 
     Clean up:
 
-      >>> from zope.app.tests.placelesssetup import tearDown
+      >>> from zope.app.testing.placelesssetup import tearDown
       >>> tearDown()
     """
 

Modified: z3/Five/branch/zope31/browser/tests/test_menu.py
==============================================================================
--- z3/Five/branch/zope31/browser/tests/test_menu.py	(original)
+++ z3/Five/branch/zope31/browser/tests/test_menu.py	Mon Oct  3 10:46:36 2005
@@ -131,7 +131,7 @@
 
     Clean up:
 
-      >>> from zope.app.tests.placelesssetup import tearDown
+      >>> from zope.app.testing.placelesssetup import tearDown
       >>> tearDown()
     """
 

Modified: z3/Five/branch/zope31/browser/tests/test_recurse.py
==============================================================================
--- z3/Five/branch/zope31/browser/tests/test_recurse.py	(original)
+++ z3/Five/branch/zope31/browser/tests/test_recurse.py	Mon Oct  3 10:46:36 2005
@@ -23,7 +23,7 @@
     """
     Test recursion
 
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
+      >>> from zope.app.testing.placelesssetup import setUp, tearDown
       >>> setUp()
 
     This test makes sure that recursion is avoided for view lookup.

Modified: z3/Five/branch/zope31/browser/tests/test_traversable.py
==============================================================================
--- z3/Five/branch/zope31/browser/tests/test_traversable.py	(original)
+++ z3/Five/branch/zope31/browser/tests/test_traversable.py	Mon Oct  3 10:46:36 2005
@@ -94,7 +94,7 @@
 
     Clean up:
 
-      >>> from zope.app.tests.placelesssetup import tearDown
+      >>> from zope.app.testing.placelesssetup import tearDown
       >>> tearDown()
     """
 

Added: z3/Five/branch/zope31/doc/zope31goals.txt
==============================================================================
--- (empty file)
+++ z3/Five/branch/zope31/doc/zope31goals.txt	Mon Oct  3 10:46:36 2005
@@ -0,0 +1,107 @@
+===============================
+Porting Five to Zope 3.1+ notes
+===============================
+
+Introduction
+------------
+
+Five needs to work in Zope 2.9. Zope 2.9 will ship with Zope 3.2. This
+means Five will need to work with Zope 3.2. Since Zope 3.2 doesn't
+truly exist yet we'll target Zope 3.1 for now.
+
+A Five Roadmap
+--------------
+
+Here is a tentative Five roadmap:
+
+Five 1.1 is to be released shortly, and its main feature is a
+refactored directory structure and Zope 3 i18n for Zope 2. It's still
+targeting the Zope X3.0 that's in Zope 2.8.
+
+Five 1.2 is still targetting Zope 2.8, and its main expected feature
+is support for local utilities.
+
+Five 1.3 is targetting Zope 2.9 and thus Zope 3.2. We're talking about
+this release of Five in this document.
+
+Main problem
+------------
+
+Zope 3.1 has internal changes that Five needs to support. Five works
+by reimplementing ZCML statements it supplies in the context of Zope
+2. This reimplementation is hard to maintain, as for each Zope 3
+upgrade we need to review all these ZCML statements and port them into
+Five again.
+
+The straightforward way to start supporting Zope 3.1+ with Five would
+be to review all the ZCML statements in Five and update them to work
+with Zope 3.1+.
+
+A more ambitious but nicer solution would be if we could reuse the
+Zope 3 ZCML statements directly. If we could accomplish this,
+maintainability of Five would be improved by a lot. Far less review of
+Five would be necessary for each Zope 3 upgrade. In the rest of this
+document we'll be discussing this scenario.
+
+Reasons for Five's modified ZCML statements
+-------------------------------------------
+
+Five ships with modified implementations of Zope 3 ZCML statements for
+a number of reasons:
+
+* could not use new-style classes that are in Zope 3 due to
+  ExtensionClass.
+
+* Five views need to work with the Zope 2 publisher, and this expects 
+  different things than the Zope 3 publisher.
+
+* cannot use the Zope 3 security system, while the Zope 3 ZCML calls
+  into this to configure it.
+
+* Five views need to work with the Zope 2 security system. This means
+  Five needs to issue Zope 2 style security declarations for views.
+
+We'll go into more detail about each of these points below.
+
+New-style ExtensionClass
+========================
+
+Five needed to be compatible with Zope 2.7, which uses old-style
+ExtensionClass. This made life difficult for Five, as Zope 3 uses
+new-style Python classes in many places. It's not easy to mix the two.
+
+Zope 2.8 changed to allow new-style ExtensionClasses, which are
+compatible with new-style Python classes. This means Five can
+hopefully be simplified as we can forget about old-style
+ExtensionClasses.
+
+Five views need to work with the Zope 2 publisher
+=================================================
+
+The Zope 2 publisher expects something quite different than the Zope 3
+publisher. 
+
+* does what is returned to the publisher need to inherit from
+  Acquisition.Explicit? (security reasons?)
+
+* we may need something that calls the right methods on the Zope 3
+  view (such as browserDefault, __call__ and publishTraverse)
+
+Cannot use the Zope 3 security system
+=====================================
+
+Do the Zope 3 security calls get in the way? Five currently removes
+these calls, but perhaps doing the calls does not harm.
+
+If they do interface, we could perhaps still trick things into
+working harmlessly.
+
+Five must issue Zope 2 security declarations for views
+======================================================
+
+This cannot be done by the ZCML implementation of Zope 3. We could
+hopefully do this by following the following pattern::
+
+  def our_directive_implementation(...):
+      original_directive_implementation(...)
+      do_the_zope2_work(...)

Modified: z3/Five/branch/zope31/form/__init__.py
==============================================================================
--- z3/Five/branch/zope31/form/__init__.py	(original)
+++ z3/Five/branch/zope31/form/__init__.py	Mon Oct  3 10:46:36 2005
@@ -25,6 +25,7 @@
 from zope.publisher.browser import isCGI_NAME
 from zope.i18n.interfaces import IUserPreferredCharsets
 
+from zope.app.form.browser.editview import EditView as zope_app_EditView
 from zope.app.location.interfaces import ILocation
 from zope.app.location import LocationProxy
 from zope.app.form.utility import setUpEditWidgets, applyWidgetsChanges
@@ -38,38 +39,13 @@
 from Products.Five.browser import BrowserView
 from Products.Five.browser.pagetemplatefile import ZopeTwoPageTemplateFile
 
-class EditView(BrowserView):
-    """Simple edit-view base class
-
-    Subclasses should provide a schema attribute defining the schema
-    to be edited.
-    """
-
-    errors = ()
-    update_status = None
-    label = ''
-    charsets = None
-
-    # Fall-back field names computes from schema
-    fieldNames = property(lambda self: getFieldNamesInOrder(self.schema))
-    # Fall-back template
+class EditView(zope_app_EditView):
     generated_form = ZopeTwoPageTemplateFile('edit.pt')
 
     def __init__(self, context, request):
-        BrowserView.__init__(self, context, request)
         self._processInputs()
         self._setPageEncoding()
-        self._setUpWidgets()
-
-    def _setUpWidgets(self):
-        adapted = self.schema(self.context)
-        if adapted is not self.context:
-            if not ILocation.providedBy(adapted):
-                adapted = LocationProxy(adapted)
-            adapted.__parent__ = self.context
-        self.adapted = adapted
-        setUpEditWidgets(self, self.schema, source=self.adapted,
-                         names=self.fieldNames)
+        super(EditView, self).__init__(context, request)
 
     # taken from zope.publisher.browser.BrowserRequest
     def _decode(self, text):
@@ -84,7 +60,7 @@
             except UnicodeError:
                 pass
         return text
-
+    
     def _processInputs(self):
         request = self.request
         for name, value in request.form.items():
@@ -101,59 +77,6 @@
         self.request.RESPONSE.setHeader(
             'Content-Type', 'text/html; charset=%s' % charsets[0])
 
-    def setPrefix(self, prefix):
-        for widget in self.widgets():
-            widget.setPrefix(prefix)
-
-    def widgets(self):
-        return [getattr(self, name+'_widget')
-                for name in self.fieldNames]
-
-    def changed(self):
-        # This method is overridden to execute logic *after* changes
-        # have been made.
-        pass
-
-    def update(self):
-        if self.update_status is not None:
-            # We've been called before. Just return the status we previously
-            # computed.
-            return self.update_status
-
-        status = ''
-
-        content = self.adapted
-
-        if Update in self.request.form.keys():
-            changed = False
-            try:
-                changed = applyWidgetsChanges(self, self.schema,
-                    target=content, names=self.fieldNames)
-                # We should not generate events when an adapter is used.
-                # That's the adapter's job.
-                if changed and self.context is self.adapted:
-                    notify(ObjectModifiedEvent(content))
-            except WidgetsError, errors:
-                self.errors = errors
-                status = _("An error occured.")
-                transaction.abort()
-            else:
-                setUpEditWidgets(self, self.schema, source=self.adapted,
-                                 ignoreStickyValues=True,
-                                 names=self.fieldNames)
-                if changed:
-                    self.changed()
-                    # XXX: Needs locale support:
-                    # formatter = self.request.locale.dates.getFormatter(
-                    #     'dateTime', 'medium')
-                    status = _("Updated on ${date_time}")
-                    # status.mapping = {'date_time': formatter.format(
-                    #     datetime.utcnow())}
-                    status.mapping = {'date_time': str(datetime.utcnow())}
-
-        self.update_status = status
-        return status
-
 class AddView(EditView):
     """Simple edit-view base class.
 

Modified: z3/Five/branch/zope31/form/metaconfigure.py
==============================================================================
--- z3/Five/branch/zope31/form/metaconfigure.py	(original)
+++ z3/Five/branch/zope31/form/metaconfigure.py	Mon Oct  3 10:46:36 2005
@@ -15,64 +15,45 @@
 
 $Id$
 """
-import ExtensionClass
-
-from zope.component import getGlobalService
-from zope.component.servicenames import Presentation
-from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.app.publisher.browser.globalbrowsermenuservice import \
-     menuItemDirective
+from zope.component import getMultiAdapter
 from zope.app.form.browser.metaconfigure import BaseFormDirective
-from zope.app.container.interfaces import IAdding
+
+from zope.app.form.browser.metaconfigure import EditFormDirective as\
+     zope_app_EditFormDirective
+from zope.app.form.browser.metaconfigure import AddFormDirective as\
+     zope_app_AddFormDirective
+
+from zope.app.form.browser.editview import EditViewFactory as\
+     zope_app_EditViewFactory
+from zope.app.form.browser.add import AddViewFactory as\
+     zope_app_AddViewFactory
 
 from Products.Five.form import EditView, AddView
-from Products.Five.metaclass import makeClass
 from Products.Five.security import protectClass, initializeClass
 from Products.Five.browser.pagetemplatefile import ZopeTwoPageTemplateFile
-from Products.Five.browser.metaconfigure import makeClassForTemplate
 
 def EditViewFactory(name, schema, label, permission, layer,
                     template, default_template, bases, for_, fields,
                     fulledit_path=None, fulledit_label=None, menu=u''):
-    s = getGlobalService(Presentation)
-    class_ = makeClassForTemplate(template, globals(), used_for=schema,
-                                  bases=bases)
-    class_.schema = schema
-    class_.label = label
-    class_.fieldNames = fields
-
-    class_.fulledit_path = fulledit_path
-    if fulledit_path and (fulledit_label is None):
-        fulledit_label = "Full edit"
-
-    class_.fulledit_label = fulledit_label
-
-    class_.generated_form = ZopeTwoPageTemplateFile(default_template)
-
-
-    s.provideView(for_, name, IBrowserRequest, class_, layer)
+    zope_app_EditViewFactory(name, schema, label, permission, layer,
+                             template, default_template, bases, for_, fields,
+                             fulledit_path, fulledit_label)
+    # fetch the class by looking up the adapter just registered
+    class_ = getMultiAdapter((for_, layer), name=name)
+    # patch in Zope 2 page templates
+    class_.index = ZopeTwoPageTemplateFile(
+        class_.index.filename)
+    class_.generated_form = ZopeTwoPageTemplateFile(
+        class_.generated_form.filename)
+    # zope 2 security
     protectClass(class_, permission)
     initializeClass(class_)
 
-class FiveFormDirective(BaseFormDirective):
-
-    def _processWidgets(self):
-        if self._widgets:
-            customWidgetsObject = makeClass('CustomWidgetsMixin', (ExtensionClass.Base,), self._widgets)
-            self.bases = self.bases + (customWidgetsObject,)
-
-class EditFormDirective(FiveFormDirective):
+class EditFormDirective(zope_app_EditFormDirective):
 
     view = EditView
     default_template = 'edit.pt'
-    title = 'Edit'
-
-    def _handle_menu(self):
-        if self.menu:
-            menuItemDirective(
-                self._context, self.menu, self.for_ or self.schema,
-                '@@' + self.name, self.title, permission=self.permission)
-
+    
     def __call__(self):
         self._processWidgets()
         self._handle_menu()
@@ -80,116 +61,37 @@
             discriminator=self._discriminator(),
             callable=EditViewFactory,
             args=self._args(),
-            kw={'menu': self.menu},
         )
 
-
 def AddViewFactory(name, schema, label, permission, layer,
                    template, default_template, bases, for_,
                    fields, content_factory, arguments,
                    keyword_arguments, set_before_add, set_after_add,
                    menu=u''):
 
-    s = getGlobalService(Presentation)
-    class_ = makeClassForTemplate(template, globals(), used_for=schema,
-                                  bases=bases)
-
-    class_.schema = schema
-    class_.label = label
-    class_.fieldNames = fields
-    class_._factory = content_factory
-    class_._arguments = arguments
-    class_._keyword_arguments = keyword_arguments
-    class_._set_before_add = set_before_add
-    class_._set_after_add = set_after_add
-
-    class_.generated_form = ZopeTwoPageTemplateFile(default_template)
-
-    s.provideView(for_, name, IBrowserRequest, class_, layer)
+    zope_add_AddViewFactory(name, schema, label, permission, layer,
+                            template, default_template, bases, for_,
+                            fields, content_factory, arguments,
+                            keyword_arguments, set_before_add, set_after_add,
+                            menu)
+    # fetch adapter just registered
+    class_ = getMultiAdapter((for_, layer), name=name)
+    # monkey the zope 3 page template engine in
+    class_.index = ZopeTwoPageTemplateFile(class_.index.filename)
+    class_.generated_form = ZopeTwoPageTemplateFile(
+        class_.generated_form.filename)
+    # zope 2 security
     protectClass(class_, permission)
     initializeClass(class_)
 
-class AddFormDirective(FiveFormDirective):
-
+class AddFormDirective(zope_app_AddFormDirective):
     view = AddView
     default_template = 'add.pt'
-    for_ = IAdding
-
-    # default add form information
-    description = None
-    content_factory = None
-    arguments = None
-    keyword_arguments = None
-    set_before_add = None
-    set_after_add = None
-
-    def _handle_menu(self):
-        if self.menu or self.title:
-            if (not self.menu) or (not self.title):
-                raise ValueError("If either menu or title are specified, "
-                                 "they must both be specified")
-            # Add forms are really for IAdding components, so do not use
-            # for=self.schema.
-            menuItemDirective(
-                self._context, self.menu, self.for_, '@@' + self.name,
-                self.title, permission=self.permission,
-                description=self.description)
-
-    def _handle_arguments(self, leftover=None):
-        schema = self.schema
-        fields = self.fields
-        arguments = self.arguments
-        keyword_arguments = self.keyword_arguments
-        set_before_add = self.set_before_add
-        set_after_add = self.set_after_add
-
-        if leftover is None:
-            leftover = fields
-
-        if arguments:
-            missing = [n for n in arguments if n not in fields]
-            if missing:
-                raise ValueError("Some arguments are not included in the form",
-                                 missing)
-            optional = [n for n in arguments if not schema[n].required]
-            if optional:
-                raise ValueError("Some arguments are optional, use"
-                                 " keyword_arguments for them",
-                                 optional)
-            leftover = [n for n in leftover if n not in arguments]
-
-        if keyword_arguments:
-            missing = [n for n in keyword_arguments if n not in fields]
-            if missing:
-                raise ValueError(
-                    "Some keyword_arguments are not included in the form",
-                    missing)
-            leftover = [n for n in leftover if n not in keyword_arguments]
-
-        if set_before_add:
-            missing = [n for n in set_before_add if n not in fields]
-            if missing:
-                raise ValueError(
-                    "Some set_before_add are not included in the form",
-                    missing)
-            leftover = [n for n in leftover if n not in set_before_add]
-
-        if set_after_add:
-            missing = [n for n in set_after_add if n not in fields]
-            if missing:
-                raise ValueError(
-                    "Some set_after_add are not included in the form",
-                    missing)
-            leftover = [n for n in leftover if n not in set_after_add]
-
-            self.set_after_add += leftover
-
-        else:
-            self.set_after_add = leftover
-
+    
     def __call__(self):
         self._processWidgets()
         self._handle_menu()
+        self._handle_content_factory()
         self._handle_arguments()
 
         self._context.action(
@@ -198,5 +100,4 @@
             args=self._args()+(self.content_factory, self.arguments,
                                  self.keyword_arguments,
                                  self.set_before_add, self.set_after_add),
-            kw={'menu': self.menu},
             )

Modified: z3/Five/branch/zope31/form/tests/forms.txt
==============================================================================
--- z3/Five/branch/zope31/form/tests/forms.txt	(original)
+++ z3/Five/branch/zope31/form/tests/forms.txt	Mon Oct  3 10:46:36 2005
@@ -571,5 +571,5 @@
 
 Finally, we need to clean up:
 
-  >>> from zope.app.tests.placelesssetup import tearDown
+  >>> from zope.app.testing.placelesssetup import tearDown
   >>> tearDown()

Modified: z3/Five/branch/zope31/form/tests/test_forms.py
==============================================================================
--- z3/Five/branch/zope31/form/tests/test_forms.py	(original)
+++ z3/Five/branch/zope31/form/tests/test_forms.py	Mon Oct  3 10:46:36 2005
@@ -56,7 +56,7 @@
 
     Clean up:
 
-      >>> from zope.app.tests.placelesssetup import tearDown
+      >>> from zope.app.testing.placelesssetup import tearDown
       >>> tearDown()
     """
 

Modified: z3/Five/branch/zope31/meta.zcml
==============================================================================
--- z3/Five/branch/zope31/meta.zcml	(original)
+++ z3/Five/branch/zope31/meta.zcml	Mon Oct  3 10:46:36 2005
@@ -7,7 +7,9 @@
 
   <!-- load the zope:modulealias and zope:hook directives -->
   <include package="zope.modulealias" file="meta.zcml" />
+  <!-- XXX this seems to have disappeared in Zope 3.1
   <include package="zope.configuration" file="meta.zcml" />
+  -->
 
   <meta:directives namespace="http://namespaces.zope.org/zope">
 
@@ -53,18 +55,6 @@
         handler="zope.app.component.metaconfigure.factory"
         />
 
-    <meta:directive
-        name="serviceType"
-        schema="zope.app.component.metadirectives.IServiceTypeDirective"
-        handler="zope.app.component.metaconfigure.serviceType"
-        />
-
-    <meta:directive
-        name="service"
-        schema="zope.app.component.metadirectives.IServiceDirective"
-        handler="zope.app.component.metaconfigure.service"
-        />
-
     <meta:complexDirective
         name="content"
         schema="zope.app.component.metadirectives.IClassDirective"

Modified: z3/Five/branch/zope31/metaconfigure.py
==============================================================================
--- z3/Five/branch/zope31/metaconfigure.py	(original)
+++ z3/Five/branch/zope31/metaconfigure.py	Mon Oct  3 10:46:36 2005
@@ -15,56 +15,25 @@
 
 $Id$
 """
-from types import ModuleType
-
-from zope.interface import classImplements
-from zope.configuration.exceptions import ConfigurationError
 
 from security import CheckerPublic
 from security import protectName, initializeClass
 
-class ContentDirective:
+from zope.app.component.contentdirective import ContentDirective as\
+     zope_app_ContentDirective
+
+class ContentDirective(zope_app_ContentDirective):
 
-    def __init__(self, _context, class_):
-        self.__class = class_
-        if isinstance(self.__class, ModuleType):
-            raise ConfigurationError('Content class attribute must be a class')
-        self.__context = _context
-
-    def implements(self, _context, interface):
-        for interface in interface:
-            _context.action(
-                discriminator = (
-                'five::directive:content', self.__class, object()),
-                callable = classImplements,
-                args = (self.__class, interface),
-                )
-            interface(_context, interface)
-
-    def require(self, _context, permission=None,
-                attributes=None, interface=None):
-        """Require a the permission to access a specific aspect"""
-
-        if not (interface or attributes):
-            raise ConfigurationError("Nothing required")
-
-        if interface:
-            for i in interface:
-                if i:
-                    self.__protectByInterface(i, permission)
+    def require(self, _context,
+                permission=None, attributes=None, interface=None,
+                like_class=None, set_attributes=None, set_schema=None):
+        super(ContentDirective, self).require(
+            _context, permission,
+            attributes, interface, like_class,
+            set_attributes, set_schema)
         if attributes:
             self.__protectNames(attributes, permission)
-
-    def allow(self, _context, attributes=None, interface=None):
-        """Like require, but with permission_id zope.Public"""
-        return self.require(_context, CheckerPublic, attributes, interface)
-
-    def __protectByInterface(self, interface, permission_id):
-        "Set a permission on names in an interface."
-        for n, d in interface.namesAndDescriptions(1):
-            self.__protectName(n, permission_id)
-        interface(self.__context, interface)
-
+        
     def __protectName(self, name, permission_id):
         "Set a permission on a particular name."
         self.__context.action(
@@ -72,11 +41,17 @@
             callable = protectName,
             args = (self.__class, name, permission_id)
             )
-
+        
     def __protectNames(self, names, permission_id):
         "Set a permission on a bunch of names."
         for name in names:
             self.__protectName(name, permission_id)
+            
+    def allow(self, _context, attributes=None, interface=None):
+        """Like require, but with permission_id zope.Public"""
+        # XXX this is using CheckerPublic while z3 is using
+        # PublicPermission
+        return self.require(_context, CheckerPublic, attributes, interface)
 
     def __call__(self):
         "Handle empty/simple declaration."

Modified: z3/Five/branch/zope31/services.zcml
==============================================================================
--- z3/Five/branch/zope31/services.zcml	(original)
+++ z3/Five/branch/zope31/services.zcml	Mon Oct  3 10:46:36 2005
@@ -1,5 +1,6 @@
 <configure xmlns="http://namespaces.zope.org/zope">
 
+<!--
   <serviceType
       id="Utilities"
       interface="zope.component.interfaces.IUtilityService" />
@@ -23,5 +24,6 @@
   <service
       serviceType="Presentation"
       factory="zope.component.presentation.GlobalPresentationService" />
- 
+-->
+
 </configure>

Modified: z3/Five/branch/zope31/skin/tests/test_standardmacros.py
==============================================================================
--- z3/Five/branch/zope31/skin/tests/test_standardmacros.py	(original)
+++ z3/Five/branch/zope31/skin/tests/test_standardmacros.py	Mon Oct  3 10:46:36 2005
@@ -72,7 +72,7 @@
 
     Clean up:
 
-      >>> from zope.app.tests.placelesssetup import tearDown
+      >>> from zope.app.testing.placelesssetup import tearDown
       >>> tearDown()
     """
 

Modified: z3/Five/branch/zope31/tests/boilerplate.py
==============================================================================
--- z3/Five/branch/zope31/tests/boilerplate.py	(original)
+++ z3/Five/branch/zope31/tests/boilerplate.py	Mon Oct  3 10:46:36 2005
@@ -21,7 +21,7 @@
 
 def test_boilerplate():
     """
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
+      >>> from zope.app.testing.placelesssetup import setUp, tearDown
       >>> setUp()
 
       >>> import Products.Five.tests

Modified: z3/Five/branch/zope31/tests/event.txt
==============================================================================
--- z3/Five/branch/zope31/tests/event.txt	(original)
+++ z3/Five/branch/zope31/tests/event.txt	Mon Oct  3 10:46:36 2005
@@ -4,7 +4,7 @@
 Before we can start, we need to set up an event subscriber that allows
 us to inspect events that will be thrown during the test:
 
-  >>> from zope.app.tests.placelesssetup import setUp, tearDown
+  >>> from zope.app.testing.placelesssetup import setUp, tearDown
   >>> setUp()
 
 Add a folder that doesn't verify objects on paste.  We use it as a

Modified: z3/Five/branch/zope31/tests/test_directives.py
==============================================================================
--- z3/Five/branch/zope31/tests/test_directives.py	(original)
+++ z3/Five/branch/zope31/tests/test_directives.py	Mon Oct  3 10:46:36 2005
@@ -23,7 +23,7 @@
     """
     Test ZCML directives
 
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
+      >>> from zope.app.testing.placelesssetup import setUp, tearDown
       >>> setUp()
 
     There isn't much to test here since the actual directive handlers

Modified: z3/Five/branch/zope31/tests/test_i18n.py
==============================================================================
--- z3/Five/branch/zope31/tests/test_i18n.py	(original)
+++ z3/Five/branch/zope31/tests/test_i18n.py	Mon Oct  3 10:46:36 2005
@@ -23,7 +23,7 @@
     """
     Test the i18n directive
 
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
+      >>> from zope.app.testing.placelesssetup import setUp, tearDown
       >>> setUp()
 
     First, we need to register the ZCML directive:

Modified: z3/Five/branch/zope31/tests/test_security.py
==============================================================================
--- z3/Five/branch/zope31/tests/test_security.py	(original)
+++ z3/Five/branch/zope31/tests/test_security.py	Mon Oct  3 10:46:36 2005
@@ -45,7 +45,7 @@
     Zope 2 can be replaced by ZCML statements without any loss of
     information.
 
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
+      >>> from zope.app.testing.placelesssetup import setUp, tearDown
       >>> setUp()
 
     We start out with two classes, ``Dummy1`` and ``Dummy2``.  They
@@ -141,7 +141,7 @@
     """
     Test checkPermission
 
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
+      >>> from zope.app.testing.placelesssetup import setUp, tearDown
       >>> setUp()
 
     Zope 3 has a function zope.security.checkPermission which provides

Modified: z3/Five/branch/zope31/tests/test_size.py
==============================================================================
--- z3/Five/branch/zope31/tests/test_size.py	(original)
+++ z3/Five/branch/zope31/tests/test_size.py	Mon Oct  3 10:46:36 2005
@@ -54,7 +54,7 @@
 
     Set up:
 
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
+      >>> from zope.app.testing.placelesssetup import setUp, tearDown
       >>> setUp()
 
       >>> configure_zcml = '''

Modified: z3/Five/branch/zope31/tests/test_viewable.py
==============================================================================
--- z3/Five/branch/zope31/tests/test_viewable.py	(original)
+++ z3/Five/branch/zope31/tests/test_viewable.py	Mon Oct  3 10:46:36 2005
@@ -23,7 +23,7 @@
     """
     Testing default view functionality
 
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
+      >>> from zope.app.testing.placelesssetup import setUp, tearDown
       >>> setUp()
 
     Take a class Foo and an interface IFoo:

Modified: z3/Five/branch/zope31/traversable.py
==============================================================================
--- z3/Five/branch/zope31/traversable.py	(original)
+++ z3/Five/branch/zope31/traversable.py	Mon Oct  3 10:46:36 2005
@@ -16,9 +16,8 @@
 $Id$
 """
 from zExceptions import NotFound
-from zope.exceptions import NotFoundError
 from zope.component import getView, ComponentLookupError
-from zope.interface import implements
+from zope.interface import implements, Interface
 from zope.publisher.interfaces.browser import IBrowserRequest
 from zope.app.traversing.interfaces import ITraverser, ITraversable
 from zope.app.traversing.adapters import DefaultTraversable
@@ -74,7 +73,7 @@
         try:
             return ITraverser(self).traverse(
                 path=[name], request=REQUEST).__of__(self)
-        except (ComponentLookupError, NotFoundError,
+        except (ComponentLookupError, LookupError,
                 AttributeError, KeyError, NotFound):
             pass
         try:
@@ -100,7 +99,7 @@
             REQUEST = FakeRequest()
         # Try to lookup a view first
         try:
-            return getView(context, name, REQUEST)
+            return getMultiAdapter((context, REQUEST), Interface, name)
         except ComponentLookupError:
             pass
         # If a view can't be found, then use default traversable

Modified: z3/Five/branch/zope31/viewable.py
==============================================================================
--- z3/Five/branch/zope31/viewable.py	(original)
+++ z3/Five/branch/zope31/viewable.py	Mon Oct  3 10:46:36 2005
@@ -17,10 +17,10 @@
 """
 import inspect
 from zExceptions import NotFound
-from zope.exceptions import NotFoundError
-from zope.component import getView, getDefaultViewName, ComponentLookupError
+from zope.component import ComponentLookupError
 from zope.interface import implements
 from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.app.zapi import getDefaultViewName
 
 from Products.Five.traversable import FakeRequest
 from Products.Five.interfaces import IBrowserDefault


More information about the z3-checkins mailing list