From bc857e7e6e71a4001f03c608a18bac7dab36ccff Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 17 Dec 2009 16:00:02 +0000 Subject: Features -------- - The ``Configurator`` object now has two new methods: ``begin`` and ``end``. The ``begin`` method is meant to be called before any "configuration" begins (e.g. before ``add_view``, et. al are called). The ``end`` method is meant to be called after all "configuration" is complete. Previously, before there was imperative configuration at all (1.1 and prior), configuration begin and end was invariably implied by the process of loading a ZCML file. When a ZCML load happened, the threadlocal data structure containing the request and registry was modified before the load, and torn down after the load, making sure that all framework code that needed ``get_current_registry`` for the duration of the ZCML load was satisfied. Some API methods called during imperative configuration, (such as ``Configurator.add_view`` when a renderer is involved) end up for historical reasons calling ``get_current_registry``. However, in 1.2a5 and below, the Configurator supplied no functionality that allowed people to make sure that ``get_current_registry`` returned the registry implied by the configurator being used. ``begin`` now serves this purpose. Inversely, ``end`` pops the thread local stack, undoing the actions of ``begin``. We make this boundary explicit to reduce the potential for confusion when the configurator is used in different circumstances (e.g. in unit tests and app code vs. just in initial app setup). Existing code written for 1.2a1-1.2a5 which does not call ``begin`` or ``end`` continues to work in the same manner it did before. It is however suggested that this code be changed to call ``begin`` and ``end`` to reduce the potential for confusion in the future. - All ``paster`` templates which generate an application skeleton now make use of the new ``begin`` and ``end`` methods of the Configurator they use in their respective copies of ``run.py`` and ``tests.py``. Documentation ------------- - All documentation that makes use of a ``Configurator`` object to do application setup and test setup now makes use of the new ``begin`` and ``end`` methods of the configurator. Bug Fixes --------- - When a ``repoze.bfg.exceptions.NotFound`` or ``repoze.bfg.exceptions.Forbidden`` *class* (as opposed to instance) was raised as an exception within a root factory (or route root factory), the exception would not be caught properly by the ``repoze.bfg.`` Router and it would propagate to up the call stack, as opposed to rendering the not found view or the forbidden view as would have been expected. --- docs/narr/configuration.rst | 67 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 8 deletions(-) (limited to 'docs/narr/configuration.rst') diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index 9e7c75005..367df2a2d 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -86,8 +86,10 @@ imperatively: if __name__ == '__main__': config = Configurator() + config.begin() config.add_view(hello_world) config.add_view(goodbye_world, name='goodbye') + config.end() app = config.make_wsgi_app() serve(app) @@ -274,12 +276,17 @@ imports and function definitions is placed within the confines of an if __name__ == '__main__': config = Configurator() + config.begin() config.add_view(hello_world) config.add_view(goodbye_world, name='goodbye') + config.end() app = config.make_wsgi_app() simple_server.make_server('', 8080, app).serve_forever() -Let's break this down this piece-by-piece: +Let's break this down this piece-by-piece. + +Configurator Construction +~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: python :linenos: @@ -315,6 +322,27 @@ this particular :mod:`repoze.bfg` application. registry object being configured by a ``Configurator`` is available as its ``registry`` attribute. +Beginning Configuration +~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + :linenos: + + config.begin() + +The ``begin`` method of a Configurator tells the the system that +application configuration has begun. In particular, this causes the +:term:`application registry` associated with this configurator to +become the "current" application registry, meaning that code which +attempts to use the application registry :term:`thread local` will +obtain the registry associated with the configurator. This is an +explicit step because it's sometimes convenient to use a configurator +without causing the registry associated with the configurator to +become "current". + +Adding Configuration +~~~~~~~~~~~~~~~~~~~~ + .. code-block:: python :linenos: @@ -411,6 +439,22 @@ the best view configuration for any request, the ``goodbye_world`` view callable will be used when the URL contains path information that ends with ``/goodbye``. +Ending Configuration +~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + :linenos: + + config.end() + +The ``end`` method of a Configurator tells the the system that +application configuration has ended. It is the inverse of +``config.begin``. In particular, this causes the :term:`application +registry` associated with this configurator to no longer be the +"current" application registry, meaning that code which attempts to +use the application registry :term:`thread local` will no longer +obtain the registry associated with the configurator. + WSGI Application Creation ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -419,13 +463,14 @@ WSGI Application Creation app = config.make_wsgi_app() -After configuring views, the script creates a WSGI *application* via -the ``config.make_wsgi_app`` method. A call to ``make_wsgi_app`` -implies that all configuration is finished (meaning all method calls -to the configurator which set up views, and various other -configuration settings have been performed). The ``make_wsgi_app`` -method returns a :term:`WSGI` application object that can be used by -any WSGI server to present an application to a requestor. +After configuring views and ending configuration, the script creates a +WSGI *application* via the ``config.make_wsgi_app`` method. A call to +``make_wsgi_app`` implies that all configuration is finished (meaning +all method calls to the configurator which set up views, and various +other configuration settings have been performed). The +``make_wsgi_app`` method returns a :term:`WSGI` application object +that can be used by any WSGI server to present an application to a +requestor. The :mod:`repoze.bfg` application object, in particular, is an instance of the ``repoze.bfg.router.Router`` class. It has a @@ -510,7 +555,9 @@ In a file named ``helloworld.py``: if __name__ == '__main__': config = Configurator() + config.begin() config.load_zcml('configure.zcml) + config.end() app = config.make_wsgi_app() serve(app) @@ -547,8 +594,10 @@ within the ``if __name__ == '__main__'`` section of ``helloworld.py``: if __name__ == '__main__': config = Configurator() + config.begin() config.add_view(hello_world) config.add_view(goodbye_world, name='goodbye') + config.end() app = config.make_wsgi_app() simple_server.make_server('', 8080, app).serve_forever() @@ -563,7 +612,9 @@ reads as: if __name__ == '__main__': config = Configurator() + config.begin() config.load_zcml('configure.zcml') + config.end() app = config.make_wsgi_app() simple_server.make_server('', 8080, app).serve_forever() -- cgit v1.2.3