* on traceback objects. This is required to inject a traceback into
* another one.
*
+ * For better windows support (not everybody has a visual studio 2003
+ * at home) it would be a good thing to have a ctypes implementation, but
+ * because the struct is not exported there is currently no sane way.
+ *
* :copyright: 2007 by Armin Ronacher.
* :license: BSD, see LICENSE for more details.
*/
if (!PyArg_ParseTuple(args, "OO", &tb, &next))
return NULL;
- if (!(PyTraceBack_Check(tb) && (PyTraceBack_Check(next) || next == Py_None))) {
+ if (!(PyTraceBack_Check(tb) && (PyTraceBack_Check(next) ||
+ next == Py_None))) {
PyErr_SetString(PyExc_TypeError, "traceback object required.");
return NULL;
}
{NULL, NULL, 0, NULL} /* Sentinel */
};
-
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
stack = property(stack)
def pop(self):
- """
- Pop the last layer from the stack and return it.
- """
+ """Pop the last layer from the stack and return it."""
rv = self._pop()
self.current = self._stack[0]
return rv
return self._undefined_singleton
def __setitem__(self, name, value):
- """
- Set a variable in the outermost layer.
- """
+ """Set a variable in the outermost layer."""
self.current[name] = value
def __delitem__(self, name):
- """
- Delete an variable in the outermost layer.
- """
+ """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.
- """
+ """ Check if the context contains a given variable."""
for layer in self._stack:
if name in layer:
return True
jinja.debugger
~~~~~~~~~~~~~~
- The debugger module of awesomeness.
+ This module implements helper function Jinja uses to give the users a
+ possibility to develop Jinja templates like they would debug python code.
+ It seamlessly integreates into the python traceback system, in fact it
+ just modifies the trackback stack so that the line numbers are correct
+ and the frame information are bound to the context and not the frame of
+ the template evaluation loop.
+
+ To achive this it raises the exception it cought before in an isolated
+ namespace at a given line. The locals namespace is set to the current
+ template context.
+
+ The traceback generated by raising that exception is then either returned
+ or linked with the former traceback if the `jinja._debugger` module is
+ available. Because it's not possible to modify traceback objects from the
+ python space this module is needed for this process.
+
+ If it's not available it just ignores the other frames. Because this can
+ lead to actually harder to debug code there is a setting on the jinja
+ environment to disable the debugging system.
+
+ The isolated namespace which is used to raise the exception also contains
+ a `__loader__` name that helds a reference to a PEP 302 compatible loader.
+ Because there are currently some traceback systems (such as the paste
+ evalexception debugger) that do not provide the frame globals when
+ retrieving the source from the linecache module, Jinja injects the source
+ to the linecache module itself and changes the filename to a URL style
+ "virtual filename" so that Jinja doesn't acidentally override other files
+ in the linecache.
:copyright: 2007 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
filename = filename.encode('utf-8')
# generate an jinja unique filename used so that linecache
- # gets data that doesn't interferes with other modules
+ # gets data that doesn't interfere with other modules
if filename is None:
vfilename = 'jinja://~%d' % randrange(0, 10000)
filename = '<string>'
except:
exc_info = sys.exc_info()
- # if we have an extended debugger we set the tb_next flag
+ # if we have an extended debugger we set the tb_next flag so that
+ # we don't loose the higher stack items.
if has_extended_debugger and traceback is not None:
tb_set_next(exc_info[2].tb_next, traceback.tb_next)
)
def get_source(self, impname):
+ """Return the source as bytestring."""
source = ''
if self.source is not None:
source = self.source