# HG changeset patch # User Ludovic Chabant # Date 1493526453 25200 # Node ID 370e74941d32f9ad5e3a8d3292c65d04e26a0d68 # Parent 8f8bbb2e70e1ea3959cbc5960dcaf6552a096039 optimize: Only load some 3rd party packages when needed. This commit only optimizes the Markdown, SmartyPants, and Pystache wrappers. diff -r 8f8bbb2e70e1 -r 370e74941d32 piecrust/formatting/markdownformatter.py --- a/piecrust/formatting/markdownformatter.py Thu Apr 27 20:55:07 2017 -0700 +++ b/piecrust/formatting/markdownformatter.py Sat Apr 29 21:27:33 2017 -0700 @@ -1,4 +1,3 @@ -from markdown import Markdown from piecrust.formatting.base import Formatter @@ -35,6 +34,6 @@ extension_configs = config.get('extension_configs', {}) + from markdown import Markdown self._formatter = Markdown(extensions=extensions, extension_configs=extension_configs) - diff -r 8f8bbb2e70e1 -r 370e74941d32 piecrust/formatting/smartypantsformatter.py --- a/piecrust/formatting/smartypantsformatter.py Thu Apr 27 20:55:07 2017 -0700 +++ b/piecrust/formatting/smartypantsformatter.py Sat Apr 29 21:27:33 2017 -0700 @@ -1,4 +1,3 @@ -import smartypants from piecrust.formatting.base import Formatter, PRIORITY_LAST @@ -10,13 +9,15 @@ super(SmartyPantsFormatter, self).__init__() self.priority = PRIORITY_LAST + import smartypants + self._sp = smartypants.smartypants + def initialize(self, app): super(SmartyPantsFormatter, self).initialize(app) self.enabled = ( - app.config.get('smartypants/enable') or - app.config.get('smartypants/enabled')) + app.config.get('smartypants/enable') or + app.config.get('smartypants/enabled')) def render(self, format_name, txt): assert format_name == 'html' - return smartypants.smartypants(txt) - + return self._sp(txt) diff -r 8f8bbb2e70e1 -r 370e74941d32 piecrust/templating/pystacheengine.py --- a/piecrust/templating/pystacheengine.py Thu Apr 27 20:55:07 2017 -0700 +++ b/piecrust/templating/pystacheengine.py Sat Apr 29 21:27:33 2017 -0700 @@ -1,9 +1,7 @@ import logging import collections.abc -import pystache -import pystache.common from piecrust.templating.base import ( - TemplateEngine, TemplateNotFoundError, TemplatingError) + TemplateEngine, TemplateNotFoundError, TemplatingError) logger = logging.getLogger(__name__) @@ -15,14 +13,16 @@ def __init__(self): self.renderer = None + self._not_found_error = None + self._pystache_error = None def renderSegmentPart(self, path, seg_part, data): self._ensureLoaded() try: return self.renderer.render(seg_part.content, data) - except pystache.common.TemplateNotFoundError as ex: + except self._not_found_error as ex: raise TemplateNotFoundError() from ex - except pystache.common.PystacheError as ex: + except self._pystache_error as ex: raise TemplatingError(str(ex), path) from ex def renderFile(self, paths, data): @@ -32,9 +32,9 @@ for p in paths: if not p.endswith('.mustache'): raise TemplatingError( - "The Mustache template engine only accepts template " - "filenames with a `.mustache` extension. Got: %s" % - p) + "The Mustache template engine only accepts template " + "filenames with a `.mustache` extension. Got: %s" % + p) name = p[:-9] # strip `.mustache` try: tpl = self.renderer.load_template(name) @@ -47,35 +47,39 @@ try: return self.renderer.render(tpl, data) - except pystache.common.PystacheError as ex: + except self._pystache_error as ex: raise TemplatingError(str(ex)) from ex def _ensureLoaded(self): if self.renderer: return + import pystache + import pystache.common + + self._not_found_error = pystache.common.TemplateNotFoundError + self._pystache_error = pystache.common.PystacheError + + class _WorkaroundRenderer(pystache.Renderer): + def _make_resolve_context(self): + mrc = super(_WorkaroundRenderer, self)._make_resolve_context() + + def _workaround(stack, name): + # Pystache will treat anything that's not a string or + # a dict as a list. This is just plain wrong, but it will + # take a while before the project can get patches on Pypi. + res = mrc(stack, name) + if res is not None and ( + res.__class__.__name__ in _knowns or + isinstance(res, collections.abc.Mapping)): + res = [res] + return res + + return _workaround + self.renderer = _WorkaroundRenderer( - search_dirs=self.app.templates_dirs) + search_dirs=self.app.templates_dirs) _knowns = ['PieCrustData', 'LazyPageConfigData', 'Paginator', 'Assetor', 'PageLinkerData'] - - -class _WorkaroundRenderer(pystache.Renderer): - def _make_resolve_context(self): - mrc = super(_WorkaroundRenderer, self)._make_resolve_context() - - def _workaround(stack, name): - # Pystache will treat anything that's not a string or a dict as - # a list. This is just plain wrong, but it will take a while before - # the project can get patches on Pypi. - res = mrc(stack, name) - if res is not None and ( - res.__class__.__name__ in _knowns or - isinstance(res, collections.abc.Mapping)): - res = [res] - return res - - return _workaround -