summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2016-12-16 00:17:11 -0600
committerMichael Merickel <michael@merickel.org>2016-12-16 20:28:17 -0600
commit0c1c5872915d79f14b1af8c7c3e597d5e83f30bb (patch)
treee535058e0de9dfba825d9916d4ac249d42e83c5f
parent1d78284a59718b02df1e05ee24f9ed2485f51cbb (diff)
downloadpyramid-0c1c5872915d79f14b1af8c7c3e597d5e83f30bb.tar.gz
pyramid-0c1c5872915d79f14b1af8c7c3e597d5e83f30bb.tar.bz2
pyramid-0c1c5872915d79f14b1af8c7c3e597d5e83f30bb.zip
defer translation_dir resolution to allow asset overrides to execute first
fixes #2046
-rw-r--r--pyramid/config/__init__.py13
-rw-r--r--pyramid/config/i18n.py45
-rw-r--r--pyramid/tests/test_config/test_i18n.py14
3 files changed, 39 insertions, 33 deletions
diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py
index d4064dc78..242fbcf4e 100644
--- a/pyramid/config/__init__.py
+++ b/pyramid/config/__init__.py
@@ -451,9 +451,6 @@ class Configurator(
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``,
@@ -651,7 +648,11 @@ class Configurator(
of this error will be information about the source of the conflict,
usually including file names and line numbers of the cause of the
configuration conflicts."""
- self.action_state.execute_actions(introspector=self.introspector)
+ self.begin()
+ try:
+ self.action_state.execute_actions(introspector=self.introspector)
+ finally:
+ self.end()
self.action_state = ActionState() # old actions have been processed
def include(self, callable, route_prefix=None):
@@ -992,11 +993,11 @@ class Configurator(
# Push the registry onto the stack in case any code that depends on
# the registry threadlocal APIs used in listeners subscribed to the
# IApplicationCreated event.
- self.manager.push({'registry': self.registry, 'request': None})
+ self.begin()
try:
self.registry.notify(ApplicationCreated(app))
finally:
- self.manager.pop()
+ self.end()
return app
diff --git a/pyramid/config/i18n.py b/pyramid/config/i18n.py
index 69af0f9bc..9387a693b 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,32 @@ class I18NConfiguratorMixin(object):
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)
+ resolver = AssetResolver(self.package_name)
def register():
- for directory in directories:
+ # defer spec resolution until register to allow for asset
+ # overrides to take place in an earlier config phase
+ 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)
+ 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 71c68af8a..ee8fcfd65 100644
--- a/pyramid/tests/test_config/test_i18n.py
+++ b/pyramid/tests/test_config/test_i18n.py
@@ -36,9 +36,8 @@ class TestI18NConfiguratorMixin(unittest.TestCase):
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 @@ class TestI18NConfiguratorMixin(unittest.TestCase):
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])