From c614ffc153135eb14d77472a46c20af7c6f6ed91 Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 11:48:58 +0200 Subject: add ``localizer`` property to the request (refs #508) --- CHANGES.txt | 3 +++ pyramid/i18n.py | 17 +++++++---------- pyramid/request.py | 8 ++++++++ pyramid/tests/test_i18n.py | 17 +++++++++++++++++ 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 48efad6d4..b805a12a0 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,6 +4,9 @@ Next Release Features -------- +- Add ``localizer`` property (reified) to the request. + See https://github.com/Pylons/pyramid/issues/508. + - Add ``pdistreport`` script, which prints the Python version in use, the Pyramid version in use, and the version number and location of all Python distributions currently installed. diff --git a/pyramid/i18n.py b/pyramid/i18n.py index b4bc0eaa7..dc2c25f18 100644 --- a/pyramid/i18n.py +++ b/pyramid/i18n.py @@ -197,17 +197,15 @@ def make_localizer(current_locale_name, translation_directories): def get_localizer(request): """ Retrieve a :class:`pyramid.i18n.Localizer` object corresponding to the current request's locale name. """ - localizer = getattr(request, 'localizer', None) - if localizer is None: - # no locale object cached on request - try: - registry = request.registry - except AttributeError: - registry = get_current_registry() + # no locale object cached on request + try: + registry = request.registry + except AttributeError: + registry = get_current_registry() - current_locale_name = get_locale_name(request) - localizer = registry.queryUtility(ILocalizer, name=current_locale_name) + current_locale_name = get_locale_name(request) + localizer = registry.queryUtility(ILocalizer, name=current_locale_name) if localizer is None: # no localizer utility registered yet @@ -216,7 +214,6 @@ def get_localizer(request): registry.registerUtility(localizer, ILocalizer, name=current_locale_name) - request.localizer = localizer return localizer diff --git a/pyramid/request.py b/pyramid/request.py index 5bca5b1f0..5dedee4f1 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -24,6 +24,7 @@ from pyramid.compat import ( ) from pyramid.decorator import reify +from pyramid.i18n import get_localizer from pyramid.response import Response from pyramid.url import URLMethodsMixin from pyramid.util import InstancePropertyMixin @@ -383,6 +384,13 @@ class Request(BaseRequest, DeprecatedRequestMethodsMixin, URLMethodsMixin, def json_body(self): return json.loads(text_(self.body, self.charset)) + @reify + def localizer(self): + """ Convenience property to return a localizer by calling + :func:`pyramid.i18n.get_localizer`. """ + return get_localizer(self) + + def route_request_iface(name, bases=()): # zope.interface treats the __name__ as the __doc__ and changes __name__ # to None for interfaces that contain spaces if you do not pass a diff --git a/pyramid/tests/test_i18n.py b/pyramid/tests/test_i18n.py index bd4998b10..4b4022dbc 100644 --- a/pyramid/tests/test_i18n.py +++ b/pyramid/tests/test_i18n.py @@ -292,6 +292,23 @@ class Test_get_localizer(unittest.TestCase): self.assertEqual(result.translate('Approve', 'deformsite'), 'Approve') + def test_request_has_localizer(self): + from pyramid.threadlocal import get_current_registry + from pyramid.interfaces import ILocalizer + from pyramid.request import Request + # register mock localizer + dummy = object() + registry = get_current_registry() + registry.registerUtility(dummy, ILocalizer, name='en') + request = Request(environ={}) + self.assertEqual(request.localizer, dummy) + # `get_localizer` is only called once... + other = object() + registry.registerUtility(other, ILocalizer, name='en') + self.assertNotEqual(request.localizer, other) + self.assertEqual(request.localizer, dummy) + + class Test_default_locale_negotiator(unittest.TestCase): def setUp(self): cleanUp() -- cgit v1.2.3 From dbe2dcbbed98e0fbfce195d8a6564dc296d0de89 Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 12:12:41 +0200 Subject: remove duplicate of `Test_get_locale_name.test_name_on_request` --- pyramid/tests/test_i18n.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pyramid/tests/test_i18n.py b/pyramid/tests/test_i18n.py index 4b4022dbc..be105495d 100644 --- a/pyramid/tests/test_i18n.py +++ b/pyramid/tests/test_i18n.py @@ -245,12 +245,6 @@ class Test_get_localizer(unittest.TestCase): result = self._callFUT(request) self.assertEqual(result, '123') - def test_locale_on_request(self): - request = DummyRequest() - request.localizer = 'abc' - result = self._callFUT(request) - self.assertEqual(result, 'abc') - def test_locale_from_registry(self): from pyramid.threadlocal import get_current_registry from pyramid.interfaces import ILocalizer -- cgit v1.2.3 From 1e83584f47b9a584fa9624bbcac92134a926297d Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 12:14:45 +0200 Subject: test the default localizer --- pyramid/tests/test_i18n.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pyramid/tests/test_i18n.py b/pyramid/tests/test_i18n.py index be105495d..2ae70234c 100644 --- a/pyramid/tests/test_i18n.py +++ b/pyramid/tests/test_i18n.py @@ -230,6 +230,14 @@ class Test_get_localizer(unittest.TestCase): from pyramid.i18n import get_localizer return get_localizer(request) + def test_default_localizer(self): + # `get_localizer` returns a default localizer for `en` + from pyramid.i18n import Localizer + request = DummyRequest() + result = self._callFUT(request) + self.assertEqual(result.__class__, Localizer) + self.assertEqual(result.locale_name, 'en') + def test_no_registry_on_request(self): request = DummyRequest() request.localizer = '123' -- cgit v1.2.3 From 85448c73ccca42a0d4ef1318433acdbbb21328ce Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 12:16:38 +0200 Subject: test a custom localizer --- pyramid/tests/test_i18n.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pyramid/tests/test_i18n.py b/pyramid/tests/test_i18n.py index 2ae70234c..e43c642be 100644 --- a/pyramid/tests/test_i18n.py +++ b/pyramid/tests/test_i18n.py @@ -238,11 +238,15 @@ class Test_get_localizer(unittest.TestCase): self.assertEqual(result.__class__, Localizer) self.assertEqual(result.locale_name, 'en') - def test_no_registry_on_request(self): + def test_custom_localizer(self): + from pyramid.threadlocal import get_current_registry + from pyramid.interfaces import ILocalizer + registry = get_current_registry() + dummy = object() + registry.registerUtility(dummy, ILocalizer, name='en') request = DummyRequest() - request.localizer = '123' result = self._callFUT(request) - self.assertEqual(result, '123') + self.assertEqual(result, dummy) def test_with_registry_on_request(self): from pyramid.threadlocal import get_current_registry -- cgit v1.2.3 From 186c2b8b9f2c259ccb264982b2433081ca26e3bf Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 12:17:17 +0200 Subject: remove test that explicitly sets a registry on the request outside tests the router puts the registry on the request, but in tests it sometimes needs to exist as well. however, it doesn't make sense to test something that's only done in tests anyway --- pyramid/tests/test_i18n.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/pyramid/tests/test_i18n.py b/pyramid/tests/test_i18n.py index e43c642be..58af96493 100644 --- a/pyramid/tests/test_i18n.py +++ b/pyramid/tests/test_i18n.py @@ -248,15 +248,6 @@ class Test_get_localizer(unittest.TestCase): result = self._callFUT(request) self.assertEqual(result, dummy) - def test_with_registry_on_request(self): - from pyramid.threadlocal import get_current_registry - registry = get_current_registry() - request = DummyRequest() - request.localizer = '123' - request.registry = registry - result = self._callFUT(request) - self.assertEqual(result, '123') - def test_locale_from_registry(self): from pyramid.threadlocal import get_current_registry from pyramid.interfaces import ILocalizer -- cgit v1.2.3 From 0064eb70d5b30507b65c05271fe12a2697f88d05 Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 12:21:50 +0200 Subject: don't use the default locale when testing custom localizer also, use an object as a dummy localizer for better readability --- pyramid/tests/test_i18n.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyramid/tests/test_i18n.py b/pyramid/tests/test_i18n.py index 58af96493..b583d1468 100644 --- a/pyramid/tests/test_i18n.py +++ b/pyramid/tests/test_i18n.py @@ -252,12 +252,12 @@ class Test_get_localizer(unittest.TestCase): from pyramid.threadlocal import get_current_registry from pyramid.interfaces import ILocalizer registry = get_current_registry() - locale = 'abc' - registry.registerUtility(locale, ILocalizer, name='en') + dummy = object() + registry.registerUtility(dummy, ILocalizer, name='ie') request = DummyRequest() - request.locale_name = 'en' + request.locale_name = 'ie' result = self._callFUT(request) - self.assertEqual(result, 'abc') + self.assertEqual(result, dummy) def test_locale_from_mo(self): from pyramid.threadlocal import get_current_registry -- cgit v1.2.3 From b3e9da039ddc3661874e815512475268b8a88ded Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 12:24:56 +0200 Subject: clean up test names --- pyramid/tests/test_i18n.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyramid/tests/test_i18n.py b/pyramid/tests/test_i18n.py index b583d1468..336e51b6a 100644 --- a/pyramid/tests/test_i18n.py +++ b/pyramid/tests/test_i18n.py @@ -238,7 +238,7 @@ class Test_get_localizer(unittest.TestCase): self.assertEqual(result.__class__, Localizer) self.assertEqual(result.locale_name, 'en') - def test_custom_localizer(self): + def test_custom_localizer_for_default_locale(self): from pyramid.threadlocal import get_current_registry from pyramid.interfaces import ILocalizer registry = get_current_registry() @@ -248,7 +248,7 @@ class Test_get_localizer(unittest.TestCase): result = self._callFUT(request) self.assertEqual(result, dummy) - def test_locale_from_registry(self): + def test_custom_localizer_for_custom_locale(self): from pyramid.threadlocal import get_current_registry from pyramid.interfaces import ILocalizer registry = get_current_registry() @@ -259,7 +259,7 @@ class Test_get_localizer(unittest.TestCase): result = self._callFUT(request) self.assertEqual(result, dummy) - def test_locale_from_mo(self): + def test_localizer_from_mo(self): from pyramid.threadlocal import get_current_registry from pyramid.interfaces import ITranslationDirectories from pyramid.i18n import Localizer @@ -275,7 +275,7 @@ class Test_get_localizer(unittest.TestCase): self.assertEqual(result.translate('Approve'), 'Approve') self.assertTrue(hasattr(result, 'pluralize')) - def test_locale_from_mo_bad_mo(self): + def test_localizer_from_mo_bad_mo(self): from pyramid.threadlocal import get_current_registry from pyramid.interfaces import ITranslationDirectories from pyramid.i18n import Localizer -- cgit v1.2.3 From c70dcb392b07859c7c75ce20ddedc16b961692ea Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 12:32:04 +0200 Subject: done :) --- TODO.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/TODO.txt b/TODO.txt index 7a3561494..46eb33b82 100644 --- a/TODO.txt +++ b/TODO.txt @@ -56,9 +56,6 @@ Nice-to-Have app1" and "domain app1.localhost = app1"), ProxyPreserveHost and the nginx equivalent, preserving HTTPS URLs. -- Make "localizer" a property of request (instead of requiring - "get_localizer(request)"? - - Alias the stupid long default session factory name. - Debug option to print view matching decision (e.g. debug_viewlookup or so). -- cgit v1.2.3