Utility functions.
- :copyright: 2008 by Armin Ronacher.
+ :copyright: (c) 2010 by the Jinja Team.
:license: BSD, see LICENSE for more details.
"""
import re
# 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
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():
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.
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
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 = []
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':
if hasattr(unicode, 'format'):
format = make_wrapper('format')
+ # not in python 3
+ if hasattr(unicode, '__getslice__'):
+ __getslice__ = make_wrapper('__getslice__')
+
del method, make_wrapper
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)
"""
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
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)
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()