loglevels.py 3.6 KB

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