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

Side by Side Diff: third_party/markupsafe/__init__.py

Issue 23445019: Add MarkupSafe library to third_party (dependency for Jinja2 2.7) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix typo Created 7 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 | Annotate | Revision Log
« no previous file with comments | « third_party/markupsafe/README.chromium ('k') | third_party/markupsafe/_compat.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 markupsafe 3 markupsafe
4 ~~~~~~~~~~ 4 ~~~~~~~~~~
5 5
6 Implements a Markup string. 6 Implements a Markup string.
7 7
8 :copyright: (c) 2010 by Armin Ronacher. 8 :copyright: (c) 2010 by Armin Ronacher.
9 :license: BSD, see LICENSE for more details. 9 :license: BSD, see LICENSE for more details.
10 """ 10 """
11 import re 11 import re
12 from itertools import imap 12 from markupsafe._compat import text_type, string_types, int_types, \
13 unichr, PY2
13 14
14 15
15 __all__ = ['Markup', 'soft_unicode', 'escape', 'escape_silent'] 16 __all__ = ['Markup', 'soft_unicode', 'escape', 'escape_silent']
16 17
17 18
18 _striptags_re = re.compile(r'(<!--.*?-->|<[^>]*>)') 19 _striptags_re = re.compile(r'(<!--.*?-->|<[^>]*>)')
19 _entity_re = re.compile(r'&([^;]+);') 20 _entity_re = re.compile(r'&([^;]+);')
20 21
21 22
22 class Markup(unicode): 23 class Markup(text_type):
23 r"""Marks a string as being safe for inclusion in HTML/XML output without 24 r"""Marks a string as being safe for inclusion in HTML/XML output without
24 needing to be escaped. This implements the `__html__` interface a couple 25 needing to be escaped. This implements the `__html__` interface a couple
25 of frameworks and web applications use. :class:`Markup` is a direct 26 of frameworks and web applications use. :class:`Markup` is a direct
26 subclass of `unicode` and provides all the methods of `unicode` just that 27 subclass of `unicode` and provides all the methods of `unicode` just that
27 it escapes arguments passed and always returns `Markup`. 28 it escapes arguments passed and always returns `Markup`.
28 29
29 The `escape` function returns markup objects so that double escaping can't 30 The `escape` function returns markup objects so that double escaping can't
30 happen. 31 happen.
31 32
32 The constructor of the :class:`Markup` class can be used for three 33 The constructor of the :class:`Markup` class can be used for three
(...skipping 28 matching lines...) Expand all
61 Markup(u'<strong>&lt;blink&gt;hacker here&lt;/blink&gt;</strong>') 62 Markup(u'<strong>&lt;blink&gt;hacker here&lt;/blink&gt;</strong>')
62 >>> Markup("<em>Hello</em> ") + "<foo>" 63 >>> Markup("<em>Hello</em> ") + "<foo>"
63 Markup(u'<em>Hello</em> &lt;foo&gt;') 64 Markup(u'<em>Hello</em> &lt;foo&gt;')
64 """ 65 """
65 __slots__ = () 66 __slots__ = ()
66 67
67 def __new__(cls, base=u'', encoding=None, errors='strict'): 68 def __new__(cls, base=u'', encoding=None, errors='strict'):
68 if hasattr(base, '__html__'): 69 if hasattr(base, '__html__'):
69 base = base.__html__() 70 base = base.__html__()
70 if encoding is None: 71 if encoding is None:
71 return unicode.__new__(cls, base) 72 return text_type.__new__(cls, base)
72 return unicode.__new__(cls, base, encoding, errors) 73 return text_type.__new__(cls, base, encoding, errors)
73 74
74 def __html__(self): 75 def __html__(self):
75 return self 76 return self
76 77
77 def __add__(self, other): 78 def __add__(self, other):
78 if hasattr(other, '__html__') or isinstance(other, basestring): 79 if isinstance(other, string_types) or hasattr(other, '__html__'):
79 return self.__class__(unicode(self) + unicode(escape(other))) 80 return self.__class__(super(Markup, self).__add__(self.escape(other) ))
80 return NotImplemented 81 return NotImplemented
81 82
82 def __radd__(self, other): 83 def __radd__(self, other):
83 if hasattr(other, '__html__') or isinstance(other, basestring): 84 if hasattr(other, '__html__') or isinstance(other, string_types):
84 return self.__class__(unicode(escape(other)) + unicode(self)) 85 return self.escape(other).__add__(self)
85 return NotImplemented 86 return NotImplemented
86 87
87 def __mul__(self, num): 88 def __mul__(self, num):
88 if isinstance(num, (int, long)): 89 if isinstance(num, int_types):
89 return self.__class__(unicode.__mul__(self, num)) 90 return self.__class__(text_type.__mul__(self, num))
90 return NotImplemented 91 return NotImplemented
91 __rmul__ = __mul__ 92 __rmul__ = __mul__
92 93
93 def __mod__(self, arg): 94 def __mod__(self, arg):
94 if isinstance(arg, tuple): 95 if isinstance(arg, tuple):
95 arg = tuple(imap(_MarkupEscapeHelper, arg)) 96 arg = tuple(_MarkupEscapeHelper(x, self.escape) for x in arg)
96 else: 97 else:
97 arg = _MarkupEscapeHelper(arg) 98 arg = _MarkupEscapeHelper(arg, self.escape)
98 return self.__class__(unicode.__mod__(self, arg)) 99 return self.__class__(text_type.__mod__(self, arg))
99 100
100 def __repr__(self): 101 def __repr__(self):
101 return '%s(%s)' % ( 102 return '%s(%s)' % (
102 self.__class__.__name__, 103 self.__class__.__name__,
103 unicode.__repr__(self) 104 text_type.__repr__(self)
104 ) 105 )
105 106
106 def join(self, seq): 107 def join(self, seq):
107 return self.__class__(unicode.join(self, imap(escape, seq))) 108 return self.__class__(text_type.join(self, map(self.escape, seq)))
108 join.__doc__ = unicode.join.__doc__ 109 join.__doc__ = text_type.join.__doc__
109 110
110 def split(self, *args, **kwargs): 111 def split(self, *args, **kwargs):
111 return map(self.__class__, unicode.split(self, *args, **kwargs)) 112 return list(map(self.__class__, text_type.split(self, *args, **kwargs)))
112 split.__doc__ = unicode.split.__doc__ 113 split.__doc__ = text_type.split.__doc__
113 114
114 def rsplit(self, *args, **kwargs): 115 def rsplit(self, *args, **kwargs):
115 return map(self.__class__, unicode.rsplit(self, *args, **kwargs)) 116 return list(map(self.__class__, text_type.rsplit(self, *args, **kwargs)) )
116 rsplit.__doc__ = unicode.rsplit.__doc__ 117 rsplit.__doc__ = text_type.rsplit.__doc__
117 118
118 def splitlines(self, *args, **kwargs): 119 def splitlines(self, *args, **kwargs):
119 return map(self.__class__, unicode.splitlines(self, *args, **kwargs)) 120 return list(map(self.__class__, text_type.splitlines(self, *args, **kwar gs)))
120 splitlines.__doc__ = unicode.splitlines.__doc__ 121 splitlines.__doc__ = text_type.splitlines.__doc__
121 122
122 def unescape(self): 123 def unescape(self):
123 r"""Unescape markup again into an unicode string. This also resolves 124 r"""Unescape markup again into an text_type string. This also resolves
124 known HTML4 and XHTML entities: 125 known HTML4 and XHTML entities:
125 126
126 >>> Markup("Main &raquo; <em>About</em>").unescape() 127 >>> Markup("Main &raquo; <em>About</em>").unescape()
127 u'Main \xbb <em>About</em>' 128 u'Main \xbb <em>About</em>'
128 """ 129 """
129 from jinja2._markupsafe._constants import HTML_ENTITIES 130 from markupsafe._constants import HTML_ENTITIES
130 def handle_match(m): 131 def handle_match(m):
131 name = m.group(1) 132 name = m.group(1)
132 if name in HTML_ENTITIES: 133 if name in HTML_ENTITIES:
133 return unichr(HTML_ENTITIES[name]) 134 return unichr(HTML_ENTITIES[name])
134 try: 135 try:
135 if name[:2] in ('#x', '#X'): 136 if name[:2] in ('#x', '#X'):
136 return unichr(int(name[2:], 16)) 137 return unichr(int(name[2:], 16))
137 elif name.startswith('#'): 138 elif name.startswith('#'):
138 return unichr(int(name[1:])) 139 return unichr(int(name[1:]))
139 except ValueError: 140 except ValueError:
140 pass 141 pass
141 return u'' 142 return u''
142 return _entity_re.sub(handle_match, unicode(self)) 143 return _entity_re.sub(handle_match, text_type(self))
143 144
144 def striptags(self): 145 def striptags(self):
145 r"""Unescape markup into an unicode string and strip all tags. This 146 r"""Unescape markup into an text_type string and strip all tags. This
146 also resolves known HTML4 and XHTML entities. Whitespace is 147 also resolves known HTML4 and XHTML entities. Whitespace is
147 normalized to one: 148 normalized to one:
148 149
149 >>> Markup("Main &raquo; <em>About</em>").striptags() 150 >>> Markup("Main &raquo; <em>About</em>").striptags()
150 u'Main \xbb About' 151 u'Main \xbb About'
151 """ 152 """
152 stripped = u' '.join(_striptags_re.sub('', self).split()) 153 stripped = u' '.join(_striptags_re.sub('', self).split())
153 return Markup(stripped).unescape() 154 return Markup(stripped).unescape()
154 155
155 @classmethod 156 @classmethod
156 def escape(cls, s): 157 def escape(cls, s):
157 """Escape the string. Works like :func:`escape` with the difference 158 """Escape the string. Works like :func:`escape` with the difference
158 that for subclasses of :class:`Markup` this function would return the 159 that for subclasses of :class:`Markup` this function would return the
159 correct subclass. 160 correct subclass.
160 """ 161 """
161 rv = escape(s) 162 rv = escape(s)
162 if rv.__class__ is not cls: 163 if rv.__class__ is not cls:
163 return cls(rv) 164 return cls(rv)
164 return rv 165 return rv
165 166
166 def make_wrapper(name): 167 def make_wrapper(name):
167 orig = getattr(unicode, name) 168 orig = getattr(text_type, name)
168 def func(self, *args, **kwargs): 169 def func(self, *args, **kwargs):
169 args = _escape_argspec(list(args), enumerate(args)) 170 args = _escape_argspec(list(args), enumerate(args), self.escape)
170 _escape_argspec(kwargs, kwargs.iteritems()) 171 #_escape_argspec(kwargs, kwargs.iteritems(), None)
171 return self.__class__(orig(self, *args, **kwargs)) 172 return self.__class__(orig(self, *args, **kwargs))
172 func.__name__ = orig.__name__ 173 func.__name__ = orig.__name__
173 func.__doc__ = orig.__doc__ 174 func.__doc__ = orig.__doc__
174 return func 175 return func
175 176
176 for method in '__getitem__', 'capitalize', \ 177 for method in '__getitem__', 'capitalize', \
177 'title', 'lower', 'upper', 'replace', 'ljust', \ 178 'title', 'lower', 'upper', 'replace', 'ljust', \
178 'rjust', 'lstrip', 'rstrip', 'center', 'strip', \ 179 'rjust', 'lstrip', 'rstrip', 'center', 'strip', \
179 'translate', 'expandtabs', 'swapcase', 'zfill': 180 'translate', 'expandtabs', 'swapcase', 'zfill':
180 locals()[method] = make_wrapper(method) 181 locals()[method] = make_wrapper(method)
181 182
182 # new in python 2.5 183 # new in python 2.5
183 if hasattr(unicode, 'partition'): 184 if hasattr(text_type, 'partition'):
184 partition = make_wrapper('partition'), 185 def partition(self, sep):
185 rpartition = make_wrapper('rpartition') 186 return tuple(map(self.__class__,
187 text_type.partition(self, self.escape(sep))))
188 def rpartition(self, sep):
189 return tuple(map(self.__class__,
190 text_type.rpartition(self, self.escape(sep))))
186 191
187 # new in python 2.6 192 # new in python 2.6
188 if hasattr(unicode, 'format'): 193 if hasattr(text_type, 'format'):
189 format = make_wrapper('format') 194 format = make_wrapper('format')
190 195
191 # not in python 3 196 # not in python 3
192 if hasattr(unicode, '__getslice__'): 197 if hasattr(text_type, '__getslice__'):
193 __getslice__ = make_wrapper('__getslice__') 198 __getslice__ = make_wrapper('__getslice__')
194 199
195 del method, make_wrapper 200 del method, make_wrapper
196 201
197 202
198 def _escape_argspec(obj, iterable): 203 def _escape_argspec(obj, iterable, escape):
199 """Helper for various string-wrapped functions.""" 204 """Helper for various string-wrapped functions."""
200 for key, value in iterable: 205 for key, value in iterable:
201 if hasattr(value, '__html__') or isinstance(value, basestring): 206 if hasattr(value, '__html__') or isinstance(value, string_types):
202 obj[key] = escape(value) 207 obj[key] = escape(value)
203 return obj 208 return obj
204 209
205 210
206 class _MarkupEscapeHelper(object): 211 class _MarkupEscapeHelper(object):
207 """Helper for Markup.__mod__""" 212 """Helper for Markup.__mod__"""
208 213
209 def __init__(self, obj): 214 def __init__(self, obj, escape):
210 self.obj = obj 215 self.obj = obj
216 self.escape = escape
211 217
212 __getitem__ = lambda s, x: _MarkupEscapeHelper(s.obj[x]) 218 __getitem__ = lambda s, x: _MarkupEscapeHelper(s.obj[x], s.escape)
213 __str__ = lambda s: str(escape(s.obj)) 219 __unicode__ = __str__ = lambda s: text_type(s.escape(s.obj))
214 __unicode__ = lambda s: unicode(escape(s.obj)) 220 __repr__ = lambda s: str(s.escape(repr(s.obj)))
215 __repr__ = lambda s: str(escape(repr(s.obj)))
216 __int__ = lambda s: int(s.obj) 221 __int__ = lambda s: int(s.obj)
217 __float__ = lambda s: float(s.obj) 222 __float__ = lambda s: float(s.obj)
218 223
219 224
220 # we have to import it down here as the speedups and native 225 # we have to import it down here as the speedups and native
221 # modules imports the markup type which is define above. 226 # modules imports the markup type which is define above.
222 try: 227 try:
223 from jinja2._markupsafe._speedups import escape, escape_silent, soft_unicode 228 from markupsafe._speedups import escape, escape_silent, soft_unicode
224 except ImportError: 229 except ImportError:
225 from jinja2._markupsafe._native import escape, escape_silent, soft_unicode 230 from markupsafe._native import escape, escape_silent, soft_unicode
231
232 if not PY2:
233 soft_str = soft_unicode
234 __all__.append('soft_str')
OLDNEW
« no previous file with comments | « third_party/markupsafe/README.chromium ('k') | third_party/markupsafe/_compat.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698