Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/markupsafe/__init__.py @ 0:26e78fe6e8c4 draft
"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
| author | shellac |
|---|---|
| date | Sat, 02 May 2020 07:14:21 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:26e78fe6e8c4 |
|---|---|
| 1 # -*- coding: utf-8 -*- | |
| 2 """ | |
| 3 markupsafe | |
| 4 ~~~~~~~~~~ | |
| 5 | |
| 6 Implements an escape function and a Markup string to replace HTML | |
| 7 special characters with safe representations. | |
| 8 | |
| 9 :copyright: 2010 Pallets | |
| 10 :license: BSD-3-Clause | |
| 11 """ | |
| 12 import re | |
| 13 import string | |
| 14 | |
| 15 from ._compat import int_types | |
| 16 from ._compat import iteritems | |
| 17 from ._compat import Mapping | |
| 18 from ._compat import PY2 | |
| 19 from ._compat import string_types | |
| 20 from ._compat import text_type | |
| 21 from ._compat import unichr | |
| 22 | |
| 23 __version__ = "1.1.1" | |
| 24 | |
| 25 __all__ = ["Markup", "soft_unicode", "escape", "escape_silent"] | |
| 26 | |
| 27 _striptags_re = re.compile(r"(<!--.*?-->|<[^>]*>)") | |
| 28 _entity_re = re.compile(r"&([^& ;]+);") | |
| 29 | |
| 30 | |
| 31 class Markup(text_type): | |
| 32 """A string that is ready to be safely inserted into an HTML or XML | |
| 33 document, either because it was escaped or because it was marked | |
| 34 safe. | |
| 35 | |
| 36 Passing an object to the constructor converts it to text and wraps | |
| 37 it to mark it safe without escaping. To escape the text, use the | |
| 38 :meth:`escape` class method instead. | |
| 39 | |
| 40 >>> Markup('Hello, <em>World</em>!') | |
| 41 Markup('Hello, <em>World</em>!') | |
| 42 >>> Markup(42) | |
| 43 Markup('42') | |
| 44 >>> Markup.escape('Hello, <em>World</em>!') | |
| 45 Markup('Hello <em>World</em>!') | |
| 46 | |
| 47 This implements the ``__html__()`` interface that some frameworks | |
| 48 use. Passing an object that implements ``__html__()`` will wrap the | |
| 49 output of that method, marking it safe. | |
| 50 | |
| 51 >>> class Foo: | |
| 52 ... def __html__(self): | |
| 53 ... return '<a href="/foo">foo</a>' | |
| 54 ... | |
| 55 >>> Markup(Foo()) | |
| 56 Markup('<a href="/foo">foo</a>') | |
| 57 | |
| 58 This is a subclass of the text type (``str`` in Python 3, | |
| 59 ``unicode`` in Python 2). It has the same methods as that type, but | |
| 60 all methods escape their arguments and return a ``Markup`` instance. | |
| 61 | |
| 62 >>> Markup('<em>%s</em>') % 'foo & bar' | |
| 63 Markup('<em>foo & bar</em>') | |
| 64 >>> Markup('<em>Hello</em> ') + '<foo>' | |
| 65 Markup('<em>Hello</em> <foo>') | |
| 66 """ | |
| 67 | |
| 68 __slots__ = () | |
| 69 | |
| 70 def __new__(cls, base=u"", encoding=None, errors="strict"): | |
| 71 if hasattr(base, "__html__"): | |
| 72 base = base.__html__() | |
| 73 if encoding is None: | |
| 74 return text_type.__new__(cls, base) | |
| 75 return text_type.__new__(cls, base, encoding, errors) | |
| 76 | |
| 77 def __html__(self): | |
| 78 return self | |
| 79 | |
| 80 def __add__(self, other): | |
| 81 if isinstance(other, string_types) or hasattr(other, "__html__"): | |
| 82 return self.__class__(super(Markup, self).__add__(self.escape(other))) | |
| 83 return NotImplemented | |
| 84 | |
| 85 def __radd__(self, other): | |
| 86 if hasattr(other, "__html__") or isinstance(other, string_types): | |
| 87 return self.escape(other).__add__(self) | |
| 88 return NotImplemented | |
| 89 | |
| 90 def __mul__(self, num): | |
| 91 if isinstance(num, int_types): | |
| 92 return self.__class__(text_type.__mul__(self, num)) | |
| 93 return NotImplemented | |
| 94 | |
| 95 __rmul__ = __mul__ | |
| 96 | |
| 97 def __mod__(self, arg): | |
| 98 if isinstance(arg, tuple): | |
| 99 arg = tuple(_MarkupEscapeHelper(x, self.escape) for x in arg) | |
| 100 else: | |
| 101 arg = _MarkupEscapeHelper(arg, self.escape) | |
| 102 return self.__class__(text_type.__mod__(self, arg)) | |
| 103 | |
| 104 def __repr__(self): | |
| 105 return "%s(%s)" % (self.__class__.__name__, text_type.__repr__(self)) | |
| 106 | |
| 107 def join(self, seq): | |
| 108 return self.__class__(text_type.join(self, map(self.escape, seq))) | |
| 109 | |
| 110 join.__doc__ = text_type.join.__doc__ | |
| 111 | |
| 112 def split(self, *args, **kwargs): | |
| 113 return list(map(self.__class__, text_type.split(self, *args, **kwargs))) | |
| 114 | |
| 115 split.__doc__ = text_type.split.__doc__ | |
| 116 | |
| 117 def rsplit(self, *args, **kwargs): | |
| 118 return list(map(self.__class__, text_type.rsplit(self, *args, **kwargs))) | |
| 119 | |
| 120 rsplit.__doc__ = text_type.rsplit.__doc__ | |
| 121 | |
| 122 def splitlines(self, *args, **kwargs): | |
| 123 return list(map(self.__class__, text_type.splitlines(self, *args, **kwargs))) | |
| 124 | |
| 125 splitlines.__doc__ = text_type.splitlines.__doc__ | |
| 126 | |
| 127 def unescape(self): | |
| 128 """Convert escaped markup back into a text string. This replaces | |
| 129 HTML entities with the characters they represent. | |
| 130 | |
| 131 >>> Markup('Main » <em>About</em>').unescape() | |
| 132 'Main » <em>About</em>' | |
| 133 """ | |
| 134 from ._constants import HTML_ENTITIES | |
| 135 | |
| 136 def handle_match(m): | |
| 137 name = m.group(1) | |
| 138 if name in HTML_ENTITIES: | |
| 139 return unichr(HTML_ENTITIES[name]) | |
| 140 try: | |
| 141 if name[:2] in ("#x", "#X"): | |
| 142 return unichr(int(name[2:], 16)) | |
| 143 elif name.startswith("#"): | |
| 144 return unichr(int(name[1:])) | |
| 145 except ValueError: | |
| 146 pass | |
| 147 # Don't modify unexpected input. | |
| 148 return m.group() | |
| 149 | |
| 150 return _entity_re.sub(handle_match, text_type(self)) | |
| 151 | |
| 152 def striptags(self): | |
| 153 """:meth:`unescape` the markup, remove tags, and normalize | |
| 154 whitespace to single spaces. | |
| 155 | |
| 156 >>> Markup('Main »\t<em>About</em>').striptags() | |
| 157 'Main » About' | |
| 158 """ | |
| 159 stripped = u" ".join(_striptags_re.sub("", self).split()) | |
| 160 return Markup(stripped).unescape() | |
| 161 | |
| 162 @classmethod | |
| 163 def escape(cls, s): | |
| 164 """Escape a string. Calls :func:`escape` and ensures that for | |
| 165 subclasses the correct type is returned. | |
| 166 """ | |
| 167 rv = escape(s) | |
| 168 if rv.__class__ is not cls: | |
| 169 return cls(rv) | |
| 170 return rv | |
| 171 | |
| 172 def make_simple_escaping_wrapper(name): # noqa: B902 | |
| 173 orig = getattr(text_type, name) | |
| 174 | |
| 175 def func(self, *args, **kwargs): | |
| 176 args = _escape_argspec(list(args), enumerate(args), self.escape) | |
| 177 _escape_argspec(kwargs, iteritems(kwargs), self.escape) | |
| 178 return self.__class__(orig(self, *args, **kwargs)) | |
| 179 | |
| 180 func.__name__ = orig.__name__ | |
| 181 func.__doc__ = orig.__doc__ | |
| 182 return func | |
| 183 | |
| 184 for method in ( | |
| 185 "__getitem__", | |
| 186 "capitalize", | |
| 187 "title", | |
| 188 "lower", | |
| 189 "upper", | |
| 190 "replace", | |
| 191 "ljust", | |
| 192 "rjust", | |
| 193 "lstrip", | |
| 194 "rstrip", | |
| 195 "center", | |
| 196 "strip", | |
| 197 "translate", | |
| 198 "expandtabs", | |
| 199 "swapcase", | |
| 200 "zfill", | |
| 201 ): | |
| 202 locals()[method] = make_simple_escaping_wrapper(method) | |
| 203 | |
| 204 def partition(self, sep): | |
| 205 return tuple(map(self.__class__, text_type.partition(self, self.escape(sep)))) | |
| 206 | |
| 207 def rpartition(self, sep): | |
| 208 return tuple(map(self.__class__, text_type.rpartition(self, self.escape(sep)))) | |
| 209 | |
| 210 def format(self, *args, **kwargs): | |
| 211 formatter = EscapeFormatter(self.escape) | |
| 212 kwargs = _MagicFormatMapping(args, kwargs) | |
| 213 return self.__class__(formatter.vformat(self, args, kwargs)) | |
| 214 | |
| 215 def __html_format__(self, format_spec): | |
| 216 if format_spec: | |
| 217 raise ValueError("Unsupported format specification " "for Markup.") | |
| 218 return self | |
| 219 | |
| 220 # not in python 3 | |
| 221 if hasattr(text_type, "__getslice__"): | |
| 222 __getslice__ = make_simple_escaping_wrapper("__getslice__") | |
| 223 | |
| 224 del method, make_simple_escaping_wrapper | |
| 225 | |
| 226 | |
| 227 class _MagicFormatMapping(Mapping): | |
| 228 """This class implements a dummy wrapper to fix a bug in the Python | |
| 229 standard library for string formatting. | |
| 230 | |
| 231 See http://bugs.python.org/issue13598 for information about why | |
| 232 this is necessary. | |
| 233 """ | |
| 234 | |
| 235 def __init__(self, args, kwargs): | |
| 236 self._args = args | |
| 237 self._kwargs = kwargs | |
| 238 self._last_index = 0 | |
| 239 | |
| 240 def __getitem__(self, key): | |
| 241 if key == "": | |
| 242 idx = self._last_index | |
| 243 self._last_index += 1 | |
| 244 try: | |
| 245 return self._args[idx] | |
| 246 except LookupError: | |
| 247 pass | |
| 248 key = str(idx) | |
| 249 return self._kwargs[key] | |
| 250 | |
| 251 def __iter__(self): | |
| 252 return iter(self._kwargs) | |
| 253 | |
| 254 def __len__(self): | |
| 255 return len(self._kwargs) | |
| 256 | |
| 257 | |
| 258 if hasattr(text_type, "format"): | |
| 259 | |
| 260 class EscapeFormatter(string.Formatter): | |
| 261 def __init__(self, escape): | |
| 262 self.escape = escape | |
| 263 | |
| 264 def format_field(self, value, format_spec): | |
| 265 if hasattr(value, "__html_format__"): | |
| 266 rv = value.__html_format__(format_spec) | |
| 267 elif hasattr(value, "__html__"): | |
| 268 if format_spec: | |
| 269 raise ValueError( | |
| 270 "Format specifier {0} given, but {1} does not" | |
| 271 " define __html_format__. A class that defines" | |
| 272 " __html__ must define __html_format__ to work" | |
| 273 " with format specifiers.".format(format_spec, type(value)) | |
| 274 ) | |
| 275 rv = value.__html__() | |
| 276 else: | |
| 277 # We need to make sure the format spec is unicode here as | |
| 278 # otherwise the wrong callback methods are invoked. For | |
| 279 # instance a byte string there would invoke __str__ and | |
| 280 # not __unicode__. | |
| 281 rv = string.Formatter.format_field(self, value, text_type(format_spec)) | |
| 282 return text_type(self.escape(rv)) | |
| 283 | |
| 284 | |
| 285 def _escape_argspec(obj, iterable, escape): | |
| 286 """Helper for various string-wrapped functions.""" | |
| 287 for key, value in iterable: | |
| 288 if hasattr(value, "__html__") or isinstance(value, string_types): | |
| 289 obj[key] = escape(value) | |
| 290 return obj | |
| 291 | |
| 292 | |
| 293 class _MarkupEscapeHelper(object): | |
| 294 """Helper for Markup.__mod__""" | |
| 295 | |
| 296 def __init__(self, obj, escape): | |
| 297 self.obj = obj | |
| 298 self.escape = escape | |
| 299 | |
| 300 def __getitem__(self, item): | |
| 301 return _MarkupEscapeHelper(self.obj[item], self.escape) | |
| 302 | |
| 303 def __str__(self): | |
| 304 return text_type(self.escape(self.obj)) | |
| 305 | |
| 306 __unicode__ = __str__ | |
| 307 | |
| 308 def __repr__(self): | |
| 309 return str(self.escape(repr(self.obj))) | |
| 310 | |
| 311 def __int__(self): | |
| 312 return int(self.obj) | |
| 313 | |
| 314 def __float__(self): | |
| 315 return float(self.obj) | |
| 316 | |
| 317 | |
| 318 # we have to import it down here as the speedups and native | |
| 319 # modules imports the markup type which is define above. | |
| 320 try: | |
| 321 from ._speedups import escape, escape_silent, soft_unicode | |
| 322 except ImportError: | |
| 323 from ._native import escape, escape_silent, soft_unicode | |
| 324 | |
| 325 if not PY2: | |
| 326 soft_str = soft_unicode | |
| 327 __all__.append("soft_str") |
