bccache.py (4586B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\jinja2\bccache.py 2 from os import path, listdir 3 import sys 4 import marshal 5 import tempfile 6 import cPickle as pickle 7 import fnmatch 8 try: 9 from hashlib import sha1 10 except ImportError: 11 from sha import new as sha1 12 13 from jinja2.utils import open_if_exists 14 if sys.version_info > (3, 0): 15 from io import BytesIO 16 marshal_dump = marshal.dump 17 marshal_load = marshal.load 18 else: 19 from cStringIO import StringIO as BytesIO 20 21 def marshal_dump(code, f): 22 if isinstance(f, file): 23 marshal.dump(code, f) 24 else: 25 f.write(marshal.dumps(code)) 26 27 28 def marshal_load(f): 29 if isinstance(f, file): 30 return marshal.load(f) 31 return marshal.loads(f.read()) 32 33 34 bc_version = 2 35 bc_magic = 'j2'.encode('ascii') + pickle.dumps(bc_version, 2) + pickle.dumps(sys.version_info[0] << 24 | sys.version_info[1]) 36 37 class Bucket(object): 38 39 def __init__(self, environment, key, checksum): 40 self.environment = environment 41 self.key = key 42 self.checksum = checksum 43 self.reset() 44 45 def reset(self): 46 self.code = None 47 48 def load_bytecode(self, f): 49 magic = f.read(len(bc_magic)) 50 if magic != bc_magic: 51 self.reset() 52 return 53 checksum = pickle.load(f) 54 if self.checksum != checksum: 55 self.reset() 56 return 57 self.code = marshal_load(f) 58 59 def write_bytecode(self, f): 60 if self.code is None: 61 raise TypeError("can't write empty bucket") 62 f.write(bc_magic) 63 pickle.dump(self.checksum, f, 2) 64 marshal_dump(self.code, f) 65 66 def bytecode_from_string(self, string): 67 self.load_bytecode(BytesIO(string)) 68 69 def bytecode_to_string(self): 70 out = BytesIO() 71 self.write_bytecode(out) 72 return out.getvalue() 73 74 75 class BytecodeCache(object): 76 77 def load_bytecode(self, bucket): 78 raise NotImplementedError() 79 80 def dump_bytecode(self, bucket): 81 raise NotImplementedError() 82 83 def clear(self): 84 pass 85 86 def get_cache_key(self, name, filename = None): 87 hash = sha1(name.encode('utf-8')) 88 if filename is not None: 89 filename = '|' + filename 90 if isinstance(filename, unicode): 91 filename = filename.encode('utf-8') 92 hash.update(filename) 93 return hash.hexdigest() 94 95 def get_source_checksum(self, source): 96 return sha1(source.encode('utf-8')).hexdigest() 97 98 def get_bucket(self, environment, name, filename, source): 99 key = self.get_cache_key(name, filename) 100 checksum = self.get_source_checksum(source) 101 bucket = Bucket(environment, key, checksum) 102 self.load_bytecode(bucket) 103 return bucket 104 105 def set_bucket(self, bucket): 106 self.dump_bytecode(bucket) 107 108 109 class FileSystemBytecodeCache(BytecodeCache): 110 111 def __init__(self, directory = None, pattern = '__jinja2_%s.cache'): 112 if directory is None: 113 directory = tempfile.gettempdir() 114 self.directory = directory 115 self.pattern = pattern 116 117 def _get_cache_filename(self, bucket): 118 return path.join(self.directory, self.pattern % bucket.key) 119 120 def load_bytecode(self, bucket): 121 f = open_if_exists(self._get_cache_filename(bucket), 'rb') 122 if f is not None: 123 try: 124 bucket.load_bytecode(f) 125 finally: 126 f.close() 127 128 def dump_bytecode(self, bucket): 129 f = open(self._get_cache_filename(bucket), 'wb') 130 try: 131 bucket.write_bytecode(f) 132 finally: 133 f.close() 134 135 def clear(self): 136 from os import remove 137 files = fnmatch.filter(listdir(self.directory), self.pattern % '*') 138 for filename in files: 139 try: 140 remove(path.join(self.directory, filename)) 141 except OSError: 142 pass 143 144 145 class MemcachedBytecodeCache(BytecodeCache): 146 147 def __init__(self, client, prefix = 'jinja2/bytecode/', timeout = None): 148 self.client = client 149 self.prefix = prefix 150 self.timeout = timeout 151 152 def load_bytecode(self, bucket): 153 code = self.client.get(self.prefix + bucket.key) 154 if code is not None: 155 bucket.bytecode_from_string(code) 156 157 def dump_bytecode(self, bucket): 158 args = (self.prefix + bucket.key, bucket.bytecode_to_string()) 159 if self.timeout is not None: 160 args += (self.timeout,) 161 self.client.set(*args)