Skip to content

Commit

Permalink
Merge pull request #463 from gratipay/fix-simplate-scoping
Browse files Browse the repository at this point in the history
fix simplate scoping
  • Loading branch information
pjz committed Jun 30, 2015
2 parents 61eb31e + d9aa73e commit 5b78b45
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 14 deletions.
26 changes: 12 additions & 14 deletions aspen/resources/simplate.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,15 @@ def __init__(self, *a, **kw):


def respond(self, state):
state.update(self.pages[0])
response = state.setdefault('response', Response(charset=self.website.charset_dynamic))
spt_locals = {}
state.setdefault('response', Response(charset=self.website.charset_dynamic))
spt_context = dict(state, **self.pages[0]) # copy the state dict to avoid accidentally
exec(self.pages[1], spt_context) # mutating it

exec(self.pages[1], state, spt_locals)
if '__all__' in spt_context:
# templates will only see variables named in __all__
spt_context = dict([ (k, spt_context[k]) for k in spt_context['__all__'] ])

# if __all__ is defined, only pass those local variables to templates
# if __all__ is not defined, pass all locals to templates

if '__all__' in spt_locals:
spt_locals = dict([ (k, spt_locals[k]) for k in spt_locals['__all__'] ])

return self.get_response(state, spt_locals)
return self.get_response(state, spt_context)


def parse_into_pages(self, raw, is_bound):
Expand Down Expand Up @@ -148,7 +144,7 @@ def compile_page(self, page):
return (renderer, media_type) # back to parent class


def get_response(self, state, spt_locals):
def get_response(self, state, spt_context):
"""Given two context dicts, return a response object.
"""
dispatch_result = state['dispatch_result']
Expand All @@ -170,15 +166,17 @@ def get_response(self, state, spt_locals):
media_type = mimeparse.best_match(self.available_types, accept)
except:
# exception means don't override the defaults
log("Problem with mimeparse.best_match(%r, %r): %r " % (self.available_types, accept, sys.exc_info()))
log( "Problem with mimeparse.best_match(%r, %r): %r "
% (self.available_types, accept, sys.exc_info())
)
else:
if media_type == '': # breakdown in negotiations
raise failure
del failure
render = self.renderers[media_type] # KeyError is a bug

response = state['response']
response.body = render(dict(state, **spt_locals))
response.body = render(spt_context)
if 'Content-Type' not in response.headers:
response.headers['Content-Type'] = media_type
if media_type.startswith('text/'):
Expand Down
11 changes: 11 additions & 0 deletions tests/test_simplates.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,14 @@ def test_can_explicitly_override_state(harness):
)
assert response.code == 299
assert response.body == 'bar'


def test_but_python_sections_exhibit_module_scoping_behavior(harness):
response = harness.simple("""
bar = 'baz'
def foo():
return bar
foo = foo()
[---] text/html via stdlib_format
{foo}""")
assert response.body == 'baz'

0 comments on commit 5b78b45

Please sign in to comment.