NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

utils.py (11639B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\jinja2\utils.py
      2 import re
      3 import sys
      4 import errno
      5 try:
      6     from urllib.parse import quote_from_bytes as url_quote
      7 except ImportError:
      8     from urllib import quote as url_quote
      9 
     10 try:
     11     from thread import allocate_lock
     12 except ImportError:
     13     from dummy_thread import allocate_lock
     14 
     15 from collections import deque
     16 from itertools import imap
     17 _word_split_re = re.compile('(\\s+)')
     18 _punctuation_re = re.compile('^(?P<lead>(?:%s)*)(?P<middle>.*?)(?P<trail>(?:%s)*)$' % ('|'.join(imap(re.escape, ('(', '<', '&lt;'))), '|'.join(imap(re.escape, ('.', ',', ')', '>', '\n', '&gt;')))))
     19 _simple_email_re = re.compile('^\\S+@[a-zA-Z0-9._-]+\\.[a-zA-Z0-9._-]+$')
     20 _striptags_re = re.compile('(<!--.*?-->|<[^>]*>)')
     21 _entity_re = re.compile('&([^;]+);')
     22 _letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
     23 _digits = '0123456789'
     24 missing = type('MissingType', (), {'__repr__': lambda x: 'missing'})()
     25 internal_code = set()
     26 _concat = u''.join
     27 try:
     28 
     29     def _test_gen_bug():
     30         raise TypeError(_test_gen_bug)
     31         yield
     32 
     33 
     34     _concat(_test_gen_bug())
     35 except TypeError as _error:
     36     if not _error.args or _error.args[0] is not _test_gen_bug:
     37 
     38         def concat(gen):
     39             try:
     40                 return _concat(list(gen))
     41             except Exception:
     42                 exc_type, exc_value, tb = sys.exc_info()
     43                 raise exc_type, exc_value, tb.tb_next
     44 
     45 
     46     else:
     47         concat = _concat
     48     del _test_gen_bug
     49     del _error
     50 
     51 try:
     52     next = next
     53 except NameError:
     54 
     55     def next(x):
     56         return x.next()
     57 
     58 
     59 if sys.version_info < (3, 0):
     60 
     61     def _encode_filename(filename):
     62         if isinstance(filename, unicode):
     63             return filename.encode('utf-8')
     64         return filename
     65 
     66 
     67 else:
     68 
     69     def _encode_filename(filename):
     70         return filename
     71 
     72 
     73 from keyword import iskeyword as is_python_keyword
     74 
     75 class _C(object):
     76 
     77     def method(self):
     78         pass
     79 
     80 
     81 def _func():
     82     yield
     83 
     84 
     85 FunctionType = type(_func)
     86 GeneratorType = type(_func())
     87 MethodType = type(_C.method)
     88 CodeType = type(_C.method.func_code)
     89 try:
     90     raise TypeError()
     91 except TypeError:
     92     _tb = sys.exc_info()[2]
     93     TracebackType = type(_tb)
     94     FrameType = type(_tb.tb_frame)
     95 
     96 del _C
     97 del _tb
     98 del _func
     99 
    100 def contextfunction(f):
    101     f.contextfunction = True
    102     return f
    103 
    104 
    105 def evalcontextfunction(f):
    106     f.evalcontextfunction = True
    107     return f
    108 
    109 
    110 def environmentfunction(f):
    111     f.environmentfunction = True
    112     return f
    113 
    114 
    115 def internalcode(f):
    116     internal_code.add(f.func_code)
    117     return f
    118 
    119 
    120 def is_undefined(obj):
    121     from jinja2.runtime import Undefined
    122     return isinstance(obj, Undefined)
    123 
    124 
    125 def consume(iterable):
    126     for event in iterable:
    127         pass
    128 
    129 
    130 def clear_caches():
    131     from jinja2.environment import _spontaneous_environments
    132     from jinja2.lexer import _lexer_cache
    133     _spontaneous_environments.clear()
    134     _lexer_cache.clear()
    135 
    136 
    137 def import_string(import_name, silent = False):
    138     try:
    139         if ':' in import_name:
    140             module, obj = import_name.split(':', 1)
    141         elif '.' in import_name:
    142             items = import_name.split('.')
    143             module = '.'.join(items[:-1])
    144             obj = items[-1]
    145         else:
    146             return __import__(import_name)
    147         return getattr(__import__(module, None, None, [obj]), obj)
    148     except (ImportError, AttributeError):
    149         if not silent:
    150             raise
    151 
    152 
    153 def open_if_exists(filename, mode = 'rb'):
    154     try:
    155         return open(filename, mode)
    156     except IOError as e:
    157         if e.errno not in (errno.ENOENT, errno.EISDIR):
    158             raise
    159 
    160 
    161 def object_type_repr(obj):
    162     if obj is None:
    163         return 'None'
    164     if obj is Ellipsis:
    165         return 'Ellipsis'
    166     if obj.__class__.__module__ in ('__builtin__', 'builtins'):
    167         name = obj.__class__.__name__
    168     else:
    169         name = obj.__class__.__module__ + '.' + obj.__class__.__name__
    170     return '%s object' % name
    171 
    172 
    173 def pformat(obj, verbose = False):
    174     try:
    175         from pretty import pretty
    176         return pretty(obj, verbose=verbose)
    177     except ImportError:
    178         from pprint import pformat
    179         return pformat(obj)
    180 
    181 
    182 def urlize(text, trim_url_limit = None, nofollow = False):
    183     trim_url = lambda x, limit = trim_url_limit: limit is not None and x[:limit] + (len(x) >= limit and '...' or '') or x
    184     words = _word_split_re.split(unicode(escape(text)))
    185     nofollow_attr = nofollow and ' rel="nofollow"' or ''
    186     for i, word in enumerate(words):
    187         match = _punctuation_re.match(word)
    188         if match:
    189             lead, middle, trail = match.groups()
    190             if middle.startswith('www.') or '@' not in middle and not middle.startswith('http://') and len(middle) > 0 and middle[0] in _letters + _digits and (middle.endswith('.org') or middle.endswith('.net') or middle.endswith('.com')):
    191                 middle = '<a href="http://%s"%s>%s</a>' % (middle, nofollow_attr, trim_url(middle))
    192             if middle.startswith('http://') or middle.startswith('https://'):
    193                 middle = '<a href="%s"%s>%s</a>' % (middle, nofollow_attr, trim_url(middle))
    194             if '@' in middle and not middle.startswith('www.') and ':' not in middle and _simple_email_re.match(middle):
    195                 middle = '<a href="mailto:%s">%s</a>' % (middle, middle)
    196             if lead + middle + trail != word:
    197                 words[i] = lead + middle + trail
    198 
    199     return u''.join(words)
    200 
    201 
    202 def generate_lorem_ipsum(n = 5, html = True, min = 20, max = 100):
    203     from jinja2.constants import LOREM_IPSUM_WORDS
    204     from random import choice, randrange
    205     words = LOREM_IPSUM_WORDS.split()
    206     result = []
    207     for _ in xrange(n):
    208         next_capitalized = True
    209         last_comma = last_fullstop = 0
    210         word = None
    211         last = None
    212         p = []
    213         for idx, _ in enumerate(xrange(randrange(min, max))):
    214             while True:
    215                 word = choice(words)
    216                 if word != last:
    217                     last = word
    218                     break
    219 
    220             if next_capitalized:
    221                 word = word.capitalize()
    222                 next_capitalized = False
    223             if idx - randrange(3, 8) > last_comma:
    224                 last_comma = idx
    225                 last_fullstop += 2
    226                 word += ','
    227             if idx - randrange(10, 20) > last_fullstop:
    228                 last_comma = last_fullstop = idx
    229                 word += '.'
    230                 next_capitalized = True
    231             p.append(word)
    232 
    233         p = u' '.join(p)
    234         if p.endswith(','):
    235             p = p[:-1] + '.'
    236         elif not p.endswith('.'):
    237             p += '.'
    238         result.append(p)
    239 
    240     if not html:
    241         return u'\n\n'.join(result)
    242     return Markup(u'\n'.join((u'<p>%s</p>' % escape(x) for x in result)))
    243 
    244 
    245 def unicode_urlencode(obj, charset = 'utf-8'):
    246     if not isinstance(obj, basestring):
    247         obj = unicode(obj)
    248     if isinstance(obj, unicode):
    249         obj = obj.encode(charset)
    250     return unicode(url_quote(obj))
    251 
    252 
    253 class LRUCache(object):
    254 
    255     def __init__(self, capacity):
    256         self.capacity = capacity
    257         self._mapping = {}
    258         self._queue = deque()
    259         self._postinit()
    260 
    261     def _postinit(self):
    262         self._popleft = self._queue.popleft
    263         self._pop = self._queue.pop
    264         if hasattr(self._queue, 'remove'):
    265             self._remove = self._queue.remove
    266         self._wlock = allocate_lock()
    267         self._append = self._queue.append
    268 
    269     def _remove(self, obj):
    270         for idx, item in enumerate(self._queue):
    271             if item == obj:
    272                 del self._queue[idx]
    273                 break
    274 
    275     def __getstate__(self):
    276         return {'capacity': self.capacity,
    277          '_mapping': self._mapping,
    278          '_queue': self._queue}
    279 
    280     def __setstate__(self, d):
    281         self.__dict__.update(d)
    282         self._postinit()
    283 
    284     def __getnewargs__(self):
    285         return (self.capacity,)
    286 
    287     def copy(self):
    288         rv = self.__class__(self.capacity)
    289         rv._mapping.update(self._mapping)
    290         rv._queue = deque(self._queue)
    291         return rv
    292 
    293     def get(self, key, default = None):
    294         try:
    295             return self[key]
    296         except KeyError:
    297             return default
    298 
    299     def setdefault(self, key, default = None):
    300         try:
    301             return self[key]
    302         except KeyError:
    303             self[key] = default
    304             return default
    305 
    306     def clear(self):
    307         self._wlock.acquire()
    308         try:
    309             self._mapping.clear()
    310             self._queue.clear()
    311         finally:
    312             self._wlock.release()
    313 
    314     def __contains__(self, key):
    315         return key in self._mapping
    316 
    317     def __len__(self):
    318         return len(self._mapping)
    319 
    320     def __repr__(self):
    321         return '<%s %r>' % (self.__class__.__name__, self._mapping)
    322 
    323     def __getitem__(self, key):
    324         rv = self._mapping[key]
    325         if self._queue[-1] != key:
    326             try:
    327                 self._remove(key)
    328             except ValueError:
    329                 pass
    330 
    331             self._append(key)
    332         return rv
    333 
    334     def __setitem__(self, key, value):
    335         self._wlock.acquire()
    336         try:
    337             if key in self._mapping:
    338                 try:
    339                     self._remove(key)
    340                 except ValueError:
    341                     pass
    342 
    343             elif len(self._mapping) == self.capacity:
    344                 del self._mapping[self._popleft()]
    345             self._append(key)
    346             self._mapping[key] = value
    347         finally:
    348             self._wlock.release()
    349 
    350     def __delitem__(self, key):
    351         self._wlock.acquire()
    352         try:
    353             del self._mapping[key]
    354             try:
    355                 self._remove(key)
    356             except ValueError:
    357                 pass
    358 
    359         finally:
    360             self._wlock.release()
    361 
    362     def items(self):
    363         result = [ (key, self._mapping[key]) for key in list(self._queue) ]
    364         result.reverse()
    365         return result
    366 
    367     def iteritems(self):
    368         return iter(self.items())
    369 
    370     def values(self):
    371         return [ x[1] for x in self.items() ]
    372 
    373     def itervalue(self):
    374         return iter(self.values())
    375 
    376     def keys(self):
    377         return list(self)
    378 
    379     def iterkeys(self):
    380         return reversed(tuple(self._queue))
    381 
    382     __iter__ = iterkeys
    383 
    384     def __reversed__(self):
    385         return iter(tuple(self._queue))
    386 
    387     __copy__ = copy
    388 
    389 
    390 try:
    391     from collections import MutableMapping
    392     MutableMapping.register(LRUCache)
    393 except ImportError:
    394     pass
    395 
    396 class Cycler(object):
    397 
    398     def __init__(self, *items):
    399         if not items:
    400             raise RuntimeError('at least one item has to be provided')
    401         self.items = items
    402         self.reset()
    403 
    404     def reset(self):
    405         self.pos = 0
    406 
    407     @property
    408     def current(self):
    409         return self.items[self.pos]
    410 
    411     def next(self):
    412         rv = self.current
    413         self.pos = (self.pos + 1) % len(self.items)
    414         return rv
    415 
    416 
    417 class Joiner(object):
    418 
    419     def __init__(self, sep = u', '):
    420         self.sep = sep
    421         self.used = False
    422 
    423     def __call__(self):
    424         if not self.used:
    425             self.used = True
    426             return u''
    427         return self.sep
    428 
    429 
    430 try:
    431     from markupsafe import Markup, escape, soft_unicode
    432 except ImportError:
    433     from jinja2._markupsafe import Markup, escape, soft_unicode
    434 
    435 try:
    436     from functools import partial
    437 except ImportError:
    438 
    439     class partial(object):
    440 
    441         def __init__(self, _func, *args, **kwargs):
    442             self._func = _func
    443             self._args = args
    444             self._kwargs = kwargs
    445 
    446         def __call__(self, *args, **kwargs):
    447             kwargs.update(self._kwargs)
    448             return self._func(*(self._args + args), **kwargs)