[Zope-Checkins] SVN: Products.Five/branches/1.5/ If Zope supports
it delay initialization of packages until a later moment when
a ZODB connection is available. This fixes
http://www.zope.org/Collectors/Zope/2293
Wichert Akkerman
wichert at wiggy.net
Sun Jun 17 15:05:59 EDT 2007
Log message for revision 76744:
If Zope supports it delay initialization of packages until a later moment when a ZODB connection is available. This fixes http://www.zope.org/Collectors/Zope/2293
Changed:
U Products.Five/branches/1.5/fiveconfigure.py
U Products.Five/branches/1.5/tests/test_registerpackage.py
-=-
Modified: Products.Five/branches/1.5/fiveconfigure.py
===================================================================
--- Products.Five/branches/1.5/fiveconfigure.py 2007-06-17 19:04:57 UTC (rev 76743)
+++ Products.Five/branches/1.5/fiveconfigure.py 2007-06-17 19:05:59 UTC (rev 76744)
@@ -201,34 +201,47 @@
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 on versions of Zope that support this.
+ #
+ # Without this processing, 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().
+ #
+ # For older versions of Zope not aware of this variable, initialize
+ # immediately as before
+ to_initialize = getattr(Products, '_packages_to_initialize', None)
+ if to_initialize is None:
+ app = Zope2.app()
+ try:
+ product = initializeProduct(module_,
+ module_.__name__,
+ module_.__path__[0],
+ app)
- product.package_name = module_.__name__
+ 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()
+ if init_func is not None:
+ newContext = ProductContext(product, app, module_)
+ init_func(newContext)
finally:
- app._p_jar.close()
+ try:
+ import transaction
+ transaction.commit()
+ finally:
+ app._p_jar.close()
+ else:
+ to_initialize.append((module_, init_func,))
def registerPackage(_context, package, initialize=None):
"""ZCML directive function for registering a python package product
Modified: Products.Five/branches/1.5/tests/test_registerpackage.py
===================================================================
--- Products.Five/branches/1.5/tests/test_registerpackage.py 2007-06-17 19:04:57 UTC (rev 76743)
+++ Products.Five/branches/1.5/tests/test_registerpackage.py 2007-06-17 19:05:59 UTC (rev 76744)
@@ -49,15 +49,28 @@
... />
... </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
-
+ NOTE: In version 1.5.3 and earlier, the call to initialize() used to
+ happen during ZCML processing. That's bad, because it attempts to do
+ a ZODB write before sufficient context is available, at least when using
+ ZEO. If you run this test on Zope 2.10.3 or below, you may see doctest
+ failures indicating that the product was loaded immediately after the
+ call to zcml.load_string() above. That's the BBB code kicking in.
+
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:
More information about the Zope-Checkins
mailing list