summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2016-12-17 14:31:21 -0600
committerMichael Merickel <michael@merickel.org>2016-12-17 14:32:09 -0600
commit804eb0edf94d971acc7c2efccd019e24735a882e (patch)
tree74abcc2a3312d0190344e0c091b3e25dc4d4fd8c
parent0c1c5872915d79f14b1af8c7c3e597d5e83f30bb (diff)
downloadpyramid-804eb0edf94d971acc7c2efccd019e24735a882e.tar.gz
pyramid-804eb0edf94d971acc7c2efccd019e24735a882e.tar.bz2
pyramid-804eb0edf94d971acc7c2efccd019e24735a882e.zip
cover more cases where the threadlocals are not setup
-rw-r--r--pyramid/config/__init__.py34
-rw-r--r--pyramid/tests/test_config/test_i18n.py22
-rw-r--r--pyramid/tests/test_config/test_init.py50
3 files changed, 94 insertions, 12 deletions
diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py
index 242fbcf4e..304d3a85e 100644
--- a/pyramid/config/__init__.py
+++ b/pyramid/config/__init__.py
@@ -603,11 +603,15 @@ class Configurator(
if autocommit:
# callables can depend on the side effects of resolving a
# deferred discriminator
- undefer(discriminator)
- if callable is not None:
- callable(*args, **kw)
- for introspectable in introspectables:
- introspectable.register(self.introspector, action_info)
+ self.begin()
+ try:
+ undefer(discriminator)
+ if callable is not None:
+ callable(*args, **kw)
+ for introspectable in introspectables:
+ introspectable.register(self.introspector, action_info)
+ finally:
+ self.end()
else:
action = extra
@@ -886,14 +890,30 @@ class Configurator(
absolute_resource_spec = absolute_asset_spec # b/w compat forever
- def begin(self, request=None):
+ def begin(self, request=_marker):
""" Indicate that application or test configuration has begun.
This pushes a dictionary containing the :term:`application
registry` implied by ``registry`` attribute of this
configurator and the :term:`request` implied by the
``request`` argument onto the :term:`thread local` stack
consulted by various :mod:`pyramid.threadlocal` API
- functions."""
+ functions.
+
+ If ``request`` is not specified and the registry owned by the
+ configurator is already pushed as the current threadlocal registry
+ then this method will keep the current threadlocal request unchanged.
+
+ .. versionchanged:: 1.8
+ The current threadlocal request is propagated if the current
+ threadlocal registry remains unchanged.
+
+ """
+ if request is _marker:
+ current = self.manager.get()
+ if current['registry'] == self.registry:
+ request = current['request']
+ else:
+ request = None
self.manager.push({'registry':self.registry, 'request':request})
def end(self):
diff --git a/pyramid/tests/test_config/test_i18n.py b/pyramid/tests/test_config/test_i18n.py
index ee8fcfd65..adfb6191c 100644
--- a/pyramid/tests/test_config/test_i18n.py
+++ b/pyramid/tests/test_config/test_i18n.py
@@ -86,7 +86,7 @@ class TestI18NConfiguratorMixin(unittest.TestCase):
self.assertEqual(config.registry.getUtility(ITranslationDirectories),
[locale])
- def test_add_translation_dirs_uses_override(self):
+ def test_add_translation_dirs_uses_override_out_of_order(self):
from pyramid.interfaces import ITranslationDirectories
config = self._makeOne()
config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale')
@@ -94,4 +94,22 @@ class TestI18NConfiguratorMixin(unittest.TestCase):
'pyramid.tests.pkgs.localeapp:locale2/')
config.commit()
self.assertEqual(config.registry.getUtility(ITranslationDirectories),
- [locale2])
+ [locale2])
+
+ def test_add_translation_dirs_doesnt_use_override_w_autocommit(self):
+ from pyramid.interfaces import ITranslationDirectories
+ config = self._makeOne(autocommit=True)
+ config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale')
+ config.override_asset('pyramid.tests.pkgs.localeapp:locale/',
+ 'pyramid.tests.pkgs.localeapp:locale2/')
+ self.assertEqual(config.registry.getUtility(ITranslationDirectories),
+ [locale])
+
+ def test_add_translation_dirs_uses_override_w_autocommit(self):
+ from pyramid.interfaces import ITranslationDirectories
+ config = self._makeOne(autocommit=True)
+ config.override_asset('pyramid.tests.pkgs.localeapp:locale/',
+ 'pyramid.tests.pkgs.localeapp:locale2/')
+ config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale')
+ self.assertEqual(config.registry.getUtility(ITranslationDirectories),
+ [locale2])
diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py
index 7078d7e26..0d5413d16 100644
--- a/pyramid/tests/test_config/test_init.py
+++ b/pyramid/tests/test_config/test_init.py
@@ -91,13 +91,54 @@ class ConfiguratorTests(unittest.TestCase):
{'registry':config.registry, 'request':request})
self.assertEqual(manager.popped, False)
+ def test_begin_overrides_request(self):
+ from pyramid.config import Configurator
+ config = Configurator()
+ manager = DummyThreadLocalManager()
+ req = object()
+ # set it up for auto-propagation
+ pushed = {'registry': config.registry, 'request': None}
+ manager.pushed = pushed
+ config.manager = manager
+ config.begin(req)
+ self.assertTrue(manager.pushed is not pushed)
+ self.assertEqual(manager.pushed['request'], req)
+ self.assertEqual(manager.pushed['registry'], config.registry)
+
+ def test_begin_propagates_request_for_same_registry(self):
+ from pyramid.config import Configurator
+ config = Configurator()
+ manager = DummyThreadLocalManager()
+ req = object()
+ pushed = {'registry': config.registry, 'request': req}
+ manager.pushed = pushed
+ config.manager = manager
+ config.begin()
+ self.assertTrue(manager.pushed is not pushed)
+ self.assertEqual(manager.pushed['request'], req)
+ self.assertEqual(manager.pushed['registry'], config.registry)
+
+ def test_begin_does_not_propagate_request_for_diff_registry(self):
+ from pyramid.config import Configurator
+ config = Configurator()
+ manager = DummyThreadLocalManager()
+ req = object()
+ pushed = {'registry': object(), 'request': req}
+ manager.pushed = pushed
+ config.manager = manager
+ config.begin()
+ self.assertTrue(manager.pushed is not pushed)
+ self.assertEqual(manager.pushed['request'], None)
+ self.assertEqual(manager.pushed['registry'], config.registry)
+
def test_end(self):
from pyramid.config import Configurator
config = Configurator()
manager = DummyThreadLocalManager()
+ pushed = manager.pushed
config.manager = manager
config.end()
- self.assertEqual(manager.pushed, None)
+ self.assertEqual(manager.pushed, pushed)
self.assertEqual(manager.popped, True)
def test_ctor_with_package_registry(self):
@@ -1940,10 +1981,13 @@ class DummyRequest:
self.cookies = {}
class DummyThreadLocalManager(object):
- pushed = None
- popped = False
+ def __init__(self):
+ self.pushed = {'registry': None, 'request': None}
+ self.popped = False
def push(self, d):
self.pushed = d
+ def get(self):
+ return self.pushed
def pop(self):
self.popped = True