Various tweaks to support bccache on Python 3. This fixes #34
authorArmin Ronacher <armin.ronacher@active-4.com>
Tue, 24 May 2011 15:50:08 +0000 (17:50 +0200)
committerArmin Ronacher <armin.ronacher@active-4.com>
Tue, 24 May 2011 15:50:08 +0000 (17:50 +0200)
jinja2/bccache.py

index 0f7f566c95cba96a350b5284e0382397ac7ced80..866568cff95c5cc427be05f5d94c3a7dca55f2eb 100644 (file)
@@ -20,7 +20,6 @@ import marshal
 import tempfile
 import cPickle as pickle
 import fnmatch
-from cStringIO import StringIO
 try:
     from hashlib import sha1
 except ImportError:
@@ -28,6 +27,26 @@ except ImportError:
 from jinja2.utils import open_if_exists
 
 
+# marshal works better on 3.x, one hack less required
+if sys.version_info > (3, 0):
+    from io import BytesIO
+    marshal_dump = marshal.dump
+    marshal_load = marshal.load
+else:
+    from cStringIO import StringIO as BytesIO
+
+    def marshal_dump(code, f):
+        if isinstance(f, file):
+            marshal.dump(code, f)
+        else:
+            f.write(marshal.dumps(code))
+
+    def marshal_load(f):
+        if isinstance(f, file):
+            return marshal.load(f)
+        return marshal.loads(f.read())
+
+
 bc_version = 2
 
 # magic version used to only change with new jinja versions.  With 2.6
@@ -71,12 +90,7 @@ class Bucket(object):
         if self.checksum != checksum:
             self.reset()
             return
-        # now load the code.  Because marshal is not able to load
-        # from arbitrary streams we have to work around that
-        if isinstance(f, file):
-            self.code = marshal.load(f)
-        else:
-            self.code = marshal.loads(f.read())
+        self.code = marshal_load(f)
 
     def write_bytecode(self, f):
         """Dump the bytecode into the file or file like object passed."""
@@ -84,18 +98,15 @@ class Bucket(object):
             raise TypeError('can\'t write empty bucket')
         f.write(bc_magic)
         pickle.dump(self.checksum, f, 2)
-        if isinstance(f, file):
-            marshal.dump(self.code, f)
-        else:
-            f.write(marshal.dumps(self.code))
+        marshal_dump(code, f)
 
     def bytecode_from_string(self, string):
         """Load bytecode from a string."""
-        self.load_bytecode(StringIO(string))
+        self.load_bytecode(BytesIO(string))
 
     def bytecode_to_string(self):
         """Return the bytecode as string."""
-        out = StringIO()
+        out = BytesIO()
         self.write_bytecode(out)
         return out.getvalue()
 
@@ -153,9 +164,10 @@ class BytecodeCache(object):
         """Returns the unique hash key for this template name."""
         hash = sha1(name.encode('utf-8'))
         if filename is not None:
+            filename = '|' + filename
             if isinstance(filename, unicode):
                 filename = filename.encode('utf-8')
-            hash.update('|' + filename)
+            hash.update(filename)
         return hash.hexdigest()
 
     def get_source_checksum(self, source):