diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-11-24 22:08:04 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-11-24 22:08:04 +0000 |
| commit | a7e6f2cdec94fc98c0bb670f545449a9d0a84f58 (patch) | |
| tree | 6095ac5a62420de408ed916795d5796a7ba9b28a | |
| parent | 13c923f6eaf56a49897af75e14c1f70d1b26c75b (diff) | |
| download | pyramid-a7e6f2cdec94fc98c0bb670f545449a9d0a84f58.tar.gz pyramid-a7e6f2cdec94fc98c0bb670f545449a9d0a84f58.tar.bz2 pyramid-a7e6f2cdec94fc98c0bb670f545449a9d0a84f58.zip | |
Make hooking getSiteManager optional.
| -rw-r--r-- | docs/api/configuration.rst | 2 | ||||
| -rw-r--r-- | repoze/bfg/configuration.py | 39 | ||||
| -rw-r--r-- | repoze/bfg/testing.py | 7 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_configuration.py | 48 |
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 |
