import tempfile
import cPickle as pickle
import fnmatch
-from cStringIO import StringIO
try:
from hashlib import sha1
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
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."""
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()
"""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):