aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/MarkupSafe/py2
diff options
context:
space:
mode:
authornkozlovskiy <nmk@ydb.tech>2023-09-29 12:24:06 +0300
committernkozlovskiy <nmk@ydb.tech>2023-09-29 12:41:34 +0300
commite0e3e1717e3d33762ce61950504f9637a6e669ed (patch)
treebca3ff6939b10ed60c3d5c12439963a1146b9711 /contrib/python/MarkupSafe/py2
parent38f2c5852db84c7b4d83adfcb009eb61541d1ccd (diff)
downloadydb-e0e3e1717e3d33762ce61950504f9637a6e669ed.tar.gz
add ydb deps
Diffstat (limited to 'contrib/python/MarkupSafe/py2')
-rw-r--r--contrib/python/MarkupSafe/py2/.dist-info/METADATA103
-rw-r--r--contrib/python/MarkupSafe/py2/.dist-info/top_level.txt1
-rw-r--r--contrib/python/MarkupSafe/py2/LICENSE.rst28
-rw-r--r--contrib/python/MarkupSafe/py2/README.rst69
-rw-r--r--contrib/python/MarkupSafe/py2/markupsafe/__init__.py327
-rw-r--r--contrib/python/MarkupSafe/py2/markupsafe/_compat.py33
-rw-r--r--contrib/python/MarkupSafe/py2/markupsafe/_constants.py264
-rw-r--r--contrib/python/MarkupSafe/py2/markupsafe/_native.py69
-rw-r--r--contrib/python/MarkupSafe/py2/tests/conftest.py37
-rw-r--r--contrib/python/MarkupSafe/py2/tests/test_escape.py30
-rw-r--r--contrib/python/MarkupSafe/py2/tests/test_exception_custom_html.py21
-rw-r--r--contrib/python/MarkupSafe/py2/tests/test_leak.py29
-rw-r--r--contrib/python/MarkupSafe/py2/tests/test_markupsafe.py196
-rw-r--r--contrib/python/MarkupSafe/py2/tests/ya.make17
-rw-r--r--contrib/python/MarkupSafe/py2/ya.make37
15 files changed, 1261 insertions, 0 deletions
diff --git a/contrib/python/MarkupSafe/py2/.dist-info/METADATA b/contrib/python/MarkupSafe/py2/.dist-info/METADATA
new file mode 100644
index 0000000000..b6d72a81d2
--- /dev/null
+++ b/contrib/python/MarkupSafe/py2/.dist-info/METADATA
@@ -0,0 +1,103 @@
+Metadata-Version: 2.1
+Name: MarkupSafe
+Version: 1.1.1
+Summary: Safely add untrusted strings to HTML/XML markup.
+Home-page: https://palletsprojects.com/p/markupsafe/
+Author: Armin Ronacher
+Author-email: armin.ronacher@active-4.com
+Maintainer: The Pallets Team
+Maintainer-email: contact@palletsprojects.com
+License: BSD-3-Clause
+Project-URL: Code, https://github.com/pallets/markupsafe
+Project-URL: Issue tracker, https://github.com/pallets/markupsafe/issues
+Project-URL: Documentation, https://markupsafe.palletsprojects.com/
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Web Environment
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: Text Processing :: Markup :: HTML
+Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*
+
+MarkupSafe
+==========
+
+MarkupSafe implements a text object that escapes characters so it is
+safe to use in HTML and XML. Characters that have special meanings are
+replaced so that they display as the actual characters. This mitigates
+injection attacks, meaning untrusted user input can safely be displayed
+on a page.
+
+
+Installing
+----------
+
+Install and update using `pip`_:
+
+.. code-block:: text
+
+ pip install -U MarkupSafe
+
+.. _pip: https://pip.pypa.io/en/stable/quickstart/
+
+
+Examples
+--------
+
+.. code-block:: pycon
+
+ >>> from markupsafe import Markup, escape
+ >>> # escape replaces special characters and wraps in Markup
+ >>> escape('<script>alert(document.cookie);</script>')
+ Markup(u'&lt;script&gt;alert(document.cookie);&lt;/script&gt;')
+ >>> # wrap in Markup to mark text "safe" and prevent escaping
+ >>> Markup('<strong>Hello</strong>')
+ Markup('<strong>hello</strong>')
+ >>> escape(Markup('<strong>Hello</strong>'))
+ Markup('<strong>hello</strong>')
+ >>> # Markup is a text subclass (str on Python 3, unicode on Python 2)
+ >>> # methods and operators escape their arguments
+ >>> template = Markup("Hello <em>%s</em>")
+ >>> template % '"World"'
+ Markup('Hello <em>&#34;World&#34;</em>')
+
+
+Donate
+------
+
+The Pallets organization develops and supports MarkupSafe and other
+libraries that use it. In order to grow the community of contributors
+and users, and allow the maintainers to devote more time to the
+projects, `please donate today`_.
+
+.. _please donate today: https://palletsprojects.com/donate
+
+
+Links
+-----
+
+* Website: https://palletsprojects.com/p/markupsafe/
+* Documentation: https://markupsafe.palletsprojects.com/
+* License: `BSD-3-Clause <https://github.com/pallets/markupsafe/blob/master/LICENSE.rst>`_
+* Releases: https://pypi.org/project/MarkupSafe/
+* Code: https://github.com/pallets/markupsafe
+* Issue tracker: https://github.com/pallets/markupsafe/issues
+* Test status:
+
+ * Linux, Mac: https://travis-ci.org/pallets/markupsafe
+ * Windows: https://ci.appveyor.com/project/pallets/markupsafe
+
+* Test coverage: https://codecov.io/gh/pallets/markupsafe
+
+
diff --git a/contrib/python/MarkupSafe/py2/.dist-info/top_level.txt b/contrib/python/MarkupSafe/py2/.dist-info/top_level.txt
new file mode 100644
index 0000000000..75bf729258
--- /dev/null
+++ b/contrib/python/MarkupSafe/py2/.dist-info/top_level.txt
@@ -0,0 +1 @@
+markupsafe
diff --git a/contrib/python/MarkupSafe/py2/LICENSE.rst b/contrib/python/MarkupSafe/py2/LICENSE.rst
new file mode 100644
index 0000000000..9d227a0cc4
--- /dev/null
+++ b/contrib/python/MarkupSafe/py2/LICENSE.rst
@@ -0,0 +1,28 @@
+Copyright 2010 Pallets
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/contrib/python/MarkupSafe/py2/README.rst b/contrib/python/MarkupSafe/py2/README.rst
new file mode 100644
index 0000000000..3548b8d1f7
--- /dev/null
+++ b/contrib/python/MarkupSafe/py2/README.rst
@@ -0,0 +1,69 @@
+MarkupSafe
+==========
+
+MarkupSafe implements a text object that escapes characters so it is
+safe to use in HTML and XML. Characters that have special meanings are
+replaced so that they display as the actual characters. This mitigates
+injection attacks, meaning untrusted user input can safely be displayed
+on a page.
+
+
+Installing
+----------
+
+Install and update using `pip`_:
+
+.. code-block:: text
+
+ pip install -U MarkupSafe
+
+.. _pip: https://pip.pypa.io/en/stable/quickstart/
+
+
+Examples
+--------
+
+.. code-block:: pycon
+
+ >>> from markupsafe import Markup, escape
+ >>> # escape replaces special characters and wraps in Markup
+ >>> escape('<script>alert(document.cookie);</script>')
+ Markup(u'&lt;script&gt;alert(document.cookie);&lt;/script&gt;')
+ >>> # wrap in Markup to mark text "safe" and prevent escaping
+ >>> Markup('<strong>Hello</strong>')
+ Markup('<strong>hello</strong>')
+ >>> escape(Markup('<strong>Hello</strong>'))
+ Markup('<strong>hello</strong>')
+ >>> # Markup is a text subclass (str on Python 3, unicode on Python 2)
+ >>> # methods and operators escape their arguments
+ >>> template = Markup("Hello <em>%s</em>")
+ >>> template % '"World"'
+ Markup('Hello <em>&#34;World&#34;</em>')
+
+
+Donate
+------
+
+The Pallets organization develops and supports MarkupSafe and other
+libraries that use it. In order to grow the community of contributors
+and users, and allow the maintainers to devote more time to the
+projects, `please donate today`_.
+
+.. _please donate today: https://palletsprojects.com/donate
+
+
+Links
+-----
+
+* Website: https://palletsprojects.com/p/markupsafe/
+* Documentation: https://markupsafe.palletsprojects.com/
+* License: `BSD-3-Clause <https://github.com/pallets/markupsafe/blob/master/LICENSE.rst>`_
+* Releases: https://pypi.org/project/MarkupSafe/
+* Code: https://github.com/pallets/markupsafe
+* Issue tracker: https://github.com/pallets/markupsafe/issues
+* Test status:
+
+ * Linux, Mac: https://travis-ci.org/pallets/markupsafe
+ * Windows: https://ci.appveyor.com/project/pallets/markupsafe
+
+* Test coverage: https://codecov.io/gh/pallets/markupsafe
diff --git a/contrib/python/MarkupSafe/py2/markupsafe/__init__.py b/contrib/python/MarkupSafe/py2/markupsafe/__init__.py
new file mode 100644
index 0000000000..da05ed328a
--- /dev/null
+++ b/contrib/python/MarkupSafe/py2/markupsafe/__init__.py
@@ -0,0 +1,327 @@
+# -*- coding: utf-8 -*-
+"""
+markupsafe
+~~~~~~~~~~
+
+Implements an escape function and a Markup string to replace HTML
+special characters with safe representations.
+
+:copyright: 2010 Pallets
+:license: BSD-3-Clause
+"""
+import re
+import string
+
+from ._compat import int_types
+from ._compat import iteritems
+from ._compat import Mapping
+from ._compat import PY2
+from ._compat import string_types
+from ._compat import text_type
+from ._compat import unichr
+
+__version__ = "1.1.1"
+
+__all__ = ["Markup", "soft_unicode", "escape", "escape_silent"]
+
+_striptags_re = re.compile(r"(<!--.*?-->|<[^>]*>)")
+_entity_re = re.compile(r"&([^& ;]+);")
+
+
+class Markup(text_type):
+ """A string that is ready to be safely inserted into an HTML or XML
+ document, either because it was escaped or because it was marked
+ safe.
+
+ Passing an object to the constructor converts it to text and wraps
+ it to mark it safe without escaping. To escape the text, use the
+ :meth:`escape` class method instead.
+
+ >>> Markup('Hello, <em>World</em>!')
+ Markup('Hello, <em>World</em>!')
+ >>> Markup(42)
+ Markup('42')
+ >>> Markup.escape('Hello, <em>World</em>!')
+ Markup('Hello &lt;em&gt;World&lt;/em&gt;!')
+
+ This implements the ``__html__()`` interface that some frameworks
+ use. Passing an object that implements ``__html__()`` will wrap the
+ output of that method, marking it safe.
+
+ >>> class Foo:
+ ... def __html__(self):
+ ... return '<a href="/foo">foo</a>'
+ ...
+ >>> Markup(Foo())
+ Markup('<a href="/foo">foo</a>')
+
+ This is a subclass of the text type (``str`` in Python 3,
+ ``unicode`` in Python 2). It has the same methods as that type, but
+ all methods escape their arguments and return a ``Markup`` instance.
+
+ >>> Markup('<em>%s</em>') % 'foo & bar'
+ Markup('<em>foo &amp; bar</em>')
+ >>> Markup('<em>Hello</em> ') + '<foo>'
+ Markup('<em>Hello</em> &lt;foo&gt;')
+ """
+
+ __slots__ = ()
+
+ def __new__(cls, base=u"", encoding=None, errors="strict"):
+ if hasattr(base, "__html__"):
+ base = base.__html__()
+ if encoding is None:
+ return text_type.__new__(cls, base)
+ return text_type.__new__(cls, base, encoding, errors)
+
+ def __html__(self):
+ return self
+
+ def __add__(self, other):
+ if isinstance(other, string_types) or hasattr(other, "__html__"):
+ return self.__class__(super(Markup, self).__add__(self.escape(other)))
+ return NotImplemented
+
+ def __radd__(self, other):
+ if hasattr(other, "__html__") or isinstance(other, string_types):
+ return self.escape(other).__add__(self)
+ return NotImplemented
+
+ def __mul__(self, num):
+ if isinstance(num, int_types):
+ return self.__class__(text_type.__mul__(self, num))
+ return NotImplemented
+
+ __rmul__ = __mul__
+
+ def __mod__(self, arg):
+ if isinstance(arg, tuple):
+ arg = tuple(_MarkupEscapeHelper(x, self.escape) for x in arg)
+ else:
+ arg = _MarkupEscapeHelper(arg, self.escape)
+ return self.__class__(text_type.__mod__(self, arg))
+
+ def __repr__(self):
+ return "%s(%s)" % (self.__class__.__name__, text_type.__repr__(self))
+
+ def join(self, seq):
+ return self.__class__(text_type.join(self, map(self.escape, seq)))
+
+ join.__doc__ = text_type.join.__doc__
+
+ def split(self, *args, **kwargs):
+ return list(map(self.__class__, text_type.split(self, *args, **kwargs)))
+
+ split.__doc__ = text_type.split.__doc__
+
+ def rsplit(self, *args, **kwargs):
+ return list(map(self.__class__, text_type.rsplit(self, *args, **kwargs)))
+
+ rsplit.__doc__ = text_type.rsplit.__doc__
+
+ def splitlines(self, *args, **kwargs):
+ return list(map(self.__class__, text_type.splitlines(self, *args, **kwargs)))
+
+ splitlines.__doc__ = text_type.splitlines.__doc__
+
+ def unescape(self):
+ """Convert escaped markup back into a text string. This replaces
+ HTML entities with the characters they represent.
+
+ >>> Markup('Main &raquo; <em>About</em>').unescape()
+ 'Main » <em>About</em>'
+ """
+ from ._constants import HTML_ENTITIES
+
+ def handle_match(m):
+ name = m.group(1)
+ if name in HTML_ENTITIES:
+ return unichr(HTML_ENTITIES[name])
+ try:
+ if name[:2] in ("#x", "#X"):
+ return unichr(int(name[2:], 16))
+ elif name.startswith("#"):
+ return unichr(int(name[1:]))
+ except ValueError:
+ pass
+ # Don't modify unexpected input.
+ return m.group()
+
+ return _entity_re.sub(handle_match, text_type(self))
+
+ def striptags(self):
+ """:meth:`unescape` the markup, remove tags, and normalize
+ whitespace to single spaces.
+
+ >>> Markup('Main &raquo;\t<em>About</em>').striptags()
+ 'Main » About'
+ """
+ stripped = u" ".join(_striptags_re.sub("", self).split())
+ return Markup(stripped).unescape()
+
+ @classmethod
+ def escape(cls, s):
+ """Escape a string. Calls :func:`escape` and ensures that for
+ subclasses the correct type is returned.
+ """
+ rv = escape(s)
+ if rv.__class__ is not cls:
+ return cls(rv)
+ return rv
+
+ def make_simple_escaping_wrapper(name): # noqa: B902
+ orig = getattr(text_type, name)
+
+ def func(self, *args, **kwargs):
+ args = _escape_argspec(list(args), enumerate(args), self.escape)
+ _escape_argspec(kwargs, iteritems(kwargs), self.escape)
+ return self.__class__(orig(self, *args, **kwargs))
+
+ func.__name__ = orig.__name__
+ func.__doc__ = orig.__doc__
+ return func
+
+ for method in (
+ "__getitem__",
+ "capitalize",
+ "title",
+ "lower",
+ "upper",
+ "replace",
+ "ljust",
+ "rjust",
+ "lstrip",
+ "rstrip",
+ "center",
+ "strip",
+ "translate",
+ "expandtabs",
+ "swapcase",
+ "zfill",
+ ):
+ locals()[method] = make_simple_escaping_wrapper(method)
+
+ def partition(self, sep):
+ return tuple(map(self.__class__, text_type.partition(self, self.escape(sep))))
+
+ def rpartition(self, sep):
+ return tuple(map(self.__class__, text_type.rpartition(self, self.escape(sep))))
+
+ def format(self, *args, **kwargs):
+ formatter = EscapeFormatter(self.escape)
+ kwargs = _MagicFormatMapping(args, kwargs)
+ return self.__class__(formatter.vformat(self, args, kwargs))
+
+ def __html_format__(self, format_spec):
+ if format_spec:
+ raise ValueError("Unsupported format specification " "for Markup.")
+ return self
+
+ # not in python 3
+ if hasattr(text_type, "__getslice__"):
+ __getslice__ = make_simple_escaping_wrapper("__getslice__")
+
+ del method, make_simple_escaping_wrapper
+
+
+class _MagicFormatMapping(Mapping):
+ """This class implements a dummy wrapper to fix a bug in the Python
+ standard library for string formatting.
+
+ See http://bugs.python.org/issue13598 for information about why
+ this is necessary.
+ """
+
+ def __init__(self, args, kwargs):
+ self._args = args
+ self._kwargs = kwargs
+ self._last_index = 0
+
+ def __getitem__(self, key):
+ if key == "":
+ idx = self._last_index
+ self._last_index += 1
+ try:
+ return self._args[idx]
+ except LookupError:
+ pass
+ key = str(idx)
+ return self._kwargs[key]
+
+ def __iter__(self):
+ return iter(self._kwargs)
+
+ def __len__(self):
+ return len(self._kwargs)
+
+
+if hasattr(text_type, "format"):
+
+ class EscapeFormatter(string.Formatter):
+ def __init__(self, escape):
+ self.escape = escape
+
+ def format_field(self, value, format_spec):
+ if hasattr(value, "__html_format__"):
+ rv = value.__html_format__(format_spec)
+ elif hasattr(value, "__html__"):
+ if format_spec:
+ raise ValueError(
+ "Format specifier {0} given, but {1} does not"
+ " define __html_format__. A class that defines"
+ " __html__ must define __html_format__ to work"
+ " with format specifiers.".format(format_spec, type(value))
+ )
+ rv = value.__html__()
+ else:
+ # We need to make sure the format spec is unicode here as
+ # otherwise the wrong callback methods are invoked. For
+ # instance a byte string there would invoke __str__ and
+ # not __unicode__.
+ rv = string.Formatter.format_field(self, value, text_type(format_spec))
+ return text_type(self.escape(rv))
+
+
+def _escape_argspec(obj, iterable, escape):
+ """Helper for various string-wrapped functions."""
+ for key, value in iterable:
+ if hasattr(value, "__html__") or isinstance(value, string_types):
+ obj[key] = escape(value)
+ return obj
+
+
+class _MarkupEscapeHelper(object):
+ """Helper for Markup.__mod__"""
+
+ def __init__(self, obj, escape):
+ self.obj = obj
+ self.escape = escape
+
+ def __getitem__(self, item):
+ return _MarkupEscapeHelper(self.obj[item], self.escape)
+
+ def __str__(self):
+ return text_type(self.escape(self.obj))
+
+ __unicode__ = __str__
+
+ def __repr__(self):
+ return str(self.escape(repr(self.obj)))
+
+ def __int__(self):
+ return int(self.obj)
+
+ def __float__(self):
+ return float(self.obj)
+
+
+# we have to import it down here as the speedups and native
+# modules imports the markup type which is define above.
+try:
+ from ._speedups import escape, escape_silent, soft_unicode
+except ImportError:
+ from ._native import escape, escape_silent, soft_unicode
+
+if not PY2:
+ soft_str = soft_unicode
+ __all__.append("soft_str")
diff --git a/contrib/python/MarkupSafe/py2/markupsafe/_compat.py b/contrib/python/MarkupSafe/py2/markupsafe/_compat.py
new file mode 100644
index 0000000000..bc05090f9e
--- /dev/null
+++ b/contrib/python/MarkupSafe/py2/markupsafe/_compat.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+"""
+markupsafe._compat
+~~~~~~~~~~~~~~~~~~
+
+:copyright: 2010 Pallets
+:license: BSD-3-Clause
+"""
+import sys
+
+PY2 = sys.version_info[0] == 2
+
+if not PY2:
+ text_type = str
+ string_types = (str,)
+ unichr = chr
+ int_types = (int,)
+
+ def iteritems(x):
+ return iter(x.items())
+
+ from collections.abc import Mapping
+
+else:
+ text_type = unicode
+ string_types = (str, unicode)
+ unichr = unichr
+ int_types = (int, long)
+
+ def iteritems(x):
+ return x.iteritems()
+
+ from collections import Mapping
diff --git a/contrib/python/MarkupSafe/py2/markupsafe/_constants.py b/contrib/python/MarkupSafe/py2/markupsafe/_constants.py
new file mode 100644
index 0000000000..7c57c2d294
--- /dev/null
+++ b/contrib/python/MarkupSafe/py2/markupsafe/_constants.py
@@ -0,0 +1,264 @@
+# -*- coding: utf-8 -*-
+"""
+markupsafe._constants
+~~~~~~~~~~~~~~~~~~~~~
+
+:copyright: 2010 Pallets
+:license: BSD-3-Clause
+"""
+
+HTML_ENTITIES = {
+ "AElig": 198,
+ "Aacute": 193,
+ "Acirc": 194,
+ "Agrave": 192,
+ "Alpha": 913,
+ "Aring": 197,
+ "Atilde": 195,
+ "Auml": 196,
+ "Beta": 914,
+ "Ccedil": 199,
+ "Chi": 935,
+ "Dagger": 8225,
+ "Delta": 916,
+ "ETH": 208,
+ "Eacute": 201,
+ "Ecirc": 202,
+ "Egrave": 200,
+ "Epsilon": 917,
+ "Eta": 919,
+ "Euml": 203,
+ "Gamma": 915,
+ "Iacute": 205,
+ "Icirc": 206,
+ "Igrave": 204,
+ "Iota": 921,
+ "Iuml": 207,
+ "Kappa": 922,
+ "Lambda": 923,
+ "Mu": 924,
+ "Ntilde": 209,
+ "Nu": 925,
+ "OElig": 338,
+ "Oacute": 211,
+ "Ocirc": 212,
+ "Ograve": 210,
+ "Omega": 937,
+ "Omicron": 927,
+ "Oslash": 216,
+ "Otilde": 213,
+ "Ouml": 214,
+ "Phi": 934,
+ "Pi": 928,
+ "Prime": 8243,
+ "Psi": 936,
+ "Rho": 929,
+ "Scaron": 352,
+ "Sigma": 931,
+ "THORN": 222,
+ "Tau": 932,
+ "Theta": 920,
+ "Uacute": 218,
+ "Ucirc": 219,
+ "Ugrave": 217,
+ "Upsilon": 933,
+ "Uuml": 220,
+ "Xi": 926,
+ "Yacute": 221,
+ "Yuml": 376,
+ "Zeta": 918,
+ "aacute": 225,
+ "acirc": 226,
+ "acute": 180,
+ "aelig": 230,
+ "agrave": 224,
+ "alefsym": 8501,
+ "alpha": 945,
+ "amp": 38,
+ "and": 8743,
+ "ang": 8736,
+ "apos": 39,
+ "aring": 229,
+ "asymp": 8776,
+ "atilde": 227,
+ "auml": 228,
+ "bdquo": 8222,
+ "beta": 946,
+ "brvbar": 166,
+ "bull": 8226,
+ "cap": 8745,
+ "ccedil": 231,
+ "cedil": 184,
+ "cent": 162,
+ "chi": 967,
+ "circ": 710,
+ "clubs": 9827,
+ "cong": 8773,
+ "copy": 169,
+ "crarr": 8629,
+ "cup": 8746,
+ "curren": 164,
+ "dArr": 8659,
+ "dagger": 8224,
+ "darr": 8595,
+ "deg": 176,
+ "delta": 948,
+ "diams": 9830,
+ "divide": 247,
+ "eacute": 233,
+ "ecirc": 234,
+ "egrave": 232,
+ "empty": 8709,
+ "emsp": 8195,
+ "ensp": 8194,
+ "epsilon": 949,
+ "equiv": 8801,
+ "eta": 951,
+ "eth": 240,
+ "euml": 235,
+ "euro": 8364,
+ "exist": 8707,
+ "fnof": 402,
+ "forall": 8704,
+ "frac12": 189,
+ "frac14": 188,
+ "frac34": 190,
+ "frasl": 8260,
+ "gamma": 947,
+ "ge": 8805,
+ "gt": 62,
+ "hArr": 8660,
+ "harr": 8596,
+ "hearts": 9829,
+ "hellip": 8230,
+ "iacute": 237,
+ "icirc": 238,
+ "iexcl": 161,
+ "igrave": 236,
+ "image": 8465,
+ "infin": 8734,
+ "int": 8747,
+ "iota": 953,
+ "iquest": 191,
+ "isin": 8712,
+ "iuml": 239,
+ "kappa": 954,
+ "lArr": 8656,
+ "lambda": 955,
+ "lang": 9001,
+ "laquo": 171,
+ "larr": 8592,
+ "lceil": 8968,
+ "ldquo": 8220,
+ "le": 8804,
+ "lfloor": 8970,
+ "lowast": 8727,
+ "loz": 9674,
+ "lrm": 8206,
+ "lsaquo": 8249,
+ "lsquo": 8216,
+ "lt": 60,
+ "macr": 175,
+ "mdash": 8212,
+ "micro": 181,
+ "middot": 183,
+ "minus": 8722,
+ "mu": 956,
+ "nabla": 8711,
+ "nbsp": 160,
+ "ndash": 8211,
+ "ne": 8800,
+ "ni": 8715,
+ "not": 172,
+ "notin": 8713,
+ "nsub": 8836,
+ "ntilde": 241,
+ "nu": 957,
+ "oacute": 243,
+ "ocirc": 244,
+ "oelig": 339,
+ "ograve": 242,
+ "oline": 8254,
+ "omega": 969,
+ "omicron": 959,
+ "oplus": 8853,
+ "or": 8744,
+ "ordf": 170,
+ "ordm": 186,
+ "oslash": 248,
+ "otilde": 245,
+ "otimes": 8855,
+ "ouml": 246,
+ "para": 182,
+ "part": 8706,
+ "permil": 8240,
+ "perp": 8869,
+ "phi": 966,
+ "pi": 960,
+ "piv": 982,
+ "plusmn": 177,
+ "pound": 163,
+ "prime": 8242,
+ "prod": 8719,
+ "prop": 8733,
+ "psi": 968,
+ "quot": 34,
+ "rArr": 8658,
+ "radic": 8730,
+ "rang": 9002,
+ "raquo": 187,
+ "rarr": 8594,
+ "rceil": 8969,
+ "rdquo": 8221,
+ "real": 8476,
+ "reg": 174,
+ "rfloor": 8971,
+ "rho": 961,
+ "rlm": 8207,
+ "rsaquo": 8250,
+ "rsquo": 8217,
+ "sbquo": 8218,
+ "scaron": 353,
+ "sdot": 8901,
+ "sect": 167,
+ "shy": 173,
+ "sigma": 963,
+ "sigmaf": 962,
+ "sim": 8764,
+ "spades": 9824,
+ "sub": 8834,
+ "sube": 8838,
+ "sum": 8721,
+ "sup": 8835,
+ "sup1": 185,
+ "sup2": 178,
+ "sup3": 179,
+ "supe": 8839,
+ "szlig": 223,
+ "tau": 964,
+ "there4": 8756,
+ "theta": 952,
+ "thetasym": 977,
+ "thinsp": 8201,
+ "thorn": 254,
+ "tilde": 732,
+ "times": 215,
+ "trade": 8482,
+ "uArr": 8657,
+ "uacute": 250,
+ "uarr": 8593,
+ "ucirc": 251,
+ "ugrave": 249,
+ "uml": 168,
+ "upsih": 978,
+ "upsilon": 965,
+ "uuml": 252,
+ "weierp": 8472,
+ "xi": 958,
+ "yacute": 253,
+ "yen": 165,
+ "yuml": 255,
+ "zeta": 950,
+ "zwj": 8205,
+ "zwnj": 8204,
+}
diff --git a/contrib/python/MarkupSafe/py2/markupsafe/_native.py b/contrib/python/MarkupSafe/py2/markupsafe/_native.py
new file mode 100644
index 0000000000..cd08752cd8
--- /dev/null
+++ b/contrib/python/MarkupSafe/py2/markupsafe/_native.py
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+"""
+markupsafe._native
+~~~~~~~~~~~~~~~~~~
+
+Native Python implementation used when the C module is not compiled.
+
+:copyright: 2010 Pallets
+:license: BSD-3-Clause
+"""
+from . import Markup
+from ._compat import text_type
+
+
+def escape(s):
+ """Replace the characters ``&``, ``<``, ``>``, ``'``, and ``"`` in
+ the string with HTML-safe sequences. Use this if you need to display
+ text that might contain such characters in HTML.
+
+ If the object has an ``__html__`` method, it is called and the
+ return value is assumed to already be safe for HTML.
+
+ :param s: An object to be converted to a string and escaped.
+ :return: A :class:`Markup` string with the escaped text.
+ """
+ if hasattr(s, "__html__"):
+ return Markup(s.__html__())
+ return Markup(
+ text_type(s)
+ .replace("&", "&amp;")
+ .replace(">", "&gt;")
+ .replace("<", "&lt;")
+ .replace("'", "&#39;")
+ .replace('"', "&#34;")
+ )
+
+
+def escape_silent(s):
+ """Like :func:`escape` but treats ``None`` as the empty string.
+ Useful with optional values, as otherwise you get the string
+ ``'None'`` when the value is ``None``.
+
+ >>> escape(None)
+ Markup('None')
+ >>> escape_silent(None)
+ Markup('')
+ """
+ if s is None:
+ return Markup()
+ return escape(s)
+
+
+def soft_unicode(s):
+ """Convert an object to a string if it isn't already. This preserves
+ a :class:`Markup` string rather than converting it back to a basic
+ string, so it will still be marked as safe and won't be escaped
+ again.
+
+ >>> value = escape('<User 1>')
+ >>> value
+ Markup('&lt;User 1&gt;')
+ >>> escape(str(value))
+ Markup('&amp;lt;User 1&amp;gt;')
+ >>> escape(soft_unicode(value))
+ Markup('&lt;User 1&gt;')
+ """
+ if not isinstance(s, text_type):
+ s = text_type(s)
+ return s
diff --git a/contrib/python/MarkupSafe/py2/tests/conftest.py b/contrib/python/MarkupSafe/py2/tests/conftest.py
new file mode 100644
index 0000000000..296cd58f5f
--- /dev/null
+++ b/contrib/python/MarkupSafe/py2/tests/conftest.py
@@ -0,0 +1,37 @@
+import pytest
+
+from markupsafe import _native
+
+try:
+ from markupsafe import _speedups
+except ImportError:
+ _speedups = None
+
+
+@pytest.fixture(
+ scope="session",
+ params=(
+ _native,
+ pytest.param(
+ _speedups,
+ marks=pytest.mark.skipif(_speedups is None, reason="speedups unavailable"),
+ ),
+ ),
+)
+def _mod(request):
+ return request.param
+
+
+@pytest.fixture(scope="session")
+def escape(_mod):
+ return _mod.escape
+
+
+@pytest.fixture(scope="session")
+def escape_silent(_mod):
+ return _mod.escape_silent
+
+
+@pytest.fixture(scope="session")
+def soft_str(_mod):
+ return _mod.soft_unicode
diff --git a/contrib/python/MarkupSafe/py2/tests/test_escape.py b/contrib/python/MarkupSafe/py2/tests/test_escape.py
new file mode 100644
index 0000000000..788134aeaa
--- /dev/null
+++ b/contrib/python/MarkupSafe/py2/tests/test_escape.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+import pytest
+
+from markupsafe import Markup
+
+
+@pytest.mark.parametrize(
+ ("value", "expect"),
+ (
+ # empty
+ (u"", u""),
+ # ascii
+ (u"abcd&><'\"efgh", u"abcd&amp;&gt;&lt;&#39;&#34;efgh"),
+ (u"&><'\"efgh", u"&amp;&gt;&lt;&#39;&#34;efgh"),
+ (u"abcd&><'\"", u"abcd&amp;&gt;&lt;&#39;&#34;"),
+ # 2 byte
+ (u"こんにちは&><'\"こんばんは", u"こんにちは&amp;&gt;&lt;&#39;&#34;こんばんは"),
+ (u"&><'\"こんばんは", u"&amp;&gt;&lt;&#39;&#34;こんばんは"),
+ (u"こんにちは&><'\"", u"こんにちは&amp;&gt;&lt;&#39;&#34;"),
+ # 4 byte
+ (
+ u"\U0001F363\U0001F362&><'\"\U0001F37A xyz",
+ u"\U0001F363\U0001F362&amp;&gt;&lt;&#39;&#34;\U0001F37A xyz",
+ ),
+ (u"&><'\"\U0001F37A xyz", u"&amp;&gt;&lt;&#39;&#34;\U0001F37A xyz"),
+ (u"\U0001F363\U0001F362&><'\"", u"\U0001F363\U0001F362&amp;&gt;&lt;&#39;&#34;"),
+ ),
+)
+def test_escape(escape, value, expect):
+ assert escape(value) == Markup(expect)
diff --git a/contrib/python/MarkupSafe/py2/tests/test_exception_custom_html.py b/contrib/python/MarkupSafe/py2/tests/test_exception_custom_html.py
new file mode 100644
index 0000000000..5f9ffde438
--- /dev/null
+++ b/contrib/python/MarkupSafe/py2/tests/test_exception_custom_html.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+import pytest
+
+from markupsafe import escape
+
+
+class CustomHtmlThatRaises(object):
+ def __html__(self):
+ raise ValueError(123)
+
+
+def test_exception_custom_html():
+ """Checks whether exceptions in custom __html__ implementations are
+ propagated correctly.
+
+ There was a bug in the native implementation at some point:
+ https://github.com/pallets/markupsafe/issues/108
+ """
+ obj = CustomHtmlThatRaises()
+ with pytest.raises(ValueError):
+ escape(obj)
diff --git a/contrib/python/MarkupSafe/py2/tests/test_leak.py b/contrib/python/MarkupSafe/py2/tests/test_leak.py
new file mode 100644
index 0000000000..b36a4ce4bc
--- /dev/null
+++ b/contrib/python/MarkupSafe/py2/tests/test_leak.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+import gc
+import sys
+
+import pytest
+
+from markupsafe import escape
+
+
+@pytest.mark.skipif(
+ escape.__module__ == "markupsafe._native",
+ reason="only test memory leak with speedups",
+)
+def test_markup_leaks():
+ counts = set()
+
+ for _i in range(20):
+ for _j in range(1000):
+ escape("foo")
+ escape("<foo>")
+ escape(u"foo")
+ escape(u"<foo>")
+
+ if hasattr(sys, "pypy_version_info"):
+ gc.collect()
+
+ counts.add(len(gc.get_objects()))
+
+ assert len(counts) == 1
diff --git a/contrib/python/MarkupSafe/py2/tests/test_markupsafe.py b/contrib/python/MarkupSafe/py2/tests/test_markupsafe.py
new file mode 100644
index 0000000000..5b08006262
--- /dev/null
+++ b/contrib/python/MarkupSafe/py2/tests/test_markupsafe.py
@@ -0,0 +1,196 @@
+# -*- coding: utf-8 -*-
+import pytest
+
+from markupsafe import escape
+from markupsafe import escape_silent
+from markupsafe import Markup
+from markupsafe._compat import PY2
+from markupsafe._compat import text_type
+
+
+def test_adding():
+ unsafe = '<script type="application/x-some-script">alert("foo");</script>'
+ safe = Markup("<em>username</em>")
+ assert unsafe + safe == text_type(escape(unsafe)) + text_type(safe)
+
+
+@pytest.mark.parametrize(
+ ("template", "data", "expect"),
+ (
+ ("<em>%s</em>", "<bad user>", "<em>&lt;bad user&gt;</em>"),
+ (
+ "<em>%(username)s</em>",
+ {"username": "<bad user>"},
+ "<em>&lt;bad user&gt;</em>",
+ ),
+ ("%i", 3.14, "3"),
+ ("%.2f", 3.14, "3.14"),
+ ),
+)
+def test_string_interpolation(template, data, expect):
+ assert Markup(template) % data == expect
+
+
+def test_type_behavior():
+ assert type(Markup("foo") + "bar") is Markup
+ x = Markup("foo")
+ assert x.__html__() is x
+
+
+def test_html_interop():
+ class Foo(object):
+ def __html__(self):
+ return "<em>awesome</em>"
+
+ def __unicode__(self):
+ return "awesome"
+
+ __str__ = __unicode__
+
+ assert Markup(Foo()) == "<em>awesome</em>"
+ result = Markup("<strong>%s</strong>") % Foo()
+ assert result == "<strong><em>awesome</em></strong>"
+
+
+def test_tuple_interpol():
+ result = Markup("<em>%s:%s</em>") % ("<foo>", "<bar>")
+ expect = Markup(u"<em>&lt;foo&gt;:&lt;bar&gt;</em>")
+ assert result == expect
+
+
+def test_dict_interpol():
+ result = Markup("<em>%(foo)s</em>") % {"foo": "<foo>"}
+ expect = Markup(u"<em>&lt;foo&gt;</em>")
+ assert result == expect
+
+ result = Markup("<em>%(foo)s:%(bar)s</em>") % {"foo": "<foo>", "bar": "<bar>"}
+ expect = Markup(u"<em>&lt;foo&gt;:&lt;bar&gt;</em>")
+ assert result == expect
+
+
+def test_escaping():
+ assert escape("\"<>&'") == "&#34;&lt;&gt;&amp;&#39;"
+ assert Markup("<em>Foo &amp; Bar</em>").striptags() == "Foo & Bar"
+
+
+def test_unescape():
+ assert Markup("&lt;test&gt;").unescape() == "<test>"
+
+ result = Markup("jack & tavi are cooler than mike &amp; russ").unescape()
+ expect = "jack & tavi are cooler than mike & russ"
+ assert result == expect
+
+ original = "&foo&#x3b;"
+ once = Markup(original).unescape()
+ twice = Markup(once).unescape()
+ expect = "&foo;"
+ assert once == expect
+ assert twice == expect
+
+
+def test_format():
+ result = Markup("<em>{awesome}</em>").format(awesome="<awesome>")
+ assert result == "<em>&lt;awesome&gt;</em>"
+
+ result = Markup("{0[1][bar]}").format([0, {"bar": "<bar/>"}])
+ assert result == "&lt;bar/&gt;"
+
+ result = Markup("{0[1][bar]}").format([0, {"bar": Markup("<bar/>")}])
+ assert result == "<bar/>"
+
+
+def test_formatting_empty():
+ formatted = Markup("{}").format(0)
+ assert formatted == Markup("0")
+
+
+def test_custom_formatting():
+ class HasHTMLOnly(object):
+ def __html__(self):
+ return Markup("<foo>")
+
+ class HasHTMLAndFormat(object):
+ def __html__(self):
+ return Markup("<foo>")
+
+ def __html_format__(self, spec):
+ return Markup("<FORMAT>")
+
+ assert Markup("{0}").format(HasHTMLOnly()) == Markup("<foo>")
+ assert Markup("{0}").format(HasHTMLAndFormat()) == Markup("<FORMAT>")
+
+
+def test_complex_custom_formatting():
+ class User(object):
+ def __init__(self, id, username):
+ self.id = id
+ self.username = username
+
+ def __html_format__(self, format_spec):
+ if format_spec == "link":
+ return Markup('<a href="/user/{0}">{1}</a>').format(
+ self.id, self.__html__()
+ )
+ elif format_spec:
+ raise ValueError("Invalid format spec")
+
+ return self.__html__()
+
+ def __html__(self):
+ return Markup("<span class=user>{0}</span>").format(self.username)
+
+ user = User(1, "foo")
+ result = Markup("<p>User: {0:link}").format(user)
+ expect = Markup('<p>User: <a href="/user/1"><span class=user>foo</span></a>')
+ assert result == expect
+
+
+def test_formatting_with_objects():
+ class Stringable(object):
+ def __unicode__(self):
+ return u"строка"
+
+ if PY2:
+
+ def __str__(self):
+ return "some other value"
+
+ else:
+ __str__ = __unicode__
+
+ assert Markup("{s}").format(s=Stringable()) == Markup(u"строка")
+
+
+def test_all_set():
+ import markupsafe as markup
+
+ for item in markup.__all__:
+ getattr(markup, item)
+
+
+def test_escape_silent():
+ assert escape_silent(None) == Markup()
+ assert escape(None) == Markup(None)
+ assert escape_silent("<foo>") == Markup(u"&lt;foo&gt;")
+
+
+def test_splitting():
+ expect = [Markup("a"), Markup("b")]
+ assert Markup("a b").split() == expect
+ assert Markup("a b").rsplit() == expect
+ assert Markup("a\nb").splitlines() == expect
+
+
+def test_mul():
+ assert Markup("a") * 3 == Markup("aaa")
+
+
+def test_escape_return_type():
+ assert isinstance(escape("a"), Markup)
+ assert isinstance(escape(Markup("a")), Markup)
+
+ class Foo:
+ def __html__(self):
+ return "<strong>Foo</strong>"
+
+ assert isinstance(escape(Foo()), Markup)
diff --git a/contrib/python/MarkupSafe/py2/tests/ya.make b/contrib/python/MarkupSafe/py2/tests/ya.make
new file mode 100644
index 0000000000..62ea965260
--- /dev/null
+++ b/contrib/python/MarkupSafe/py2/tests/ya.make
@@ -0,0 +1,17 @@
+PY2TEST()
+
+PEERDIR(
+ contrib/python/MarkupSafe
+)
+
+TEST_SRCS(
+ conftest.py
+ test_escape.py
+ test_exception_custom_html.py
+ test_leak.py
+ test_markupsafe.py
+)
+
+NO_LINT()
+
+END()
diff --git a/contrib/python/MarkupSafe/py2/ya.make b/contrib/python/MarkupSafe/py2/ya.make
new file mode 100644
index 0000000000..fa01deed75
--- /dev/null
+++ b/contrib/python/MarkupSafe/py2/ya.make
@@ -0,0 +1,37 @@
+PY2_LIBRARY()
+
+LICENSE(BSD-3-Clause)
+
+VERSION(1.1.1)
+
+PY_SRCS(
+ TOP_LEVEL
+ markupsafe/_compat.py
+ markupsafe/_constants.py
+ markupsafe/__init__.py
+ markupsafe/_native.py
+)
+
+#SRCS(
+# markupsafe/_speedups.c
+#)
+
+#PY_REGISTER(
+# markupsafe._speedups
+#)
+
+NO_LINT()
+
+NO_COMPILER_WARNINGS()
+
+RESOURCE_FILES(
+ PREFIX contrib/python/MarkupSafe/py2/
+ .dist-info/METADATA
+ .dist-info/top_level.txt
+)
+
+END()
+
+RECURSE_FOR_TESTS(
+ tests
+)