Chris McDonough
2012-10-05 9811b08518c594c24fddf86dba8f5956117fa89b
Merge branch 'fix.templatemacroreg'
5 files modified
85 ■■■■ changed files
pyramid/renderers.py 31 ●●●●● patch | view | raw | blame | history
pyramid/scripts/pserve.py 37 ●●●●● patch | view | raw | blame | history
pyramid/tests/fixtures/withmacro.pt 1 ●●●● patch | view | raw | blame | history
pyramid/tests/test_chameleon_zpt.py 9 ●●●● patch | view | raw | blame | history
pyramid/tests/test_renderers.py 7 ●●●● patch | view | raw | blame | history
pyramid/renderers.py
@@ -367,6 +367,12 @@
@implementer(IChameleonLookup)
class ChameleonRendererLookup(object):
    spec_re = re.compile(
        r'(?P<asset>[\w_.:/-]+)'
        r'(?:\#(?P<defname>[\w_]+))?'
        r'(\.(?P<ext>.*))'
        )
    def __init__(self, impl, registry):
        self.impl = impl
        self.registry = registry
@@ -417,6 +423,12 @@
            return False
        return settings.get('reload_templates', False)
    def _crack_spec(self, spec):
        asset, macro, ext = self.spec_re.match(spec).group(
            'asset', 'defname', 'ext'
            )
        return asset, macro, ext
    def __call__(self, info):
        spec = self.get_spec(info.name, info.package)
        registry = info.registry
@@ -436,27 +448,22 @@
            # spec is a package:relpath asset spec
            renderer = registry.queryUtility(ITemplateRenderer, name=spec)
            if renderer is None:
                p = re.compile(
                    r'(?P<asset>[\w_.:/-]+)'
                    r'(?:\#(?P<defname>[\w_]+))?'
                    r'(\.(?P<ext>.*))'
                    )
                asset, macro, ext = p.match(spec).group(
                    'asset', 'defname', 'ext'
                    )
                spec = '%s.%s' % (asset, ext)
                asset, macro, ext = self._crack_spec(spec)
                spec_without_macro = '%s.%s' % (asset, ext)
                try:
                    package_name, filename = spec.split(':', 1)
                    package_name, filename = spec_without_macro.split(':', 1)
                except ValueError: # pragma: no cover
                    # somehow we were passed a relative pathname; this
                    # should die
                    package_name = caller_package(4).__name__
                    filename = spec
                    filename = spec_without_macro
                abspath = pkg_resources.resource_filename(package_name,
                                                          filename)
                if not pkg_resources.resource_exists(package_name, filename):
                    raise ValueError(
                        'Missing template asset: %s (%s)' % (spec, abspath))
                        'Missing template asset: %s (%s)' % (
                            spec_without_macro, abspath)
                        )
                renderer = self.impl(abspath, self, macro=macro)
                settings = info.settings
                if not settings.get('reload_assets'):
pyramid/scripts/pserve.py
@@ -150,7 +150,8 @@
    _reloader_environ_key = 'PYTHON_RELOADER_SHOULD_RUN'
    _monitor_environ_key = 'PASTE_MONITOR_SHOULD_RUN'
    possible_subcommands = ('start', 'stop', 'restart', 'status')
    possible_subcommands = ('start', 'stop', 'restart', 'status',
                            'handle_reload_error')
    def __init__(self, argv, quiet=False):
        self.quiet = quiet
@@ -191,6 +192,34 @@
                install_reloader(int(self.options.reload_interval), [app_spec])
                # if self.requires_config_file:
                #     watch_file(self.args[0])
                if cmd == 'handle_reload_error':
                    self.out(
                        'There was a reload error: your application did not '
                        'start properly when restarted by the reloader. You  '
                        'will need to examine the traceback above, and fix '
                        'the issue.  The process will restart after each code '
                        'change until the problem is fixed.  In some '
                        'circumstances (such as when there is an ImportError '
                        'raised at module scope), changes you make to the '
                        'offending module will not cause a restart '
                        'and you will need to change the __init__.py '
                        'of your application to force a reload.  If that '
                        'does not work, you will need to restart the process '
                        'by hand.')
                    app_name = self.options.app_name
                    base = os.getcwd()
                    vars = self.parse_vars(restvars)
                    if not self._scheme_re.search(app_spec):
                        app_spec = 'config:' + app_spec
                    try: # populate sys.modules
                        app = self.loadapp(
                            app_spec, name=app_name,
                            relative_to=base, global_conf=vars)
                    except: # but ignore any exceptions
                        pass
                    while 1:
                        time.sleep(1)
            else:
                return self.restart_with_reloader()
@@ -526,8 +555,10 @@
            if reloader:
                # Reloader always exits with code 3; but if we are
                # a monitor, any exit code will restart
                if exit_code != 3:
                    return exit_code
                while exit_code != 3:
                    handle_error_args = args + ['handle_reload_error']
                    proc = subprocess.Popen(handle_error_args, env=new_environ)
                    exit_code = proc.wait()
            if self.verbose > 0:
                self.out('%s %s %s' % ('-' * 20, 'Restarting', '-' * 20))
pyramid/tests/fixtures/withmacro.pt
@@ -1,4 +1,5 @@
<html>
Outside macro
<metal:m define-macro="foo">
  Hello!
</metal:m>
pyramid/tests/test_chameleon_zpt.py
@@ -132,8 +132,13 @@
        result = instance.implementation()()
        self.assertEqual(result, '\n  Hello!\n')
        
    def test_macro_notsupplied(self):
        minimal = self._getTemplatePath('withmacro.pt')
        lookup = DummyLookup()
        instance = self._makeOne(minimal, lookup)
        result = instance.implementation()()
        self.assertEqual(result,
                         '<html>\nOutside macro\n\n  Hello!\n\n</html>\n\n')
class DummyLookup(object):
    auto_reload=True
pyramid/tests/test_renderers.py
@@ -295,6 +295,7 @@
        self.assertEqual(factory.kw, {'macro':None})
    def test___call__spec_withmacro(self):
        from pyramid.interfaces import ITemplateRenderer
        import os
        from pyramid import tests
        module_name = tests.__name__
@@ -302,10 +303,11 @@
        renderer = {}
        factory = DummyFactory(renderer)
        spec = '%s:%s' % (module_name, relpath)
        reg = self.config.registry
        info = DummyRendererInfo({
            'name':spec,
            'package':None,
            'registry':self.config.registry,
            'registry':reg,
            'settings':{},
            'type':'type',
            })
@@ -318,6 +320,9 @@
            'withmacro.pt')
        self.assertTrue(factory.path.startswith(path))
        self.assertEqual(factory.kw, {'macro':'foo'})
        self.assertTrue(
            reg.getUtility(ITemplateRenderer, name=spec) is renderer
            )
    def test___call__reload_assets_true(self):
        import pyramid.tests