summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/api/configuration.rst4
-rw-r--r--docs/glossary.rst12
-rw-r--r--docs/narr/MyProject/myproject/run.py2
-rw-r--r--docs/narr/MyProject/myproject/tests.py6
-rw-r--r--docs/narr/configuration.rst67
-rw-r--r--docs/narr/project.rst2
-rw-r--r--docs/narr/threadlocals.rst14
-rw-r--r--docs/narr/unittesting.rst122
-rw-r--r--docs/tutorials/bfgwiki/src/authorization/tutorial/run.py2
-rw-r--r--docs/tutorials/bfgwiki/src/authorization/tutorial/tests.py2
-rw-r--r--docs/tutorials/bfgwiki/src/basiclayout/tutorial/run.py2
-rw-r--r--docs/tutorials/bfgwiki/src/basiclayout/tutorial/tests.py6
-rw-r--r--docs/tutorials/bfgwiki/src/models/tutorial/run.py2
-rw-r--r--docs/tutorials/bfgwiki/src/models/tutorial/tests.py6
-rw-r--r--docs/tutorials/bfgwiki/src/viewdecorators/tutorial/run.py2
-rw-r--r--docs/tutorials/bfgwiki/src/viewdecorators/tutorial/tests.py2
-rw-r--r--docs/tutorials/bfgwiki/src/views/tutorial/run.py2
-rw-r--r--docs/tutorials/bfgwiki/src/views/tutorial/tests.py2
-rw-r--r--docs/tutorials/bfgwiki2/src/authorization/tutorial/run.py2
-rw-r--r--docs/tutorials/bfgwiki2/src/authorization/tutorial/tests.py44
-rw-r--r--docs/tutorials/bfgwiki2/src/basiclayout/tutorial/run.py2
-rw-r--r--docs/tutorials/bfgwiki2/src/basiclayout/tutorial/tests.py6
-rw-r--r--docs/tutorials/bfgwiki2/src/models/tutorial/run.py2
-rw-r--r--docs/tutorials/bfgwiki2/src/models/tutorial/tests.py6
-rw-r--r--docs/tutorials/bfgwiki2/src/views/tutorial/run.py2
-rw-r--r--docs/tutorials/bfgwiki2/src/views/tutorial/tests.py44
-rw-r--r--docs/whatsnew-1.2.rst15
27 files changed, 269 insertions, 111 deletions
diff --git a/docs/api/configuration.rst b/docs/api/configuration.rst
index 376ff3e40..5e16ac13b 100644
--- a/docs/api/configuration.rst
+++ b/docs/api/configuration.rst
@@ -7,6 +7,10 @@
.. autoclass:: Configurator(registry=None, package=None, settings=None, root_factory=None, authentication_policy=None, authorization_policy=None, renderers=DEFAULT_RENDERERS, debug_logger=None)
+ .. automethod:: begin
+
+ .. automethod:: end
+
.. automethod:: add_renderer(name, factory)
.. automethod:: add_route
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 0fa827188..fab733878 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -509,3 +509,15 @@ Glossary
:mod:`repoze.bfg` provides a default implementation of a
forbidden view; it can be overridden. See
:ref:`changing_the_forbidden_view`.
+ Thread Local
+ A thread-local variable is one which is essentially a global
+ variable in terms of how it is accessed and treated, however,
+ each `thread
+ <http://en.wikipedia.org/wiki/Thread_(computer_science)>` used by
+ the application may have a different value for this same "global"
+ variable. :mod:`repoze.bfg` uses a small number of thread local
+ variables, as described in :ref:`threadlocals_chapter`. See also
+ the `threading.local documentation
+ <http://docs.python.org/library/threading.html#threading.local>`
+ for more information.
+
diff --git a/docs/narr/MyProject/myproject/run.py b/docs/narr/MyProject/myproject/run.py
index 0d7647aa7..6a3671c1e 100644
--- a/docs/narr/MyProject/myproject/run.py
+++ b/docs/narr/MyProject/myproject/run.py
@@ -6,8 +6,10 @@ def app(global_config, **settings):
is usually called by the PasteDeploy framework during ``paster
serve``"""
config = Configurator(root_factory=get_root, settings=settings)
+ config.begin()
zcml_file = settings.get('configure_zcml', 'configure.zcml')
config.load_zcml(zcml_file)
+ config.end()
return config.make_wsgi_app()
diff --git a/docs/narr/MyProject/myproject/tests.py b/docs/narr/MyProject/myproject/tests.py
index 7c3caac74..498bd96e8 100644
--- a/docs/narr/MyProject/myproject/tests.py
+++ b/docs/narr/MyProject/myproject/tests.py
@@ -1,13 +1,15 @@
import unittest
+from repoze.bfg.configuration import Configurator
from repoze.bfg import testing
class ViewTests(unittest.TestCase):
def setUp(self):
- testing.setUp()
+ self.config = Configurator()
+ self.config.begin()
def tearDown(self):
- testing.tearDown()
+ self.config.end()
def test_my_view(self):
from myproject.views import my_view
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()
diff --git a/docs/narr/project.rst b/docs/narr/project.rst
index 81e570e36..16879b69b 100644
--- a/docs/narr/project.rst
+++ b/docs/narr/project.rst
@@ -724,7 +724,7 @@ without the PasteDeploy configuration file:
#. Line 2 imports the ``get_root`` function from
:mod:`myproject.models` that we use later.
-#. Lines 4-11 define a function that returns a :mod:`repoze.bfg`
+#. Lines 4-13 define a function that returns a :mod:`repoze.bfg`
WSGI application. This function is meant to be called
by the :term:`PasteDeploy` framework as a result of running
``paster serve``.
diff --git a/docs/narr/threadlocals.rst b/docs/narr/threadlocals.rst
index 476b179ec..b97d9e4f2 100644
--- a/docs/narr/threadlocals.rst
+++ b/docs/narr/threadlocals.rst
@@ -69,10 +69,11 @@ defined entirely by the behavior of a repoze.bfg :term:`Router`.
However, during unit testing, no Router code is ever invoked, and the
definition of "current" is defined by the boundary between calls to
-the ``repoze.bfg.testing.setUp`` and ``repoze.bfg.testing.tearDown``.
-These functions push and pop the threadlocal stack when the system is
-under test. See :ref:`test_setup_and_teardown` for the definitions of
-these functions.
+the ``begin`` and ``end`` methods of a :term:`Configurator` (or,
+pre-1.2a6, between calls to the ``repoze.bfg.testing.setUp`` and
+``repoze.bfg.testing.tearDown`` functions). These functions push and
+pop the threadlocal stack when the system is under test. See
+:ref:`test_setup_and_teardown` for the definitions of these functions.
Scripts which use :mod:`repoze.bfg` machinery but never actually start
a WSGI server or receive requests via HTTP such as scripts which use
@@ -142,7 +143,8 @@ and the hack that uses ``get_current_request`` is removed. This would
be an appropriate place to use the ``get_current_request`` function.
Use of the ``get_current_registry`` function should be limited to
-testing scenarios. The registry created by
-``repoze.bfg.testing.setUp`` when you do not pass one in is available
+testing scenarios. The registry made current by use of a
+Configurator's ``begin`` method during a test (or pre-1.2a6, via
+``repoze.bfg.testing.setUp``) when you do not pass one in is available
to you via this API.
diff --git a/docs/narr/unittesting.rst b/docs/narr/unittesting.rst
index cc8ab6e32..790c0577d 100644
--- a/docs/narr/unittesting.rst
+++ b/docs/narr/unittesting.rst
@@ -56,7 +56,7 @@ functions.
Test Set Up and Tear Down
--------------------------
-:mod:`repoze.bfg` uses a "global" (actually thread-local) data
+:mod:`repoze.bfg` uses a "global" (actually :term:`thread local`) data
structure to hold on to two items: the current :term:`request` and the
current :term:`application registry`. These data structures are
available via the ``repoze.bfg.threadlocal.get_current_request`` and
@@ -65,42 +65,84 @@ respectively. See :ref:`threadlocals_chapter` for information about
these functions and the data structures they return.
If your code uses these ``get_current_*`` functions or calls
-:mod:`repoze.bfg` code which uses the ``get_current_*`` functions, you
-will need to use the ``repoze.bfg.testing.setUp`` and
-``repoze.bfg.testing.tearDown`` functions within the ``setUp`` and
-``tearDown`` methods of your unit tests, respectively.
+:mod:`repoze.bfg` code which uses ``get_current_*`` functions, you
+will need to construct at :term:`Configurator` and call its ``begin``
+method within the ``setUp`` method of your unit test and call the same
+configurator's ``end`` method within the ``tearDown`` method of your
+unit test.
-The ``repoze.bfg.testing.setUp`` and ``repoze.bfg.testing.tearDown``
-functions allow you to supply a unit test with an environment that has
-a default registry and a default request for the duration of a single
-test. Here's an example of using both:
+The use of a Configurator and its ``begin`` and ``end`` methods allows
+you to supply each unit test method in a test case with an environment
+that has a isolated registry and an isolated request for the duration
+of a single test. Here's an example of using this feature:
.. code-block:: python
:linenos:
import unittest
- from repoze.bfg import testing
+ from repoze.bfg.configuration import Configurator
+
+ class MyTest(unittest.TestCase):
+ def setUp(self):
+ self.config = Configurator()
+ self.config.begin()
+
+ def tearDown(self):
+ self.config.end()
+
+The above will make sure that
+``repoze.bfg.threadlocal.get_current_registry`` will return the
+:term:`application registry` associated with the ``config``
+Configurator instance when ``get_current_registry`` is called in a
+test case method attached to ``MyTest``. Each test case method
+attached to ``MyTest`` will use an isolated registry.
+
+The ``begin`` method of a Configurator accepts various arguments that
+influence the code run during the test. See the
+:ref:`configuration_module` chapter for information about the API of a
+:term:`Configurator`, including its ``begin`` and ``end`` methods.
+
+If you also want to make ``repoze.bfg.get_current_registry`` return
+something other than ``None`` during the course of a single test, you
+can pass a :term:`request` object into the ``begin`` method of the
+Configurator within the ``setUp`` method of your test:
+
+.. code-block:: python
+ :linenos:
+
+ import unittest
+ from repoze.bfg.configuration import Configurator
+ from repoze.bfg.request import Request
class MyTest(unittest.TestCase):
def setUp(self):
- testing.setUp()
+ self.config = Configurator()
+ request = Request()
+ self.config.begin(request=request)
def tearDown(self):
- testing.tearDown()
-
-If you don't *know* whether you're calling code that uses these
-functions, a rule of thumb applies: just always use the
-``repoze.bfg.testing.setUp`` and ``repoze.bfg.testing.tearDown``
-functions in the ``setUp`` and ``tearDown`` respectively of unit tests
-that test :mod:`repoze.bfg` application code, unless it's obvious
-you're not calling any :mod:`repoze.bfg` APIs which might make use of
-the any "current" global.
-
-The ``repoze.bfg.testing.setUp`` and ``repoze.bfg.testing.tearDown``
-functions accept various arguments that influence the code run during
-the test. See the :ref:`testing_module` chapter for information about
-the APIs of ``repoze.bfg.testing.setUp`` and
-``repoze.bfg.testing.tearDown``.
+ self.config.end()
+
+If you pass a term:`Request` object into the ``begin`` method of the
+configurator within your test case's ``setUp``, any test method
+attached to the ``MyTest`` test case that directly or indirectly calls
+``get_current_request`` will receive the request you passed into the
+``begin`` method. Otherwise, during testing, ``get_current_request``
+will return ``None``.
+
+What?
+~~~~~
+
+Thread local data structures are always a bit confusing, especially
+when used by frameworks. Sorry. So here's a rule of thumb: if you
+don't *know* whether you're calling code that uses the
+``get_current_registry`` or ``get_current_request`` functions, or you
+don't care about any of this, but you still want to write test code,
+just always create a configurator instance and call its ``begin``
+method within the ``setUp`` of a unit test, then subsequently call its
+``end`` method in the test's ``tearDown``. This won't really hurt
+anything if the application you're testing does not call any
+``get_current*`` function.
Using the ``repoze.bfg.testing`` API in Unit Tests
--------------------------------------------------
@@ -148,14 +190,16 @@ you could write a unittest TestCase that used the testing API.
:linenos:
import unittest
+ from repoze.bfg.configuration import Configurator
from repoze.bfg import testing
class MyTest(unittest.TestCase):
def setUp(self):
- testing.setUp()
+ self.config = Configurator()
+ self.config.begin()
def tearDown(self):
- testing.tearDown()
+ self.config.end()
def test_view_fn_not_submitted(self):
from my.package import view_fn
@@ -204,12 +248,12 @@ assertion. We assert at the end of this that the renderer's ``say``
attribute is ``Yo``, as this is what is expected of the view function
in the branch it's testing.
-Note that the test calls the ``repoze.bfg.testing.setUp`` function in
-its ``setUp`` method and the ``repoze.bfg.testing.tearDown`` function
-in its ``tearDown`` method. Use of this pattern is required to
-perform cleanup between the test runs. If you use any of the testing
-API, be sure to call ``repoze.bfg.testing.setUp`` in the test setup
-and ``repoze.bfg.testing.tearDown`` in the test teardown.
+Note that the test calls the ``begin`` method of a
+:term:`Configurator` in its ``setUp`` method and the ``end`` method of
+the same in its ``tearDown`` method. If you use any of the
+``repoze.bfg.testing`` APIs, be sure to use this pattern in your test
+setUp and tearDown; these methods make sure you're using a "fresh"
+:term:`application registry` per test run.
See the :ref:`testing_module` chapter for the entire :mod:`repoze.bfg`
-specific testing API. This chapter describes APIs for registering a
@@ -251,6 +295,7 @@ environment.
import unittest
+ from repoze.bfg.configuration import Configurator
from repoze.bfg import testing
class ViewIntegrationTests(unittest.TestCase):
@@ -259,15 +304,14 @@ environment.
registrations your application declares in its configure.zcml
(including dependent registrations for repoze.bfg itself).
"""
- from repoze.bfg.configuration import Configurator
import myapp
- configurator = Configurator(package=myapp)
- configurator.load_zcml('myapp:configure.zcml')
- testing.setUp(registry=configurator.registry)
+ self.config = Configurator(package=myapp)
+ self.config.begin()
+ self.config.load_zcml('myapp:configure.zcml')
def tearDown(self):
""" Clear out the application registry """
- testing.tearDown()
+ self.config.end()
def test_my_view(self):
from myapp.views import my_view
diff --git a/docs/tutorials/bfgwiki/src/authorization/tutorial/run.py b/docs/tutorials/bfgwiki/src/authorization/tutorial/run.py
index 98baa440b..c80fce02a 100644
--- a/docs/tutorials/bfgwiki/src/authorization/tutorial/run.py
+++ b/docs/tutorials/bfgwiki/src/authorization/tutorial/run.py
@@ -15,6 +15,8 @@ def app(global_config, **settings):
def get_root(request):
return finder(request.environ)
config = Configurator(root_factory=get_root, settings=settings)
+ config.begin()
config.load_zcml('configure.zcml')
+ config.end()
return config.make_wsgi_app()
diff --git a/docs/tutorials/bfgwiki/src/authorization/tutorial/tests.py b/docs/tutorials/bfgwiki/src/authorization/tutorial/tests.py
index fa025787e..6853bc376 100644
--- a/docs/tutorials/bfgwiki/src/authorization/tutorial/tests.py
+++ b/docs/tutorials/bfgwiki/src/authorization/tutorial/tests.py
@@ -94,7 +94,7 @@ class AddPageTests(unittest.TestCase):
request = testing.DummyRequest({'form.submitted':True,
'body':'Hello yo!'})
request.subpath = ['AnotherPage']
- response = self._callFUT(context, request)
+ self._callFUT(context, request)
page = context['AnotherPage']
self.assertEqual(page.data, 'Hello yo!')
self.assertEqual(page.__name__, 'AnotherPage')
diff --git a/docs/tutorials/bfgwiki/src/basiclayout/tutorial/run.py b/docs/tutorials/bfgwiki/src/basiclayout/tutorial/run.py
index 748b13eef..7d4220717 100644
--- a/docs/tutorials/bfgwiki/src/basiclayout/tutorial/run.py
+++ b/docs/tutorials/bfgwiki/src/basiclayout/tutorial/run.py
@@ -15,5 +15,7 @@ def app(global_config, **settings):
def get_root(request):
return finder(request.environ)
config = Configurator(root_factory=get_root, settings=settings)
+ config.begin()
config.load_zcml('configure.zcml')
+ config.end()
return config.make_wsgi_app()
diff --git a/docs/tutorials/bfgwiki/src/basiclayout/tutorial/tests.py b/docs/tutorials/bfgwiki/src/basiclayout/tutorial/tests.py
index 849e75ad4..32821ce0e 100644
--- a/docs/tutorials/bfgwiki/src/basiclayout/tutorial/tests.py
+++ b/docs/tutorials/bfgwiki/src/basiclayout/tutorial/tests.py
@@ -1,13 +1,15 @@
import unittest
+from repoze.bfg.configuration import Configurator
from repoze.bfg import testing
class ViewTests(unittest.TestCase):
def setUp(self):
- testing.setUp()
+ self.config = Configurator()
+ self.config.begin()
def tearDown(self):
- testing.tearDown()
+ self.config.end()
def test_my_view(self):
from tutorial.views import my_view
diff --git a/docs/tutorials/bfgwiki/src/models/tutorial/run.py b/docs/tutorials/bfgwiki/src/models/tutorial/run.py
index 748b13eef..7d4220717 100644
--- a/docs/tutorials/bfgwiki/src/models/tutorial/run.py
+++ b/docs/tutorials/bfgwiki/src/models/tutorial/run.py
@@ -15,5 +15,7 @@ def app(global_config, **settings):
def get_root(request):
return finder(request.environ)
config = Configurator(root_factory=get_root, settings=settings)
+ config.begin()
config.load_zcml('configure.zcml')
+ config.end()
return config.make_wsgi_app()
diff --git a/docs/tutorials/bfgwiki/src/models/tutorial/tests.py b/docs/tutorials/bfgwiki/src/models/tutorial/tests.py
index 1c1faf855..1eee68e7f 100644
--- a/docs/tutorials/bfgwiki/src/models/tutorial/tests.py
+++ b/docs/tutorials/bfgwiki/src/models/tutorial/tests.py
@@ -1,5 +1,6 @@
import unittest
+from repoze.bfg.configuration import Configurator
from repoze.bfg import testing
class PageModelTests(unittest.TestCase):
@@ -49,10 +50,11 @@ class AppmakerTests(unittest.TestCase):
class ViewTests(unittest.TestCase):
def setUp(self):
- testing.setUp()
+ self.config = Configurator()
+ self.config.begin()
def tearDown(self):
- testing.tearDown()
+ self.config.end()
def test_my_view(self):
from tutorial.views import my_view
diff --git a/docs/tutorials/bfgwiki/src/viewdecorators/tutorial/run.py b/docs/tutorials/bfgwiki/src/viewdecorators/tutorial/run.py
index 748b13eef..7d4220717 100644
--- a/docs/tutorials/bfgwiki/src/viewdecorators/tutorial/run.py
+++ b/docs/tutorials/bfgwiki/src/viewdecorators/tutorial/run.py
@@ -15,5 +15,7 @@ def app(global_config, **settings):
def get_root(request):
return finder(request.environ)
config = Configurator(root_factory=get_root, settings=settings)
+ config.begin()
config.load_zcml('configure.zcml')
+ config.end()
return config.make_wsgi_app()
diff --git a/docs/tutorials/bfgwiki/src/viewdecorators/tutorial/tests.py b/docs/tutorials/bfgwiki/src/viewdecorators/tutorial/tests.py
index fa025787e..6853bc376 100644
--- a/docs/tutorials/bfgwiki/src/viewdecorators/tutorial/tests.py
+++ b/docs/tutorials/bfgwiki/src/viewdecorators/tutorial/tests.py
@@ -94,7 +94,7 @@ class AddPageTests(unittest.TestCase):
request = testing.DummyRequest({'form.submitted':True,
'body':'Hello yo!'})
request.subpath = ['AnotherPage']
- response = self._callFUT(context, request)
+ self._callFUT(context, request)
page = context['AnotherPage']
self.assertEqual(page.data, 'Hello yo!')
self.assertEqual(page.__name__, 'AnotherPage')
diff --git a/docs/tutorials/bfgwiki/src/views/tutorial/run.py b/docs/tutorials/bfgwiki/src/views/tutorial/run.py
index 748b13eef..7d4220717 100644
--- a/docs/tutorials/bfgwiki/src/views/tutorial/run.py
+++ b/docs/tutorials/bfgwiki/src/views/tutorial/run.py
@@ -15,5 +15,7 @@ def app(global_config, **settings):
def get_root(request):
return finder(request.environ)
config = Configurator(root_factory=get_root, settings=settings)
+ config.begin()
config.load_zcml('configure.zcml')
+ config.end()
return config.make_wsgi_app()
diff --git a/docs/tutorials/bfgwiki/src/views/tutorial/tests.py b/docs/tutorials/bfgwiki/src/views/tutorial/tests.py
index 1b2ea972a..bbf86633a 100644
--- a/docs/tutorials/bfgwiki/src/views/tutorial/tests.py
+++ b/docs/tutorials/bfgwiki/src/views/tutorial/tests.py
@@ -94,7 +94,7 @@ class AddPageTests(unittest.TestCase):
request = testing.DummyRequest({'form.submitted':True,
'body':'Hello yo!'})
request.subpath = ['AnotherPage']
- response = self._callFUT(context, request)
+ self._callFUT(context, request)
page = context['AnotherPage']
self.assertEqual(page.data, 'Hello yo!')
self.assertEqual(page.__name__, 'AnotherPage')
diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/run.py b/docs/tutorials/bfgwiki2/src/authorization/tutorial/run.py
index 9ca9fe71e..332f0408f 100644
--- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/run.py
+++ b/docs/tutorials/bfgwiki2/src/authorization/tutorial/run.py
@@ -23,5 +23,7 @@ def app(global_config, **settings):
raise ValueError("No 'db_string' value in application configuration.")
initialize_sql(db_string)
config = Configurator(settings=settings)
+ config.begin()
config.load_zcml('configure.zcml')
+ config.end()
return config.make_wsgi_app()
diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/tests.py b/docs/tutorials/bfgwiki2/src/authorization/tutorial/tests.py
index 52d2fed86..7bc8e11ce 100644
--- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/tests.py
+++ b/docs/tutorials/bfgwiki2/src/authorization/tutorial/tests.py
@@ -1,4 +1,6 @@
import unittest
+
+from repoze.bfg.configuration import Configurator
from repoze.bfg import testing
def _initTestingDB():
@@ -11,21 +13,22 @@ def _initTestingDB():
Base.metadata.create_all(engine)
return DBSession
-def _registerRoutes():
- testing.registerRoute(':pagename', 'view_page')
- testing.registerRoute(':pagename/edit_page', 'edit_page')
- testing.registerRoute('add_page/:pagename', 'add_page')
+def _registerRoutes(config):
+ config.add_route('view_page', ':pagename')
+ config.add_route('edit_page', ':pagename/edit_page')
+ config.add_route('add_page', 'add_page/:pagename')
class ViewWikiTests(unittest.TestCase):
def setUp(self):
- testing.setUp()
+ self.config = Configurator()
+ self.config.begin()
def tearDown(self):
- testing.tearDown()
+ self.config.end()
def test_it(self):
from tutorial.views import view_wiki
- testing.registerRoute(':pagename', 'view_page')
+ self.config.add_route('view_page', ':pagename')
request = testing.DummyRequest()
response = view_wiki(request)
self.assertEqual(response.location, 'http://example.com/FrontPage')
@@ -33,11 +36,12 @@ class ViewWikiTests(unittest.TestCase):
class ViewPageTests(unittest.TestCase):
def setUp(self):
self.session = _initTestingDB()
- testing.setUp()
+ self.config = Configurator()
+ self.config.begin()
def tearDown(self):
self.session.remove()
- testing.tearDown()
+ self.config.end()
def _callFUT(self, request):
from tutorial.views import view_page
@@ -49,7 +53,7 @@ class ViewPageTests(unittest.TestCase):
request.matchdict['pagename'] = 'IDoExist'
page = Page('IDoExist', 'Hello CruelWorld IDoExist')
self.session.add(page)
- _registerRoutes()
+ _registerRoutes(self.config)
info = self._callFUT(request)
self.assertEqual(info['page'], page)
self.assertEqual(
@@ -67,18 +71,19 @@ class ViewPageTests(unittest.TestCase):
class AddPageTests(unittest.TestCase):
def setUp(self):
self.session = _initTestingDB()
- testing.setUp()
+ self.config = Configurator()
+ self.config.begin()
def tearDown(self):
self.session.remove()
- testing.tearDown()
+ self.config.end()
def _callFUT(self, request):
from tutorial.views import add_page
return add_page(request)
def test_it_notsubmitted(self):
- _registerRoutes()
+ _registerRoutes(self.config)
request = testing.DummyRequest()
request.matchdict = {'pagename':'AnotherPage'}
info = self._callFUT(request)
@@ -88,22 +93,23 @@ class AddPageTests(unittest.TestCase):
def test_it_submitted(self):
from tutorial.models import Page
- _registerRoutes()
+ _registerRoutes(self.config)
request = testing.DummyRequest({'form.submitted':True,
'body':'Hello yo!'})
request.matchdict = {'pagename':'AnotherPage'}
- response = self._callFUT(request)
+ self._callFUT(request)
page = self.session.query(Page).filter_by(name='AnotherPage').one()
self.assertEqual(page.data, 'Hello yo!')
class EditPageTests(unittest.TestCase):
def setUp(self):
self.session = _initTestingDB()
- testing.setUp()
+ self.config = Configurator()
+ self.config.begin()
def tearDown(self):
self.session.remove()
- testing.tearDown()
+ self.config.end()
def _callFUT(self, request):
from tutorial.views import edit_page
@@ -111,7 +117,7 @@ class EditPageTests(unittest.TestCase):
def test_it_notsubmitted(self):
from tutorial.models import Page
- _registerRoutes()
+ _registerRoutes(self.config)
request = testing.DummyRequest()
request.matchdict = {'pagename':'abc'}
page = Page('abc', 'hello')
@@ -122,7 +128,7 @@ class EditPageTests(unittest.TestCase):
def test_it_submitted(self):
from tutorial.models import Page
- _registerRoutes()
+ _registerRoutes(self.config)
request = testing.DummyRequest({'form.submitted':True,
'body':'Hello yo!'})
request.matchdict = {'pagename':'abc'}
diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/run.py b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/run.py
index 9ca9fe71e..332f0408f 100644
--- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/run.py
+++ b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/run.py
@@ -23,5 +23,7 @@ def app(global_config, **settings):
raise ValueError("No 'db_string' value in application configuration.")
initialize_sql(db_string)
config = Configurator(settings=settings)
+ config.begin()
config.load_zcml('configure.zcml')
+ config.end()
return config.make_wsgi_app()
diff --git a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/tests.py b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/tests.py
index 0c44baf16..2ef74cce7 100644
--- a/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/tests.py
+++ b/docs/tutorials/bfgwiki2/src/basiclayout/tutorial/tests.py
@@ -1,4 +1,5 @@
import unittest
+from repoze.bfg.configuration import Configurator
from repoze.bfg import testing
def _initTestingDB():
@@ -8,11 +9,12 @@ def _initTestingDB():
class TestMyView(unittest.TestCase):
def setUp(self):
- testing.setUp()
+ self.config = Configurator()
+ self.config.begin()
_initTestingDB()
def tearDown(self):
- testing.tearDown()
+ self.config.end()
def test_it(self):
from tutorial.views import my_view
diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/run.py b/docs/tutorials/bfgwiki2/src/models/tutorial/run.py
index 9ca9fe71e..332f0408f 100644
--- a/docs/tutorials/bfgwiki2/src/models/tutorial/run.py
+++ b/docs/tutorials/bfgwiki2/src/models/tutorial/run.py
@@ -23,5 +23,7 @@ def app(global_config, **settings):
raise ValueError("No 'db_string' value in application configuration.")
initialize_sql(db_string)
config = Configurator(settings=settings)
+ config.begin()
config.load_zcml('configure.zcml')
+ config.end()
return config.make_wsgi_app()
diff --git a/docs/tutorials/bfgwiki2/src/models/tutorial/tests.py b/docs/tutorials/bfgwiki2/src/models/tutorial/tests.py
index 0c44baf16..2ef74cce7 100644
--- a/docs/tutorials/bfgwiki2/src/models/tutorial/tests.py
+++ b/docs/tutorials/bfgwiki2/src/models/tutorial/tests.py
@@ -1,4 +1,5 @@
import unittest
+from repoze.bfg.configuration import Configurator
from repoze.bfg import testing
def _initTestingDB():
@@ -8,11 +9,12 @@ def _initTestingDB():
class TestMyView(unittest.TestCase):
def setUp(self):
- testing.setUp()
+ self.config = Configurator()
+ self.config.begin()
_initTestingDB()
def tearDown(self):
- testing.tearDown()
+ self.config.end()
def test_it(self):
from tutorial.views import my_view
diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/run.py b/docs/tutorials/bfgwiki2/src/views/tutorial/run.py
index 9ca9fe71e..332f0408f 100644
--- a/docs/tutorials/bfgwiki2/src/views/tutorial/run.py
+++ b/docs/tutorials/bfgwiki2/src/views/tutorial/run.py
@@ -23,5 +23,7 @@ def app(global_config, **settings):
raise ValueError("No 'db_string' value in application configuration.")
initialize_sql(db_string)
config = Configurator(settings=settings)
+ config.begin()
config.load_zcml('configure.zcml')
+ config.end()
return config.make_wsgi_app()
diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/tests.py b/docs/tutorials/bfgwiki2/src/views/tutorial/tests.py
index 52d2fed86..7bc8e11ce 100644
--- a/docs/tutorials/bfgwiki2/src/views/tutorial/tests.py
+++ b/docs/tutorials/bfgwiki2/src/views/tutorial/tests.py
@@ -1,4 +1,6 @@
import unittest
+
+from repoze.bfg.configuration import Configurator
from repoze.bfg import testing
def _initTestingDB():
@@ -11,21 +13,22 @@ def _initTestingDB():
Base.metadata.create_all(engine)
return DBSession
-def _registerRoutes():
- testing.registerRoute(':pagename', 'view_page')
- testing.registerRoute(':pagename/edit_page', 'edit_page')
- testing.registerRoute('add_page/:pagename', 'add_page')
+def _registerRoutes(config):
+ config.add_route('view_page', ':pagename')
+ config.add_route('edit_page', ':pagename/edit_page')
+ config.add_route('add_page', 'add_page/:pagename')
class ViewWikiTests(unittest.TestCase):
def setUp(self):
- testing.setUp()
+ self.config = Configurator()
+ self.config.begin()
def tearDown(self):
- testing.tearDown()
+ self.config.end()
def test_it(self):
from tutorial.views import view_wiki
- testing.registerRoute(':pagename', 'view_page')
+ self.config.add_route('view_page', ':pagename')
request = testing.DummyRequest()
response = view_wiki(request)
self.assertEqual(response.location, 'http://example.com/FrontPage')
@@ -33,11 +36,12 @@ class ViewWikiTests(unittest.TestCase):
class ViewPageTests(unittest.TestCase):
def setUp(self):
self.session = _initTestingDB()
- testing.setUp()
+ self.config = Configurator()
+ self.config.begin()
def tearDown(self):
self.session.remove()
- testing.tearDown()
+ self.config.end()
def _callFUT(self, request):
from tutorial.views import view_page
@@ -49,7 +53,7 @@ class ViewPageTests(unittest.TestCase):
request.matchdict['pagename'] = 'IDoExist'
page = Page('IDoExist', 'Hello CruelWorld IDoExist')
self.session.add(page)
- _registerRoutes()
+ _registerRoutes(self.config)
info = self._callFUT(request)
self.assertEqual(info['page'], page)
self.assertEqual(
@@ -67,18 +71,19 @@ class ViewPageTests(unittest.TestCase):
class AddPageTests(unittest.TestCase):
def setUp(self):
self.session = _initTestingDB()
- testing.setUp()
+ self.config = Configurator()
+ self.config.begin()
def tearDown(self):
self.session.remove()
- testing.tearDown()
+ self.config.end()
def _callFUT(self, request):
from tutorial.views import add_page
return add_page(request)
def test_it_notsubmitted(self):
- _registerRoutes()
+ _registerRoutes(self.config)
request = testing.DummyRequest()
request.matchdict = {'pagename':'AnotherPage'}
info = self._callFUT(request)
@@ -88,22 +93,23 @@ class AddPageTests(unittest.TestCase):
def test_it_submitted(self):
from tutorial.models import Page
- _registerRoutes()
+ _registerRoutes(self.config)
request = testing.DummyRequest({'form.submitted':True,
'body':'Hello yo!'})
request.matchdict = {'pagename':'AnotherPage'}
- response = self._callFUT(request)
+ self._callFUT(request)
page = self.session.query(Page).filter_by(name='AnotherPage').one()
self.assertEqual(page.data, 'Hello yo!')
class EditPageTests(unittest.TestCase):
def setUp(self):
self.session = _initTestingDB()
- testing.setUp()
+ self.config = Configurator()
+ self.config.begin()
def tearDown(self):
self.session.remove()
- testing.tearDown()
+ self.config.end()
def _callFUT(self, request):
from tutorial.views import edit_page
@@ -111,7 +117,7 @@ class EditPageTests(unittest.TestCase):
def test_it_notsubmitted(self):
from tutorial.models import Page
- _registerRoutes()
+ _registerRoutes(self.config)
request = testing.DummyRequest()
request.matchdict = {'pagename':'abc'}
page = Page('abc', 'hello')
@@ -122,7 +128,7 @@ class EditPageTests(unittest.TestCase):
def test_it_submitted(self):
from tutorial.models import Page
- _registerRoutes()
+ _registerRoutes(self.config)
request = testing.DummyRequest({'form.submitted':True,
'body':'Hello yo!'})
request.matchdict = {'pagename':'abc'}
diff --git a/docs/whatsnew-1.2.rst b/docs/whatsnew-1.2.rst
index c417ba3ae..4332c9948 100644
--- a/docs/whatsnew-1.2.rst
+++ b/docs/whatsnew-1.2.rst
@@ -41,7 +41,9 @@ The simplest possible :mod:`repoze.bfg` application is now:
if __name__ == '__main__':
config = Configurator()
+ config.begin()
config.add_view(hello_world)
+ config.end()
app = config.make_wsgi_app()
simple_server.make_server('', 8080, app).serve_forever()
@@ -141,10 +143,11 @@ Backwards Incompatibilites
- When there is no "current registry" in the
``repoze.bfg.threadlocal.manager`` threadlocal data structure (this
is the case when there is no "current request" or we're not in the
- midst of a ``r.b.testing.setUp``-bounded unit test), the ``.get``
- method of the manager returns a data structure containing a *global*
- registry. In previous releases, this function returned the global
- Zope "base" registry: the result of
+ midst of a ``r.b.testing.setUp`` or
+ ``r.b.configuration.Configurator.begin`` bounded unit test), the
+ ``.get`` method of the manager returns a data structure containing a
+ *global* registry. In previous releases, this function returned the
+ global Zope "base" registry: the result of
``zope.component.getGlobalSiteManager``, which is an instance of the
``zope.component.registry.Component`` class. In this release,
however, the global registry returns a globally importable instance
@@ -153,8 +156,8 @@ Backwards Incompatibilites
``repoze.bfg.registry.global_registry``.
Effectively, this means that when you call
- ``repoze.bfg.threadlocal.get_current_registry`` when no request or
- ``setUp`` bounded unit test is in effect, you will always get back
+ ``repoze.bfg.threadlocal.get_current_registry`` when no "real"
+ request or bounded unit test is in effect, you will always get back
the global registry that lives in
``repoze.bfg.registry.global_registry``. It also means that
:mod:`repoze.bfg` APIs that *call* ``get_current_registry`` will use