X-Git-Url: https://git.korewanetadesu.com/?p=python-collate.git;a=blobdiff_plain;f=collate%2F_locale.py;fp=collate%2F_locale.py;h=bebbc957608beb017b4e2cca28b6ccc8fe5b0057;hp=0000000000000000000000000000000000000000;hb=f7fd328bfc2886f6aed2c09b84cc1e039c7c3240;hpb=22570a3c13079d27cfb60110f631b164dbd8b831 diff --git a/collate/_locale.py b/collate/_locale.py new file mode 100644 index 0000000..bebbc95 --- /dev/null +++ b/collate/_locale.py @@ -0,0 +1,123 @@ +"""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_) +