SVN: Zope/trunk/ Removed persistent default code like the `error_log` and `temp_folder`.

Hanno Schlichting <[email protected]>
Newsgroups gmane.comp.web.zope.cvs
Message-ID <[email protected]>
Log message for revision 122071:
  Removed persistent default code like the `error_log` and `temp_folder`.
  

Changed:
  U   Zope/trunk/doc/CHANGES.rst
  U   Zope/trunk/src/OFS/Application.py
  U   Zope/trunk/src/OFS/tests/testAcquisition.py
  U   Zope/trunk/src/OFS/tests/testAppInitializer.py
  U   Zope/trunk/src/Products/SiteAccess/tests/testVirtualHostMonster.py
  U   Zope/trunk/src/Zope2/App/startup.py
  U   Zope/trunk/src/webdav/tests/testPUT_factory.py

-=-
Modified: Zope/trunk/doc/CHANGES.rst
===================================================================
--- Zope/trunk/doc/CHANGES.rst	2011-07-02 21:54:14 UTC (rev 122070)
+++ Zope/trunk/doc/CHANGES.rst	2011-07-03 12:25:49 UTC (rev 122071)
@@ -33,6 +33,8 @@
 Restructuring
 +++++++++++++
 
+- Removed persistent default code like the `error_log` and `temp_folder`.
+
 - Removed persistent default content, including the `standard_error_message`
   template.
 

Modified: Zope/trunk/src/OFS/Application.py
===================================================================
--- Zope/trunk/src/OFS/Application.py	2011-07-02 21:54:14 UTC (rev 122070)
+++ Zope/trunk/src/OFS/Application.py	2011-07-03 12:25:49 UTC (rev 122071)
@@ -23,7 +23,6 @@
 from AccessControl.Permission import ApplicationDefaultPermissions
 from Acquisition import aq_base
 from App.ApplicationManager import ApplicationManager
-from App.config import getConfiguration
 from App import FactoryDispatcher
 from DateTime import DateTime
 from OFS.metaconfigure import get_packages_to_initialize
@@ -59,8 +58,8 @@
     security = ClassSecurityInfo()
 
     title = 'Zope'
-    __defined_roles__ = ('Manager','Anonymous','Owner')
-    web__form__method = 'GET'
+    __defined_roles__ = ('Manager', 'Anonymous', 'Owner')
+    __error_log__ = None
     isTopLevelPrincipiaApplicationObject = 1
 
     manage_options=((
@@ -70,25 +69,16 @@
                     Folder.Folder.manage_options[2:]
                     )
 
-    p_=misc_.p_
-    misc_=misc_.misc_
+    p_ = misc_.p_
+    misc_ = misc_.misc_
+    _reserved_names = ('Control_Panel', )
 
-    _reserved_names=('Control_Panel',
-                     'browser_id_manager',
-                     'temp_folder')
-
     # This class-default __allow_groups__ ensures that the
     # emergency user can still access the system if the top-level
     # UserFolder is deleted. This is necessary to allow people
     # to replace the top-level UserFolder object.
-
     __allow_groups__ = UserFolder()
 
-    # Set the universal default method to index_html
-    _object_manager_browser_default_id = 'index_html'
-
-    _initializer_registry = None
-
     def __init__(self):
         # Initialize users
         uf = UserFolder()
@@ -98,7 +88,7 @@
     def id(self):
         try:
             return self.REQUEST['SCRIPT_NAME'][1:]
-        except:
+        except (KeyError, TypeError):
             return self.title
 
     def title_and_id(self):
@@ -197,21 +187,8 @@
         together.
         """
         # We're at the base of the path.
-        return ('',)
+        return ('', )
 
-    security.declarePrivate('_setInitializerFlag')
-    def _setInitializerFlag(self, flag):
-        if self._initializer_registry is None:
-            self._initializer_registry = {}
-        self._initializer_registry[flag] = 1
-
-    security.declarePrivate('_getInitializerFlag')
-    def _getInitializerFlag(self, flag):
-        reg = self._initializer_registry
-        if reg is None:
-            reg = {}
-        return reg.get(flag)
-
 InitializeClass(Application)
 
 
@@ -253,15 +230,10 @@
     def initialize(self):
         # make sure to preserve relative ordering of calls below.
         self.install_cp_and_products()
-        self.install_tempfolder_and_sdc()
-        self.install_session_data_manager()
-        self.install_browser_id_manager()
         self.install_required_roles()
         self.install_inituser()
-        self.install_errorlog()
         self.install_products()
         self.install_standards()
-        self.install_virtual_hosting()
 
     def install_cp_and_products(self):
         global APP_MANAGER
@@ -277,130 +249,6 @@
             app._objects = tuple(i for i in app._objects if i['id'] != 'Control_Panel')
             self.commit('Removed persistent Control_Panel')
 
-    def install_tempfolder_and_sdc(self):
-        app = self.getApp()
-        from Products.ZODBMountPoint.MountedObject import manage_addMounts,\
-             MountedObject
-        from Products.ZODBMountPoint.MountedObject import getConfiguration as \
-             getDBTabConfiguration
-
-        dbtab_config = getDBTabConfiguration()
-
-        tf = getattr(app, 'temp_folder', None)
-
-        if getattr(tf, 'meta_type', None) == MountedObject.meta_type:
-            # tf is a MountPoint object.  This means that the temp_folder
-            # couldn't be mounted properly (the meta_type would have been
-            # the meta type of the container class otherwise).  The
-            # MountPoint object writes a message to zLOG so we don't
-            # need to.
-            return
-
-        if tf is None:
-            # do nothing if we've already installed one
-            if not app._getInitializerFlag('temp_folder'):
-                if dbtab_config is None:
-                    # DefaultConfiguration, do nothing
-                    return
-                mount_paths = [ x[0] for x in dbtab_config.listMountPaths() ]
-                if not '/temp_folder' in mount_paths:
-                    # we won't be able to create the mount point properly
-                    LOG.error('Could not initialze a Temporary Folder because '
-                              'a database was not configured to be mounted at '
-                              'the /temp_folder mount point')
-                    return
-                try:
-                    manage_addMounts(app, ('/temp_folder',))
-                    app._setInitializerFlag('temp_folder')
-                    self.commit('Added temp_folder')
-                    tf = app.temp_folder
-                except:
-                    LOG.error('Could not add a /temp_folder mount point due to an '
-                              'error.', exc_info=sys.exc_info())
-                    return
-
-        # Ensure that there is a transient object container in the temp folder
-        config = getConfiguration()
-
-        if not hasattr(aq_base(tf), 'session_data'):
-            from Products.Transience.Transience import TransientObjectContainer
-            addnotify = getattr(config, 'session_add_notify_script_path', None)
-            delnotify = getattr(config, 'session_delete_notify_script_path',
-                                None)
-            default_limit = 1000
-            default_period_secs = 20
-            default_timeout_mins = 20
-
-            limit = getattr(config, 'maximum_number_of_session_objects',
-                            default_limit)
-            timeout_spec = getattr(config, 'session_timeout_minutes',
-                                   default_timeout_mins)
-            period_spec = getattr(config, 'session_resolution_seconds',
-                                  default_period_secs)
-
-            if addnotify and app.unrestrictedTraverse(addnotify, None) is None:
-                LOG.warn('failed to use nonexistent "%s" script as '
-                         'session-add-notify-script-path' % addnotify)
-                addnotify=None
-
-            if delnotify and app.unrestrictedTraverse(delnotify, None) is None:
-                LOG.warn('failed to use nonexistent "%s" script as '
-                         'session-delete-notify-script-path' % delnotify)
-                delnotify=None
-
-            if 1:  # Preserve indentation for diff
-                toc = TransientObjectContainer('session_data',
-                                               'Session Data Container',
-                                               timeout_mins = timeout_spec,
-                                               addNotification = addnotify,
-                                               delNotification = delnotify,
-                                               limit=limit,
-                                               period_secs = period_spec)
-
-            tf._setObject('session_data', toc)
-            tf_reserved = getattr(tf, '_reserved_names', ())
-            if 'session_data' not in tf_reserved:
-                tf._reserved_names = tf_reserved + ('session_data',)
-            self.commit('Added session_data to temp_folder')
-            return tf # return the tempfolder object for test purposes
-
-    def install_browser_id_manager(self):
-        app = self.getApp()
-        if app._getInitializerFlag('browser_id_manager'):
-            # do nothing if we've already installed one
-            return
-        # Ensure that a browser ID manager exists
-        if not hasattr(app, 'browser_id_manager'):
-            from Products.Sessions.BrowserIdManager import BrowserIdManager
-            bid = BrowserIdManager('browser_id_manager', 'Browser Id Manager')
-            app._setObject('browser_id_manager', bid)
-            # FIXME explicitely call manage_afterAdd, as sometimes
-            # events are initialized too late
-            browser_id_manager = app.browser_id_manager
-            browser_id_manager.manage_afterAdd(browser_id_manager, app)
-            app._setInitializerFlag('browser_id_manager')
-            self.commit('Added browser_id_manager')
-
-    def install_session_data_manager(self):
-        app = self.getApp()
-        if app._getInitializerFlag('session_data_manager'):
-            # do nothing if we've already installed one
-            return
-        # Ensure that a session data manager exists
-        if not hasattr(app, 'session_data_manager'):
-            from Products.Sessions.SessionDataManager import SessionDataManager
-            sdm = SessionDataManager('session_data_manager',
-                title='Session Data Manager',
-                path='/temp_folder/session_data',
-                requestName='SESSION')
-            app._setObject('session_data_manager', sdm)
-            # FIXME explicitely call manage_afterAdd, as sometimes
-            # events are initialized too late
-            session_data_manager = app.session_data_manager
-            session_data_manager.manage_afterAdd(session_data_manager, app)
-            app._setInitializerFlag('session_data_manager')
-            self.commit('Added session_data_manager')
-
     def install_required_roles(self):
         app = self.getApp()
 
@@ -439,47 +287,16 @@
                     transaction.get().note('Migrated user folder')
                     transaction.commit()
 
-    def install_errorlog(self):
-        app = self.getApp()
-        if app._getInitializerFlag('error_log'):
-            # do nothing if we've already installed one
-            return
-
-        # Install an error_log
-        if not hasattr(app, 'error_log'):
-            from Products.SiteErrorLog.SiteErrorLog import SiteErrorLog
-            error_log = SiteErrorLog()
-            app._setObject('error_log', error_log)
-            # FIXME explicitely call manage_afterAdd, as sometimes
-            # events are initialized too late
-            error_log = app.error_log
-            error_log.manage_afterAdd(error_log, app)
-            app._setInitializerFlag('error_log')
-            self.commit('Added site error_log at /error_log')
-
-    def install_virtual_hosting(self):
-        app = self.getApp()
-        if app._getInitializerFlag('virtual_hosting'):
-            return
-        if (not app.objectIds('Virtual Host Monster') and
-            not hasattr(app, 'virtual_hosting')):
-            from Products.SiteAccess.VirtualHostMonster \
-                import VirtualHostMonster
-            vhm = VirtualHostMonster()
-            vhm.id = 'virtual_hosting'
-            vhm.addToContainer(app)
-            app._setInitializerFlag('virtual_hosting')
-            self.commit('Added virtual_hosting')
-
     def install_products(self):
         return install_products()
 
     def install_standards(self):
         app = self.getApp()
-        if getattr(app, '_standard_objects_have_been_added', None) is None:
-            return
-        delattr(app, '_standard_objects_have_been_added')
-        transaction.get().note('Removed standard objects flag')
+        if getattr(app, '_standard_objects_have_been_added', None) is not None:
+            delattr(app, '_standard_objects_have_been_added')
+        if getattr(app, '_initializer_registry', None) is not None:
+            delattr(app, '_initializer_registry')
+        transaction.get().note('Removed unused application attributes.')
         transaction.commit()
 
 

Modified: Zope/trunk/src/OFS/tests/testAcquisition.py
===================================================================
--- Zope/trunk/src/OFS/tests/testAcquisition.py	2011-07-02 21:54:14 UTC (rev 122070)
+++ Zope/trunk/src/OFS/tests/testAcquisition.py	2011-07-03 12:25:49 UTC (rev 122071)
@@ -29,10 +29,9 @@
 from AccessControl.class_init import InitializeClass
 from AccessControl.SecurityManagement import newSecurityManager
 from AccessControl.SecurityManagement import noSecurityManager
-from AccessControl.Permissions import view, view_management_screens
+from AccessControl.Permissions import view_management_screens
 from AccessControl.ImplPython import guarded_getattr as guarded_getattr_py
 from AccessControl.ImplC import guarded_getattr as guarded_getattr_c
-from Products.SiteErrorLog.SiteErrorLog import SiteErrorLog
 
 
 class AllowedItem(SimpleItem):
@@ -56,17 +55,7 @@
 
 InitializeClass(ProtectedItem)
 
-class ProtectedSiteErrorLog(SiteErrorLog):
-    '''This differs from the base by declaring security
-       for the object itself.
-    '''
-    id = 'error_log2'
-    security = ClassSecurityInfo()
-    security.declareObjectProtected(view)
 
-InitializeClass(ProtectedSiteErrorLog)
-
-
 class TestGetAttr(unittest.TestCase):
 
     def setUp(self):
@@ -83,7 +72,6 @@
 
             # Set up objects in the root that we want to aquire
             self.app.manage_addFolder('plain_folder')
-            self.app._setObject('error_log2', ProtectedSiteErrorLog())
 
             # We also want to be able to acquire simple attributes
             self.app.manage_addProperty(id='simple_type', type='string', value='a string')
@@ -131,74 +119,13 @@
         self.assertEqual(o, self.app.acl_users)
 
     def testAclUsersDenied(self):
-        # XXX: Fails in 2.7.3
         o = self.guarded_getattr(self.folder.denied, 'acl_users')
         self.assertEqual(o, self.app.acl_users)
 
     def testAclUsersProtected(self):
-        # XXX: Fails in 2.7.3 for Anonymous
         o = self.guarded_getattr(self.folder.protected, 'acl_users')
         self.assertEqual(o, self.app.acl_users)
 
-    # Acquire browser id manager
-
-    def testBrowserIdManagerAllowed(self):
-        o = self.guarded_getattr(self.folder.allowed, 'browser_id_manager')
-        self.assertEqual(o, self.app.browser_id_manager)
-
-    def testBrowserIdManagerDenied(self):
-        o = self.guarded_getattr(self.folder.denied, 'browser_id_manager')
-        self.assertEqual(o, self.app.browser_id_manager)
-
-    def testBrowserIdManagerProtected(self):
-        o = self.guarded_getattr(self.folder.protected, 'browser_id_manager')
-        self.assertEqual(o, self.app.browser_id_manager)
-
-    # Acquire error log
-
-    def testErrorLogAllowed(self):
-        o = self.guarded_getattr(self.folder.allowed, 'error_log')
-        self.assertEqual(o, self.app.error_log)
-
-    def testErrorLogDenied(self):
-        # XXX: Fails in 2.7.3
-        o = self.guarded_getattr(self.folder.denied, 'error_log')
-        self.assertEqual(o, self.app.error_log)
-
-    def testErrorLogProtected(self):
-        # XXX: Fails in 2.7.3 for Anonymous
-        o = self.guarded_getattr(self.folder.protected, 'error_log')
-        self.assertEqual(o, self.app.error_log)
-
-    # Now watch this: error log with object security declaration works fine!
-
-    def testProtectedErrorLogAllowed(self):
-        o = self.guarded_getattr(self.folder.allowed, 'error_log2')
-        self.assertEqual(o, self.app.error_log2)
-
-    def testProtectedErrorLogDenied(self):
-        o = self.guarded_getattr(self.folder.denied, 'error_log2')
-        self.assertEqual(o, self.app.error_log2)
-
-    def testProtectedErrorLogProtected(self):
-        o = self.guarded_getattr(self.folder.protected, 'error_log2')
-        self.assertEqual(o, self.app.error_log2)
-
-    # This appears to mean that any potential acquiree must make sure
-    # to declareObjectProtected(SomePermission).
-
-    # From the ZDG:
-    # We've seen how to make  assertions on methods - but in the case of
-    # someObject we are not trying to access any particular method, but
-    # rather the object itself (to pass it to some_method). Because the
-    # security machinery will try to validate access to someObject, we
-    # need a way to let the security machinery know how to handle access
-    # to the object itself in addition to protecting its methods.
-
-    # IOW, acquiring an object in restricted Python now amounts to
-    # "passing it to some_method".
-
-
     # Also test Richard Jones' use-case of acquiring a string:
 
     def testSimpleTypeAllowed(self):
@@ -206,12 +133,10 @@
         self.assertEqual(o, 'a string')
 
     def testSimpleTypeDenied(self):
-        # XXX: Fails in 2.7.3
         o = self.guarded_getattr(self.folder.denied, 'simple_type')
         self.assertEqual(o, 'a string')
 
     def testSimpleTypeProtected(self):
-        # XXX: Fails in 2.7.3 for Anonymous
         o = self.guarded_getattr(self.folder.protected, 'simple_type')
         self.assertEqual(o, 'a string')
 

Modified: Zope/trunk/src/OFS/tests/testAppInitializer.py
===================================================================
--- Zope/trunk/src/OFS/tests/testAppInitializer.py	2011-07-02 21:54:14 UTC (rev 122070)
+++ Zope/trunk/src/OFS/tests/testAppInitializer.py	2011-07-03 12:25:49 UTC (rev 122071)
@@ -14,8 +14,6 @@
 
 import os, unittest, tempfile, cStringIO
 
-from logging import getLogger
-
 from OFS.Application import Application, AppInitializer
 import Zope2.Startup
 import ZConfig
@@ -101,69 +99,6 @@
         self.assertTrue(hasattr(app, 'Control_Panel'))
         self.assertEqual(app.Control_Panel.meta_type, 'Control Panel')
 
-    def test_install_tempfolder_and_sdc(self):
-        self.configure(good_cfg)
-        i = self.getOne()
-        i.install_tempfolder_and_sdc()
-        app = i.getApp()
-        self.assertEqual(app.temp_folder.meta_type, 'Temporary Folder')
-        self.assertEqual(app.temp_folder.session_data.meta_type,
-                         'Transient Object Container')
-        self.assertTrue(app._getInitializerFlag('temp_folder'))
-
-    def test_install_tempfolder_and_sdc_status(self):
-        self.configure(good_cfg)
-        i = self.getOne()
-        status = i.install_tempfolder_and_sdc()
-        self.assertTrue(status)
-
-        i = self.getOne()
-        self.configure(bad_cfg)
-        try:
-            logger = getLogger('Zope.ZODBMountPoint')
-            logger.disabled = 1
-            status = i.install_tempfolder_and_sdc()
-        finally:
-            logger.disabled = 0
-        self.assertFalse(status)
-
-    def test_install_tempfolder_and_sdc_unlimited_sessions(self):
-        unlimited_cfg = good_cfg + """
-        maximum-number-of-session-objects 0
-        """
-        self.configure(unlimited_cfg)
-        i = self.getOne()
-        status = i.install_tempfolder_and_sdc()
-        self.assertTrue(status)
-
-        sdc = i.getApp().temp_folder.session_data
-        self.assertEqual(sdc.getSubobjectLimit(), 0)
-
-    def test_install_browser_id_manager(self):
-        self.configure(good_cfg)
-        i = self.getOne()
-        app = i.getApp()
-        i.install_browser_id_manager()
-        self.assertEqual(app.browser_id_manager.meta_type,'Browser Id Manager')
-        self.assertTrue(app._getInitializerFlag('browser_id_manager'))
-
-    def test_install_virtual_hosting(self):
-        self.configure(good_cfg)
-        i = self.getOne()
-        app = i.getApp()
-        i.install_virtual_hosting()
-        self.assertEqual(app.virtual_hosting.meta_type,'Virtual Host Monster')
-        self.assertTrue(app._getInitializerFlag('virtual_hosting'))
-
-    def test_install_session_data_manager(self):
-        self.configure(good_cfg)
-        i = self.getOne()
-        i.install_session_data_manager()
-        app = i.getApp()
-        self.assertEqual(app.session_data_manager.meta_type,
-                         'Session Data Manager')
-        self.assertTrue(app._getInitializerFlag('session_data_manager'))
-
     def test_install_required_roles(self):
         self.configure(good_cfg)
         i = self.getOne()
@@ -187,14 +122,6 @@
             if os.path.exists(fname):
                 os.unlink(fname)
 
-    def test_install_errorlog(self):
-        self.configure(good_cfg)
-        i = self.getOne()
-        i.install_errorlog()
-        app = i.getApp()
-        self.assertEqual(app.error_log.meta_type, 'Site Error Log')
-        self.assertTrue(app._getInitializerFlag('error_log'))
-
     def test_install_products(self):
         self.configure(good_cfg)
         i = self.getOne()

Modified: Zope/trunk/src/Products/SiteAccess/tests/testVirtualHostMonster.py
===================================================================
--- Zope/trunk/src/Products/SiteAccess/tests/testVirtualHostMonster.py	2011-07-02 21:54:14 UTC (rev 122070)
+++ Zope/trunk/src/Products/SiteAccess/tests/testVirtualHostMonster.py	2011-07-03 12:25:49 UTC (rev 122071)
@@ -17,7 +17,7 @@
         from Testing.ZopeTestCase.ZopeLite import app
         transaction.begin()
         self.app = makerequest(app())
-        if 'virtual_hosting' not in  self.app.objectIds():
+        if 'virtual_hosting' not in self.app.objectIds():
             # If ZopeLite was imported, we have no default virtual
             # host monster
             from Products.SiteAccess.VirtualHostMonster \

Modified: Zope/trunk/src/Zope2/App/startup.py
===================================================================
--- Zope/trunk/src/Zope2/App/startup.py	2011-07-02 21:54:14 UTC (rev 122070)
+++ Zope/trunk/src/Zope2/App/startup.py	2011-07-03 12:25:49 UTC (rev 122071)
@@ -200,16 +200,15 @@
                     # ouch, a user saw this conflict error :-(
                     self.unresolved_conflict_errors += 1
 
-            if isinstance(published, list):
-                # special case for zope root
-                error_log_url = ''
-            else:
+            error_log_url = ''
+            if not isinstance(published, list):
                 try:
                     log = aq_acquire(published, '__error_log__', containment=1)
                 except AttributeError:
-                    error_log_url = ''
+                    pass
                 else:
-                    error_log_url = log.raising((t, v, traceback))
+                    if log is not None:
+                        error_log_url = log.raising((t, v, traceback))
 
             if (REQUEST is None or
                 (getattr(REQUEST.get('RESPONSE', None), '_error_format', '')

Modified: Zope/trunk/src/webdav/tests/testPUT_factory.py
===================================================================
--- Zope/trunk/src/webdav/tests/testPUT_factory.py	2011-07-02 21:54:14 UTC (rev 122070)
+++ Zope/trunk/src/webdav/tests/testPUT_factory.py	2011-07-03 12:25:49 UTC (rev 122071)
@@ -1,8 +1,8 @@
 import unittest
-import Testing
 import Zope2
 Zope2.startup()
 
+from Products.SiteAccess.VirtualHostMonster import VirtualHostMonster
 from Testing.makerequest import makerequest
 import transaction
 import base64
@@ -14,24 +14,23 @@
 
     def setUp(self):
         self.app = makerequest(Zope2.app())
-        try:
-            # Make a manager user
-            uf = self.app.acl_users
-            uf._doAddUser('manager', 'secret', ['Manager'], [])
-            # Make a folder to put stuff into
-            self.app.manage_addFolder('folder', '')
-            self.folder = self.app.folder
-            # Fake a WebDAV PUT request
-            request = self.app.REQUEST
-            request['PARENTS'] = [self.app]
-            request['BODY'] = 'bar'
-            request.environ['CONTENT_TYPE'] = 'text/plain'
-            request.environ['REQUEST_METHOD'] = 'PUT'
-            request.environ['WEBDAV_SOURCE_PORT'] = 1
-            request._auth = auth_info
-        except:
-            self.tearDown()
-            raise
+        # Make a manager user
+        uf = self.app.acl_users
+        uf._doAddUser('manager', 'secret', ['Manager'], [])
+        # Make a folder to put stuff into
+        self.app.manage_addFolder('folder', '')
+        self.folder = self.app.folder
+        # Setup VHM
+        vhm = VirtualHostMonster()
+        vhm.addToContainer(self.app)
+        # Fake a WebDAV PUT request
+        request = self.app.REQUEST
+        request['PARENTS'] = [self.app]
+        request['BODY'] = 'bar'
+        request.environ['CONTENT_TYPE'] = 'text/plain'
+        request.environ['REQUEST_METHOD'] = 'PUT'
+        request.environ['WEBDAV_SOURCE_PORT'] = 1
+        request._auth = auth_info
 
     def tearDown(self):
         transaction.abort()
@@ -69,7 +68,6 @@
         self.assertTrue('doc' in self.folder.objectIds())
 
     def testCollector2261(self):
-        from OFS.Folder import manage_addFolder
         from OFS.DTMLMethod import addDTMLMethod
 
         self.app.manage_addFolder('A', '')

_______________________________________________
Zope-Checkins maillist  -  [email protected]
https://mail.zope.org/mailman/listinfo/zope-checkins
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.