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() + _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins