Various tweaks to support bccache on Python 3. This fixes #34
diff --git a/jinja2/bccache.py b/jinja2/bccache.py
index 0f7f566..866568c 100644
--- a/jinja2/bccache.py
+++ b/jinja2/bccache.py
@@ -20,7 +20,6 @@
import tempfile
import cPickle as pickle
import fnmatch
-from cStringIO import StringIO
try:
from hashlib import sha1
except ImportError:
@@ -28,6 +27,26 @@
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 @@
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 @@
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 @@
"""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):