X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=scripts%2Fjinja2%2Fbccache.py;h=0b0ccad1f243c598fc23c84191275d2570c65330;hb=8205228fcd3fd0e1dec436e1650cf09720bd6503;hp=1e2236c3a5cead1b6c53c021ec35546d5184ca87;hpb=1a3b7d363474ab544c13093a2f0b578718d37c7a;p=libfirm diff --git a/scripts/jinja2/bccache.py b/scripts/jinja2/bccache.py index 1e2236c3a..0b0ccad1f 100644 --- a/scripts/jinja2/bccache.py +++ b/scripts/jinja2/bccache.py @@ -15,11 +15,11 @@ :license: BSD. """ from os import path, listdir +import sys import marshal import tempfile import cPickle as pickle import fnmatch -from cStringIO import StringIO try: from hashlib import sha1 except ImportError: @@ -27,8 +27,36 @@ except ImportError: from jinja2.utils import open_if_exists -bc_version = 1 -bc_magic = 'j2'.encode('ascii') + pickle.dumps(bc_version, 2) +# 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 +# we change this to also take Python version changes into account. The +# reason for this is that Python tends to segfault if fed earlier bytecode +# versions because someone thought it would be a good idea to reuse opcodes +# or make Python incompatible with earlier versions. +bc_magic = 'j2'.encode('ascii') + \ + pickle.dumps(bc_version, 2) + \ + pickle.dumps((sys.version_info[0] << 24) | sys.version_info[1]) class Bucket(object): @@ -62,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.""" @@ -75,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(self.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() @@ -144,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):