Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: third_party/jinja2/bccache.py

Issue 2316103002: binding: Updates Jinja2 from 2.7.1 to 2.8. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/jinja2/_compat.py ('k') | third_party/jinja2/compiler.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 """ 2 """
3 jinja2.bccache 3 jinja2.bccache
4 ~~~~~~~~~~~~~~ 4 ~~~~~~~~~~~~~~
5 5
6 This module implements the bytecode cache system Jinja is optionally 6 This module implements the bytecode cache system Jinja is optionally
7 using. This is useful if you have very complex template situations and 7 using. This is useful if you have very complex template situations and
8 the compiliation of all those templates slow down your application too 8 the compiliation of all those templates slow down your application too
9 much. 9 much.
10 10
11 Situations where this is useful are often forking web applications that 11 Situations where this is useful are often forking web applications that
12 are initialized on the first request. 12 are initialized on the first request.
13 13
14 :copyright: (c) 2010 by the Jinja Team. 14 :copyright: (c) 2010 by the Jinja Team.
15 :license: BSD. 15 :license: BSD.
16 """ 16 """
17 from os import path, listdir 17 from os import path, listdir
18 import os
18 import sys 19 import sys
20 import stat
21 import errno
19 import marshal 22 import marshal
20 import tempfile 23 import tempfile
21 import fnmatch 24 import fnmatch
22 from hashlib import sha1 25 from hashlib import sha1
23 from jinja2.utils import open_if_exists 26 from jinja2.utils import open_if_exists
24 from jinja2._compat import BytesIO, pickle, PY2, text_type 27 from jinja2._compat import BytesIO, pickle, PY2, text_type
25 28
26 29
27 # marshal works better on 3.x, one hack less required 30 # marshal works better on 3.x, one hack less required
28 if not PY2: 31 if not PY2:
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 # make sure the magic header is correct 81 # make sure the magic header is correct
79 magic = f.read(len(bc_magic)) 82 magic = f.read(len(bc_magic))
80 if magic != bc_magic: 83 if magic != bc_magic:
81 self.reset() 84 self.reset()
82 return 85 return
83 # the source code of the file changed, we need to reload 86 # the source code of the file changed, we need to reload
84 checksum = pickle.load(f) 87 checksum = pickle.load(f)
85 if self.checksum != checksum: 88 if self.checksum != checksum:
86 self.reset() 89 self.reset()
87 return 90 return
88 self.code = marshal_load(f) 91 # if marshal_load fails then we need to reload
92 try:
93 self.code = marshal_load(f)
94 except (EOFError, ValueError, TypeError):
95 self.reset()
96 return
89 97
90 def write_bytecode(self, f): 98 def write_bytecode(self, f):
91 """Dump the bytecode into the file or file like object passed.""" 99 """Dump the bytecode into the file or file like object passed."""
92 if self.code is None: 100 if self.code is None:
93 raise TypeError('can\'t write empty bucket') 101 raise TypeError('can\'t write empty bucket')
94 f.write(bc_magic) 102 f.write(bc_magic)
95 pickle.dump(self.checksum, f, 2) 103 pickle.dump(self.checksum, f, 2)
96 marshal_dump(self.code, f) 104 marshal_dump(self.code, f)
97 105
98 def bytecode_from_string(self, string): 106 def bytecode_from_string(self, string):
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 def set_bucket(self, bucket): 190 def set_bucket(self, bucket):
183 """Put the bucket into the cache.""" 191 """Put the bucket into the cache."""
184 self.dump_bytecode(bucket) 192 self.dump_bytecode(bucket)
185 193
186 194
187 class FileSystemBytecodeCache(BytecodeCache): 195 class FileSystemBytecodeCache(BytecodeCache):
188 """A bytecode cache that stores bytecode on the filesystem. It accepts 196 """A bytecode cache that stores bytecode on the filesystem. It accepts
189 two arguments: The directory where the cache items are stored and a 197 two arguments: The directory where the cache items are stored and a
190 pattern string that is used to build the filename. 198 pattern string that is used to build the filename.
191 199
192 If no directory is specified the system temporary items folder is used. 200 If no directory is specified a default cache directory is selected. On
201 Windows the user's temp directory is used, on UNIX systems a directory
202 is created for the user in the system temp directory.
193 203
194 The pattern can be used to have multiple separate caches operate on the 204 The pattern can be used to have multiple separate caches operate on the
195 same directory. The default pattern is ``'__jinja2_%s.cache'``. ``%s`` 205 same directory. The default pattern is ``'__jinja2_%s.cache'``. ``%s``
196 is replaced with the cache key. 206 is replaced with the cache key.
197 207
198 >>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache') 208 >>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache')
199 209
200 This bytecode cache supports clearing of the cache using the clear method. 210 This bytecode cache supports clearing of the cache using the clear method.
201 """ 211 """
202 212
203 def __init__(self, directory=None, pattern='__jinja2_%s.cache'): 213 def __init__(self, directory=None, pattern='__jinja2_%s.cache'):
204 if directory is None: 214 if directory is None:
205 directory = tempfile.gettempdir() 215 directory = self._get_default_cache_dir()
206 self.directory = directory 216 self.directory = directory
207 self.pattern = pattern 217 self.pattern = pattern
208 218
219 def _get_default_cache_dir(self):
220 def _unsafe_dir():
221 raise RuntimeError('Cannot determine safe temp directory. You '
222 'need to explicitly provide one.')
223
224 tmpdir = tempfile.gettempdir()
225
226 # On windows the temporary directory is used specific unless
227 # explicitly forced otherwise. We can just use that.
228 if os.name == 'nt':
229 return tmpdir
230 if not hasattr(os, 'getuid'):
231 _unsafe_dir()
232
233 dirname = '_jinja2-cache-%d' % os.getuid()
234 actual_dir = os.path.join(tmpdir, dirname)
235
236 try:
237 os.mkdir(actual_dir, stat.S_IRWXU)
238 except OSError as e:
239 if e.errno != errno.EEXIST:
240 raise
241 try:
242 os.chmod(actual_dir, stat.S_IRWXU)
243 actual_dir_stat = os.lstat(actual_dir)
244 if actual_dir_stat.st_uid != os.getuid() \
245 or not stat.S_ISDIR(actual_dir_stat.st_mode) \
246 or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU:
247 _unsafe_dir()
248 except OSError as e:
249 if e.errno != errno.EEXIST:
250 raise
251
252 actual_dir_stat = os.lstat(actual_dir)
253 if actual_dir_stat.st_uid != os.getuid() \
254 or not stat.S_ISDIR(actual_dir_stat.st_mode) \
255 or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU:
256 _unsafe_dir()
257
258 return actual_dir
259
209 def _get_cache_filename(self, bucket): 260 def _get_cache_filename(self, bucket):
210 return path.join(self.directory, self.pattern % bucket.key) 261 return path.join(self.directory, self.pattern % bucket.key)
211 262
212 def load_bytecode(self, bucket): 263 def load_bytecode(self, bucket):
213 f = open_if_exists(self._get_cache_filename(bucket), 'rb') 264 f = open_if_exists(self._get_cache_filename(bucket), 'rb')
214 if f is not None: 265 if f is not None:
215 try: 266 try:
216 bucket.load_bytecode(f) 267 bucket.load_bytecode(f)
217 finally: 268 finally:
218 f.close() 269 f.close()
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 353
303 def dump_bytecode(self, bucket): 354 def dump_bytecode(self, bucket):
304 args = (self.prefix + bucket.key, bucket.bytecode_to_string()) 355 args = (self.prefix + bucket.key, bucket.bytecode_to_string())
305 if self.timeout is not None: 356 if self.timeout is not None:
306 args += (self.timeout,) 357 args += (self.timeout,)
307 try: 358 try:
308 self.client.set(*args) 359 self.client.set(*args)
309 except Exception: 360 except Exception:
310 if not self.ignore_memcache_errors: 361 if not self.ignore_memcache_errors:
311 raise 362 raise
OLDNEW
« no previous file with comments | « third_party/jinja2/_compat.py ('k') | third_party/jinja2/compiler.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698