[Zope-Checkins] SVN: Zope/trunk/lib/python/ Forward port
packages-as-products refactoring from 2.10 branch.
Stefan H. Holek
stefan at epy.co.at
Sat Jun 23 11:37:10 EDT 2007
Log message for revision 76988:
Forward port packages-as-products refactoring from 2.10 branch.
Changed:
U Zope/trunk/lib/python/OFS/Application.py
U Zope/trunk/lib/python/Testing/ZopeTestCase/ZopeLite.py
U Zope/trunk/lib/python/Testing/ZopeTestCase/__init__.py
U Zope/trunk/lib/python/Testing/ZopeTestCase/doc/CHANGES.txt
A Zope/trunk/lib/python/Testing/ZopeTestCase/testpackage/
A Zope/trunk/lib/python/Testing/ZopeTestCase/zopedoctest/testPackageAsProduct.py
-=-
Modified: Zope/trunk/lib/python/OFS/Application.py
===================================================================
--- Zope/trunk/lib/python/OFS/Application.py 2007-06-23 15:02:50 UTC (rev 76987)
+++ Zope/trunk/lib/python/OFS/Application.py 2007-06-23 15:37:09 UTC (rev 76988)
@@ -633,21 +633,9 @@
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()
+ # Delayed install of packages-as-products
+ for module, init_func in getattr(Products, '_packages_to_initialize', []):
+ install_package(app, module, init_func, raise_exc=debug_mode)
if hasattr(Products, '_packages_to_initialize'):
del Products._packages_to_initialize
@@ -855,6 +843,34 @@
if raise_exc:
raise
+
+def install_package(app, module, init_func, raise_exc=False, log_exc=True):
+ """Installs a Python package like a product."""
+ 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)
+
+ if not doInstall():
+ transaction.abort()
+ else:
+ transaction.get().note('Installed package %s' % module.__name__)
+ transaction.commit()
+
+ except:
+ if log_exc:
+ LOG.error("Couldn't install %s" % module.__name__,
+ exc_info=True)
+ transaction.abort()
+ if raise_exc:
+ raise
+
+
def install_standards(app):
# Check to see if we've already done this before
# Don't do it twice (Casey)
Modified: Zope/trunk/lib/python/Testing/ZopeTestCase/ZopeLite.py
===================================================================
--- Zope/trunk/lib/python/Testing/ZopeTestCase/ZopeLite.py 2007-06-23 15:02:50 UTC (rev 76987)
+++ Zope/trunk/lib/python/Testing/ZopeTestCase/ZopeLite.py 2007-06-23 15:37:09 UTC (rev 76988)
@@ -26,7 +26,6 @@
"""
import os, sys, time
-import transaction
# Allow code to tell it is run by the test framework
os.environ['ZOPETESTCASE'] = '1'
@@ -133,62 +132,60 @@
# Allow test authors to install Zope products into the test environment. Note
# that installProduct() must be called at module level -- never from tests.
-from OFS.Application import get_folder_permissions, get_products, install_product
+from OFS.Application import get_folder_permissions, get_products
+from OFS.Application import install_product, install_package
from OFS.Folder import Folder
import Products
_theApp = Zope2.app()
_installedProducts = {}
+_installedPackages = {}
def hasProduct(name):
'''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, package=False):
+def installProduct(name, quiet=0):
'''Installs a Zope product.'''
start = time.time()
meta_types = []
if _patched and not _installedProducts.has_key(name):
- 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)
+ 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)
- product.package_name = module_.__name__
+def hasPackage(name):
+ '''Checks if a package has been registered with five:registerPackage.'''
+ return name in [m.__name__ for m in getattr(Products, '_registered_packages', [])]
- 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
+def installPackage(name, quiet=0):
+ '''Installs a registered Python package like a Zope product.'''
+ start = time.time()
+ if _patched and not _installedPackages.has_key(name):
+ for module, init_func in getattr(Products, '_packages_to_initialize', []):
+ if module.__name__ == name:
+ if not quiet: _print('Installing %s ... ' % module.__name__)
+ # We want to fail immediately if a package throws an exception
+ # during install, so we set the raise_exc flag.
+ install_package(_theApp, module, init_func, raise_exc=1)
+ _installedPackages[module.__name__] = 1
+ Products._packages_to_initialize.remove((module, init_func))
+ if not quiet: _print('done (%.3fs)\n' % (time.time() - start))
+ break
else:
- 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)
+ if not quiet: _print('Installing %s ... NOT FOUND\n' % name)
def _load_control_panel():
# Loading the Control_Panel of an existing ZODB may take
@@ -219,6 +216,7 @@
configure = Zope2.configure
def startup(): pass
Zope = Zope2
+active = _patched
# ZODB sandbox factory
from ZODB.DemoStorage import DemoStorage
Modified: Zope/trunk/lib/python/Testing/ZopeTestCase/__init__.py
===================================================================
--- Zope/trunk/lib/python/Testing/ZopeTestCase/__init__.py 2007-06-23 15:02:50 UTC (rev 76987)
+++ Zope/trunk/lib/python/Testing/ZopeTestCase/__init__.py 2007-06-23 15:37:09 UTC (rev 76988)
@@ -20,6 +20,8 @@
from ZopeLite import hasProduct
from ZopeLite import installProduct
+from ZopeLite import hasPackage
+from ZopeLite import installPackage
from ZopeLite import _print
from ZopeTestCase import folder_name
Modified: Zope/trunk/lib/python/Testing/ZopeTestCase/doc/CHANGES.txt
===================================================================
--- Zope/trunk/lib/python/Testing/ZopeTestCase/doc/CHANGES.txt 2007-06-23 15:02:50 UTC (rev 76987)
+++ Zope/trunk/lib/python/Testing/ZopeTestCase/doc/CHANGES.txt 2007-06-23 15:37:09 UTC (rev 76988)
@@ -18,6 +18,8 @@
publish_module(). Thanks to Andreas Zeidler.
- Fixed doctestsuite factory to copy layers from test_class to the suite.
Thanks to Whit Morris.
+- Added hasPackage and installPackage functions for dealing with "products"
+ registered via five:registerPackage.
0.9.8 (Zope 2.8 edition)
- Renamed 'doctest' package to 'zopedoctest' because of name-shadowing
Copied: Zope/trunk/lib/python/Testing/ZopeTestCase/testpackage (from rev 76966, Zope/branches/2.10/lib/python/Testing/ZopeTestCase/testpackage)
Copied: Zope/trunk/lib/python/Testing/ZopeTestCase/zopedoctest/testPackageAsProduct.py (from rev 76966, Zope/branches/2.10/lib/python/Testing/ZopeTestCase/zopedoctest/testPackageAsProduct.py)
===================================================================
--- Zope/trunk/lib/python/Testing/ZopeTestCase/zopedoctest/testPackageAsProduct.py (rev 0)
+++ Zope/trunk/lib/python/Testing/ZopeTestCase/zopedoctest/testPackageAsProduct.py 2007-06-23 15:37:09 UTC (rev 76988)
@@ -0,0 +1,122 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Corporation and Contributors. All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Tests for installPackage
+
+$Id$
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from unittest import TestSuite
+from Testing import ZopeTestCase
+from Testing.ZopeTestCase import ZopeLite
+from Testing.ZopeTestCase import ZopeDocTestSuite
+from Products.Five import zcml
+from zope.testing import cleanup
+import Products
+
+
+def testInstallPackage():
+ """
+ Test if installPackage works.
+
+ >>> from Testing import ZopeTestCase
+ >>> from Products.Five import zcml
+
+ Register testpackage
+
+ >>> ZopeTestCase.hasPackage('testpackage')
+ False
+
+ >>> config = '''
+ ... <configure
+ ... xmlns:five="http://namespaces.zope.org/five">
+ ... <five:registerPackage
+ ... package="testpackage"
+ ... initialize="testpackage.initialize"
+ ... />
+ ... </configure>'''
+ >>> zcml.load_string(config)
+
+ The package is registered now
+
+ >>> ZopeTestCase.hasPackage('testpackage')
+ True
+
+ But not yet installed
+
+ >>> app = self._app()
+ >>> 'testpackage' in app.Control_Panel.Products.objectIds()
+ False
+
+ Install it
+
+ >>> ZopeTestCase.installPackage('testpackage', quiet=True)
+ testpackage.initialize called
+
+ Now it shows up in Control_Panel
+
+ >>> app = self._app()
+ >>> 'testpackage' in app.Control_Panel.Products.objectIds()
+ True
+
+ hasPackage still returns True
+
+ >>> ZopeTestCase.hasPackage('testpackage')
+ True
+
+ A package is only installed once, subsequent calls to installPackage
+ are ignored:
+
+ >>> ZopeTestCase.installPackage('testpackage', quiet=True)
+ """
+
+
+class TestClass(ZopeTestCase.FunctionalTestCase):
+
+ def afterSetUp(self):
+ cleanup.cleanUp()
+ zcml._initialized = False
+ zcml.load_site()
+
+ self.saved = sys.path[:]
+ sys.path.append(ZopeTestCase.__path__[0])
+
+ def afterClear(self):
+ cleanup.cleanUp()
+ sys.path[:] = self.saved
+
+ registered = getattr(Products, '_registered_packages', None)
+ if registered is not None:
+ Products._registered_packages = [m for m in registered
+ if m.__name__ != 'testpackage']
+
+ to_initialize = getattr(Products, '_packages_to_initialize', None)
+ if to_initialize is not None:
+ Products._packages_to_initialize = [(m, f) for (m, f) in to_initialize
+ if m.__name__ != 'testpackage']
+
+
+def test_suite():
+ if ZopeLite.active:
+ return TestSuite((
+ ZopeDocTestSuite(test_class=TestClass),
+ ))
+ else:
+ return TestSuite()
+
+if __name__ == '__main__':
+ framework()
+
More information about the Zope-Checkins
mailing list