85 lines
2.6 KiB
Python
85 lines
2.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
jinja._native
|
|
~~~~~~~~~~~~~
|
|
|
|
This module implements the native base classes in case of not
|
|
having a jinja with the _speedups module compiled.
|
|
|
|
Note that if you change semantics here you have to edit the
|
|
_speedups.c file to in order to support those changes for jinja
|
|
setups with enabled speedup module.
|
|
|
|
:copyright: 2007 by Armin Ronacher.
|
|
:license: BSD, see LICENSE for more details.
|
|
"""
|
|
from jinja.datastructure import Deferred
|
|
from jinja.utils import deque
|
|
|
|
|
|
class BaseContext(object):
|
|
|
|
def __init__(self, undefined_singleton, globals, initial):
|
|
self._undefined_singleton = undefined_singleton
|
|
self.current = current = {}
|
|
self._stack = deque([current, initial, globals])
|
|
self.globals = globals
|
|
self.initial = initial
|
|
|
|
self._push = self._stack.appendleft
|
|
self._pop = self._stack.popleft
|
|
|
|
def stack(self):
|
|
return list(self._stack)[::-1]
|
|
stack = property(stack)
|
|
|
|
def pop(self):
|
|
"""Pop the last layer from the stack and return it."""
|
|
rv = self._pop()
|
|
self.current = self._stack[0]
|
|
return rv
|
|
|
|
def push(self, data=None):
|
|
"""
|
|
Push one layer to the stack and return it. Layer must be
|
|
a dict or omitted.
|
|
"""
|
|
data = data or {}
|
|
self._push(data)
|
|
self.current = self._stack[0]
|
|
return data
|
|
|
|
def __getitem__(self, name):
|
|
"""
|
|
Resolve one item. Restrict the access to internal variables
|
|
such as ``'::cycle1'``. Resolve deferreds.
|
|
"""
|
|
if not name.startswith('::'):
|
|
for d in self._stack:
|
|
if name in d:
|
|
rv = d[name]
|
|
if rv.__class__ is Deferred:
|
|
rv = rv(self, name)
|
|
# never touch the globals!
|
|
if d is self.globals:
|
|
self.initial[name] = rv
|
|
else:
|
|
d[name] = rv
|
|
return rv
|
|
return self._undefined_singleton
|
|
|
|
def __setitem__(self, name, value):
|
|
"""Set a variable in the outermost layer."""
|
|
self.current[name] = value
|
|
|
|
def __delitem__(self, name):
|
|
"""Delete a variable in the outermost layer."""
|
|
if name in self.current:
|
|
del self.current[name]
|
|
|
|
def __contains__(self, name):
|
|
""" Check if the context contains a given variable."""
|
|
for layer in self._stack:
|
|
if name in layer:
|
|
return True
|
|
return False
|