diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-09-16 18:25:31 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-09-16 18:25:31 +0000 |
| commit | 470737a5f5a7d86b809b260b9dbc09f266d4b69c (patch) | |
| tree | a3df44da970fe2e8db956b105acfc228f0319c9c | |
| parent | 6eca545a5571618bd7498fa68571d8e0e21fecf1 (diff) | |
| download | pyramid-470737a5f5a7d86b809b260b9dbc09f266d4b69c.tar.gz pyramid-470737a5f5a7d86b809b260b9dbc09f266d4b69c.tar.bz2 pyramid-470737a5f5a7d86b809b260b9dbc09f266d4b69c.zip | |
- The ``repoze.bfg.testing.registerDummyRenderer`` API has been
deprecated in favor of
``repoze.bfg.testing.registerTemplateRenderer``. A deprecation
warning is *not* issued at import time for the former name; it will
exist "forever".
- The ``repoze.bfg.templating.renderer_from_cache`` function has been
moved to ``repoze.bfg.renderer.template_renderer_factory``. This
was never an API, but code in the wild was spotted that used it. A
deprecation warning is issued at import time for the former.
- Better error message when a wrapper view returns None.
| -rw-r--r-- | CHANGES.txt | 100 | ||||
| -rw-r--r-- | docs/api/testing.rst | 2 | ||||
| -rw-r--r-- | docs/narr/unittesting.rst | 6 | ||||
| -rw-r--r-- | repoze/bfg/testing.py | 16 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_testing.py | 8 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_zcml.py | 13 | ||||
| -rw-r--r-- | repoze/bfg/zcml.py | 16 |
7 files changed, 107 insertions, 54 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 6a9f76a7f..1d9e0c27f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,37 +1,20 @@ Next release ============ -- When used under Python < 2.6, BFG now has an installation time - dependency on the ``simplejson`` package. - -- The previous release (1.1a2) added a view configuration attribute - named ``template``. In this release, the attribute has been renamed - to ``renderer``. This signifies that the attribute is more generic: - it can now be not just a template name but any renderer name (ala - ``json``). A "renderer" is an object which accepts the return value - of a view and converts it to a string. This includes, but is not - limited to, templating systems. - -- In the previous release (1.1a2), the Chameleon text template - renderer was used if the system didn't associate the ``template`` - view configuration value with a filename with a "known" extension. - In this release, you must use a ``renderer`` attribute which is a - path that ends with a ``.txt`` extension - (e.g. ``templates/foo.txt``) to use the Chameleon text renderer. +Documentation +------------- -- The ``ITemplateRenderer`` interface has been changed. Previously - its ``__call__`` method accepted ``**kw``. It now accepts a single - positional parameter named ``kw``. +- The "Views" narrative chapter in the documentation has been updated + extensively to discuss "renderers". -- The ``ITemplateRendererFactory`` interface has been changed. - Previously its ``__call__`` method accepted an ``auto_reload`` - keyword parameter. Now it accepts no keyword parameters. Renderers - are now themselves responsible for determining details of - auto-reload. +Features +-------- -- The ``templating`` module has been removed. The bulk of its - functionality has been moved to a different module named - ``renderers``. +- A ``renderer`` attribute has been added to view configurations, + replacing the previous (1.1a2) version's ``template`` attribute. A + "renderer" is an object which accepts the return value of a view and + converts it to a string. This includes, but is not limited to, + templating systems. - A new interface named ``IRenderer`` was added. The existing interface, ``ITemplateRenderer`` now derives from this new @@ -41,9 +24,6 @@ Next release interface named ``ITemplateRenderer`` now derives from this interface. This interface is internal. -- The "Views" narrative chapter in the documentation has been updated - extensively to discuss "renderers". - - The ``view`` attribute of the ``view`` ZCML directive is no longer required if the ZCML directive also has a ``renderer`` attribute. This is useful when the renderer is a template renderer and no names @@ -52,9 +32,6 @@ Next release - A new zcml directive ``renderer`` has been added. It is documented in the "Views" narrative chapter of the documentation. -- The ``template_renderer`` ZCML directive introduced in 1.1a2 has - been removed. It has been replaced by the ``renderer`` directive. - - A ZCML ``view`` directive (and the associated ``bfg_view`` decorator) can now accept a "wrapper" value. If a "wrapper" value is supplied, it is the value of a separate view's *name* attribute. @@ -69,6 +46,61 @@ Next release between views using only ZCML or decorators (as opposed always using ZPT METAL and analogues to wrap view renderings in outer wrappers). +Dependencies +------------ + +- When used under Python < 2.6, BFG now has an installation time + dependency on the ``simplejson`` package. + +Deprecations +------------ + +- The ``repoze.bfg.testing.registerDummyRenderer`` API has been + deprecated in favor of + ``repoze.bfg.testing.registerTemplateRenderer``. A deprecation + warning is *not* issued at import time for the former name; it will + exist "forever". + +- The ``repoze.bfg.templating.renderer_from_cache`` function has been + moved to ``repoze.bfg.renderer.template_renderer_factory``. This + was never an API, but code in the wild was spotted that used it. A + deprecation warning is issued at import time for the former. + +Backwards Incompatibilities +--------------------------- + +- The ``ITemplateRenderer`` interface has been changed. Previously + its ``__call__`` method accepted ``**kw``. It now accepts a single + positional parameter named ``kw``. This is mostly an internal + change, but it was exposed in APIs in one place: if you've used the + ``repoze.bfg.testing.registerDummyRenderer`` API in your tests with + a custom "renderer" argument with your own renderer implementation, + you will need to change that renderer implementation to accept + ``kw`` instead of ``**kw`` in its ``__call__`` method. + +- The ``ITemplateRendererFactory`` interface has been changed. + Previously its ``__call__`` method accepted an ``auto_reload`` + keyword parameter. Now its ``__call__`` method accepts no keyword + parameters. Renderers are now themselves responsible for + determining details of auto-reload. This is purely an internal + change. This interface was never external. + +- The ``template_renderer`` ZCML directive introduced in 1.1a2 has + been removed. It has been replaced by the ``renderer`` directive. + +- The previous release (1.1a2) added a view configuration attribute + named ``template``. In this release, the attribute has been renamed + to ``renderer``. This signifies that the attribute is more generic: + it can now be not just a template name but any renderer name (ala + ``json``). + +- In the previous release (1.1a2), the Chameleon text template + renderer was used if the system didn't associate the ``template`` + view configuration value with a filename with a "known" extension. + In this release, you must use a ``renderer`` attribute which is a + path that ends with a ``.txt`` extension + (e.g. ``templates/foo.txt``) to use the Chameleon text renderer. + 1.1a2 (2009-09-14) ================== diff --git a/docs/api/testing.rst b/docs/api/testing.rst index 7870ed1d3..80342e0f6 100644 --- a/docs/api/testing.rst +++ b/docs/api/testing.rst @@ -11,7 +11,7 @@ .. autofunction:: registerEventListener - .. autofunction:: registerDummyRenderer + .. autofunction:: registerTemplateRenderer .. autofunction:: registerView diff --git a/docs/narr/unittesting.rst b/docs/narr/unittesting.rst index 22a36318a..064be4739 100644 --- a/docs/narr/unittesting.rst +++ b/docs/narr/unittesting.rst @@ -57,7 +57,7 @@ unittest TestCase that used the testing API. def test_view_fn_not_submitted(self): from my.package import view_fn - renderer = testing.registerDummyRenderer('templates/show.pt') + renderer = testing.registerTemplateRenderer('templates/show.pt') context = testing.DummyModel() request = testing.DummyRequest() response = view_fn(context, request) @@ -65,7 +65,7 @@ unittest TestCase that used the testing API. def test_view_fn_submitted(self): from my.package import view_fn - renderer = testing.registerDummyRenderer('templates/submitted.pt') + renderer = testing.registerTemplateRenderer('templates/submitted.pt') context = testing.DummyModel() request = testing.DummyRequest() request.params['say'] = 'Yo' @@ -81,7 +81,7 @@ The first test method, ``test_view_fn_not_submitted`` tests the ``view_fn`` function in the case that no "form" values (represented by request.params) have been submitted. Its first line registers a "dummy template renderer" named ``templates/show.pt`` via the -``registerDummyRenderer`` function (a ``repoze.bfg.testing`` API); +``registerTemplateRenderer`` function (a ``repoze.bfg.testing`` API); this function returns a DummyTemplateRenderer instance which we hang on to for later. We then create a ``DummyRequest`` object (it simulates a WebOb request object), and we create a ``DummyModel`` diff --git a/repoze/bfg/testing.py b/repoze/bfg/testing.py index bdf60de40..7b694b242 100644 --- a/repoze/bfg/testing.py +++ b/repoze/bfg/testing.py @@ -69,11 +69,11 @@ def registerEventListener(event_iface=Interface): registerSubscriber(subscriber, event_iface) return L -def registerDummyRenderer(path, renderer=None): - """ Register a 'renderer' at ``path`` (usually a relative filename - ala ``templates/foo.pt``) and return the renderer object. If the - ``renderer`` argument is None, a 'dummy' renderer will be used. - This function is useful when testing code that calls the +def registerTemplateRenderer(path, renderer=None): + """ Register a 'template renderer' at ``path`` (usually a relative + filename ala ``templates/foo.pt``) and return the renderer object. + If the ``renderer`` argument is None, a 'dummy' renderer will be + used. This function is useful when testing code that calls the ``render_template_to_response`` or any other ``render_template*`` API of any of the built-in templating systems.""" from repoze.bfg.interfaces import ITemplateRenderer @@ -81,6 +81,10 @@ def registerDummyRenderer(path, renderer=None): renderer = DummyTemplateRenderer() return registerUtility(renderer, ITemplateRenderer, path) +# registerDummyRenderer is a deprecated alias that should never be removed +# (far too much usage in the wild) +registerDummyRenderer = registerTemplateRenderer + def registerView(name, result='', view=None, for_=(Interface, Interface), permission=None): """ Registers ``repoze.bfg`` view function under the name @@ -251,7 +255,7 @@ class DummySecurityPolicy: class DummyTemplateRenderer: """ An instance of this class is returned from - ``registerDummyRenderer``. It has a helper function (``assert_``) + ``registerTemplateRenderer``. It has a helper function (``assert_``) that makes it possible to make an assertion which compares data passed to the renderer by the view function against expected key/value pairs. diff --git a/repoze/bfg/tests/test_testing.py b/repoze/bfg/tests/test_testing.py index f479106ce..6c6b55337 100644 --- a/repoze/bfg/tests/test_testing.py +++ b/repoze/bfg/tests/test_testing.py @@ -54,20 +54,20 @@ class TestTestingFunctions(unittest.TestCase): from repoze.bfg.traversal import find_model self.assertEqual(find_model(None, '/ob1'), ob1) - def test_registerDummyRenderer(self): + def test_registerTemplateRenderer(self): from repoze.bfg import testing - renderer = testing.registerDummyRenderer('templates/foo') + renderer = testing.registerTemplateRenderer('templates/foo') from repoze.bfg.testing import DummyTemplateRenderer self.failUnless(isinstance(renderer, DummyTemplateRenderer)) from repoze.bfg.chameleon_zpt import render_template_to_response response = render_template_to_response('templates/foo', foo=1, bar=2) self.assertEqual(dict(foo=1, bar=2), renderer._received) - def test_registerDummyRenderer_explicitrenderer(self): + def test_registerTemplateRenderer_explicitrenderer(self): from repoze.bfg import testing def renderer(kw): raise ValueError - renderer = testing.registerDummyRenderer('templates/foo', renderer) + renderer = testing.registerTemplateRenderer('templates/foo', renderer) from repoze.bfg.chameleon_zpt import render_template_to_response self.assertRaises(ValueError, render_template_to_response, 'templates/foo', foo=1, bar=2) diff --git a/repoze/bfg/tests/test_zcml.py b/repoze/bfg/tests/test_zcml.py index 21d55504d..7af9ab193 100644 --- a/repoze/bfg/tests/test_zcml.py +++ b/repoze/bfg/tests/test_zcml.py @@ -1376,7 +1376,8 @@ class TestDeriveView(unittest.TestCase): return Response('outer ' + request.wrapped_body) sm = getSiteManager() sm.registerAdapter(outer_view, (None, None), IView, 'owrap') - result = self._callFUT(inner_view, wrapper_viewname='owrap') + result = self._callFUT(inner_view, viewname='inner', + wrapper_viewname='owrap') self.failIf(result is inner_view) self.assertEqual(inner_view.__module__, result.__module__) self.assertEqual(inner_view.__doc__, result.__doc__) @@ -1384,6 +1385,16 @@ class TestDeriveView(unittest.TestCase): response = result(None, request) self.assertEqual(response.body, 'outer OK') + def test_view_with_wrapper_viewname_notfound(self): + from webob import Response + inner_response = Response('OK') + def inner_view(context, request): + return inner_response + request = DummyRequest() + wrapped = self._callFUT( + inner_view, viewname='inner', wrapper_viewname='owrap') + result = self.assertRaises(ValueError, wrapped, None, request) + class TestConnectRouteFunction(unittest.TestCase): def setUp(self): cleanUp() diff --git a/repoze/bfg/zcml.py b/repoze/bfg/zcml.py index 94bb7371d..a9a6a95a0 100644 --- a/repoze/bfg/zcml.py +++ b/repoze/bfg/zcml.py @@ -182,7 +182,7 @@ def view( def register(): derived_view = derive_view(view, permission, predicates, attr, renderer, - wrapper) + wrapper, name) r_for_ = for_ r_request_type = request_type if r_for_ is None: @@ -252,15 +252,15 @@ def forbidden(_context, view): view_utility(_context, view, IForbiddenView) def derive_view(original_view, permission=None, predicates=(), attr=None, - renderer=None, wrapper_viewname=None): + renderer=None, wrapper_viewname=None, viewname=None): mapped_view = map_view(original_view, attr, renderer) - owrapped_view = owrap_view(mapped_view, wrapper_viewname) + owrapped_view = owrap_view(mapped_view, viewname, wrapper_viewname) secured_view = secure_view(owrapped_view, permission) debug_view = authdebug_view(secured_view, permission) derived_view = predicate_wrap(debug_view, predicates) return derived_view -def owrap_view(view, wrapper_viewname): +def owrap_view(view, viewname, wrapper_viewname): if not wrapper_viewname: return view def _owrapped_view(context, request): @@ -268,7 +268,13 @@ def owrap_view(view, wrapper_viewname): request.wrapped_response = response request.wrapped_body = response.body request.wrapped_view = view - return render_view_to_response(context, request, wrapper_viewname) + wrapped_response = render_view_to_response(context, request, + wrapper_viewname) + if wrapped_response is None: + raise ValueError( + 'No wrapper view named %r found when executing view named %r' % + (wrapper_viewname, viewname)) + return wrapped_response decorate_view(_owrapped_view, view) return _owrapped_view |
