_native.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import typing as t
  2. from . import Markup
  3. def escape(s: t.Any) -> Markup:
  4. """Replace the characters ``&``, ``<``, ``>``, ``'``, and ``"`` in
  5. the string with HTML-safe sequences. Use this if you need to display
  6. text that might contain such characters in HTML.
  7. If the object has an ``__html__`` method, it is called and the
  8. return value is assumed to already be safe for HTML.
  9. :param s: An object to be converted to a string and escaped.
  10. :return: A :class:`Markup` string with the escaped text.
  11. """
  12. if hasattr(s, "__html__"):
  13. return Markup(s.__html__())
  14. return Markup(
  15. str(s)
  16. .replace("&", "&amp;")
  17. .replace(">", "&gt;")
  18. .replace("<", "&lt;")
  19. .replace("'", "&#39;")
  20. .replace('"', "&#34;")
  21. )
  22. def escape_silent(s: t.Optional[t.Any]) -> Markup:
  23. """Like :func:`escape` but treats ``None`` as the empty string.
  24. Useful with optional values, as otherwise you get the string
  25. ``'None'`` when the value is ``None``.
  26. >>> escape(None)
  27. Markup('None')
  28. >>> escape_silent(None)
  29. Markup('')
  30. """
  31. if s is None:
  32. return Markup()
  33. return escape(s)
  34. def soft_str(s: t.Any) -> str:
  35. """Convert an object to a string if it isn't already. This preserves
  36. a :class:`Markup` string rather than converting it back to a basic
  37. string, so it will still be marked as safe and won't be escaped
  38. again.
  39. >>> value = escape("<User 1>")
  40. >>> value
  41. Markup('&lt;User 1&gt;')
  42. >>> escape(str(value))
  43. Markup('&amp;lt;User 1&amp;gt;')
  44. >>> escape(soft_str(value))
  45. Markup('&lt;User 1&gt;')
  46. """
  47. if not isinstance(s, str):
  48. return str(s)
  49. return s