Skip to content

Commit

Permalink
new branch that is slightly leaner. lost all the cruft.
Browse files Browse the repository at this point in the history
  • Loading branch information
jvanasco committed Oct 12, 2016
1 parent 432336e commit 1ab00b1
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 94 deletions.
15 changes: 9 additions & 6 deletions CHANGELOG.txt
Expand Up @@ -3,13 +3,16 @@ unreleased

modified:
run_tests.py
two new flags (off by default)
new flags (off by default)

--benchmark
runs benchmarks

--run_unittests
runs unittests

--disable_core
disables the initial core tests

python run_tests.py --benchmark --run_unittests

Expand All @@ -18,12 +21,12 @@ unreleased
runtests was extended to search for unittests and run them if found by a flag
everything is doubly checked to be an `AshesTest` instance, so other test classes can be integrated at a later date

`ashes.Template`
is_convertable is a new boolean instance value. it defaults onto the class for lookup.

`ashes.Template.__init__`
new kwargs:
source_ast=None,
source_python_string=None,
source_python_code=None,
source_python_func=None,
the default for last_mtime was moved out into the class. no sense setting it to `None` on every request

`ashes.Template._get_render_func`
now returns a tuple of `python_code` and `python_func`
`ret_str=True` was migrated to `ashes._get_render_string`
Expand Down
23 changes: 4 additions & 19 deletions README.md
Expand Up @@ -236,32 +236,17 @@ python code string.
* ``ashes.python_string_to_function`` generates a python function from an ashes
python code string.

The ``Template.__init__`` method also accepts keyword arguments for each of
these hooks:

* ``source_ast``
* ``source_python_string``
* ``source_python_code``
* ``source_python_func``


A very easy way to implement this is with a custom TemplateLoader. Template
Loaders are a flexible framework that can be used to precompile families of
templates or even lazily preload them as needed.

Detailed examples are provided in the tests.

If a custom loader is not used, the template must be registered with the active
ashes environment:

ashesEnv = ashes.AshesEnv(loaders=(ashesLoader, ))
templateObj = ashes.Template('apples.dust',
None, # source
source_ast=source_ast,
source_python_string=source_python_string,
source_python_code=source_python_code,
source_python_func=source_python_func,
)
templateObj = ashes.Template.from_python_code(source_python_code,
name='apples.dust',
)
ashesEnv.register(templateObj,
name="apples.dust",
)
Expand All @@ -275,7 +260,7 @@ ashes environment:
| ast | Yes | Safe | 65% |
| python string | Yes | Possible Security Risk | 20-35% |
| python code | Yes | Same Risk, must `marshal` | 6-8% |
| python func | Yes | - | 3% |
| python func | Yes | No. | 3% |
```

## Compatibility
Expand Down
40 changes: 12 additions & 28 deletions ashes.py
Expand Up @@ -1798,10 +1798,6 @@ def __init__(self,
keep_source=True,
env=None,
lazy=False,
source_ast=None,
source_python_string=None,
source_python_code=None,
source_python_func=None,
):
if not source and source_file:
(source, source_abs_path) = load_template_path(source_file)
Expand All @@ -1816,26 +1812,6 @@ def __init__(self,
env = default_env
self.env = env

# some templates are from source...
if source_ast or source_python_string or source_python_code or source_python_func:
# prefer in order of speed
if source_python_func:
self.render_func = source_python_func
elif source_python_code:
self.render_func = _python_exec(source_python_code, name='render')
elif source_python_string:
render_code = _python_compile(source_python_string)
self.render_func = _python_exec(render_code, name='render')
else:
(render_code,
self.render_func
) = self._ast_to_render_func(source_ast)
if not keep_source:
self.source = None
self.is_convertable = False
# exit EARLY
return

if lazy: # lazy is only for testing
self.render_func = None
return
Expand Down Expand Up @@ -1870,7 +1846,11 @@ def from_ast(cls, ast, name=None, **kw):
kwargs:
``name`` default ``None``.
"""
template = cls(name=name, source='', source_ast=ast, lazy=True, **kw)
template = cls(name=name, source='', lazy=True, **kw)
(render_code,
render_func
) = template._ast_to_render_func(ast)
template.render_func = render_func
template.is_convertable = False
return template

Expand All @@ -1884,7 +1864,9 @@ def from_python_string(cls, python_string, name=None, **kw):
kwargs:
``name`` default ``None``.
"""
template = cls(name=name, source='', source_python_string=python_string, lazy=True, **kw)
template = cls(name=name, source='', lazy=True, **kw)
render_code = _python_compile(python_string)
template.render_func = _python_exec(render_code, name='render')
template.is_convertable = False
return template

Expand All @@ -1898,7 +1880,8 @@ def from_python_code(cls, python_code, name=None, **kw):
kwargs:
``name`` default ``None``.
"""
template = cls(name=name, source='', source_python_code=python_code, lazy=True, **kw)
template = cls(name=name, source='', lazy=True, **kw)
template.render_func = _python_exec(python_code, name='render')
template.is_convertable = False
return template

Expand All @@ -1912,7 +1895,8 @@ def from_python_func(cls, python_func, name=None, **kw):
kwargs:
``name`` default ``None``.
"""
template = cls(name=name, source='', source_python_func=python_func, lazy=True, **kw)
template = cls(name=name, source='', lazy=True, **kw)
template.render_func = python_func
template.is_convertable = False
return template

Expand Down
28 changes: 4 additions & 24 deletions tests/template_loaders.py
Expand Up @@ -66,10 +66,7 @@ def test_Template_tofrom_ast(self):
(ashesEnvSrc, ashesEnvDest) = self._generate_envs_tofrom()
for (fname, fdata) in self._ChertData.chert_data.items():
source_ast = ashesEnvSrc.load(fname).to_ast()
template2_object = ashes.Template(
fname, None,
source_ast=source_ast,
)
template2_object = ashes.Template.from_ast(source_ast)
ashesEnvDest.register(template2_object, fname)
rendered2 = ashesEnvDest.render(fname, fdata)
assert rendered2 == self._ChertData.renders_expected[fname]
Expand All @@ -81,10 +78,7 @@ def test_Template_tofrom_python_string(self):
(ashesEnvSrc, ashesEnvDest) = self._generate_envs_tofrom()
for (fname, fdata) in self._ChertData.chert_data.items():
source_python_string = ashesEnvSrc.load(fname).to_python_string()
template2_object = ashes.Template(
fname, None,
source_python_string=source_python_string,
)
template2_object = ashes.Template.from_python_string(source_python_string)
ashesEnvDest.register(template2_object, fname)
rendered2 = ashesEnvDest.render(fname, fdata)
assert rendered2 == self._ChertData.renders_expected[fname]
Expand All @@ -96,10 +90,7 @@ def test_Template_tofrom_python_code(self):
(ashesEnvSrc, ashesEnvDest) = self._generate_envs_tofrom()
for (fname, fdata) in self._ChertData.chert_data.items():
source_python_code = ashesEnvSrc.load(fname).to_python_code()
template2_object = ashes.Template(
fname, None,
source_python_code=source_python_code,
)
template2_object = ashes.Template.from_python_code(source_python_code)
ashesEnvDest.register(template2_object, fname)
rendered2 = ashesEnvDest.render(fname, fdata)
assert rendered2 == self._ChertData.renders_expected[fname]
Expand All @@ -111,10 +102,7 @@ def test_Template_tofrom_python_func(self):
(ashesEnvSrc, ashesEnvDest) = self._generate_envs_tofrom()
for (fname, fdata) in self._ChertData.chert_data.items():
source_python_func = ashesEnvSrc.load(fname).to_python_func()
template2_object = ashes.Template(
fname, None,
source_python_func=source_python_func,
)
template2_object = ashes.Template.from_python_func(source_python_func)
ashesEnvDest.register(template2_object, fname)
rendered2 = ashesEnvDest.render(fname, fdata)
assert rendered2 == self._ChertData.renders_expected[fname]
Expand Down Expand Up @@ -172,14 +160,6 @@ def _helper_test_template_init__args(self, fruit, source_payload=None, source_cl
"""helper class for _helper_test_template_init__args_* tests"""
source_data = self._SimpleFruitData.compiled_template_data[fruit][source_payload]

# this generates a {'source_ast': value}
kwargs = {"source_%s"%source_payload: source_data}

# can it render via source kwarg
_template = ashes.Template(fruit, None, **kwargs)
_rendered = _template.render({})
self.assertEquals(_rendered, self._SimpleFruitData.renders_expected[fruit])

# can it render via classmethod?
_template = source_classmethod(source_data)
_rendered = _template.render({})
Expand Down
41 changes: 24 additions & 17 deletions tests/utils.py
Expand Up @@ -247,12 +247,13 @@ def load_from_cacheable(self, templates_cache):
templates_cache is generated via `generate_all_cacheable`
"""
for (_template_name, payload) in templates_cache.items():
self._template_objects[_template_name] = ashes.Template(
_template_name, None,
source_ast=payload.get('ast'),
source_python_string=payload.get('python_string'),
source_python_code=payload.get('python_code'),
)
if payload.get('ast'):
_template = ashes.Template.from_ast(payload.get('ast'))
if payload.get('python_string'):
_template = ashes.Template.from_python_string(payload.get('python_string'))
if payload.get('python_code'):
_template = ashes.Template.from_python_code(payload.get('python_code'))
self._template_objects[_template_name] = _template

def generate_all_cacheable(self):
"""
Expand Down Expand Up @@ -326,13 +327,20 @@ def load_precompiled(
source_python_code=None,
source_python_func=None,
):
template = ashes.Template(template_name,
source,
source_ast=source_ast,
source_python_string=source_python_string,
source_python_code=source_python_code,
source_python_func=source_python_func,
)
if source_python_func:
template = ashes.Template.from_python_func(source_python_func, name=template_name)
elif source_python_code:
template = ashes.Template.from_python_code(source_python_code, name=template_name)
elif source_python_string:
template = ashes.Template.from_python_string(source_python_string, name=template_name)
elif source_ast:
template = ashes.Template.from_ast(source_ast, name=template_name)
elif source:
template = ashes.Template(template_name,
source,
)
else:
raise ValueError("nothing to load")
return template

def load(self, template_name, env=None):
Expand All @@ -349,10 +357,9 @@ def register_template(self, template_name, template_object):
self._templates_loaded[template_name] = template_object

def register_template_render_func(self, template_name, source_python_func):
template_object = ashes.Template(template_name,
None,
source_python_func=source_python_func,
)
template_object = ashes.Template.from_python_func(source_python_func,
template_name,
)
self.register_template(template_name, template_object)
return template_object

Expand Down

0 comments on commit 1ab00b1

Please sign in to comment.