diff options
| author | Chris McDonough <chrism@agendaless.com> | 2008-12-21 03:33:08 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2008-12-21 03:33:08 +0000 |
| commit | 4e46a6f458fa31ca5f252dd31b1229fcb775299d (patch) | |
| tree | c0e1edd7cd9aabbec53298b0db3c7868ac73db85 | |
| parent | 6a530543757a92ed09b7ba624a868140f890511d (diff) | |
| download | pyramid-4e46a6f458fa31ca5f252dd31b1229fcb775299d.tar.gz pyramid-4e46a6f458fa31ca5f252dd31b1229fcb775299d.tar.bz2 pyramid-4e46a6f458fa31ca5f252dd31b1229fcb775299d.zip | |
Backwards Incompatibilities (Major)
- Rather than prepare the "stock" implementations of the ZCML
directives from the ``zope.configuration`` package for use under
:mod:`repoze.bfg`, :mod:`repoze.bfg` now makes available the
implementations of directives from the ``repoze.zcml`` package
(see http://static.repoze.org/zcmldocs). As a result, the
:mod:`repoze.bfg` package now depends on the ``repoze.zcml``
package, and no longer depends directly on the ``zope.component``,
``zope.configuration``, ``zope.interface``, or ``zope.proxy``
packages.
The primary reason for this change is to enable us to eventually
reduce the number of inappropriate :mod:`repoze.bfg` Zope package
dependencies, as well as to shed features of dependent package
directives that don't make sense for :mod:`repoze.bfg`.
Note that currently the set of requirements necessary to use bfg
has not changed. This is due to inappropriate Zope package
requirements in ``chameleon.zpt``, which will hopefully be
remedied soon.
- BFG applications written prior to this release which expect the
"stock" ``zope.component`` ZCML directive implementations
(e.g. ``adapter``, ``subscriber``, or ``utility``) to function now
must either 1) include the ``meta.zcml`` file from
``zope.component`` manually (e.g. ``<include
package="zope.component" file="meta.zcml">``) and include the
``zope.security`` package as an ``install_requires`` dependency or
2) change the ZCML in their applications to use the declarations
from `repoze.zcml <http://static.repoze.org/zcmldocs/>`_ instead
of the stock declarations. ``repoze.zcml`` only makes available
the ``adapter``, ``subscriber`` and ``utility`` directives.
- The ``http://namespaces.repoze.org/bfg`` XML namespace is now the
default XML namespace in ZCML for paster-generated applications.
- The copies of BFG's ``meta.zcml`` and ``configure.zcml`` were
removed from the root of the ``repoze.bfg`` package. In 0.3.6, a
new package named ``repoze.bfg.includes`` was added, which
contains the "correct" copies of these ZCML files; the ones that
were removed were for backwards compatibility purposes.
Other
- The minimum requirement for ``chameleon.core`` is now 1.0b13. The
minimum requirement for ``chameleon.zpt`` is now 1.0b7. The
minimum requirement for ``chameleon.genshi`` is now 1.0b2.
27 files changed, 399 insertions, 142 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 28ce65e6f..20dc4e651 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,54 @@ +Next release + + Backwards Incompatibilities (Major) + + - Rather than prepare the "stock" implementations of the ZCML + directives from the ``zope.configuration`` package for use under + :mod:`repoze.bfg`, :mod:`repoze.bfg` now makes available the + implementations of directives from the ``repoze.zcml`` package + (see http://static.repoze.org/zcmldocs). As a result, the + :mod:`repoze.bfg` package now depends on the ``repoze.zcml`` + package, and no longer depends directly on the ``zope.component``, + ``zope.configuration``, ``zope.interface``, or ``zope.proxy`` + packages. + + The primary reason for this change is to enable us to eventually + reduce the number of inappropriate :mod:`repoze.bfg` Zope package + dependencies, as well as to shed features of dependent package + directives that don't make sense for :mod:`repoze.bfg`. + + Note that currently the set of requirements necessary to use bfg + has not changed. This is due to inappropriate Zope package + requirements in ``chameleon.zpt``, which will hopefully be + remedied soon. + + - BFG applications written prior to this release which expect the + "stock" ``zope.component`` ZCML directive implementations + (e.g. ``adapter``, ``subscriber``, or ``utility``) to function now + must either 1) include the ``meta.zcml`` file from + ``zope.component`` manually (e.g. ``<include + package="zope.component" file="meta.zcml">``) and include the + ``zope.security`` package as an ``install_requires`` dependency or + 2) change the ZCML in their applications to use the declarations + from `repoze.zcml <http://static.repoze.org/zcmldocs/>`_ instead + of the stock declarations. ``repoze.zcml`` only makes available + the ``adapter``, ``subscriber`` and ``utility`` directives. + + - The ``http://namespaces.repoze.org/bfg`` XML namespace is now the + default XML namespace in ZCML for paster-generated applications. + + - The copies of BFG's ``meta.zcml`` and ``configure.zcml`` were + removed from the root of the ``repoze.bfg`` package. In 0.3.6, a + new package named ``repoze.bfg.includes`` was added, which + contains the "correct" copies of these ZCML files; the ones that + were removed were for backwards compatibility purposes. + + Other + + - The minimum requirement for ``chameleon.core`` is now 1.0b13. The + minimum requirement for ``chameleon.zpt`` is now 1.0b7. The + minimum requirement for ``chameleon.genshi`` is now 1.0b2. + 0.5.6 (12/18/2008) - Speed up ``traversal.model_url`` execution by using a custom url diff --git a/docs/glossary.rst b/docs/glossary.rst index 92286dfb1..c15f94883 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -240,7 +240,7 @@ Glossary used by Zope and :mod:`repoze.bfg` to describe associating a view with a model type. ZCML is capable of performing many different registrations and declarations, but its primary purpose in - :mod:`repoze.bfg` is to perform view mappings via the ``bfg:view`` + :mod:`repoze.bfg` is to perform view mappings via the ``view`` declaration. The ``configure.zcml`` file in a :mod:`repoze.bfg` application represents the application's :term:`application registry`. See :term:`repoze.bfg.convention` for an alternative @@ -259,7 +259,7 @@ Glossary or a request object in order to identify that the object is "of a type". Interfaces are used internally by :mod:`repoze.bfg` to perform view lookups and security policy lookups. Interfaces are - exposed to application programmers by the ``bfg:view`` ZCML + exposed to application programmers by the ``view`` ZCML directive in the form of both the ``for_`` attribute and the ``request_type`` attribute. They may be exposed to application developers when using the :term:`event` system as diff --git a/docs/narr/MyProject/myproject/configure.zcml b/docs/narr/MyProject/myproject/configure.zcml index 96f51d3c1..584dee906 100644 --- a/docs/narr/MyProject/myproject/configure.zcml +++ b/docs/narr/MyProject/myproject/configure.zcml @@ -1,11 +1,9 @@ -<configure xmlns="http://namespaces.zope.org/zope" - xmlns:bfg="http://namespaces.repoze.org/bfg" - i18n_domain="repoze.bfg"> +<configure xmlns="http://namespaces.repoze.org/bfg"> <!-- this must be included for the view declarations to work --> <include package="repoze.bfg.includes" /> - <bfg:view + <view for=".models.MyModel" view=".views.my_view" /> diff --git a/docs/narr/events.rst b/docs/narr/events.rst index c6242c25d..adb0ae7b0 100644 --- a/docs/narr/events.rst +++ b/docs/narr/events.rst @@ -152,13 +152,13 @@ the same model object. /> <!-- html default view --> - <bfg:view + <view for=".models.MyModel" request_type="repoze.bfg.interfaces.IRequest" view=".views.html_view"/> <!-- JSON default view --> - <bfg:view + <view for=".models.MyModel" request_type=".interfaces.IJSONRequest" view=".views.json_view"/> diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 041fff89d..87eaeae0a 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -50,7 +50,7 @@ For example, the following declaration protects the view named .. code-block:: xml :linenos: - <bfg:view + <view for=".models.IBlog" view=".views.blog_entry_add_view" name="add_entry.html" diff --git a/docs/narr/unittesting.rst b/docs/narr/unittesting.rst index b3b2321dd..165e92411 100644 --- a/docs/narr/unittesting.rst +++ b/docs/narr/unittesting.rst @@ -31,9 +31,9 @@ this view function will result in an error. When a :mod:`repoze.bfg` application starts normally, it will create an application registry from the information it finds in the application's ``configure.zcml`` file. But if this application registry is not created and populated -(e.g. with ``bfg:view`` statements), like when you invoke application -code via a unit test, :mod:`repoze.bfg` API functions will tend to -fail. +(e.g. with ``view`` declarations in ZCML), like when you invoke +application code via a unit test, :mod:`repoze.bfg` API functions will +tend to fail. The testing API provided by ``repoze.bfg`` allows you to simulate various application registry registrations for use under a unit diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index e1f07f88e..7572ddd65 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -134,14 +134,14 @@ call the "fallback" ``get_root`` callable provided to it above. Example 2 --------- -An example of configuring a ``bfg:view`` stanza in ``configure.zcml`` +An example of configuring a ``view`` declaration in ``configure.zcml`` that maps a context found via :term:`Routes` URL dispatch to a view function is as follows: .. code-block:: xml :linenos: - <bfg:view + <view for="repoze.bfg.interfaces.IRoutesContext" view=".views.articles_view" name="articles" diff --git a/docs/narr/views.rst b/docs/narr/views.rst index d61cdb06e..9e2d2887f 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -66,12 +66,12 @@ Mapping Views to URLs You may associate a view with a URL by adding information to your :term:`application registry` via :term:`ZCML` in your -``configure.zcml`` file using a ``bfg:view`` declaration. +``configure.zcml`` file using a ``view`` declaration. .. code-block:: xml :linenos: - <bfg:view + <view for=".models.Hello" view=".views.hello_world" name="hello.html" @@ -83,9 +83,9 @@ Python class represented by ``.models.Hello`` when the *view name* is ``hello.html``. .. note:: Values prefixed with a period (``.``)for the ``for`` and - ``view`` attributes of a ``bfg:view`` (such as those above) mean + ``view`` attributes of a ``view`` (such as those above) mean "relative to the Python package directory in which this - :term:`ZCML` file is stored". So if the above ``bfg:view`` + :term:`ZCML` file is stored". So if the above ``view`` declaration was made inside a ``configure.zcml`` file that lived in the ``hello`` package, you could replace the relative ``.models.Hello`` with the absolute ``hello.models.Hello``; @@ -100,7 +100,7 @@ You can also declare a *default view* for a model type: .. code-block:: xml :linenos: - <bfg:view + <view for=".models.Hello" view=".views.hello_world" /> @@ -115,7 +115,7 @@ the special ``*`` character in the ``for`` attribute: .. code-block:: xml :linenos: - <bfg:view + <view for="*" view=".views.hello_world" name="hello.html" @@ -204,7 +204,7 @@ this interface. .. code-block:: xml :linenos: - <bfg:view + <view for=".models.IHello" view=".views.hello_world" name="hello.html" @@ -223,10 +223,10 @@ implemented by the context, the view registered for the class will See :term:`Interface` in the glossary to find more information about interfaces. -The ``bfg:view`` ZCML Element ------------------------------ +The ``view`` ZCML Element +------------------------- -The ``bfg:view`` ZCML element has these possible attributes: +The ``view`` ZCML element has these possible attributes: view @@ -262,14 +262,14 @@ request_type View Request Types ------------------ -You can optionally add a *request_type* attribute to your ``bfg:view`` +You can optionally add a *request_type* attribute to your ``view`` declaration, which indicates what "kind" of request the view should be used for. For example: .. code-block:: xml :linenos: - <bfg:view + <view for=".models.IHello" view=".views.hello_json" name="hello.json" @@ -325,16 +325,16 @@ View Security ------------- If a :term:`security policy` is active, any :term:`permission` -attached to a ``bfg:view`` declaration will be consulted to ensure +attached to a ``view`` declaration will be consulted to ensure that the currently authenticated user possesses that permission against the context before the view function is actually called. -Here's an example of specifying a permission in a ``bfg:view`` +Here's an example of specifying a permission in a ``view`` declaration: .. code-block:: xml :linenos: - <bfg:view + <view for=".models.IBlog" view=".views.add_entry" name="add.html" diff --git a/docs/tutorials/lxmlgraph/step01/myapp/configure.zcml b/docs/tutorials/lxmlgraph/step01/myapp/configure.zcml index b139396fa..e06023c24 100644 --- a/docs/tutorials/lxmlgraph/step01/myapp/configure.zcml +++ b/docs/tutorials/lxmlgraph/step01/myapp/configure.zcml @@ -1,11 +1,10 @@ -<configure xmlns="http://namespaces.zope.org/zope" - xmlns:bfg="http://namespaces.repoze.org/bfg"> +<configure xmlns="http://namespaces.repoze.org/bfg"> <!-- this must be included for the view declarations to work --> - <include package="repoze.bfg" /> + <include package="repoze.bfg.includes" /> <!-- the default view for a MyModel --> - <bfg:view + <view for=".models.IMyModel" view=".views.my_hello_view" /> diff --git a/docs/tutorials/lxmlgraph/step02/myapp/configure.zcml b/docs/tutorials/lxmlgraph/step02/myapp/configure.zcml index d299dc883..2414ae6b2 100644 --- a/docs/tutorials/lxmlgraph/step02/myapp/configure.zcml +++ b/docs/tutorials/lxmlgraph/step02/myapp/configure.zcml @@ -1,9 +1,8 @@ -<configure xmlns="http://namespaces.zope.org/zope" - xmlns:bfg="http://namespaces.repoze.org/bfg"> +<configure xmlns="http://namespaces.repoze.org/bfg"> - <include package="repoze.bfg" /> + <include package="repoze.bfg.includes" /> - <bfg:view + <view for=".models.IMyModel" view=".views.my_view" /> diff --git a/docs/tutorials/lxmlgraph/step03.rst b/docs/tutorials/lxmlgraph/step03.rst index 0f54f8761..ce88b78c8 100644 --- a/docs/tutorials/lxmlgraph/step03.rst +++ b/docs/tutorials/lxmlgraph/step03.rst @@ -20,14 +20,12 @@ Change your project's ``configure.zcml`` so that it looks like this: .. code-block:: xml - <configure xmlns="http://namespaces.zope.org/zope" - xmlns:bfg="http://namespaces.repoze.org/bfg" - i18n_domain="repoze.bfg"> + <configure xmlns="http://namespaces.repoze.org/bfg"> <!-- this must be included for the view declarations to work --> - <include package="repoze.bfg" /> + <include package="repoze.bfg.includes" /> - <bfg:view + <view for=".models.IMyModel" view=".views.zpt_view" /> diff --git a/docs/tutorials/lxmlgraph/step03/myapp/configure.zcml b/docs/tutorials/lxmlgraph/step03/myapp/configure.zcml index 83d83ab61..43b766cfb 100644 --- a/docs/tutorials/lxmlgraph/step03/myapp/configure.zcml +++ b/docs/tutorials/lxmlgraph/step03/myapp/configure.zcml @@ -1,14 +1,13 @@ -<configure xmlns="http://namespaces.zope.org/zope" - xmlns:bfg="http://namespaces.repoze.org/bfg"> +<configure xmlns="http://namespaces.repoze.org/bfg"> - <include package="repoze.bfg" /> + <include package="repoze.bfg.includes" /> - <bfg:view + <view for=".models.IMyModel" view=".views.zpt_view" /> - <bfg:view + <view for=".models.IMyModel" view=".views.xslt_view" name="xsltview.html" diff --git a/docs/tutorials/lxmlgraph/step04/myapp/configure.zcml b/docs/tutorials/lxmlgraph/step04/myapp/configure.zcml index 1ba4c9155..c2d59effb 100644 --- a/docs/tutorials/lxmlgraph/step04/myapp/configure.zcml +++ b/docs/tutorials/lxmlgraph/step04/myapp/configure.zcml @@ -1,9 +1,8 @@ -<configure xmlns="http://namespaces.zope.org/zope" - xmlns:bfg="http://namespaces.repoze.org/bfg"> +<configure xmlns="http://namespaces.repoze.org/bfg"> - <include package="repoze.bfg" /> + <include package="repoze.bfg.includes" /> - <bfg:view + <view for=".models.IMyModel" view=".views.xslt_view" /> diff --git a/repoze/bfg/configure.zcml b/repoze/bfg/configure.zcml deleted file mode 100644 index 517b5fd54..000000000 --- a/repoze/bfg/configure.zcml +++ /dev/null @@ -1,24 +0,0 @@ -<configure xmlns="http://namespaces.zope.org/zope" - i18n_domain="repoze.bfg"> - - <!-- superseded by includes/configure.zcml --> - - <include package="zope.component" file="meta.zcml" /> - - <include package="chameleon.zpt" file="configure.zcml"/> - - <adapter - factory=".traversal.ModelGraphTraverser" - provides=".interfaces.ITraverserFactory" - for="*" - /> - - <adapter - factory=".urldispatch.RoutesModelTraverser" - provides=".interfaces.ITraverserFactory" - for=".interfaces.IRoutesContext" - /> - - <include file="meta.zcml" /> - -</configure> diff --git a/repoze/bfg/includes/configure.zcml b/repoze/bfg/includes/configure.zcml index e758fb192..6e830e96f 100644 --- a/repoze/bfg/includes/configure.zcml +++ b/repoze/bfg/includes/configure.zcml @@ -1,7 +1,6 @@ -<configure xmlns="http://namespaces.zope.org/zope" - i18n_domain="repoze.bfg"> +<configure xmlns="http://namespaces.repoze.org/bfg"> - <include package="zope.component" file="meta.zcml" /> + <include package="repoze.zcml" file="meta.zcml" /> <include package="chameleon.zpt" file="configure.zcml"/> diff --git a/repoze/bfg/meta.zcml b/repoze/bfg/meta.zcml deleted file mode 100644 index e35184a34..000000000 --- a/repoze/bfg/meta.zcml +++ /dev/null @@ -1,17 +0,0 @@ -<configure - xmlns="http://namespaces.zope.org/zope" - xmlns:meta="http://namespaces.zope.org/meta"> - - <!-- superseded by includes/meta.zcml --> - - <meta:directives namespace="http://namespaces.repoze.org/bfg"> - - <meta:directive - name="view" - schema=".zcml.IViewDirective" - handler=".zcml.view" - /> - - </meta:directives> - -</configure> diff --git a/repoze/bfg/paster_template/+package+/configure.zcml b/repoze/bfg/paster_template/+package+/configure.zcml index 96f51d3c1..584dee906 100644 --- a/repoze/bfg/paster_template/+package+/configure.zcml +++ b/repoze/bfg/paster_template/+package+/configure.zcml @@ -1,11 +1,9 @@ -<configure xmlns="http://namespaces.zope.org/zope" - xmlns:bfg="http://namespaces.repoze.org/bfg" - i18n_domain="repoze.bfg"> +<configure xmlns="http://namespaces.repoze.org/bfg"> <!-- this must be included for the view declarations to work --> <include package="repoze.bfg.includes" /> - <bfg:view + <view for=".models.MyModel" view=".views.my_view" /> diff --git a/repoze/bfg/tests/fixtureapp/another.zcml b/repoze/bfg/tests/fixtureapp/another.zcml index f29e7e59e..c01245656 100644 --- a/repoze/bfg/tests/fixtureapp/another.zcml +++ b/repoze/bfg/tests/fixtureapp/another.zcml @@ -1,8 +1,6 @@ -<configure xmlns="http://namespaces.zope.org/zope" - xmlns:bfg="http://namespaces.repoze.org/bfg" - i18n_domain="repoze.bfg"> +<configure xmlns="http://namespaces.repoze.org/bfg"> - <bfg:view + <view view=".views.fixture_view" for="*" name="another.html" diff --git a/repoze/bfg/tests/fixtureapp/configure.zcml b/repoze/bfg/tests/fixtureapp/configure.zcml index a56c1cbdf..29d7a7329 100644 --- a/repoze/bfg/tests/fixtureapp/configure.zcml +++ b/repoze/bfg/tests/fixtureapp/configure.zcml @@ -1,16 +1,14 @@ -<configure xmlns="http://namespaces.zope.org/zope" - xmlns:bfg="http://namespaces.repoze.org/bfg" - i18n_domain="repoze.bfg"> +<configure xmlns="http://namespaces.repoze.org/bfg"> - <include package="repoze.bfg" /> + <include package="repoze.bfg.includes" /> - <bfg:view + <view view=".views.fixture_view" for=".models.IFixture" permission="repoze.view" /> - <bfg:view + <view view=".views.fixture_view" for=".models.IFixture" name="dummyskin.html" @@ -20,5 +18,4 @@ <include file="another.zcml"/> - </configure> diff --git a/repoze/bfg/tests/test_chameleon_genshi.py b/repoze/bfg/tests/test_chameleon_genshi.py index 8012101f5..3b0c05b34 100644 --- a/repoze/bfg/tests/test_chameleon_genshi.py +++ b/repoze/bfg/tests/test_chameleon_genshi.py @@ -10,9 +10,10 @@ class Base(PlacelessSetup): PlacelessSetup.tearDown(self) def _zcmlConfigure(self): - import repoze.bfg + import repoze.bfg.includes import zope.configuration.xmlconfig - zope.configuration.xmlconfig.file('configure.zcml', package=repoze.bfg) + zope.configuration.xmlconfig.file('configure.zcml', + package=repoze.bfg.includes) def _getTemplatePath(self, name): import os @@ -51,7 +52,8 @@ class GenshiTemplateRendererTests(unittest.TestCase, Base): instance = self._makeOne(minimal) result = instance() self.failUnless(isinstance(result, str)) - self.assertEqual(result, '<div>\n</div>\n') + self.assertEqual(result, + '<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') def test_implementation(self): self._zcmlConfigure() @@ -59,7 +61,8 @@ class GenshiTemplateRendererTests(unittest.TestCase, Base): instance = self._makeOne(minimal) result = instance.implementation()() self.failUnless(isinstance(result, str)) - self.assertEqual(result, '<div>\n</div>\n') + self.assertEqual(result, + '<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') class RenderTemplateTests(unittest.TestCase, Base): def setUp(self): @@ -77,7 +80,8 @@ class RenderTemplateTests(unittest.TestCase, Base): render = self._getFUT() result = render(minimal) self.failUnless(isinstance(result, str)) - self.assertEqual(result, '<div>\n</div>\n') + self.assertEqual(result, + '<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') class RenderTemplateToResponseTests(unittest.TestCase, Base): def setUp(self): @@ -96,7 +100,8 @@ class RenderTemplateToResponseTests(unittest.TestCase, Base): result = render(minimal) from webob import Response self.failUnless(isinstance(result, Response)) - self.assertEqual(result.app_iter, ['<div>\n</div>\n']) + self.assertEqual(result.app_iter, + ['<div xmlns="http://www.w3.org/1999/xhtml">\n</div>']) self.assertEqual(result.status, '200 OK') self.assertEqual(len(result.headerlist), 2) diff --git a/repoze/bfg/tests/test_chameleon_text.py b/repoze/bfg/tests/test_chameleon_text.py index 594c2806f..f61cfe963 100644 --- a/repoze/bfg/tests/test_chameleon_text.py +++ b/repoze/bfg/tests/test_chameleon_text.py @@ -10,9 +10,10 @@ class Base: cleanUp() def _zcmlConfigure(self): - import repoze.bfg + import repoze.bfg.includes import zope.configuration.xmlconfig - zope.configuration.xmlconfig.file('configure.zcml', package=repoze.bfg) + zope.configuration.xmlconfig.file('configure.zcml', + package=repoze.bfg.includes) def _getTemplatePath(self, name): import os diff --git a/repoze/bfg/tests/test_chameleon_zpt.py b/repoze/bfg/tests/test_chameleon_zpt.py index d2ee1704f..995dd92e1 100644 --- a/repoze/bfg/tests/test_chameleon_zpt.py +++ b/repoze/bfg/tests/test_chameleon_zpt.py @@ -10,9 +10,10 @@ class Base(PlacelessSetup): PlacelessSetup.tearDown(self) def _zcmlConfigure(self): - import repoze.bfg + import repoze.bfg.includes import zope.configuration.xmlconfig - zope.configuration.xmlconfig.file('configure.zcml', package=repoze.bfg) + zope.configuration.xmlconfig.file('configure.zcml', + package=repoze.bfg.includes) def _getTemplatePath(self, name): import os @@ -51,7 +52,8 @@ class ZPTTemplateRendererTests(unittest.TestCase, Base): instance = self._makeOne(minimal) result = instance() self.failUnless(isinstance(result, str)) - self.assertEqual(result, '<div>\n</div>\n') + self.assertEqual(result, + '<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') def test_implementation(self): self._zcmlConfigure() @@ -59,7 +61,8 @@ class ZPTTemplateRendererTests(unittest.TestCase, Base): instance = self._makeOne(minimal) result = instance.implementation()() self.failUnless(isinstance(result, str)) - self.assertEqual(result, '<div>\n</div>\n') + self.assertEqual(result, + '<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') class RenderTemplateTests(unittest.TestCase, Base): @@ -79,7 +82,8 @@ class RenderTemplateTests(unittest.TestCase, Base): render = self._getFUT() result = render(minimal) self.failUnless(isinstance(result, str)) - self.assertEqual(result, '<div>\n</div>\n') + self.assertEqual(result, + '<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') class RenderTemplateToResponseTests(unittest.TestCase, Base): def setUp(self): @@ -99,7 +103,8 @@ class RenderTemplateToResponseTests(unittest.TestCase, Base): result = render(minimal) from webob import Response self.failUnless(isinstance(result, Response)) - self.assertEqual(result.app_iter, ['<div>\n</div>\n']) + self.assertEqual(result.app_iter, + ['<div xmlns="http://www.w3.org/1999/xhtml">\n</div>']) self.assertEqual(result.status, '200 OK') self.assertEqual(len(result.headerlist), 2) diff --git a/repoze/bfg/tests/test_push.py b/repoze/bfg/tests/test_push.py index e8d257c03..83f02850b 100644 --- a/repoze/bfg/tests/test_push.py +++ b/repoze/bfg/tests/test_push.py @@ -10,9 +10,10 @@ class Test_pushpage(unittest.TestCase, PlacelessSetup): PlacelessSetup.tearDown(self) def _zcmlConfigure(self): - import repoze.bfg + import repoze.bfg.includes import zope.configuration.xmlconfig - zope.configuration.xmlconfig.file('configure.zcml', package=repoze.bfg) + zope.configuration.xmlconfig.file('configure.zcml', + package=repoze.bfg.includes) def _getTargetClass(self): from repoze.bfg.push import pushpage @@ -32,7 +33,8 @@ class Test_pushpage(unittest.TestCase, PlacelessSetup): pp = self._makeOne('pp.pt') wrapped = pp(to_wrap) response = wrapped(object(), object()) - self.assertEqual(response.body, '<p>WRAPPED</p>\n') + self.assertEqual(response.body, + '<p xmlns="http://www.w3.org/1999/xhtml">WRAPPED</p>') def to_wrap(context, request): return {'wrapped': 'WRAPPED'} diff --git a/repoze/bfg/tests/test_template.py b/repoze/bfg/tests/test_template.py index f66d045cd..31aa074d8 100644 --- a/repoze/bfg/tests/test_template.py +++ b/repoze/bfg/tests/test_template.py @@ -14,9 +14,10 @@ class Base(PlacelessSetup): PlacelessSetup.tearDown(self) def _zcmlConfigure(self): - import repoze.bfg + import repoze.bfg.includes import zope.configuration.xmlconfig - zope.configuration.xmlconfig.file('configure.zcml', package=repoze.bfg) + zope.configuration.xmlconfig.file('configure.zcml', + package=repoze.bfg.includes) def _getTemplatePath(self, name): import os @@ -40,7 +41,8 @@ class RenderTemplateTests(unittest.TestCase, Base): render = self._getFUT() result = render(minimal) self.failUnless(isinstance(result, str)) - self.assertEqual(result, '<div>\n</div>\n') + self.assertEqual(result, + '<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') class RenderTemplateToResponseTests(unittest.TestCase, Base): def setUp(self): @@ -60,7 +62,8 @@ class RenderTemplateToResponseTests(unittest.TestCase, Base): result = render(minimal) from webob import Response self.failUnless(isinstance(result, Response)) - self.assertEqual(result.app_iter, ['<div>\n</div>\n']) + self.assertEqual(result.app_iter, + ['<div xmlns="http://www.w3.org/1999/xhtml">\n</div>']) self.assertEqual(result.status, '200 OK') self.assertEqual(len(result.headerlist), 2) diff --git a/repoze/bfg/tests/test_xslt.py b/repoze/bfg/tests/test_xslt.py index 66e268331..cff33457a 100644 --- a/repoze/bfg/tests/test_xslt.py +++ b/repoze/bfg/tests/test_xslt.py @@ -10,9 +10,10 @@ class Base(PlacelessSetup): PlacelessSetup.tearDown(self) def _zcmlConfigure(self): - import repoze.bfg + import repoze.bfg.includes import zope.configuration.xmlconfig - zope.configuration.xmlconfig.file('configure.zcml', package=repoze.bfg) + zope.configuration.xmlconfig.file('configure.zcml', + package=repoze.bfg.includes) def _getTemplatePath(self, name): import os diff --git a/repoze/bfg/zcml.py b/repoze/bfg/zcml.py index 79d4c2561..91f5d9152 100644 --- a/repoze/bfg/zcml.py +++ b/repoze/bfg/zcml.py @@ -128,6 +128,246 @@ class IViewDirective(Interface): required=False ) +def adapter(_context, factory, provides=None, for_=None, name=''): + + if for_ is None: + if len(factory) == 1: + for_ = zope.component.adaptedBy(factory[0]) + + if for_ is None: + raise TypeError("No for attribute was provided and can't " + "determine what the factory adapts.") + + for_ = tuple(for_) + + if provides is None: + if len(factory) == 1: + p = list(zope.interface.implementedBy(factory[0])) + if len(p) == 1: + provides = p[0] + + if provides is None: + raise TypeError("Missing 'provides' attribute") + + # Generate a single factory from multiple factories: + factories = factory + if len(factories) == 1: + factory = factories[0] + elif len(factories) < 1: + raise ValueError("No factory specified") + elif len(factories) > 1 and len(for_) != 1: + raise ValueError("Can't use multiple factories and multiple for") + else: + factory = _rolledUpFactory(factories) + + _context.action( + discriminator = ('adapter', for_, provides, name), + callable = handler, + args = ('registerAdapter', + factory, for_, provides, name, _context.info), + ) + _context.action( + discriminator = None, + callable = provideInterface, + args = ('', provides) + ) + if for_: + for iface in for_: + if iface is not None: + _context.action( + discriminator = None, + callable = provideInterface, + args = ('', iface) + ) + +class IAdapterDirective(zope.interface.Interface): + """ + Register an adapter + """ + + factory = zope.configuration.fields.Tokens( + title=u"Adapter factory/factories", + description=(u"A list of factories (usually just one) that create" + " the adapter instance."), + required=True, + value_type=zope.configuration.fields.GlobalObject() + ) + + provides = zope.configuration.fields.GlobalInterface( + title=u"Interface the component provides", + description=(u"This attribute specifies the interface the adapter" + " instance must provide."), + required=False, + ) + + for_ = zope.configuration.fields.Tokens( + title=u"Specifications to be adapted", + description=u"This should be a list of interfaces or classes", + required=False, + value_type=zope.configuration.fields.GlobalObject( + missing_value=object(), + ), + ) + + name = zope.schema.TextLine( + title=u"Name", + description=(u"Adapters can have names.\n\n" + "This attribute allows you to specify the name for" + " this adapter."), + required=False, + ) + +_handler = handler +def subscriber(_context, for_=None, factory=None, handler=None, provides=None): + if factory is None: + if handler is None: + raise TypeError("No factory or handler provided") + if provides is not None: + raise TypeError("Cannot use handler with provides") + factory = handler + else: + if handler is not None: + raise TypeError("Cannot use handler with factory") + if provides is None: + raise TypeError( + "You must specify a provided interface when registering " + "a factory") + + if for_ is None: + for_ = zope.component.adaptedBy(factory) + if for_ is None: + raise TypeError("No for attribute was provided and can't " + "determine what the factory (or handler) adapts.") + + for_ = tuple(for_) + + if handler is not None: + _context.action( + discriminator = None, + callable = _handler, + args = ('registerHandler', + handler, for_, u'', _context.info), + ) + else: + _context.action( + discriminator = None, + callable = _handler, + args = ('registerSubscriptionAdapter', + factory, for_, provides, u'', _context.info), + ) + + if provides is not None: + _context.action( + discriminator = None, + callable = provideInterface, + args = ('', provides) + ) + + # For each interface, state that the adapter provides that interface. + for iface in for_: + if iface is not None: + _context.action( + discriminator = None, + callable = provideInterface, + args = ('', iface) + ) + +class ISubscriberDirective(zope.interface.Interface): + """ + Register a subscriber + """ + + factory = zope.configuration.fields.GlobalObject( + title=u"Subscriber factory", + description=u"A factory used to create the subscriber instance.", + required=False, + ) + + handler = zope.configuration.fields.GlobalObject( + title=u"Handler", + description=u"A callable object that handles events.", + required=False, + ) + + provides = zope.configuration.fields.GlobalInterface( + title=u"Interface the component provides", + description=(u"This attribute specifies the interface the adapter" + " instance must provide."), + required=False, + ) + + for_ = zope.configuration.fields.Tokens( + title=u"Interfaces or classes that this subscriber depends on", + description=u"This should be a list of interfaces or classes", + required=False, + value_type=zope.configuration.fields.GlobalObject( + missing_value = object(), + ), + ) + +def utility(_context, provides=None, component=None, factory=None, name=''): + if factory and component: + raise TypeError("Can't specify factory and component.") + + if provides is None: + if factory: + provides = list(zope.interface.implementedBy(factory)) + else: + provides = list(zope.interface.providedBy(component)) + if len(provides) == 1: + provides = provides[0] + else: + raise TypeError("Missing 'provides' attribute") + + _context.action( + discriminator = ('utility', provides, name), + callable = handler, + args = ('registerUtility', component, provides, name), + kw = dict(factory=factory), + ) + + _context.action( + discriminator = None, + callable = provideInterface, + args = (provides.__module__ + '.' + provides.getName(), provides) + ) + +class IUtilityDirective(Interface): + """Register a utility.""" + + component = zope.configuration.fields.GlobalObject( + title=u"Component to use", + description=(u"Python name of the implementation object. This" + " must identify an object in a module using the" + " full dotted name. If specified, the" + " ``factory`` field must be left blank."), + required=False, + ) + + factory = zope.configuration.fields.GlobalObject( + title=u"Factory", + description=(u"Python name of a factory which can create the" + " implementation object. This must identify an" + " object in a module using the full dotted name." + " If specified, the ``component`` field must" + " be left blank."), + required=False, + ) + + provides = zope.configuration.fields.GlobalInterface( + title=u"Provided interface", + description=u"Interface provided by the utility.", + required=False, + ) + + name = zope.schema.TextLine( + title=u"Name", + description=(u"Name of the registration. This is used by" + " application code when locating a utility."), + required=False, + ) + + PVERSION = 1 def pickle_name(name, package): @@ -216,4 +456,13 @@ def file_configure(name, package, dump=cPickle.dump): return False - +def _rolledUpFactory(factories): + # This has to be named 'factory', aparently, so as not to confuse + # apidoc :( + def factory(ob): + for f in factories: + ob = f(ob) + return ob + # Store the original factory for documentation + factory.factory = factories[0] + return factory @@ -12,7 +12,7 @@ # ############################################################################## -__version__ = '0.5.6' +__version__ = '0.6.0' import os @@ -29,18 +29,15 @@ except IOError: README = CHANGES = '' install_requires=[ - 'chameleon.core [lxml]', - 'chameleon.genshi', - 'chameleon.zpt', + 'chameleon.core [lxml] >= 1.0b13', + 'chameleon.genshi >= 1.0b2', + 'chameleon.zpt >= 1.0b7', 'PasteScript', 'Routes', 'setuptools', 'WebOb', - 'zope.component', - 'zope.configuration', + 'repoze.zcml', 'zope.hookable', - 'zope.interface', - 'zope.proxy', 'zope.testing', ] |
