gooderp18绿色标准版
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
4.0KB

  1. # -*- coding: utf-8 -*-
  2. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  3. import contextlib
  4. import warnings
  5. LOG_NOTSET = 'notset'
  6. LOG_DEBUG = 'debug'
  7. LOG_INFO = 'info'
  8. LOG_WARNING = 'warn'
  9. LOG_ERROR = 'error'
  10. LOG_CRITICAL = 'critical'
  11. # TODO get_encodings, ustr and exception_to_unicode were originally from tools.misc.
  12. # There are here until we refactor tools so that this module doesn't depends on tools.
  13. def get_encodings(hint_encoding='utf-8'):
  14. warnings.warn(
  15. "Deprecated since Odoo 18. Mostly nonsensical as the "
  16. "second/third encoding it yields is latin-1 which always succeeds...",
  17. stacklevel=2,
  18. category=DeprecationWarning,
  19. )
  20. fallbacks = {
  21. 'latin1': 'latin9',
  22. 'iso-8859-1': 'iso8859-15',
  23. 'iso-8859-8-i': 'iso8859-8',
  24. 'cp1252': '1252',
  25. }
  26. if hint_encoding:
  27. yield hint_encoding
  28. if hint_encoding.lower() in fallbacks:
  29. yield fallbacks[hint_encoding.lower()]
  30. # some defaults (also taking care of pure ASCII)
  31. for charset in ['utf8','latin1']:
  32. if not hint_encoding or (charset.lower() != hint_encoding.lower()):
  33. yield charset
  34. from locale import getpreferredencoding
  35. prefenc = getpreferredencoding()
  36. if prefenc and prefenc.lower() != 'utf-8':
  37. yield prefenc
  38. prefenc = fallbacks.get(prefenc.lower())
  39. if prefenc:
  40. yield prefenc
  41. def ustr(value, hint_encoding='utf-8', errors='strict'):
  42. """This method is similar to the builtin `unicode`, except
  43. that it may try multiple encodings to find one that works
  44. for decoding `value`, and defaults to 'utf-8' first.
  45. :param value: the value to convert
  46. :param hint_encoding: an optional encoding that was detected
  47. upstream and should be tried first to decode ``value``.
  48. :param str errors: optional `errors` flag to pass to the unicode
  49. built-in to indicate how illegal character values should be
  50. treated when converting a string: 'strict', 'ignore' or 'replace'
  51. (see ``unicode()`` constructor).
  52. Passing anything other than 'strict' means that the first
  53. encoding tried will be used, even if it's not the correct
  54. one to use, so be careful! Ignored if value is not a string/unicode.
  55. :raise: UnicodeError if value cannot be coerced to unicode
  56. :return: unicode string representing the given value
  57. """
  58. warnings.warn(
  59. "Deprecated since Odoo 18: ustr() is a garbage bag of weirdo fallbacks "
  60. "which mostly don't do anything as\n"
  61. "- the first attempt will always work if errors is not `strict`\n"
  62. "- if utf8 fails it moves on to latin-1 which always works\n"
  63. "- and it always tries hint-encoding twice",
  64. stacklevel=2,
  65. category=DeprecationWarning,
  66. )
  67. # We use direct type comparison instead of `isinstance`
  68. # as much as possible, in order to make the most common
  69. # cases faster (isinstance/issubclass are significantly slower)
  70. ttype = type(value)
  71. if ttype is str:
  72. return value
  73. # special short-circuit for str, as we still needs to support
  74. # str subclasses such as `odoo.tools.unquote`
  75. if ttype is bytes or issubclass(ttype, bytes):
  76. # try hint_encoding first, avoids call to get_encoding()
  77. # for the most common case
  78. with contextlib.suppress(Exception):
  79. return value.decode(hint_encoding, errors=errors)
  80. # rare: no luck with hint_encoding, attempt other ones
  81. for ln in get_encodings(hint_encoding):
  82. with contextlib.suppress(Exception):
  83. return value.decode(ln, errors=errors)
  84. if isinstance(value, Exception):
  85. return exception_to_unicode(value)
  86. # fallback for non-string values
  87. try:
  88. return str(value)
  89. except Exception as e:
  90. raise UnicodeError(f'unable to convert {value!r}') from e
  91. def exception_to_unicode(e):
  92. if getattr(e, 'args', ()):
  93. return "\n".join(map(str, e.args))
  94. try:
  95. return str(e)
  96. except Exception:
  97. return "Unknown message"
上海开阖软件有限公司 沪ICP备12045867号-1