[Checkins] SVN: z3c.zcmlhook/trunk/ Initial implementation

Martin Aspeli optilude at gmx.net
Sat Jan 2 07:44:27 EST 2010


Log message for revision 107543:
  Initial implementation

Changed:
  _U  z3c.zcmlhook/trunk/
  A   z3c.zcmlhook/trunk/README.txt
  A   z3c.zcmlhook/trunk/buildout.cfg
  A   z3c.zcmlhook/trunk/docs/
  A   z3c.zcmlhook/trunk/docs/HISTORY.txt
  A   z3c.zcmlhook/trunk/docs/LICENSE.ZPL
  A   z3c.zcmlhook/trunk/setup.cfg
  A   z3c.zcmlhook/trunk/setup.py
  A   z3c.zcmlhook/trunk/src/
  A   z3c.zcmlhook/trunk/src/z3c/
  A   z3c.zcmlhook/trunk/src/z3c/__init__.py
  A   z3c.zcmlhook/trunk/src/z3c/zcmlhook/
  A   z3c.zcmlhook/trunk/src/z3c/zcmlhook/__init__.py
  A   z3c.zcmlhook/trunk/src/z3c/zcmlhook/meta.zcml
  A   z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/
  A   z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/__init__.py
  A   z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test1.zcml
  A   z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test2.zcml
  A   z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test3.zcml
  A   z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test4.zcml
  A   z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test_zcml.py
  A   z3c.zcmlhook/trunk/src/z3c/zcmlhook/zcml.py

-=-

Property changes on: z3c.zcmlhook/trunk
___________________________________________________________________
Added: svn:ignore
   + .installed.cfg
bin
parts
develop-eggs
eggs


Added: z3c.zcmlhook/trunk/README.txt
===================================================================
--- z3c.zcmlhook/trunk/README.txt	                        (rev 0)
+++ z3c.zcmlhook/trunk/README.txt	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1,78 @@
+Introduction
+============
+
+This package provides means of hooking into the Zope (ZCML) configuration
+process.
+
+Custom ZCML actions
+-------------------
+
+It is sometimes useful to execute a function during the execution of 
+configuration actions, for example to perform one-off configuration that does
+not warrant a new directive. The ``<zcml:customAction />`` directive is
+provided for this purpose.
+
+For example, you may want to call a function called
+``my.package.finalConfiguration()`` "late" in the configuration action
+execution cycle. This can be achieved with the following ZCML statements::
+
+    <configure
+        xmlns="http://namespaces.zope.org/zope"
+        xmlns:zcml="http://namespaces.zope.org/zcml"
+        i18n_domain="my.package">
+        
+        <include package="z3c.zcmlhook" file="meta.zcml" />
+        
+        <zcml:customAction
+            handler="my.package.finalConfiguration"
+            order="9999"
+            />
+        
+    </configure>
+
+The ``handler`` attribute gives the name of a function to execute. The
+function should take no arguments. The ``order`` attribute is optional, and
+can be used to influence when in the configuration cycle the function is
+executed. The default value for this, as for most Zope configuration actions,
+is ``0``.
+
+Overriding custom actions
+-------------------------
+
+If you want to override the invocation of a custom handler in an
+``overrides.zcml``, you need to tell ``zope.configuration`` which handler to
+override. You can do that by setting the *discriminator* explicitly. A
+discriminator is used to uniquely identify a configuration action. In the
+case of the ``<zcml:customAction />`` directive, the discriminator is based
+on the full dotted name to the function by default. Thus, you could override
+the function call above like so::
+
+        <zcml:customAction
+            handler="my.otherpackage.overrideFinalConfiguration"
+            discriminator="my.package.finalConfiguration"
+            order="9999"
+            />
+
+Using a method more than once
+-----------------------------
+
+The ``discriminator`` attribute can also be used to explicitly allow using
+the same handler more than once. If you wanted to call
+``my.package.finalConfiguration`` again, you would normally get a
+configuration conflict. However, with a (unique) custom discriminator, the
+second call is allowed::
+
+        <zcml:customAction
+            handler="my.package.finalConfiguration"
+            discriminator="my.package.finalConfiguration:early"
+            order="-9999"
+            />
+
+        <zcml:customAction
+            handler="my.package.finalConfiguration"
+            discriminator="my.package.finalConfiguration:late"
+            order="9999"
+            />
+
+Here, we are attempting to call our configuration action "very early" as
+well as "very late" in the configuration process.
\ No newline at end of file

Added: z3c.zcmlhook/trunk/buildout.cfg
===================================================================
--- z3c.zcmlhook/trunk/buildout.cfg	                        (rev 0)
+++ z3c.zcmlhook/trunk/buildout.cfg	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1,8 @@
+[buildout]
+parts = test
+develop = .
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = z3c.zcmlhook
+defaults = ['--exit-with-status', '--auto-progress', '--auto-color']

Added: z3c.zcmlhook/trunk/docs/HISTORY.txt
===================================================================
--- z3c.zcmlhook/trunk/docs/HISTORY.txt	                        (rev 0)
+++ z3c.zcmlhook/trunk/docs/HISTORY.txt	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1,8 @@
+Changelog
+=========
+
+1.0b1 - January 2nd, 2010
+-------------------------
+
+* Initial release
+  [optilude]

Added: z3c.zcmlhook/trunk/docs/LICENSE.ZPL
===================================================================
--- z3c.zcmlhook/trunk/docs/LICENSE.ZPL	                        (rev 0)
+++ z3c.zcmlhook/trunk/docs/LICENSE.ZPL	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1,43 @@
+Some code carries the Zope Public License (as indicated in the comments):
+
+Zope Public License (ZPL) Version 2.0
+
+This software is Copyright (c) Zope Corporation (tm) and Contributors. 
+All rights reserved.
+
+This license has been certified as open source. It has also been designated as 
+GPL compatible by the Free Software Foundation (FSF).
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+* Redistributions in source code must retain the above copyright notice, this 
+  list of conditions, and the following disclaimer. 
+* Redistributions in binary form must reproduce the above copyright notice, 
+  this list of conditions, and the following disclaimer in the documentation 
+  and/or other materials provided with the distribution. 
+* The name Zope Corporation (tm) must not be used to endorse or promote 
+  products derived from this software without prior written permission from 
+  Zope Corporation. 
+* The right to distribute this software or to use it for any purpose does not 
+  give you the right to use Servicemarks (sm) or Trademarks (tm) of Zope 
+  Corporation. Use of them is covered in a separate agreement 
+  (see http://www.zope.com/Marks). 
+If any files are modified, you must cause the modified files to carry prominent 
+notices stating that you changed the files and the date of any change. 
+
+Disclaimer
+THIS SOFTWARE IS PROVIDED BY ZOPE CORPORATION ``AS IS'' AND ANY EXPRESSED OR 
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 
+EVENT SHALL ZOPE CORPORATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This software consists of contributions made by Zope Corporation and many 
+individuals on behalf of Zope Corporation. Specific attributions are listed 
+in the accompanying credits file.

Added: z3c.zcmlhook/trunk/setup.cfg
===================================================================
--- z3c.zcmlhook/trunk/setup.cfg	                        (rev 0)
+++ z3c.zcmlhook/trunk/setup.cfg	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1,4 @@
+[egg_info]
+tag_build = dev
+tag_svn_revision = true
+

Added: z3c.zcmlhook/trunk/setup.py
===================================================================
--- z3c.zcmlhook/trunk/setup.py	                        (rev 0)
+++ z3c.zcmlhook/trunk/setup.py	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1,38 @@
+from setuptools import setup, find_packages
+import os.path
+
+version = "1.0b1"
+
+setup(name                  = "z3c.zcmlhook",
+      version               = version,
+      description           = "Easily hook into the ZCML processing machinery",
+      long_description      = open("README.txt").read() + "\n" +
+                              open(os.path.join("docs", "HISTORY.txt")).read(),
+      classifiers           = [
+            "Environment :: Web Environment",
+            "Intended Audience :: Developers",
+            "License :: OSI Approved :: Zope Public License",
+            "Programming Language :: Python",
+            "Topic :: Software Development :: Libraries :: Python Modules",
+        ],
+      keywords              = "zope zcml hook",
+      author                = "Martin Aspeli",
+      author_email          = "zope-dev at zope.org",
+      url                   = "",
+      license               = "ZPL",
+      namespace_packages    = ["z3c"],
+      packages              = find_packages("src", exclude=["ez_setup"]),
+      package_dir           = {"": "src"},
+      include_package_data  = True,
+      zip_safe              = False,
+      install_requires      = [
+          "setuptools",
+          "zope.component",
+          "zope.interface",
+          "zope.schema",
+          "zope.configuration",
+          ],
+      extras_require        = {},
+      tests_require         = "nose >=0.10.0b1",
+      test_suite            = "nose.collector",
+      )


Property changes on: z3c.zcmlhook/trunk/src
___________________________________________________________________
Added: svn:ignore
   + *.egg-info


Added: z3c.zcmlhook/trunk/src/z3c/__init__.py
===================================================================
--- z3c.zcmlhook/trunk/src/z3c/__init__.py	                        (rev 0)
+++ z3c.zcmlhook/trunk/src/z3c/__init__.py	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)

Added: z3c.zcmlhook/trunk/src/z3c/zcmlhook/__init__.py
===================================================================
--- z3c.zcmlhook/trunk/src/z3c/zcmlhook/__init__.py	                        (rev 0)
+++ z3c.zcmlhook/trunk/src/z3c/zcmlhook/__init__.py	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1 @@
+

Added: z3c.zcmlhook/trunk/src/z3c/zcmlhook/meta.zcml
===================================================================
--- z3c.zcmlhook/trunk/src/z3c/zcmlhook/meta.zcml	                        (rev 0)
+++ z3c.zcmlhook/trunk/src/z3c/zcmlhook/meta.zcml	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1,15 @@
+<configure 
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:meta="http://namespaces.zope.org/meta">
+
+  <meta:directives namespace="http://namespaces.zope.org/zcml">
+    
+    <meta:directive
+        name="customAction"
+        schema=".zcml.ICustomActionDirective"
+        handler=".zcml.customAction"
+        />
+  
+  </meta:directives>
+
+</configure>

Added: z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/__init__.py
===================================================================
--- z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/__init__.py	                        (rev 0)
+++ z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/__init__.py	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1 @@
+

Added: z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test1.zcml
===================================================================
--- z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test1.zcml	                        (rev 0)
+++ z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test1.zcml	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1,10 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:zcml="http://namespaces.zope.org/zcml">
+
+    <include package="z3c.zcmlhook" file="meta.zcml" />
+
+    <zcml:customAction
+        handler="z3c.zcmlhook.tests.test_zcml.test_fn1"
+        />
+
+</configure>

Added: z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test2.zcml
===================================================================
--- z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test2.zcml	                        (rev 0)
+++ z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test2.zcml	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1,16 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:zcml="http://namespaces.zope.org/zcml">
+
+    <include package="z3c.zcmlhook" file="meta.zcml" />
+
+    <zcml:customAction
+        handler="z3c.zcmlhook.tests.test_zcml.test_fn1"
+        order="1"
+        />
+
+    <zcml:customAction
+        handler="z3c.zcmlhook.tests.test_zcml.test_fn2"
+        order="-1"
+        />
+
+</configure>

Added: z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test3.zcml
===================================================================
--- z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test3.zcml	                        (rev 0)
+++ z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test3.zcml	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1,14 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:zcml="http://namespaces.zope.org/zcml">
+
+    <include package="z3c.zcmlhook" file="meta.zcml" />
+
+    <zcml:customAction
+        handler="z3c.zcmlhook.tests.test_zcml.test_fn1"
+        />
+
+    <zcml:customAction
+        handler="z3c.zcmlhook.tests.test_zcml.test_fn1"
+        />
+
+</configure>

Added: z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test4.zcml
===================================================================
--- z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test4.zcml	                        (rev 0)
+++ z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test4.zcml	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1,15 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:zcml="http://namespaces.zope.org/zcml">
+
+    <include package="z3c.zcmlhook" file="meta.zcml" />
+
+    <zcml:customAction
+        handler="z3c.zcmlhook.tests.test_zcml.test_fn1"
+        discriminator="z3c.zcmlhook.tests.test_zcml.test_fn1:custom"
+        />
+
+    <zcml:customAction
+        handler="z3c.zcmlhook.tests.test_zcml.test_fn1"
+        />
+
+</configure>

Added: z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test_zcml.py
===================================================================
--- z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test_zcml.py	                        (rev 0)
+++ z3c.zcmlhook/trunk/src/z3c/zcmlhook/tests/test_zcml.py	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1,51 @@
+from unittest import TestCase
+
+from zope.configuration import xmlconfig
+from zope.configuration.config import ConfigurationConflictError
+
+import zope.component.testing
+import z3c.zcmlhook
+
+import threading
+
+testState = threading.local()
+
+def test_fn1():
+    testState.executions.append('test_fn1')
+
+def test_fn2():
+    testState.executions.append('test_fn2')
+
+class TestZCMLDeclarations(TestCase):
+    
+    def setUp(self):
+        global testState
+        testState.executions = []
+    
+    def tearDown(self):
+        zope.component.testing.tearDown()
+
+    def test_invoke(self):
+        zcml = xmlconfig.XMLConfig("test1.zcml", z3c.zcmlhook.tests)
+        zcml()
+        
+        self.assertEquals(['test_fn1'], testState.executions)
+    
+    def test_invoke_order(self):
+        zcml = xmlconfig.XMLConfig("test2.zcml", z3c.zcmlhook.tests)
+        zcml()
+        
+        self.assertEquals(['test_fn2', 'test_fn1'], testState.executions)
+    
+    def test_invoke_conflict(self):
+        zcml = xmlconfig.XMLConfig("test3.zcml", z3c.zcmlhook.tests)
+        self.assertRaises(ConfigurationConflictError, zcml)
+    
+    def test_custom_discriminator(self):
+        zcml = xmlconfig.XMLConfig("test4.zcml", z3c.zcmlhook.tests)
+        zcml()
+        self.assertEquals(['test_fn1', 'test_fn1'], testState.executions)
+    
+def test_suite():
+    import unittest
+    return unittest.defaultTestLoader.loadTestsFromName(__name__)

Added: z3c.zcmlhook/trunk/src/z3c/zcmlhook/zcml.py
===================================================================
--- z3c.zcmlhook/trunk/src/z3c/zcmlhook/zcml.py	                        (rev 0)
+++ z3c.zcmlhook/trunk/src/z3c/zcmlhook/zcml.py	2010-01-02 12:44:27 UTC (rev 107543)
@@ -0,0 +1,41 @@
+from zope.interface import Interface
+from zope import schema
+from zope.configuration.fields import GlobalObject
+
+class ICustomActionDirective(Interface):
+    
+    handler = GlobalObject(
+            title=u"Function to execute",
+            description=u"This function will be executed during ZCML processing",
+            default=None,
+            required=True,
+        )
+    
+    order = schema.Int(
+            title=u"Execution order",
+            description=u"Set to a high number to execute late, or a negative number to execute early",
+            default=0,
+            required=False,
+        )
+    
+    discriminator = schema.ASCIILine(
+            title=u"Custom discriminator",
+            description=u"By default, the full dotted name to the handler "
+                        u"function is used as the discriminator. If you want "
+                        u"to use the same function more than once, or if you "
+                        u"want to override a custom action defined elsewhere "
+                        u"with an overrides.zcml, you can set the "
+                        u"discriminator explicitly.",
+            default=None,
+            required=False,
+        )
+
+def customAction(_context, handler, order=0, discriminator=None):
+    if discriminator is None:
+        discriminator = "%s.%s" % (handler.__module__, handler.__name__,)
+    
+    _context.action(
+            discriminator=("executeCustomFunction", discriminator),
+            callable=handler,
+            args=(),
+            order=order)



More information about the checkins mailing list