summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-11-24 22:08:04 +0000
committerChris McDonough <chrism@agendaless.com>2009-11-24 22:08:04 +0000
commita7e6f2cdec94fc98c0bb670f545449a9d0a84f58 (patch)
tree6095ac5a62420de408ed916795d5796a7ba9b28a
parent13c923f6eaf56a49897af75e14c1f70d1b26c75b (diff)
downloadpyramid-a7e6f2cdec94fc98c0bb670f545449a9d0a84f58.tar.gz
pyramid-a7e6f2cdec94fc98c0bb670f545449a9d0a84f58.tar.bz2
pyramid-a7e6f2cdec94fc98c0bb670f545449a9d0a84f58.zip
Make hooking getSiteManager optional.
-rw-r--r--docs/api/configuration.rst2
-rw-r--r--repoze/bfg/configuration.py39
-rw-r--r--repoze/bfg/testing.py7
-rw-r--r--repoze/bfg/tests/test_configuration.py48
4 files changed, 71 insertions, 25 deletions
diff --git a/docs/api/configuration.rst b/docs/api/configuration.rst
index e621fbbe1..1107e840b 100644
--- a/docs/api/configuration.rst
+++ b/docs/api/configuration.rst
@@ -5,7 +5,7 @@
.. automodule:: repoze.bfg.configuration
- .. autoclass:: Configurator(registry=None, package=None, settings=None, root_factory=None, zcml_file=None, authentication_policy=None, authorization_policy=None, renderers=DEFAULT_RENDERERS, debug_logger=None)
+ .. autoclass:: Configurator(registry=None, package=None, settings=None, root_factory=None, zcml_file=None, authentication_policy=None, authorization_policy=None, renderers=DEFAULT_RENDERERS, debug_logger=None, hook_zca=False)
.. automethod:: add_renderer(name, factory)
diff --git a/repoze/bfg/configuration.py b/repoze/bfg/configuration.py
index 13f730d97..861b6c0ad 100644
--- a/repoze/bfg/configuration.py
+++ b/repoze/bfg/configuration.py
@@ -132,12 +132,23 @@ class Configurator(object):
If ``debug_logger`` is not passed, a default debug logger that
logs to stderr will be used. If it is passed, it should be an
instance of a ``logging.Logger`` (PEP 282) class.
-
- """
+
+ If ``hook_zca`` is ``True``, the configurator constructor will run
+ ``zope.component.getSiteManager.sethook(
+ repoze.bfg.threadlocals.get_current_registry)``. This causes the
+ ``zope.component.getSiteManager`` API to return the
+ :mod:`repoze.bfg` thread local registry. This has the effect of
+ causing ``zope.component`` thread local API functions such as
+ ``getUtility`` and ``getMultiAdapter`` to use the
+ :mod:`repoze.bfg` registry instead of the global Zope registry
+ during the scope of every :mod:`repoze.bfg` :term:`request`. By
+ default, this is ``False``. """
+
def __init__(self, registry=None, package=None, settings=None,
root_factory=None, zcml_file=None,
authentication_policy=None, authorization_policy=None,
- renderers=DEFAULT_RENDERERS, debug_logger=None):
+ renderers=DEFAULT_RENDERERS, debug_logger=None,
+ hook_zca=False):
self.package = package or caller_package()
self.registry = registry
if registry is None:
@@ -158,6 +169,8 @@ class Configurator(object):
self.add_renderer(name, renderer)
if zcml_file is not None:
self.load_zcml(zcml_file)
+ if hook_zca:
+ getSiteManager.sethook(get_current_registry)
def _set_settings(self, mapping):
settings = Settings(mapping or {})
@@ -278,18 +291,17 @@ class Configurator(object):
self.registry.registerHandler(subscriber, iface)
return subscriber
- def make_wsgi_app(self, manager=manager, getSiteManager=getSiteManager):
+ def make_wsgi_app(self, manager=manager):
""" Returns a :mod:`repoze.bfg` WSGI application representing
- the current configuration state."""
- # manager and getSiteManager in arglist for testing dep injection only
+ the current configuration state and sends a
+ ``repoze.bfg.interfaces.WSGIApplicationCreatedEvent`` event to
+ all listeners."""
+ # manager in arglist for testing dep injection only
from repoze.bfg.router import Router # avoid circdep
app = Router(self.registry)
- # executing sethook means we're taking over getSiteManager for
- # the lifetime of this process
- getSiteManager.sethook(get_current_registry)
- # We push the registry on to the stack here in case any ZCA API is
- # used in listeners subscribed to the WSGIApplicationCreatedEvent
- # we send.
+ # We push the registry on to the stack here in case any code
+ # that depends on the registry threadlocal APIis used in
+ # listeners subscribed to the WSGIApplicationCreatedEvent.
manager.push({'registry':self.registry, 'request':None})
try:
self.registry.notify(WSGIApplicationCreatedEvent(app))
@@ -1037,7 +1049,8 @@ def make_app(root_factory, package=None, filename='configure.zcml',
settings = settings or options or {}
zcml_file = settings.get('configure_zcml', filename)
config = Configurator(package=package, settings=settings,
- root_factory=root_factory, zcml_file=zcml_file)
+ root_factory=root_factory, zcml_file=zcml_file,
+ hook_zca=True) # hook_zca for bw compat
app = config.make_wsgi_app()
return app
diff --git a/repoze/bfg/testing.py b/repoze/bfg/testing.py
index 4a4acf98b..cfcf82125 100644
--- a/repoze/bfg/testing.py
+++ b/repoze/bfg/testing.py
@@ -523,13 +523,14 @@ class DummyRequest:
self.__dict__.update(kw)
def setUp():
- """Set up a fresh BFG testing registry. Use in the ``setUp``
+ """
+ Set up a fresh BFG testing registry. Use in the ``setUp``
method of unit tests that use the ``register*`` methods in the
testing module (e.g. if your unit test uses
``repoze.bfg.testing.registerDummySecurityPolicy``). If you use
the ``register*`` functions without calling ``setUp``, unit tests
will not be isolated with respect to registrations they perform.
- Additionally, the *global* component registry will be used, which
+ Additionally, a *global* component registry will be used, which
may have a different API than is expected by BFG itself.
.. note:: This feature is new as of :mod:`repoze.bfg` 1.1.
@@ -541,7 +542,7 @@ def setUp():
request.registry = registry
manager.push({'registry':registry, 'request':request})
getSiteManager.sethook(get_current_registry)
- _clearContext()
+ _clearContext() # XXX why?
def tearDown():
"""Tear down a previously set up (via
diff --git a/repoze/bfg/tests/test_configuration.py b/repoze/bfg/tests/test_configuration.py
index 549663f2f..a6c412c3f 100644
--- a/repoze/bfg/tests/test_configuration.py
+++ b/repoze/bfg/tests/test_configuration.py
@@ -156,6 +156,39 @@ class ConfiguratorTests(unittest.TestCase):
self.assertEqual(config.registry.getUtility(IRendererFactory, 'yeah'),
renderer)
+ def test_ctor_hook_zca_true(self):
+ from zope.component import getSiteManager
+ from repoze.bfg.threadlocal import get_current_registry
+ try:
+ getSiteManager.reset()
+ config = self._makeOne(hook_zca=True)
+ hooked = getSiteManager.sethook(None)
+ self.assertEqual(hooked, get_current_registry)
+ finally:
+ getSiteManager.reset()
+
+ def test_ctor_hook_zca_false(self):
+ from zope.component import getSiteManager
+ from repoze.bfg.threadlocal import get_current_registry
+ try:
+ getSiteManager.reset()
+ config = self._makeOne(hook_zca=False)
+ hooked = getSiteManager.sethook(None)
+ self.failIfEqual(hooked, get_current_registry)
+ finally:
+ getSiteManager.reset()
+
+ def test_ctor_hook_zca_default_false(self):
+ from zope.component import getSiteManager
+ from repoze.bfg.threadlocal import get_current_registry
+ try:
+ getSiteManager.reset()
+ config = self._makeOne()
+ hooked = getSiteManager.sethook(None)
+ self.failIfEqual(hooked, get_current_registry)
+ finally:
+ getSiteManager.reset()
+
def test_add_subscriber_defaults(self):
from zope.interface import implements
from zope.interface import Interface
@@ -215,25 +248,19 @@ class ConfiguratorTests(unittest.TestCase):
self.assertEqual(len(L), 1)
def test_make_wsgi_app(self):
- from repoze.bfg.threadlocal import get_current_registry
from repoze.bfg.router import Router
from repoze.bfg.interfaces import IWSGIApplicationCreatedEvent
- class GetSiteManager(object):
- def sethook(self, reg):
- self.hook = reg
class ThreadLocalManager(object):
def push(self, d):
self.pushed = d
def pop(self):
self.popped = True
- gsm = GetSiteManager()
manager = ThreadLocalManager()
config = self._makeOne()
subscriber = self._registerEventListener(config,
IWSGIApplicationCreatedEvent)
- app = config.make_wsgi_app(getSiteManager=gsm, manager=manager)
+ app = config.make_wsgi_app(manager=manager)
self.assertEqual(app.__class__, Router)
- self.assertEqual(gsm.hook, get_current_registry)
self.assertEqual(manager.pushed['registry'], config.registry)
self.assertEqual(manager.pushed['request'], None)
self.failUnless(manager.popped)
@@ -2338,6 +2365,7 @@ class TestMakeApp(unittest.TestCase):
self.assertEqual(app.root_factory, rootfactory)
self.assertEqual(app.settings, settings)
self.assertEqual(app.zcml_file, 'configure.zcml')
+ self.assertEqual(app.hook_zca, True)
def test_it_options_means_settings(self):
settings = {'a':1}
@@ -2440,12 +2468,16 @@ class DummySecurityPolicy:
class DummyConfigurator(object):
def __init__(self, registry=None, package=None,
root_factory=None, zcml_file=None,
- settings=None):
+ settings=None, hook_zca=False):
self.root_factory = root_factory
self.package = package
self.zcml_file = zcml_file
self.settings = settings
+ self.hook_zca = hook_zca
def make_wsgi_app(self):
return self
+class DummyGetSiteManager(object):
+ def sethook(self, reg):
+ self.hook = reg