From e38c247d33541b6c6d40aaf160828cefbefe022e Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 16 Dec 2016 00:17:11 -0600 Subject: [PATCH] defer translation_dir resolution to allow asset overrides to execute first fixes #2046 --- pyramid/config/__init__.py | 3 -- pyramid/config/i18n.py | 53 ++++++++++++++------------ pyramid/tests/test_config/test_i18n.py | 14 +++++-- 3 files changed, 40 insertions(+), 30 deletions(-) diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py index d4064dc787..47d95d42b3 100644 --- a/pyramid/config/__init__.py +++ b/pyramid/config/__init__.py @@ -451,9 +451,6 @@ def _make_spec(self, path_or_spec): return filename # absolute filename return '%s:%s' % (package, filename) - def _split_spec(self, path_or_spec): - return resolve_asset_spec(path_or_spec, self.package_name) - def _fix_registry(self): """ Fix up a ZCA component registry that is not a pyramid.registry.Registry by adding analogues of ``has_listeners``, diff --git a/pyramid/config/i18n.py b/pyramid/config/i18n.py index 69af0f9bc9..0b10277756 100644 --- a/pyramid/config/i18n.py +++ b/pyramid/config/i18n.py @@ -1,13 +1,10 @@ -import os -import sys - from pyramid.interfaces import ( ILocaleNegotiator, ITranslationDirectories, ) from pyramid.exceptions import ConfigurationError -from pyramid.path import package_path +from pyramid.path import AssetResolver from pyramid.util import action_method class I18NConfiguratorMixin(object): @@ -69,32 +66,40 @@ def add_translation_dirs(self, *specs): directories will be inserted into the beginning of the directory list in the order they're provided in the ``*specs`` list argument (items earlier in the list trump ones later in the list). + """ - directories = [] introspectables = [] - for spec in specs[::-1]: # reversed - package_name, filename = self._split_spec(spec) - if package_name is None: # absolute filename - directory = filename - else: - __import__(package_name) - package = sys.modules[package_name] - directory = os.path.join(package_path(package), filename) - - if not os.path.isdir(os.path.realpath(directory)): - raise ConfigurationError('"%s" is not a directory' % - directory) - intr = self.introspectable('translation directories', directory, - spec, 'translation directory') - intr['directory'] = directory - intr['spec'] = spec - introspectables.append(intr) - directories.append(directory) + # defer spec resolution until register to allow for asset + # overrides to take place in an earlier config phase + def resolve_directories(): + resolver = AssetResolver(self.package_name) + directories = [] + for spec in specs[::-1]: # reversed + # the trailing slash helps match asset overrides for folders + if not spec.endswith('/'): + spec += '/' + asset = resolver.resolve(spec) + directory = asset.abspath() + if not asset.isdir(): + raise ConfigurationError('"%s" is not a directory' % + directory) + intr = self.introspectable('translation directories', directory, + spec, 'translation directory') + intr['directory'] = directory + intr['spec'] = spec + introspectables.append(intr) + directories.append(directory) + return directories def register(): - for directory in directories: + self.begin() + try: + directories = resolve_directories() + finally: + self.end() + for directory in directories: tdirs = self.registry.queryUtility(ITranslationDirectories) if tdirs is None: tdirs = [] diff --git a/pyramid/tests/test_config/test_i18n.py b/pyramid/tests/test_config/test_i18n.py index 71c68af8a0..ee8fcfd65c 100644 --- a/pyramid/tests/test_config/test_i18n.py +++ b/pyramid/tests/test_config/test_i18n.py @@ -36,9 +36,8 @@ def test_set_locale_negotiator_dottedname(self): def test_add_translation_dirs_missing_dir(self): from pyramid.exceptions import ConfigurationError config = self._makeOne() - self.assertRaises(ConfigurationError, - config.add_translation_dirs, - '/wont/exist/on/my/system') + config.add_translation_dirs('/wont/exist/on/my/system') + self.assertRaises(ConfigurationError, config.commit) def test_add_translation_dirs_no_specs(self): from pyramid.interfaces import ITranslationDirectories @@ -87,3 +86,12 @@ def test_add_translation_dirs_abspath(self): self.assertEqual(config.registry.getUtility(ITranslationDirectories), [locale]) + def test_add_translation_dirs_uses_override(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne() + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') + config.override_asset('pyramid.tests.pkgs.localeapp:locale/', + 'pyramid.tests.pkgs.localeapp:locale2/') + config.commit() + self.assertEqual(config.registry.getUtility(ITranslationDirectories), + [locale2])