X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=scripts%2Fjinja2%2Futils.py;h=c24d7aa5b937dac44e849c537c605b7ee2d31a9e;hb=753399e387c8fa3b26116f6693a74cf9a824b177;hp=3f3d053de7e4ccb044be2f6371e53a063fb8cc5e;hpb=279822e9e2a4f26deaf67b5fe8423b27837a75d7;p=libfirm diff --git a/scripts/jinja2/utils.py b/scripts/jinja2/utils.py index 3f3d053de..c24d7aa5b 100644 --- a/scripts/jinja2/utils.py +++ b/scripts/jinja2/utils.py @@ -5,7 +5,7 @@ Utility functions. - :copyright: 2008 by Armin Ronacher. + :copyright: (c) 2010 by the Jinja Team. :license: BSD, see LICENSE for more details. """ import re @@ -35,6 +35,9 @@ _digits = '0123456789' # special singleton representing missing values for the runtime missing = type('MissingType', (), {'__repr__': lambda x: 'missing'})() +# internal code +internal_code = set() + # concatenate a list of strings and convert them to unicode. # unfortunately there is a bug in python 2.4 and lower that causes @@ -60,23 +63,37 @@ except TypeError, _error: del _test_gen_bug, _error -# ironpython without stdlib doesn't have keyword +# for python 2.x we create outselves a next() function that does the +# basics without exception catching. try: - from keyword import iskeyword as is_python_keyword -except ImportError: - _py_identifier_re = re.compile(r'^[a-zA-Z_][a-zA-Z0-9]*$') - def is_python_keyword(name): - if _py_identifier_re.search(name) is None: - return False - try: - exec name + " = 42" - except SyntaxError: - return False - return True + next = next +except NameError: + def next(x): + return x.next() + + +# if this python version is unable to deal with unicode filenames +# when passed to encode we let this function encode it properly. +# This is used in a couple of places. As far as Jinja is concerned +# filenames are unicode *or* bytestrings in 2.x and unicode only in +# 3.x because compile cannot handle bytes +if sys.version_info < (3, 0): + def _encode_filename(filename): + if isinstance(filename, unicode): + return filename.encode('utf-8') + return filename +else: + def _encode_filename(filename): + assert filename is None or isinstance(filename, str), \ + 'filenames must be strings' + return filename + +from keyword import iskeyword as is_python_keyword # common types. These do exist in the special types module too which however -# does not exist in IronPython out of the box. +# does not exist in IronPython out of the box. Also that way we don't have +# to deal with implementation specific stuff here class _C(object): def method(self): pass def _func(): @@ -120,6 +137,12 @@ def environmentfunction(f): return f +def internalcode(f): + """Marks the function as internally used""" + internal_code.add(f.func_code) + return f + + def is_undefined(obj): """Check if the object passed is undefined. This does nothing more than performing an instance check against :class:`Undefined` but looks nicer. @@ -180,12 +203,12 @@ def import_string(import_name, silent=False): raise -def open_if_exists(filename, mode='r'): +def open_if_exists(filename, mode='rb'): """Returns a file descriptor for the filename if that file exists, otherwise `None`. """ try: - return file(filename, mode) + return open(filename, mode) except IOError, e: if e.errno not in (errno.ENOENT, errno.EISDIR): raise @@ -250,7 +273,7 @@ def urlize(text, trim_url_limit=None, nofollow=False): def generate_lorem_ipsum(n=5, html=True, min=20, max=100): """Generate some lorem impsum for the template.""" from jinja2.constants import LOREM_IPSUM_WORDS - from random import choice, random, randrange + from random import choice, randrange words = LOREM_IPSUM_WORDS.split() result = [] @@ -451,7 +474,7 @@ class Markup(unicode): func.__doc__ = orig.__doc__ return func - for method in '__getitem__', '__getslice__', 'capitalize', \ + for method in '__getitem__', 'capitalize', \ 'title', 'lower', 'upper', 'replace', 'ljust', \ 'rjust', 'lstrip', 'rstrip', 'center', 'strip', \ 'translate', 'expandtabs', 'swapcase', 'zfill': @@ -466,6 +489,10 @@ class Markup(unicode): if hasattr(unicode, 'format'): format = make_wrapper('format') + # not in python 3 + if hasattr(unicode, '__getslice__'): + __getslice__ = make_wrapper('__getslice__') + del method, make_wrapper @@ -484,8 +511,8 @@ class _MarkupEscapeHelper(object): self.obj = obj __getitem__ = lambda s, x: _MarkupEscapeHelper(s.obj[x]) - __unicode__ = lambda s: unicode(escape(s.obj)) __str__ = lambda s: str(escape(s.obj)) + __unicode__ = lambda s: unicode(escape(s.obj)) __repr__ = lambda s: str(escape(repr(s.obj))) __int__ = lambda s: int(s.obj) __float__ = lambda s: float(s.obj) @@ -589,7 +616,13 @@ class LRUCache(object): """ rv = self._mapping[key] if self._queue[-1] != key: - self._remove(key) + try: + self._remove(key) + except ValueError: + # if something removed the key from the container + # when we read, ignore the ValueError that we would + # get otherwise. + pass self._append(key) return rv @@ -600,7 +633,11 @@ class LRUCache(object): self._wlock.acquire() try: if key in self._mapping: - self._remove(key) + try: + self._remove(key) + except ValueError: + # __getitem__ is not locked, it might happen + pass elif len(self._mapping) == self.capacity: del self._mapping[self._popleft()] self._append(key) @@ -615,7 +652,11 @@ class LRUCache(object): self._wlock.acquire() try: del self._mapping[key] - self._remove(key) + try: + self._remove(key) + except ValueError: + # __getitem__ is not locked, it might happen + pass finally: self._wlock.release()