diff --git a/powerline/__init__.py b/powerline/__init__.py index 4df195dd..465680d6 100644 --- a/powerline/__init__.py +++ b/powerline/__init__.py @@ -7,33 +7,14 @@ import logging from powerline.colorscheme import Colorscheme from powerline.lib.config import ConfigLoader +from powerline.lib.unicode import safe_unicode from threading import Lock, Event -try: - from __builtin__ import unicode -except ImportError: - unicode = str # NOQA - DEFAULT_SYSTEM_CONFIG_DIR = None -def safe_unicode(s): - '''Return unicode instance without raising an exception. - ''' - try: - try: - return unicode(s) - except UnicodeDecodeError: - try: - return unicode(s, 'utf-8') - except TypeError: - return unicode(str(s), 'utf-8') - except Exception as e: - return safe_unicode(e) - - class FailedUnicode(unicode): '''Builtin ``unicode`` (``str`` in python 3) subclass indicating fatal error. @@ -69,7 +50,7 @@ class PowerlineLogger(object): prefix = self.ext + ((':' + prefix) if prefix else '') if args or kwargs: msg = msg.format(*args, **kwargs) - msg = prefix + ':' + msg + msg = prefix + ':' + safe_unicode(msg) key = attr + ':' + prefix if msg != self.last_msgs.get(key): getattr(self.logger, attr)(msg) diff --git a/powerline/lib/unicode.py b/powerline/lib/unicode.py index 645d4d7b..aa717fee 100644 --- a/powerline/lib/unicode.py +++ b/powerline/lib/unicode.py @@ -1,5 +1,9 @@ # vim:fileencoding=utf-8:noet + +from locale import getpreferredencoding + + try: from __builtin__ import unicode except ImportError: @@ -7,7 +11,35 @@ except ImportError: def u(s): + '''Return unicode instance assuming UTF-8 encoded string. + ''' if type(s) is unicode: return s else: return unicode(s, 'utf-8') + + +def safe_unicode(s): + '''Return unicode instance without raising an exception. + + Order of assumptions: + * ASCII string or unicode object + * UTF-8 string + * Object with __str__() or __repr__() method that returns UTF-8 string or + unicode object (depending on python version) + * String in locale.getpreferredencoding() encoding + * If everything failed use safe_unicode on last exception with which + everything failed + ''' + try: + try: + return unicode(s) + except UnicodeDecodeError: + try: + return unicode(s, 'utf-8') + except TypeError: + return unicode(str(s), 'utf-8') + except UnicodeDecodeError: + return unicode(s, getpreferredencoding()) + except Exception as e: + return safe_unicode(e)