Skip to content

Commit

Permalink
turn the Configurator into a context manager
Browse files Browse the repository at this point in the history
fixes #2872
  • Loading branch information
mmerickel committed Dec 16, 2016
1 parent 1a7242b commit 2c712a6
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
8 changes: 4 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ and deployment more fun, more predictable, and more productive.
return Response('Hello %(name)s!' % request.matchdict)
if __name__ == '__main__':
config = Configurator()
config.add_route('hello', '/hello/{name}')
config.add_view(hello_world, route_name='hello')
app = config.make_wsgi_app()
with Configurator() as config:
config.add_route('hello', '/hello/{name}')
config.add_view(hello_world, route_name='hello')
app = config.make_wsgi_app()
server = make_server('0.0.0.0', 8080, app)
server.serve_forever()
Expand Down
25 changes: 25 additions & 0 deletions pyramid/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@ class Configurator(
A Configurator is used to configure a :app:`Pyramid`
:term:`application registry`.
To enable all application state to be available during configuration,
the Configurator may be used as a context manager to automatically handle
calling :meth:`pyramid.config.Configurator.begin` and
:meth:`pyramid.config.Configurator.end`. Without using one of the
following approaches, certain APIs such as :term:`asset spec` resolution
may not work as intended.
.. code-block:: python
with Configurator() as config:
config.add_route('home', '/')
app = config.make_wsgi_app()
If the ``registry`` argument is not ``None``, it must
be an instance of the :class:`pyramid.registry.Registry` class
representing the registry to configure. If ``registry`` is ``None``, the
Expand Down Expand Up @@ -265,6 +278,11 @@ class Configurator(
.. versionadded:: 1.6
The ``root_package`` argument.
The ``response_factory`` argument.
.. versionadded:: 1.8
The ability to use the configurator as a context manager with the
``with``-statement to make threadlocal configuration available for
further configuration.
"""
manager = manager # for testing injection
venusian = venusian # for testing injection
Expand Down Expand Up @@ -903,6 +921,13 @@ def end(self):
"""
return self.manager.pop()

def __enter__(self):
self.begin()
return self

def __exit__(self, exc_type, exc_value, exc_traceback):
self.end()

# this is *not* an action method (uses caller_package)
def scan(self, package=None, categories=None, onerror=None, ignore=None,
**kw):
Expand Down
12 changes: 12 additions & 0 deletions pyramid/tests/test_config/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@ def test_end(self):
self.assertEqual(manager.pushed, None)
self.assertEqual(manager.popped, True)

def test_context_manager(self):
from pyramid.config import Configurator
config = Configurator()
manager = DummyThreadLocalManager()
config.manager = manager
with config as ctx:
self.assertEqual(config, ctx)
self.assertEqual(manager.pushed,
{'registry': config.registry, 'request': None})
self.assertFalse(manager.popped)
self.assertTrue(manager.popped)

def test_ctor_with_package_registry(self):
import sys
from pyramid.config import Configurator
Expand Down

0 comments on commit 2c712a6

Please sign in to comment.