diff options
| -rw-r--r-- | CHANGES.txt | 9 | ||||
| -rw-r--r-- | TODO.txt | 6 | ||||
| -rw-r--r-- | pyramid/mako_templating.py | 125 | ||||
| -rw-r--r-- | pyramid/tests/test_mako_templating.py | 98 |
4 files changed, 149 insertions, 89 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index feba9156e..f3ba85cc3 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -105,6 +105,15 @@ Dependencies - Depend on ``venusian`` >= 1.0a3 to provide scan ``ignore`` support. +Internal +-------- + +- Create a "MakoRendererFactoryHelper" that provides customizable settings + key prefixes. Allows settings prefixes other than "mako." to be used to + create different factories that don't use the global mako settings. This + will be useful for the debug toolbar, which can currently be sabotaged by + someone using custom mako configuration settings. + 1.3a7 (2012-02-07) ================== @@ -4,12 +4,6 @@ Pyramid TODOs Nice-to-Have ------------ -- Create a "mako_renderer_factory_factory" that provides searches in settings - for "mako."-prefixed keys but allows other prefixes to be used to create - different factories that don't use the global mako settings. This would be - useful for the debug toolbar, which can currently be sabotaged by someone - using custom mako configuration settings. - - Add docs about upgrading between Pyramid versions (e.g. how to see deprecation warnings). diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py index 761695220..b2db28ba7 100644 --- a/pyramid/mako_templating.py +++ b/pyramid/mako_templating.py @@ -65,58 +65,79 @@ class PkgResourceTemplateLookup(TemplateLookup): registry_lock = threading.Lock() -def renderer_factory(info): - path = info.name - registry = info.registry - settings = info.settings - lookup = registry.queryUtility(IMakoLookup) - if lookup is None: - reload_templates = settings.get('reload_templates', False) - directories = settings.get('mako.directories', []) - module_directory = settings.get('mako.module_directory', None) - input_encoding = settings.get('mako.input_encoding', 'utf-8') - error_handler = settings.get('mako.error_handler', None) - default_filters = settings.get('mako.default_filters', 'h') - imports = settings.get('mako.imports', None) - strict_undefined = settings.get('mako.strict_undefined', 'false') - preprocessor = settings.get('mako.preprocessor', None) - if not is_nonstr_iter(directories): - directories = list(filter(None, directories.splitlines())) - directories = [ abspath_from_asset_spec(d) for d in directories ] - if module_directory is not None: - module_directory = abspath_from_asset_spec(module_directory) - if error_handler is not None: - dotted = DottedNameResolver(info.package) - error_handler = dotted.maybe_resolve(error_handler) - if default_filters is not None: - if not is_nonstr_iter(default_filters): - default_filters = list(filter( - None, default_filters.splitlines())) - if imports is not None: - if not is_nonstr_iter(imports): - imports = list(filter(None, imports.splitlines())) - strict_undefined = asbool(strict_undefined) - if preprocessor is not None: - dotted = DottedNameResolver(info.package) - preprocessor = dotted.maybe_resolve(preprocessor) - - - lookup = PkgResourceTemplateLookup(directories=directories, - module_directory=module_directory, - input_encoding=input_encoding, - error_handler=error_handler, - default_filters=default_filters, - imports=imports, - filesystem_checks=reload_templates, - strict_undefined=strict_undefined, - preprocessor=preprocessor) - registry_lock.acquire() - try: - registry.registerUtility(lookup, IMakoLookup) - finally: - registry_lock.release() - - return MakoLookupTemplateRenderer(path, lookup) +class MakoRendererFactoryHelper(object): + def __init__(self, settings_prefix=None): + self.settings_prefix = settings_prefix + + def __call__(self, info): + path = info.name + registry = info.registry + settings = info.settings + settings_prefix = self.settings_prefix + + if settings_prefix is None: + settings_prefix = info.type +'.' + + lookup = registry.queryUtility(IMakoLookup, name=settings_prefix) + + def sget(name, default=None): + return settings.get(settings_prefix + name, default) + + if lookup is None: + reload_templates = settings.get('pyramid.reload_templates', None) + if reload_templates is None: + reload_templates = settings.get('reload_templates', False) + reload_templates = asbool(reload_templates) + directories = sget('directories', []) + module_directory = sget('module_directory', None) + input_encoding = sget('input_encoding', 'utf-8') + error_handler = sget('error_handler', None) + default_filters = sget('default_filters', 'h') + imports = sget('imports', None) + strict_undefined = asbool(sget('strict_undefined', False)) + preprocessor = sget('preprocessor', None) + if not is_nonstr_iter(directories): + directories = list(filter(None, directories.splitlines())) + directories = [ abspath_from_asset_spec(d) for d in directories ] + if module_directory is not None: + module_directory = abspath_from_asset_spec(module_directory) + if error_handler is not None: + dotted = DottedNameResolver(info.package) + error_handler = dotted.maybe_resolve(error_handler) + if default_filters is not None: + if not is_nonstr_iter(default_filters): + default_filters = list(filter( + None, default_filters.splitlines())) + if imports is not None: + if not is_nonstr_iter(imports): + imports = list(filter(None, imports.splitlines())) + if preprocessor is not None: + dotted = DottedNameResolver(info.package) + preprocessor = dotted.maybe_resolve(preprocessor) + + + lookup = PkgResourceTemplateLookup( + directories=directories, + module_directory=module_directory, + input_encoding=input_encoding, + error_handler=error_handler, + default_filters=default_filters, + imports=imports, + filesystem_checks=reload_templates, + strict_undefined=strict_undefined, + preprocessor=preprocessor + ) + + registry_lock.acquire() + try: + registry.registerUtility(lookup, IMakoLookup, + name=settings_prefix) + finally: + registry_lock.release() + + return MakoLookupTemplateRenderer(path, lookup) + +renderer_factory = MakoRendererFactoryHelper('mako.') class MakoRenderingException(Exception): def __init__(self, text): diff --git a/pyramid/tests/test_mako_templating.py b/pyramid/tests/test_mako_templating.py index 4c444facf..0726c5250 100644 --- a/pyramid/tests/test_mako_templating.py +++ b/pyramid/tests/test_mako_templating.py @@ -21,8 +21,11 @@ class Test_renderer_factory(Base, unittest.TestCase): from pyramid.mako_templating import renderer_factory return renderer_factory(info) - def test_no_directories(self): + def _getLookup(self, name='mako.'): from pyramid.mako_templating import IMakoLookup + return self.config.registry.getUtility(IMakoLookup, name=name) + + def test_no_directories(self): info = DummyRendererInfo({ 'name':'pyramid.tests:fixtures/helloworld.mak', 'package':None, @@ -30,7 +33,7 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':{}, }) renderer = self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.directories, []) self.assertEqual(lookup.filesystem_checks, False) self.assertEqual(renderer.path, @@ -38,7 +41,6 @@ class Test_renderer_factory(Base, unittest.TestCase): self.assertEqual(renderer.lookup, lookup) def test_no_lookup(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir} info = DummyRendererInfo({ 'name':'helloworld.mak', @@ -47,14 +49,13 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) renderer = self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.directories, [self.templates_dir]) self.assertEqual(lookup.filesystem_checks, False) self.assertEqual(renderer.path, 'helloworld.mak') self.assertEqual(renderer.lookup, lookup) def test_composite_directories_path(self): - from pyramid.mako_templating import IMakoLookup twice = '\n' + self.templates_dir + '\n' + self.templates_dir + '\n' settings = {'mako.directories':twice} info = DummyRendererInfo({ @@ -64,13 +65,12 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.directories, [self.templates_dir]*2) def test_directories_list(self): import sys import os.path - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':['a', 'b']} info = DummyRendererInfo({ 'name':'helloworld.mak', @@ -79,7 +79,7 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() module_path = os.path.dirname( sys.modules['__main__'].__file__).rstrip('.') # ./setup.py self.assertEqual(lookup.directories, [ @@ -88,7 +88,6 @@ class Test_renderer_factory(Base, unittest.TestCase): def test_with_module_directory_asset_spec(self): import os - from pyramid.mako_templating import IMakoLookup module_directory = 'pyramid.tests:fixtures' settings = {'mako.directories':self.templates_dir, 'mako.module_directory':module_directory} @@ -99,13 +98,12 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() fixtures = os.path.join(os.path.dirname(__file__), 'fixtures') self.assertEqual(lookup.module_directory, fixtures) def test_with_module_directory_asset_abspath(self): import os - from pyramid.mako_templating import IMakoLookup fixtures = os.path.join(os.path.dirname(__file__), 'fixtures') settings = {'mako.directories':self.templates_dir, 'mako.module_directory':fixtures} @@ -116,11 +114,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.module_directory, fixtures) def test_with_input_encoding(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.input_encoding':'utf-16'} info = DummyRendererInfo({ @@ -130,11 +127,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['input_encoding'], 'utf-16') def test_with_error_handler(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.error_handler':'pyramid.tests'} import pyramid.tests @@ -145,11 +141,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['error_handler'], pyramid.tests) def test_with_preprocessor(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.preprocessor':'pyramid.tests'} import pyramid.tests @@ -160,11 +155,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['preprocessor'], pyramid.tests) def test_with_default_filters(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.default_filters':'\nh\ng\n\n'} info = DummyRendererInfo({ @@ -174,11 +168,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['default_filters'], ['h', 'g']) def test_with_default_filters_list(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.default_filters':['h', 'g']} info = DummyRendererInfo({ @@ -188,11 +181,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['default_filters'], ['h', 'g']) def test_with_imports(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.imports':'\none\ntwo\n\n'} info = DummyRendererInfo({ @@ -202,11 +194,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['imports'], ['one', 'two']) def test_with_imports_list(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.imports':['one', 'two']} info = DummyRendererInfo({ @@ -216,11 +207,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['imports'], ['one', 'two']) def test_with_strict_undefined_true(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.strict_undefined':'true'} info = DummyRendererInfo({ @@ -230,11 +220,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['strict_undefined'], True) def test_with_strict_undefined_false(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.strict_undefined':'false'} info = DummyRendererInfo({ @@ -244,13 +233,13 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['strict_undefined'], False) def test_with_lookup(self): from pyramid.mako_templating import IMakoLookup lookup = dict() - self.config.registry.registerUtility(lookup, IMakoLookup) + self.config.registry.registerUtility(lookup, IMakoLookup, name='mako.') info = DummyRendererInfo({ 'name':'helloworld.mak', 'package':None, @@ -261,6 +250,53 @@ class Test_renderer_factory(Base, unittest.TestCase): self.assertEqual(renderer.lookup, lookup) self.assertEqual(renderer.path, 'helloworld.mak') +class MakoRendererFactoryHelperTests(Base, unittest.TestCase): + def _getTargetClass(self): + from pyramid.mako_templating import MakoRendererFactoryHelper + return MakoRendererFactoryHelper + + def _makeOne(self, *arg, **kw): + klass = self._getTargetClass() + return klass(*arg, **kw) + + def _getLookup(self, name='mako.'): + from pyramid.mako_templating import IMakoLookup + return self.config.registry.getUtility(IMakoLookup, name=name) + + def test_no_settings_prefix(self): + settings = {'foo.directories':self.templates_dir} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + 'type':'foo', + }) + helper = self._makeOne() + renderer = helper(info) + lookup = self._getLookup('foo.') + self.assertEqual(lookup.directories, [self.templates_dir]) + self.assertEqual(lookup.filesystem_checks, False) + self.assertEqual(renderer.path, 'helloworld.mak') + self.assertEqual(renderer.lookup, lookup) + + def test_custom_settings_prefix(self): + settings = {'bar.directories':self.templates_dir} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + 'type':'foo', + }) + helper = self._makeOne('bar.') + renderer = helper(info) + lookup = self._getLookup('bar.') + self.assertEqual(lookup.directories, [self.templates_dir]) + self.assertEqual(lookup.filesystem_checks, False) + self.assertEqual(renderer.path, 'helloworld.mak') + self.assertEqual(renderer.lookup, lookup) + class MakoLookupTemplateRendererTests(Base, unittest.TestCase): def _getTargetClass(self): from pyramid.mako_templating import MakoLookupTemplateRenderer |
