[svn] added ugly, ugly, ugly even more ugly but working hack to jinja to patch the...
authorArmin Ronacher <armin.ronacher@active-4.com>
Thu, 5 Apr 2007 20:38:44 +0000 (22:38 +0200)
committerArmin Ronacher <armin.ronacher@active-4.com>
Thu, 5 Apr 2007 20:38:44 +0000 (22:38 +0200)
--HG--
branch : trunk

CHANGES
jinja/utils.py

diff --git a/CHANGES b/CHANGES
index 77aee3f4375a3fd43b7a0cc1c35e0054a6710918..1fb0393faa53189603437d414a38b1d1caac7a1c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -8,6 +8,7 @@ Version 1.1
 - blocks now support ``{{ super() }}`` to render the parent output.
 
 - debugging system improved, smaller filesize for the cached files.
+  Debugging works now well for any module using linecache.
 
 - added whitespace management system for the template designer.
 
index cb219862f9993f592f413058152ca544bf3214e6..b3dce7bf788d14d6b1a86b9e650b98d14cfc845d 100644 (file)
@@ -274,13 +274,25 @@ def fake_template_exception(exception, filename, lineno, source,
         env = context_or_env
         namespace = {}
 
+    # generate an jinja unique filename used so that linecache
+    # gets data that doesn't interferes with other modules
+    if filename is None:
+        from random import randrange
+        vfilename = 'jinja://~%d' % randrange(0, 10000)
+        filename = '<string>'
+    else:
+        vfilename = 'jinja://%s' % filename
+
     offset = '\n' * (lineno - 1)
     code = compile(offset + 'raise __exception_to_raise__',
-                   filename or '<template>', 'exec')
+                   vfilename or '<template>', 'exec')
+
+    loader = TracebackLoader(env, source, filename)
+    loader.update_linecache(vfilename)
     globals = {
-        '__name__':                 filename,
-        '__file__':                 filename,
-        '__loader__':               TracebackLoader(env, source, filename),
+        '__name__':                 vfilename,
+        '__file__':                 vfilename,
+        '__loader__':               loader,
         '__exception_to_raise__':   exception
     }
     try:
@@ -361,15 +373,37 @@ class TracebackLoader(object):
         self.source = source
         self.filename = filename
 
+    def update_linecache(self, virtual_filename):
+        """
+        Hacky way to let traceback systems know about the
+        Jinja template sourcecode. Very hackish indeed.
+        """
+        # check for linecache, not every implementation of python
+        # might have such an module.
+        try:
+            from linecache import cache
+        except ImportError:
+            return
+        data = self.get_source(None)
+        cache[virtual_filename] = (
+            len(data),
+            None,
+            data.splitlines(True),
+            virtual_filename
+        )
+
     def get_source(self, impname):
+        source = ''
         if self.source is not None:
-            return self.source
+            source = self.source
         elif self.loader is not None:
             try:
-                return self.loader.get_source(self.filename)
+                source = self.loader.get_source(self.filename)
             except TemplateNotFound:
                 pass
-        return ''
+        if isinstance(source, unicode):
+            source = source.encode('utf-8')
+        return source
 
 
 class CacheDict(object):