[Zope-Checkins] SVN: Zope/trunk/lib/python/ Delay registration of
python packages until a moment when a ZODB connection is
available http://www.zope.org/Collectors/Zope/2293
Wichert Akkerman
wichert at wiggy.net
Sun Jun 17 14:16:24 EDT 2007
Log message for revision 76740:
Delay registration of python packages until a moment when a ZODB connection is available http://www.zope.org/Collectors/Zope/2293
Changed:
U Zope/trunk/lib/python/OFS/Application.py
U Zope/trunk/lib/python/OFS/ObjectManager.py
U Zope/trunk/lib/python/OFS/tests/testObjectManager.py
U Zope/trunk/lib/python/Products/Five/fiveconfigure.py
U Zope/trunk/lib/python/Products/Five/tests/test_registerpackage.py
U Zope/trunk/lib/python/Testing/ZopeTestCase/ZopeLite.py
-=-
Modified: Zope/trunk/lib/python/OFS/Application.py
===================================================================
--- Zope/trunk/lib/python/OFS/Application.py 2007-06-17 18:10:22 UTC (rev 76739)
+++ Zope/trunk/lib/python/OFS/Application.py 2007-06-17 18:16:23 UTC (rev 76740)
@@ -633,6 +633,24 @@
install_product(app, product_dir, product_name, meta_types,
folder_permissions, raise_exc=debug_mode)
+ # Delayed install of products-as-packages
+ for module_, init_func in getattr(Products, '_packages_to_initialize', []):
+ try:
+ product = App.Product.initializeProduct(module_,
+ module_.__name__,
+ module_.__path__[0],
+ app)
+
+ product.package_name = module_.__name__
+
+ if init_func is not None:
+ newContext = ProductContext(product, app, module_)
+ init_func(newContext)
+ finally:
+ transaction.commit()
+ if hasattr(Products, '_packages_to_initialize'):
+ del Products._packages_to_initialize
+
Products.meta_types=Products.meta_types+tuple(meta_types)
InitializeClass(Folder.Folder)
Modified: Zope/trunk/lib/python/OFS/ObjectManager.py
===================================================================
--- Zope/trunk/lib/python/OFS/ObjectManager.py 2007-06-17 18:10:22 UTC (rev 76739)
+++ Zope/trunk/lib/python/OFS/ObjectManager.py 2007-06-17 18:16:23 UTC (rev 76740)
@@ -705,6 +705,7 @@
out=out+((k,stat),)
return marshal.dumps(out)
+ security.declareProtected(access_contents_information, 'manage_hasId')
def manage_hasId(self, REQUEST):
""" check if the folder has an object with REQUEST['id'] """
Modified: Zope/trunk/lib/python/OFS/tests/testObjectManager.py
===================================================================
--- Zope/trunk/lib/python/OFS/tests/testObjectManager.py 2007-06-17 18:10:22 UTC (rev 76739)
+++ Zope/trunk/lib/python/OFS/tests/testObjectManager.py 2007-06-17 18:16:23 UTC (rev 76740)
@@ -411,6 +411,16 @@
self.failUnless(filename.endswith('.zexp') or
filename.endswith('.xml'))
+ def test_hasId(self):
+ om = self._makeOne()
+ request={'id' : 'test'}
+ self.assertRaises(KeyError, om.manage_hasId, request)
+
+ si = SimpleItem('test')
+ om._setObject('test', si)
+ om.manage_hasId(request)
+
+
def test_suite():
suite = unittest.TestSuite()
suite.addTest( unittest.makeSuite( ObjectManagerTests ) )
Modified: Zope/trunk/lib/python/Products/Five/fiveconfigure.py
===================================================================
--- Zope/trunk/lib/python/Products/Five/fiveconfigure.py 2007-06-17 18:10:22 UTC (rev 76739)
+++ Zope/trunk/lib/python/Products/Five/fiveconfigure.py 2007-06-17 18:16:23 UTC (rev 76740)
@@ -201,35 +201,25 @@
def _registerPackage(module_, init_func=None):
"""Registers the given python package as a Zope 2 style product
"""
-
+
if not hasattr(module_, '__path__'):
raise ValueError("Must be a package and the " \
"package must be filesystem based")
- app = Zope2.app()
- try:
- product = initializeProduct(module_,
- module_.__name__,
- module_.__path__[0],
- app)
+ registered_packages = getattr(Products, '_registered_packages', None)
+ if registered_packages is None:
+ registered_packages = Products._registered_packages = []
+ registered_packages.append(module_)
+
+ # Delay the actual setup until the usual product loading time in
+ # OFS.Application. Otherwise, we may get database write errors in
+ # ZEO, when there's no connection with which to write an entry to
+ # Control_Panel. We would also get multiple calls to initialize().
+ to_initialize = getattr(Products, '_packages_to_initialize', None)
+ if to_initialize is None:
+ to_initialize = Products._packages_to_initialize = []
+ to_initialize.append((module_, init_func,))
- product.package_name = module_.__name__
-
- if init_func is not None:
- newContext = ProductContext(product, app, module_)
- init_func(newContext)
-
- registered_packages = getattr(Products, '_registered_packages', None)
- if registered_packages is None:
- registered_packages = Products._registered_packages = []
- registered_packages.append(module_)
- finally:
- try:
- import transaction
- transaction.commit()
- finally:
- app._p_jar.close()
-
def registerPackage(_context, package, initialize=None):
"""ZCML directive function for registering a python package product
"""
Modified: Zope/trunk/lib/python/Products/Five/tests/test_registerpackage.py
===================================================================
--- Zope/trunk/lib/python/Products/Five/tests/test_registerpackage.py 2007-06-17 18:10:22 UTC (rev 76739)
+++ Zope/trunk/lib/python/Products/Five/tests/test_registerpackage.py 2007-06-17 18:16:23 UTC (rev 76740)
@@ -49,15 +49,21 @@
... />
... </configure>'''
>>> zcml.load_string(configure_zcml)
+
+ We need to load the product as well. This would normally happen during
+ Zope startup, but in the test, we're already too late.
+
+ >>> import Zope2
+ >>> from OFS.Application import install_products
+
+ >>> app = Zope2.app()
+ >>> install_products(app)
pythonproduct2 initialized
-
Test to see if the pythonproduct2 python package actually gets setup
as a zope2 product in the Control Panel.
>>> product_listing = []
- >>> import Zope2
- >>> app = Zope2.app()
>>> try:
... product_listing = app.Control_Panel.Products.objectIds()
... finally:
Modified: Zope/trunk/lib/python/Testing/ZopeTestCase/ZopeLite.py
===================================================================
--- Zope/trunk/lib/python/Testing/ZopeTestCase/ZopeLite.py 2007-06-17 18:10:22 UTC (rev 76739)
+++ Zope/trunk/lib/python/Testing/ZopeTestCase/ZopeLite.py 2007-06-17 18:16:23 UTC (rev 76740)
@@ -26,6 +26,7 @@
"""
import os, sys, time
+import transaction
# Allow code to tell it is run by the test framework
os.environ['ZOPETESTCASE'] = '1'
@@ -143,26 +144,51 @@
'''Checks if a product can be found along Products.__path__'''
return name in [n[1] for n in get_products()]
-def installProduct(name, quiet=0):
+def installProduct(name, quiet=0, package=False):
'''Installs a Zope product.'''
start = time.time()
meta_types = []
if _patched and not _installedProducts.has_key(name):
- for priority, product_name, index, product_dir in get_products():
- if product_name == name:
- if not quiet: _print('Installing %s ... ' % product_name)
- # We want to fail immediately if a product throws an exception
- # during install, so we set the raise_exc flag.
- install_product(_theApp, product_dir, product_name, meta_types,
- get_folder_permissions(), raise_exc=1)
- _installedProducts[product_name] = 1
- Products.meta_types = Products.meta_types + tuple(meta_types)
- Globals.InitializeClass(Folder)
- if not quiet: _print('done (%.3fs)\n' % (time.time() - start))
- break
+ if package:
+ # Processing of products-as-packages can be simpler; also check
+ # whether this has been registered with <five:registerPackage />
+ # and has not been loaded.
+ for module_, init_func in getattr(Products, '_packages_to_initialize', []):
+ if module_.__name__ == name:
+ if not quiet: _print('Installing %s ... ' % name)
+ try:
+ product = App.Product.initializeProduct(module_,
+ module_.__name__,
+ module_.__path__[0],
+ _theApp)
+
+ product.package_name = module_.__name__
+
+ if init_func is not None:
+ newContext = App.ProductContext.ProductContext(product, app, module_)
+ init_func(newContext)
+ finally:
+ transaction.commit()
+
+ Globals.InitializeClass(Folder)
+ if not quiet: _print('done (%.3fs)\n' % (time.time() - start))
+ break
else:
- if name != 'SomeProduct': # Ignore the skeleton tests :-P
- if not quiet: _print('Installing %s ... NOT FOUND\n' % name)
+ for priority, product_name, index, product_dir in get_products():
+ if product_name == name:
+ if not quiet: _print('Installing %s ... ' % product_name)
+ # We want to fail immediately if a product throws an exception
+ # during install, so we set the raise_exc flag.
+ install_product(_theApp, product_dir, product_name, meta_types,
+ get_folder_permissions(), raise_exc=1)
+ _installedProducts[product_name] = 1
+ Products.meta_types = Products.meta_types + tuple(meta_types)
+ Globals.InitializeClass(Folder)
+ if not quiet: _print('done (%.3fs)\n' % (time.time() - start))
+ break
+ else:
+ if name != 'SomeProduct': # Ignore the skeleton tests :-P
+ if not quiet: _print('Installing %s ... NOT FOUND\n' % name)
def _load_control_panel():
# Loading the Control_Panel of an existing ZODB may take
More information about the Zope-Checkins
mailing list