X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=scripts%2Fjinja2%2Fbccache.py;h=0b0ccad1f243c598fc23c84191275d2570c65330;hb=d543bd3efe5deadc0a34423cb8645db7ff9ce704;hp=2c57616ec11083b4b6b54b902d00a03c18dd190b;hpb=279822e9e2a4f26deaf67b5fe8423b27837a75d7;p=libfirm diff --git a/scripts/jinja2/bccache.py b/scripts/jinja2/bccache.py index 2c57616ec..0b0ccad1f 100644 --- a/scripts/jinja2/bccache.py +++ b/scripts/jinja2/bccache.py @@ -11,15 +11,15 @@ Situations where this is useful are often forking web applications that are initialized on the first request. - :copyright: Copyright 2008 by Armin Ronacher. + :copyright: (c) 2010 by the Jinja Team. :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' + 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() @@ -108,12 +128,12 @@ class BytecodeCache(object): def load_bytecode(self, bucket): filename = path.join(self.directory, bucket.key) if path.exists(filename): - with file(filename, 'rb') as f: + with open(filename, 'rb') as f: bucket.load_bytecode(f) def dump_bytecode(self, bucket): filename = path.join(self.directory, bucket.key) - with file(filename, 'wb') as f: + with open(filename, 'wb') as f: bucket.write_bytecode(f) A more advanced version of a filesystem based bytecode cache is part of @@ -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): @@ -202,7 +223,7 @@ class FileSystemBytecodeCache(BytecodeCache): f.close() def dump_bytecode(self, bucket): - f = file(self._get_cache_filename(bucket), 'wb') + f = open(self._get_cache_filename(bucket), 'wb') try: bucket.write_bytecode(f) finally: