"""Locale utility routines.""" import sys try: import locale except ImportError: locale = None try: import codecs except ImportError: codecs = None __all__ = ["localelist"] def localelist(*locales): """Normalize and return a list of locales, with appended defaults. e.g. on a system with en_US as the default locale, localelist('en_GB.utf8', 'de_DE') => ['en_GB', 'en', 'de_DE', 'de', 'en_US', 'C'] """ locales = list(locales) if locale is not None: # Set the locale if it hasn't already been set, but don't fail # if we can't set it for some reason. if locale.getlocale(locale.LC_COLLATE)[0] is None: try: locale.setlocale(locale.LC_COLLATE, '') except locale.Error: pass # Throw in the user's specified collation locale, the current locale, # the default locale, and POSIX, for free. locales.append(locale.getlocale(locale.LC_COLLATE)[0]) locales.append(locale.getlocale()[0]) locales.append(locale.getdefaultlocale()[0]) locales.append("C") # Don't put the same locale in the return list more than twice. added = set() retlist = [] for code in locales: if not code: continue if locale is not None: code = locale.normalize(code) # Strip off encoding if present. code = code.split(".")[0] if code.lower() not in added: retlist.append(code) added.add(code.lower()) # Strip off territory if present. code = code.split("_")[0] if code.lower() not in added: retlist.append(code) added.add(code.lower()) return retlist def encoding(preferred=None): """Try to find an optimal encoding. Arguments: preferred - use this encoding if possible Otherwise, the locale encoding or the Python system encoding are used. """ # can't use any codecs, use the system one (ascii). if codecs is None: return sys.getdefaultencoding() # if preferred is a valid codec, use it. if preferred is not None: try: return codecs.lookup(preferred).name except (LookupError, AttributeError): pass # preferred is bad and can't get it from locale. if locale is None: return sys.getdefaultencoding() # try to get it from the locale, if not there, set it and try again. fromlocale = locale.getlocale(locale.LC_COLLATE)[1] if fromlocale is not None: return fromlocale try: locale.setlocale(locale.LC_COLLATE, '')[1] except locale.Error: pass else: fromlocale = locale.getlocale(locale.LC_COLLATE) if fromlocale is not None: return fromlocale # okay, LC_COLLATE isn't set, maybe the generic locale is. fromlocale = locale.getlocale()[1] if fromlocale is not None: return fromlocale # but we won't reset the generic locale if it isn't, that'd be # rude. # if the locale can't even give us a simple encoding, go back # to the system one, and give up. return locale.getpreferredencoding() or sys.getdefaultencoding() def getpair(locale_, encoding_): if "." in locale_: if encoding_ is None: locale_, encoding_ = locale_.rsplit(".", 1) else: locale_ = locale_.rsplit(".")[0] return locale_, encoding(encoding_)