• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""Locale support module.
2
3The module provides low-level access to the C lib's locale APIs and adds high
4level number formatting APIs as well as a locale aliasing engine to complement
5these.
6
7The aliasing engine includes support for many commonly used locale names and
8maps them to values suitable for passing to the C lib's setlocale() function. It
9also includes default encodings for all supported locale names.
10
11"""
12
13import sys
14import encodings
15import encodings.aliases
16import re
17import _collections_abc
18from builtins import str as _builtin_str
19import functools
20
21# Try importing the _locale module.
22#
23# If this fails, fall back on a basic 'C' locale emulation.
24
25# Yuck:  LC_MESSAGES is non-standard:  can't tell whether it exists before
26# trying the import.  So __all__ is also fiddled at the end of the file.
27__all__ = ["getlocale", "getdefaultlocale", "getpreferredencoding", "Error",
28           "setlocale", "localeconv", "strcoll", "strxfrm",
29           "str", "atof", "atoi", "format_string", "currency",
30           "normalize", "LC_CTYPE", "LC_COLLATE", "LC_TIME", "LC_MONETARY",
31           "LC_NUMERIC", "LC_ALL", "CHAR_MAX", "getencoding"]
32
33def _strcoll(a,b):
34    """ strcoll(string,string) -> int.
35        Compares two strings according to the locale.
36    """
37    return (a > b) - (a < b)
38
39def _strxfrm(s):
40    """ strxfrm(string) -> string.
41        Returns a string that behaves for cmp locale-aware.
42    """
43    return s
44
45try:
46
47    from _locale import *
48
49except ImportError:
50
51    # Locale emulation
52
53    CHAR_MAX = 127
54    LC_ALL = 6
55    LC_COLLATE = 3
56    LC_CTYPE = 0
57    LC_MESSAGES = 5
58    LC_MONETARY = 4
59    LC_NUMERIC = 1
60    LC_TIME = 2
61    Error = ValueError
62
63    def localeconv():
64        """ localeconv() -> dict.
65            Returns numeric and monetary locale-specific parameters.
66        """
67        # 'C' locale default values
68        return {'grouping': [127],
69                'currency_symbol': '',
70                'n_sign_posn': 127,
71                'p_cs_precedes': 127,
72                'n_cs_precedes': 127,
73                'mon_grouping': [],
74                'n_sep_by_space': 127,
75                'decimal_point': '.',
76                'negative_sign': '',
77                'positive_sign': '',
78                'p_sep_by_space': 127,
79                'int_curr_symbol': '',
80                'p_sign_posn': 127,
81                'thousands_sep': '',
82                'mon_thousands_sep': '',
83                'frac_digits': 127,
84                'mon_decimal_point': '',
85                'int_frac_digits': 127}
86
87    def setlocale(category, value=None):
88        """ setlocale(integer,string=None) -> string.
89            Activates/queries locale processing.
90        """
91        if value not in (None, '', 'C'):
92            raise Error('_locale emulation only supports "C" locale')
93        return 'C'
94
95# These may or may not exist in _locale, so be sure to set them.
96if 'strxfrm' not in globals():
97    strxfrm = _strxfrm
98if 'strcoll' not in globals():
99    strcoll = _strcoll
100
101
102_localeconv = localeconv
103
104# With this dict, you can override some items of localeconv's return value.
105# This is useful for testing purposes.
106_override_localeconv = {}
107
108@functools.wraps(_localeconv)
109def localeconv():
110    d = _localeconv()
111    if _override_localeconv:
112        d.update(_override_localeconv)
113    return d
114
115
116### Number formatting APIs
117
118# Author: Martin von Loewis
119# improved by Georg Brandl
120
121# Iterate over grouping intervals
122def _grouping_intervals(grouping):
123    last_interval = None
124    for interval in grouping:
125        # if grouping is -1, we are done
126        if interval == CHAR_MAX:
127            return
128        # 0: re-use last group ad infinitum
129        if interval == 0:
130            if last_interval is None:
131                raise ValueError("invalid grouping")
132            while True:
133                yield last_interval
134        yield interval
135        last_interval = interval
136
137#perform the grouping from right to left
138def _group(s, monetary=False):
139    conv = localeconv()
140    thousands_sep = conv[monetary and 'mon_thousands_sep' or 'thousands_sep']
141    grouping = conv[monetary and 'mon_grouping' or 'grouping']
142    if not grouping:
143        return (s, 0)
144    if s[-1] == ' ':
145        stripped = s.rstrip()
146        right_spaces = s[len(stripped):]
147        s = stripped
148    else:
149        right_spaces = ''
150    left_spaces = ''
151    groups = []
152    for interval in _grouping_intervals(grouping):
153        if not s or s[-1] not in "0123456789":
154            # only non-digit characters remain (sign, spaces)
155            left_spaces = s
156            s = ''
157            break
158        groups.append(s[-interval:])
159        s = s[:-interval]
160    if s:
161        groups.append(s)
162    groups.reverse()
163    return (
164        left_spaces + thousands_sep.join(groups) + right_spaces,
165        len(thousands_sep) * (len(groups) - 1)
166    )
167
168# Strip a given amount of excess padding from the given string
169def _strip_padding(s, amount):
170    lpos = 0
171    while amount and s[lpos] == ' ':
172        lpos += 1
173        amount -= 1
174    rpos = len(s) - 1
175    while amount and s[rpos] == ' ':
176        rpos -= 1
177        amount -= 1
178    return s[lpos:rpos+1]
179
180_percent_re = re.compile(r'%(?:\((?P<key>.*?)\))?'
181                         r'(?P<modifiers>[-#0-9 +*.hlL]*?)[eEfFgGdiouxXcrs%]')
182
183def _format(percent, value, grouping=False, monetary=False, *additional):
184    if additional:
185        formatted = percent % ((value,) + additional)
186    else:
187        formatted = percent % value
188    if percent[-1] in 'eEfFgGdiu':
189        formatted = _localize(formatted, grouping, monetary)
190    return formatted
191
192# Transform formatted as locale number according to the locale settings
193def _localize(formatted, grouping=False, monetary=False):
194    # floats and decimal ints need special action!
195    if '.' in formatted:
196        seps = 0
197        parts = formatted.split('.')
198        if grouping:
199            parts[0], seps = _group(parts[0], monetary=monetary)
200        decimal_point = localeconv()[monetary and 'mon_decimal_point'
201                                              or 'decimal_point']
202        formatted = decimal_point.join(parts)
203        if seps:
204            formatted = _strip_padding(formatted, seps)
205    else:
206        seps = 0
207        if grouping:
208            formatted, seps = _group(formatted, monetary=monetary)
209        if seps:
210            formatted = _strip_padding(formatted, seps)
211    return formatted
212
213def format_string(f, val, grouping=False, monetary=False):
214    """Formats a string in the same way that the % formatting would use,
215    but takes the current locale into account.
216
217    Grouping is applied if the third parameter is true.
218    Conversion uses monetary thousands separator and grouping strings if
219    forth parameter monetary is true."""
220    percents = list(_percent_re.finditer(f))
221    new_f = _percent_re.sub('%s', f)
222
223    if isinstance(val, _collections_abc.Mapping):
224        new_val = []
225        for perc in percents:
226            if perc.group()[-1]=='%':
227                new_val.append('%')
228            else:
229                new_val.append(_format(perc.group(), val, grouping, monetary))
230    else:
231        if not isinstance(val, tuple):
232            val = (val,)
233        new_val = []
234        i = 0
235        for perc in percents:
236            if perc.group()[-1]=='%':
237                new_val.append('%')
238            else:
239                starcount = perc.group('modifiers').count('*')
240                new_val.append(_format(perc.group(),
241                                      val[i],
242                                      grouping,
243                                      monetary,
244                                      *val[i+1:i+1+starcount]))
245                i += (1 + starcount)
246    val = tuple(new_val)
247
248    return new_f % val
249
250def currency(val, symbol=True, grouping=False, international=False):
251    """Formats val according to the currency settings
252    in the current locale."""
253    conv = localeconv()
254
255    # check for illegal values
256    digits = conv[international and 'int_frac_digits' or 'frac_digits']
257    if digits == 127:
258        raise ValueError("Currency formatting is not possible using "
259                         "the 'C' locale.")
260
261    s = _localize(f'{abs(val):.{digits}f}', grouping, monetary=True)
262    # '<' and '>' are markers if the sign must be inserted between symbol and value
263    s = '<' + s + '>'
264
265    if symbol:
266        smb = conv[international and 'int_curr_symbol' or 'currency_symbol']
267        precedes = conv[val<0 and 'n_cs_precedes' or 'p_cs_precedes']
268        separated = conv[val<0 and 'n_sep_by_space' or 'p_sep_by_space']
269
270        if precedes:
271            s = smb + (separated and ' ' or '') + s
272        else:
273            if international and smb[-1] == ' ':
274                smb = smb[:-1]
275            s = s + (separated and ' ' or '') + smb
276
277    sign_pos = conv[val<0 and 'n_sign_posn' or 'p_sign_posn']
278    sign = conv[val<0 and 'negative_sign' or 'positive_sign']
279
280    if sign_pos == 0:
281        s = '(' + s + ')'
282    elif sign_pos == 1:
283        s = sign + s
284    elif sign_pos == 2:
285        s = s + sign
286    elif sign_pos == 3:
287        s = s.replace('<', sign)
288    elif sign_pos == 4:
289        s = s.replace('>', sign)
290    else:
291        # the default if nothing specified;
292        # this should be the most fitting sign position
293        s = sign + s
294
295    return s.replace('<', '').replace('>', '')
296
297def str(val):
298    """Convert float to string, taking the locale into account."""
299    return _format("%.12g", val)
300
301def delocalize(string):
302    "Parses a string as a normalized number according to the locale settings."
303
304    conv = localeconv()
305
306    #First, get rid of the grouping
307    ts = conv['thousands_sep']
308    if ts:
309        string = string.replace(ts, '')
310
311    #next, replace the decimal point with a dot
312    dd = conv['decimal_point']
313    if dd:
314        string = string.replace(dd, '.')
315    return string
316
317def localize(string, grouping=False, monetary=False):
318    """Parses a string as locale number according to the locale settings."""
319    return _localize(string, grouping, monetary)
320
321def atof(string, func=float):
322    "Parses a string as a float according to the locale settings."
323    return func(delocalize(string))
324
325def atoi(string):
326    "Converts a string to an integer according to the locale settings."
327    return int(delocalize(string))
328
329def _test():
330    setlocale(LC_ALL, "")
331    #do grouping
332    s1 = format_string("%d", 123456789,1)
333    print(s1, "is", atoi(s1))
334    #standard formatting
335    s1 = str(3.14)
336    print(s1, "is", atof(s1))
337
338### Locale name aliasing engine
339
340# Author: Marc-Andre Lemburg, mal@lemburg.com
341# Various tweaks by Fredrik Lundh <fredrik@pythonware.com>
342
343# store away the low-level version of setlocale (it's
344# overridden below)
345_setlocale = setlocale
346
347def _replace_encoding(code, encoding):
348    if '.' in code:
349        langname = code[:code.index('.')]
350    else:
351        langname = code
352    # Convert the encoding to a C lib compatible encoding string
353    norm_encoding = encodings.normalize_encoding(encoding)
354    #print('norm encoding: %r' % norm_encoding)
355    norm_encoding = encodings.aliases.aliases.get(norm_encoding.lower(),
356                                                  norm_encoding)
357    #print('aliased encoding: %r' % norm_encoding)
358    encoding = norm_encoding
359    norm_encoding = norm_encoding.lower()
360    if norm_encoding in locale_encoding_alias:
361        encoding = locale_encoding_alias[norm_encoding]
362    else:
363        norm_encoding = norm_encoding.replace('_', '')
364        norm_encoding = norm_encoding.replace('-', '')
365        if norm_encoding in locale_encoding_alias:
366            encoding = locale_encoding_alias[norm_encoding]
367    #print('found encoding %r' % encoding)
368    return langname + '.' + encoding
369
370def _append_modifier(code, modifier):
371    if modifier == 'euro':
372        if '.' not in code:
373            return code + '.ISO8859-15'
374        _, _, encoding = code.partition('.')
375        if encoding in ('ISO8859-15', 'UTF-8'):
376            return code
377        if encoding == 'ISO8859-1':
378            return _replace_encoding(code, 'ISO8859-15')
379    return code + '@' + modifier
380
381def normalize(localename):
382
383    """ Returns a normalized locale code for the given locale
384        name.
385
386        The returned locale code is formatted for use with
387        setlocale().
388
389        If normalization fails, the original name is returned
390        unchanged.
391
392        If the given encoding is not known, the function defaults to
393        the default encoding for the locale code just like setlocale()
394        does.
395
396    """
397    # Normalize the locale name and extract the encoding and modifier
398    code = localename.lower()
399    if ':' in code:
400        # ':' is sometimes used as encoding delimiter.
401        code = code.replace(':', '.')
402    if '@' in code:
403        code, modifier = code.split('@', 1)
404    else:
405        modifier = ''
406    if '.' in code:
407        langname, encoding = code.split('.')[:2]
408    else:
409        langname = code
410        encoding = ''
411
412    # First lookup: fullname (possibly with encoding and modifier)
413    lang_enc = langname
414    if encoding:
415        norm_encoding = encoding.replace('-', '')
416        norm_encoding = norm_encoding.replace('_', '')
417        lang_enc += '.' + norm_encoding
418    lookup_name = lang_enc
419    if modifier:
420        lookup_name += '@' + modifier
421    code = locale_alias.get(lookup_name, None)
422    if code is not None:
423        return code
424    #print('first lookup failed')
425
426    if modifier:
427        # Second try: fullname without modifier (possibly with encoding)
428        code = locale_alias.get(lang_enc, None)
429        if code is not None:
430            #print('lookup without modifier succeeded')
431            if '@' not in code:
432                return _append_modifier(code, modifier)
433            if code.split('@', 1)[1].lower() == modifier:
434                return code
435        #print('second lookup failed')
436
437    if encoding:
438        # Third try: langname (without encoding, possibly with modifier)
439        lookup_name = langname
440        if modifier:
441            lookup_name += '@' + modifier
442        code = locale_alias.get(lookup_name, None)
443        if code is not None:
444            #print('lookup without encoding succeeded')
445            if '@' not in code:
446                return _replace_encoding(code, encoding)
447            code, modifier = code.split('@', 1)
448            return _replace_encoding(code, encoding) + '@' + modifier
449
450        if modifier:
451            # Fourth try: langname (without encoding and modifier)
452            code = locale_alias.get(langname, None)
453            if code is not None:
454                #print('lookup without modifier and encoding succeeded')
455                if '@' not in code:
456                    code = _replace_encoding(code, encoding)
457                    return _append_modifier(code, modifier)
458                code, defmod = code.split('@', 1)
459                if defmod.lower() == modifier:
460                    return _replace_encoding(code, encoding) + '@' + defmod
461
462    return localename
463
464def _parse_localename(localename):
465
466    """ Parses the locale code for localename and returns the
467        result as tuple (language code, encoding).
468
469        The localename is normalized and passed through the locale
470        alias engine. A ValueError is raised in case the locale name
471        cannot be parsed.
472
473        The language code corresponds to RFC 1766.  code and encoding
474        can be None in case the values cannot be determined or are
475        unknown to this implementation.
476
477    """
478    code = normalize(localename)
479    if '@' in code:
480        # Deal with locale modifiers
481        code, modifier = code.split('@', 1)
482        if modifier == 'euro' and '.' not in code:
483            # Assume Latin-9 for @euro locales. This is bogus,
484            # since some systems may use other encodings for these
485            # locales. Also, we ignore other modifiers.
486            return code, 'iso-8859-15'
487
488    if '.' in code:
489        return tuple(code.split('.')[:2])
490    elif code == 'C':
491        return None, None
492    elif code == 'UTF-8':
493        # On macOS "LC_CTYPE=UTF-8" is a valid locale setting
494        # for getting UTF-8 handling for text.
495        return None, 'UTF-8'
496    raise ValueError('unknown locale: %s' % localename)
497
498def _build_localename(localetuple):
499
500    """ Builds a locale code from the given tuple (language code,
501        encoding).
502
503        No aliasing or normalizing takes place.
504
505    """
506    try:
507        language, encoding = localetuple
508
509        if language is None:
510            language = 'C'
511        if encoding is None:
512            return language
513        else:
514            return language + '.' + encoding
515    except (TypeError, ValueError):
516        raise TypeError('Locale must be None, a string, or an iterable of '
517                        'two strings -- language code, encoding.') from None
518
519def getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')):
520
521    """ Tries to determine the default locale settings and returns
522        them as tuple (language code, encoding).
523
524        According to POSIX, a program which has not called
525        setlocale(LC_ALL, "") runs using the portable 'C' locale.
526        Calling setlocale(LC_ALL, "") lets it use the default locale as
527        defined by the LANG variable. Since we don't want to interfere
528        with the current locale setting we thus emulate the behavior
529        in the way described above.
530
531        To maintain compatibility with other platforms, not only the
532        LANG variable is tested, but a list of variables given as
533        envvars parameter. The first found to be defined will be
534        used. envvars defaults to the search path used in GNU gettext;
535        it must always contain the variable name 'LANG'.
536
537        Except for the code 'C', the language code corresponds to RFC
538        1766.  code and encoding can be None in case the values cannot
539        be determined.
540
541    """
542
543    import warnings
544    warnings._deprecated(
545        "locale.getdefaultlocale",
546        "{name!r} is deprecated and slated for removal in Python {remove}. "
547        "Use setlocale(), getencoding() and getlocale() instead.",
548        remove=(3, 15))
549    return _getdefaultlocale(envvars)
550
551
552def _getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')):
553    try:
554        # check if it's supported by the _locale module
555        import _locale
556        code, encoding = _locale._getdefaultlocale()
557    except (ImportError, AttributeError):
558        pass
559    else:
560        # make sure the code/encoding values are valid
561        if sys.platform == "win32" and code and code[:2] == "0x":
562            # map windows language identifier to language name
563            code = windows_locale.get(int(code, 0))
564        # ...add other platform-specific processing here, if
565        # necessary...
566        return code, encoding
567
568    # fall back on POSIX behaviour
569    import os
570    lookup = os.environ.get
571    for variable in envvars:
572        localename = lookup(variable,None)
573        if localename:
574            if variable == 'LANGUAGE':
575                localename = localename.split(':')[0]
576            break
577    else:
578        localename = 'C'
579    return _parse_localename(localename)
580
581
582def getlocale(category=LC_CTYPE):
583
584    """ Returns the current setting for the given locale category as
585        tuple (language code, encoding).
586
587        category may be one of the LC_* value except LC_ALL. It
588        defaults to LC_CTYPE.
589
590        Except for the code 'C', the language code corresponds to RFC
591        1766.  code and encoding can be None in case the values cannot
592        be determined.
593
594    """
595    localename = _setlocale(category)
596    if category == LC_ALL and ';' in localename:
597        raise TypeError('category LC_ALL is not supported')
598    return _parse_localename(localename)
599
600def setlocale(category, locale=None):
601
602    """ Set the locale for the given category.  The locale can be
603        a string, an iterable of two strings (language code and encoding),
604        or None.
605
606        Iterables are converted to strings using the locale aliasing
607        engine.  Locale strings are passed directly to the C lib.
608
609        category may be given as one of the LC_* values.
610
611    """
612    if locale and not isinstance(locale, _builtin_str):
613        # convert to string
614        locale = normalize(_build_localename(locale))
615    return _setlocale(category, locale)
616
617
618try:
619    from _locale import getencoding
620except ImportError:
621    # When _locale.getencoding() is missing, locale.getencoding() uses the
622    # Python filesystem encoding.
623    def getencoding():
624        return sys.getfilesystemencoding()
625
626
627try:
628    CODESET
629except NameError:
630    def getpreferredencoding(do_setlocale=True):
631        """Return the charset that the user is likely using."""
632        if sys.flags.warn_default_encoding:
633            import warnings
634            warnings.warn(
635                "UTF-8 Mode affects locale.getpreferredencoding(). Consider locale.getencoding() instead.",
636                EncodingWarning, 2)
637        if sys.flags.utf8_mode:
638            return 'utf-8'
639        return getencoding()
640else:
641    # On Unix, if CODESET is available, use that.
642    def getpreferredencoding(do_setlocale=True):
643        """Return the charset that the user is likely using,
644        according to the system configuration."""
645
646        if sys.flags.warn_default_encoding:
647            import warnings
648            warnings.warn(
649                "UTF-8 Mode affects locale.getpreferredencoding(). Consider locale.getencoding() instead.",
650                EncodingWarning, 2)
651        if sys.flags.utf8_mode:
652            return 'utf-8'
653
654        if not do_setlocale:
655            return getencoding()
656
657        old_loc = setlocale(LC_CTYPE)
658        try:
659            try:
660                setlocale(LC_CTYPE, "")
661            except Error:
662                pass
663            return getencoding()
664        finally:
665            setlocale(LC_CTYPE, old_loc)
666
667
668### Database
669#
670# The following data was extracted from the locale.alias file which
671# comes with X11 and then hand edited removing the explicit encoding
672# definitions and adding some more aliases. The file is usually
673# available as /usr/lib/X11/locale/locale.alias.
674#
675
676#
677# The local_encoding_alias table maps lowercase encoding alias names
678# to C locale encoding names (case-sensitive). Note that normalize()
679# first looks up the encoding in the encodings.aliases dictionary and
680# then applies this mapping to find the correct C lib name for the
681# encoding.
682#
683locale_encoding_alias = {
684
685    # Mappings for non-standard encoding names used in locale names
686    '437':                          'C',
687    'c':                            'C',
688    'en':                           'ISO8859-1',
689    'jis':                          'JIS7',
690    'jis7':                         'JIS7',
691    'ajec':                         'eucJP',
692    'koi8c':                        'KOI8-C',
693    'microsoftcp1251':              'CP1251',
694    'microsoftcp1255':              'CP1255',
695    'microsoftcp1256':              'CP1256',
696    '88591':                        'ISO8859-1',
697    '88592':                        'ISO8859-2',
698    '88595':                        'ISO8859-5',
699    '885915':                       'ISO8859-15',
700
701    # Mappings from Python codec names to C lib encoding names
702    'ascii':                        'ISO8859-1',
703    'latin_1':                      'ISO8859-1',
704    'iso8859_1':                    'ISO8859-1',
705    'iso8859_10':                   'ISO8859-10',
706    'iso8859_11':                   'ISO8859-11',
707    'iso8859_13':                   'ISO8859-13',
708    'iso8859_14':                   'ISO8859-14',
709    'iso8859_15':                   'ISO8859-15',
710    'iso8859_16':                   'ISO8859-16',
711    'iso8859_2':                    'ISO8859-2',
712    'iso8859_3':                    'ISO8859-3',
713    'iso8859_4':                    'ISO8859-4',
714    'iso8859_5':                    'ISO8859-5',
715    'iso8859_6':                    'ISO8859-6',
716    'iso8859_7':                    'ISO8859-7',
717    'iso8859_8':                    'ISO8859-8',
718    'iso8859_9':                    'ISO8859-9',
719    'iso2022_jp':                   'JIS7',
720    'shift_jis':                    'SJIS',
721    'tactis':                       'TACTIS',
722    'euc_jp':                       'eucJP',
723    'euc_kr':                       'eucKR',
724    'utf_8':                        'UTF-8',
725    'koi8_r':                       'KOI8-R',
726    'koi8_t':                       'KOI8-T',
727    'koi8_u':                       'KOI8-U',
728    'kz1048':                       'RK1048',
729    'cp1251':                       'CP1251',
730    'cp1255':                       'CP1255',
731    'cp1256':                       'CP1256',
732
733    # XXX This list is still incomplete. If you know more
734    # mappings, please file a bug report. Thanks.
735}
736
737for k, v in sorted(locale_encoding_alias.items()):
738    k = k.replace('_', '')
739    locale_encoding_alias.setdefault(k, v)
740del k, v
741
742#
743# The locale_alias table maps lowercase alias names to C locale names
744# (case-sensitive). Encodings are always separated from the locale
745# name using a dot ('.'); they should only be given in case the
746# language name is needed to interpret the given encoding alias
747# correctly (CJK codes often have this need).
748#
749# Note that the normalize() function which uses this tables
750# removes '_' and '-' characters from the encoding part of the
751# locale name before doing the lookup. This saves a lot of
752# space in the table.
753#
754# MAL 2004-12-10:
755# Updated alias mapping to most recent locale.alias file
756# from X.org distribution using makelocalealias.py.
757#
758# These are the differences compared to the old mapping (Python 2.4
759# and older):
760#
761#    updated 'bg' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251'
762#    updated 'bg_bg' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251'
763#    updated 'bulgarian' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251'
764#    updated 'cz' -> 'cz_CZ.ISO8859-2' to 'cs_CZ.ISO8859-2'
765#    updated 'cz_cz' -> 'cz_CZ.ISO8859-2' to 'cs_CZ.ISO8859-2'
766#    updated 'czech' -> 'cs_CS.ISO8859-2' to 'cs_CZ.ISO8859-2'
767#    updated 'dutch' -> 'nl_BE.ISO8859-1' to 'nl_NL.ISO8859-1'
768#    updated 'et' -> 'et_EE.ISO8859-4' to 'et_EE.ISO8859-15'
769#    updated 'et_ee' -> 'et_EE.ISO8859-4' to 'et_EE.ISO8859-15'
770#    updated 'fi' -> 'fi_FI.ISO8859-1' to 'fi_FI.ISO8859-15'
771#    updated 'fi_fi' -> 'fi_FI.ISO8859-1' to 'fi_FI.ISO8859-15'
772#    updated 'iw' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8'
773#    updated 'iw_il' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8'
774#    updated 'japanese' -> 'ja_JP.SJIS' to 'ja_JP.eucJP'
775#    updated 'lt' -> 'lt_LT.ISO8859-4' to 'lt_LT.ISO8859-13'
776#    updated 'lv' -> 'lv_LV.ISO8859-4' to 'lv_LV.ISO8859-13'
777#    updated 'sl' -> 'sl_CS.ISO8859-2' to 'sl_SI.ISO8859-2'
778#    updated 'slovene' -> 'sl_CS.ISO8859-2' to 'sl_SI.ISO8859-2'
779#    updated 'th_th' -> 'th_TH.TACTIS' to 'th_TH.ISO8859-11'
780#    updated 'zh_cn' -> 'zh_CN.eucCN' to 'zh_CN.gb2312'
781#    updated 'zh_cn.big5' -> 'zh_TW.eucTW' to 'zh_TW.big5'
782#    updated 'zh_tw' -> 'zh_TW.eucTW' to 'zh_TW.big5'
783#
784# MAL 2008-05-30:
785# Updated alias mapping to most recent locale.alias file
786# from X.org distribution using makelocalealias.py.
787#
788# These are the differences compared to the old mapping (Python 2.5
789# and older):
790#
791#    updated 'cs_cs.iso88592' -> 'cs_CZ.ISO8859-2' to 'cs_CS.ISO8859-2'
792#    updated 'serbocroatian' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2'
793#    updated 'sh' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2'
794#    updated 'sh_hr.iso88592' -> 'sh_HR.ISO8859-2' to 'hr_HR.ISO8859-2'
795#    updated 'sh_sp' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2'
796#    updated 'sh_yu' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2'
797#    updated 'sp' -> 'sp_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
798#    updated 'sp_yu' -> 'sp_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
799#    updated 'sr' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
800#    updated 'sr@cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
801#    updated 'sr_sp' -> 'sr_SP.ISO8859-2' to 'sr_CS.ISO8859-2'
802#    updated 'sr_yu' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
803#    updated 'sr_yu.cp1251@cyrillic' -> 'sr_YU.CP1251' to 'sr_CS.CP1251'
804#    updated 'sr_yu.iso88592' -> 'sr_YU.ISO8859-2' to 'sr_CS.ISO8859-2'
805#    updated 'sr_yu.iso88595' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
806#    updated 'sr_yu.iso88595@cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
807#    updated 'sr_yu.microsoftcp1251@cyrillic' -> 'sr_YU.CP1251' to 'sr_CS.CP1251'
808#    updated 'sr_yu.utf8@cyrillic' -> 'sr_YU.UTF-8' to 'sr_CS.UTF-8'
809#    updated 'sr_yu@cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
810#
811# AP 2010-04-12:
812# Updated alias mapping to most recent locale.alias file
813# from X.org distribution using makelocalealias.py.
814#
815# These are the differences compared to the old mapping (Python 2.6.5
816# and older):
817#
818#    updated 'ru' -> 'ru_RU.ISO8859-5' to 'ru_RU.UTF-8'
819#    updated 'ru_ru' -> 'ru_RU.ISO8859-5' to 'ru_RU.UTF-8'
820#    updated 'serbocroatian' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin'
821#    updated 'sh' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin'
822#    updated 'sh_yu' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin'
823#    updated 'sr' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8'
824#    updated 'sr@cyrillic' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8'
825#    updated 'sr@latn' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin'
826#    updated 'sr_cs.utf8@latn' -> 'sr_CS.UTF-8' to 'sr_RS.UTF-8@latin'
827#    updated 'sr_cs@latn' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin'
828#    updated 'sr_yu' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8@latin'
829#    updated 'sr_yu.utf8@cyrillic' -> 'sr_CS.UTF-8' to 'sr_RS.UTF-8'
830#    updated 'sr_yu@cyrillic' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8'
831#
832# SS 2013-12-20:
833# Updated alias mapping to most recent locale.alias file
834# from X.org distribution using makelocalealias.py.
835#
836# These are the differences compared to the old mapping (Python 3.3.3
837# and older):
838#
839#    updated 'a3' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C'
840#    updated 'a3_az' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C'
841#    updated 'a3_az.koi8c' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C'
842#    updated 'cs_cs.iso88592' -> 'cs_CS.ISO8859-2' to 'cs_CZ.ISO8859-2'
843#    updated 'hebrew' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8'
844#    updated 'hebrew.iso88598' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8'
845#    updated 'sd' -> 'sd_IN@devanagari.UTF-8' to 'sd_IN.UTF-8'
846#    updated 'sr@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin'
847#    updated 'sr_cs' -> 'sr_RS.UTF-8' to 'sr_CS.UTF-8'
848#    updated 'sr_cs.utf8@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin'
849#    updated 'sr_cs@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin'
850#
851# SS 2014-10-01:
852# Updated alias mapping with glibc 2.19 supported locales.
853#
854# SS 2018-05-05:
855# Updated alias mapping with glibc 2.27 supported locales.
856#
857# These are the differences compared to the old mapping (Python 3.6.5
858# and older):
859#
860#    updated 'ca_es@valencia' -> 'ca_ES.ISO8859-15@valencia' to 'ca_ES.UTF-8@valencia'
861#    updated 'kk_kz' -> 'kk_KZ.RK1048' to 'kk_KZ.ptcp154'
862#    updated 'russian' -> 'ru_RU.ISO8859-5' to 'ru_RU.KOI8-R'
863
864locale_alias = {
865    'a3':                                   'az_AZ.KOI8-C',
866    'a3_az':                                'az_AZ.KOI8-C',
867    'a3_az.koic':                           'az_AZ.KOI8-C',
868    'aa_dj':                                'aa_DJ.ISO8859-1',
869    'aa_er':                                'aa_ER.UTF-8',
870    'aa_et':                                'aa_ET.UTF-8',
871    'af':                                   'af_ZA.ISO8859-1',
872    'af_za':                                'af_ZA.ISO8859-1',
873    'agr_pe':                               'agr_PE.UTF-8',
874    'ak_gh':                                'ak_GH.UTF-8',
875    'am':                                   'am_ET.UTF-8',
876    'am_et':                                'am_ET.UTF-8',
877    'american':                             'en_US.ISO8859-1',
878    'an_es':                                'an_ES.ISO8859-15',
879    'anp_in':                               'anp_IN.UTF-8',
880    'ar':                                   'ar_AA.ISO8859-6',
881    'ar_aa':                                'ar_AA.ISO8859-6',
882    'ar_ae':                                'ar_AE.ISO8859-6',
883    'ar_bh':                                'ar_BH.ISO8859-6',
884    'ar_dz':                                'ar_DZ.ISO8859-6',
885    'ar_eg':                                'ar_EG.ISO8859-6',
886    'ar_in':                                'ar_IN.UTF-8',
887    'ar_iq':                                'ar_IQ.ISO8859-6',
888    'ar_jo':                                'ar_JO.ISO8859-6',
889    'ar_kw':                                'ar_KW.ISO8859-6',
890    'ar_lb':                                'ar_LB.ISO8859-6',
891    'ar_ly':                                'ar_LY.ISO8859-6',
892    'ar_ma':                                'ar_MA.ISO8859-6',
893    'ar_om':                                'ar_OM.ISO8859-6',
894    'ar_qa':                                'ar_QA.ISO8859-6',
895    'ar_sa':                                'ar_SA.ISO8859-6',
896    'ar_sd':                                'ar_SD.ISO8859-6',
897    'ar_ss':                                'ar_SS.UTF-8',
898    'ar_sy':                                'ar_SY.ISO8859-6',
899    'ar_tn':                                'ar_TN.ISO8859-6',
900    'ar_ye':                                'ar_YE.ISO8859-6',
901    'arabic':                               'ar_AA.ISO8859-6',
902    'as':                                   'as_IN.UTF-8',
903    'as_in':                                'as_IN.UTF-8',
904    'ast_es':                               'ast_ES.ISO8859-15',
905    'ayc_pe':                               'ayc_PE.UTF-8',
906    'az':                                   'az_AZ.ISO8859-9E',
907    'az_az':                                'az_AZ.ISO8859-9E',
908    'az_az.iso88599e':                      'az_AZ.ISO8859-9E',
909    'az_ir':                                'az_IR.UTF-8',
910    'be':                                   'be_BY.CP1251',
911    'be@latin':                             'be_BY.UTF-8@latin',
912    'be_bg.utf8':                           'bg_BG.UTF-8',
913    'be_by':                                'be_BY.CP1251',
914    'be_by@latin':                          'be_BY.UTF-8@latin',
915    'bem_zm':                               'bem_ZM.UTF-8',
916    'ber_dz':                               'ber_DZ.UTF-8',
917    'ber_ma':                               'ber_MA.UTF-8',
918    'bg':                                   'bg_BG.CP1251',
919    'bg_bg':                                'bg_BG.CP1251',
920    'bhb_in.utf8':                          'bhb_IN.UTF-8',
921    'bho_in':                               'bho_IN.UTF-8',
922    'bho_np':                               'bho_NP.UTF-8',
923    'bi_vu':                                'bi_VU.UTF-8',
924    'bn_bd':                                'bn_BD.UTF-8',
925    'bn_in':                                'bn_IN.UTF-8',
926    'bo_cn':                                'bo_CN.UTF-8',
927    'bo_in':                                'bo_IN.UTF-8',
928    'bokmal':                               'nb_NO.ISO8859-1',
929    'bokm\xe5l':                            'nb_NO.ISO8859-1',
930    'br':                                   'br_FR.ISO8859-1',
931    'br_fr':                                'br_FR.ISO8859-1',
932    'brx_in':                               'brx_IN.UTF-8',
933    'bs':                                   'bs_BA.ISO8859-2',
934    'bs_ba':                                'bs_BA.ISO8859-2',
935    'bulgarian':                            'bg_BG.CP1251',
936    'byn_er':                               'byn_ER.UTF-8',
937    'c':                                    'C',
938    'c-french':                             'fr_CA.ISO8859-1',
939    'c.ascii':                              'C',
940    'c.en':                                 'C',
941    'c.iso88591':                           'en_US.ISO8859-1',
942    'c.utf8':                               'C.UTF-8',
943    'c_c':                                  'C',
944    'c_c.c':                                'C',
945    'ca':                                   'ca_ES.ISO8859-1',
946    'ca_ad':                                'ca_AD.ISO8859-1',
947    'ca_es':                                'ca_ES.ISO8859-1',
948    'ca_es@valencia':                       'ca_ES.UTF-8@valencia',
949    'ca_fr':                                'ca_FR.ISO8859-1',
950    'ca_it':                                'ca_IT.ISO8859-1',
951    'catalan':                              'ca_ES.ISO8859-1',
952    'ce_ru':                                'ce_RU.UTF-8',
953    'cextend':                              'en_US.ISO8859-1',
954    'chinese-s':                            'zh_CN.eucCN',
955    'chinese-t':                            'zh_TW.eucTW',
956    'chr_us':                               'chr_US.UTF-8',
957    'ckb_iq':                               'ckb_IQ.UTF-8',
958    'cmn_tw':                               'cmn_TW.UTF-8',
959    'crh_ua':                               'crh_UA.UTF-8',
960    'croatian':                             'hr_HR.ISO8859-2',
961    'cs':                                   'cs_CZ.ISO8859-2',
962    'cs_cs':                                'cs_CZ.ISO8859-2',
963    'cs_cz':                                'cs_CZ.ISO8859-2',
964    'csb_pl':                               'csb_PL.UTF-8',
965    'cv_ru':                                'cv_RU.UTF-8',
966    'cy':                                   'cy_GB.ISO8859-1',
967    'cy_gb':                                'cy_GB.ISO8859-1',
968    'cz':                                   'cs_CZ.ISO8859-2',
969    'cz_cz':                                'cs_CZ.ISO8859-2',
970    'czech':                                'cs_CZ.ISO8859-2',
971    'da':                                   'da_DK.ISO8859-1',
972    'da_dk':                                'da_DK.ISO8859-1',
973    'danish':                               'da_DK.ISO8859-1',
974    'dansk':                                'da_DK.ISO8859-1',
975    'de':                                   'de_DE.ISO8859-1',
976    'de_at':                                'de_AT.ISO8859-1',
977    'de_be':                                'de_BE.ISO8859-1',
978    'de_ch':                                'de_CH.ISO8859-1',
979    'de_de':                                'de_DE.ISO8859-1',
980    'de_it':                                'de_IT.ISO8859-1',
981    'de_li.utf8':                           'de_LI.UTF-8',
982    'de_lu':                                'de_LU.ISO8859-1',
983    'deutsch':                              'de_DE.ISO8859-1',
984    'doi_in':                               'doi_IN.UTF-8',
985    'dutch':                                'nl_NL.ISO8859-1',
986    'dutch.iso88591':                       'nl_BE.ISO8859-1',
987    'dv_mv':                                'dv_MV.UTF-8',
988    'dz_bt':                                'dz_BT.UTF-8',
989    'ee':                                   'ee_EE.ISO8859-4',
990    'ee_ee':                                'ee_EE.ISO8859-4',
991    'eesti':                                'et_EE.ISO8859-1',
992    'el':                                   'el_GR.ISO8859-7',
993    'el_cy':                                'el_CY.ISO8859-7',
994    'el_gr':                                'el_GR.ISO8859-7',
995    'el_gr@euro':                           'el_GR.ISO8859-15',
996    'en':                                   'en_US.ISO8859-1',
997    'en_ag':                                'en_AG.UTF-8',
998    'en_au':                                'en_AU.ISO8859-1',
999    'en_be':                                'en_BE.ISO8859-1',
1000    'en_bw':                                'en_BW.ISO8859-1',
1001    'en_ca':                                'en_CA.ISO8859-1',
1002    'en_dk':                                'en_DK.ISO8859-1',
1003    'en_dl.utf8':                           'en_DL.UTF-8',
1004    'en_gb':                                'en_GB.ISO8859-1',
1005    'en_hk':                                'en_HK.ISO8859-1',
1006    'en_ie':                                'en_IE.ISO8859-1',
1007    'en_il':                                'en_IL.UTF-8',
1008    'en_in':                                'en_IN.ISO8859-1',
1009    'en_ng':                                'en_NG.UTF-8',
1010    'en_nz':                                'en_NZ.ISO8859-1',
1011    'en_ph':                                'en_PH.ISO8859-1',
1012    'en_sc.utf8':                           'en_SC.UTF-8',
1013    'en_sg':                                'en_SG.ISO8859-1',
1014    'en_uk':                                'en_GB.ISO8859-1',
1015    'en_us':                                'en_US.ISO8859-1',
1016    'en_us@euro@euro':                      'en_US.ISO8859-15',
1017    'en_za':                                'en_ZA.ISO8859-1',
1018    'en_zm':                                'en_ZM.UTF-8',
1019    'en_zw':                                'en_ZW.ISO8859-1',
1020    'en_zw.utf8':                           'en_ZS.UTF-8',
1021    'eng_gb':                               'en_GB.ISO8859-1',
1022    'english':                              'en_EN.ISO8859-1',
1023    'english.iso88591':                     'en_US.ISO8859-1',
1024    'english_uk':                           'en_GB.ISO8859-1',
1025    'english_united-states':                'en_US.ISO8859-1',
1026    'english_united-states.437':            'C',
1027    'english_us':                           'en_US.ISO8859-1',
1028    'eo':                                   'eo_XX.ISO8859-3',
1029    'eo.utf8':                              'eo.UTF-8',
1030    'eo_eo':                                'eo_EO.ISO8859-3',
1031    'eo_us.utf8':                           'eo_US.UTF-8',
1032    'eo_xx':                                'eo_XX.ISO8859-3',
1033    'es':                                   'es_ES.ISO8859-1',
1034    'es_ar':                                'es_AR.ISO8859-1',
1035    'es_bo':                                'es_BO.ISO8859-1',
1036    'es_cl':                                'es_CL.ISO8859-1',
1037    'es_co':                                'es_CO.ISO8859-1',
1038    'es_cr':                                'es_CR.ISO8859-1',
1039    'es_cu':                                'es_CU.UTF-8',
1040    'es_do':                                'es_DO.ISO8859-1',
1041    'es_ec':                                'es_EC.ISO8859-1',
1042    'es_es':                                'es_ES.ISO8859-1',
1043    'es_gt':                                'es_GT.ISO8859-1',
1044    'es_hn':                                'es_HN.ISO8859-1',
1045    'es_mx':                                'es_MX.ISO8859-1',
1046    'es_ni':                                'es_NI.ISO8859-1',
1047    'es_pa':                                'es_PA.ISO8859-1',
1048    'es_pe':                                'es_PE.ISO8859-1',
1049    'es_pr':                                'es_PR.ISO8859-1',
1050    'es_py':                                'es_PY.ISO8859-1',
1051    'es_sv':                                'es_SV.ISO8859-1',
1052    'es_us':                                'es_US.ISO8859-1',
1053    'es_uy':                                'es_UY.ISO8859-1',
1054    'es_ve':                                'es_VE.ISO8859-1',
1055    'estonian':                             'et_EE.ISO8859-1',
1056    'et':                                   'et_EE.ISO8859-15',
1057    'et_ee':                                'et_EE.ISO8859-15',
1058    'eu':                                   'eu_ES.ISO8859-1',
1059    'eu_es':                                'eu_ES.ISO8859-1',
1060    'eu_fr':                                'eu_FR.ISO8859-1',
1061    'fa':                                   'fa_IR.UTF-8',
1062    'fa_ir':                                'fa_IR.UTF-8',
1063    'fa_ir.isiri3342':                      'fa_IR.ISIRI-3342',
1064    'ff_sn':                                'ff_SN.UTF-8',
1065    'fi':                                   'fi_FI.ISO8859-15',
1066    'fi_fi':                                'fi_FI.ISO8859-15',
1067    'fil_ph':                               'fil_PH.UTF-8',
1068    'finnish':                              'fi_FI.ISO8859-1',
1069    'fo':                                   'fo_FO.ISO8859-1',
1070    'fo_fo':                                'fo_FO.ISO8859-1',
1071    'fr':                                   'fr_FR.ISO8859-1',
1072    'fr_be':                                'fr_BE.ISO8859-1',
1073    'fr_ca':                                'fr_CA.ISO8859-1',
1074    'fr_ch':                                'fr_CH.ISO8859-1',
1075    'fr_fr':                                'fr_FR.ISO8859-1',
1076    'fr_lu':                                'fr_LU.ISO8859-1',
1077    'fran\xe7ais':                          'fr_FR.ISO8859-1',
1078    'fre_fr':                               'fr_FR.ISO8859-1',
1079    'french':                               'fr_FR.ISO8859-1',
1080    'french.iso88591':                      'fr_CH.ISO8859-1',
1081    'french_france':                        'fr_FR.ISO8859-1',
1082    'fur_it':                               'fur_IT.UTF-8',
1083    'fy_de':                                'fy_DE.UTF-8',
1084    'fy_nl':                                'fy_NL.UTF-8',
1085    'ga':                                   'ga_IE.ISO8859-1',
1086    'ga_ie':                                'ga_IE.ISO8859-1',
1087    'galego':                               'gl_ES.ISO8859-1',
1088    'galician':                             'gl_ES.ISO8859-1',
1089    'gd':                                   'gd_GB.ISO8859-1',
1090    'gd_gb':                                'gd_GB.ISO8859-1',
1091    'ger_de':                               'de_DE.ISO8859-1',
1092    'german':                               'de_DE.ISO8859-1',
1093    'german.iso88591':                      'de_CH.ISO8859-1',
1094    'german_germany':                       'de_DE.ISO8859-1',
1095    'gez_er':                               'gez_ER.UTF-8',
1096    'gez_et':                               'gez_ET.UTF-8',
1097    'gl':                                   'gl_ES.ISO8859-1',
1098    'gl_es':                                'gl_ES.ISO8859-1',
1099    'greek':                                'el_GR.ISO8859-7',
1100    'gu_in':                                'gu_IN.UTF-8',
1101    'gv':                                   'gv_GB.ISO8859-1',
1102    'gv_gb':                                'gv_GB.ISO8859-1',
1103    'ha_ng':                                'ha_NG.UTF-8',
1104    'hak_tw':                               'hak_TW.UTF-8',
1105    'he':                                   'he_IL.ISO8859-8',
1106    'he_il':                                'he_IL.ISO8859-8',
1107    'hebrew':                               'he_IL.ISO8859-8',
1108    'hi':                                   'hi_IN.ISCII-DEV',
1109    'hi_in':                                'hi_IN.ISCII-DEV',
1110    'hi_in.isciidev':                       'hi_IN.ISCII-DEV',
1111    'hif_fj':                               'hif_FJ.UTF-8',
1112    'hne':                                  'hne_IN.UTF-8',
1113    'hne_in':                               'hne_IN.UTF-8',
1114    'hr':                                   'hr_HR.ISO8859-2',
1115    'hr_hr':                                'hr_HR.ISO8859-2',
1116    'hrvatski':                             'hr_HR.ISO8859-2',
1117    'hsb_de':                               'hsb_DE.ISO8859-2',
1118    'ht_ht':                                'ht_HT.UTF-8',
1119    'hu':                                   'hu_HU.ISO8859-2',
1120    'hu_hu':                                'hu_HU.ISO8859-2',
1121    'hungarian':                            'hu_HU.ISO8859-2',
1122    'hy_am':                                'hy_AM.UTF-8',
1123    'hy_am.armscii8':                       'hy_AM.ARMSCII_8',
1124    'ia':                                   'ia.UTF-8',
1125    'ia_fr':                                'ia_FR.UTF-8',
1126    'icelandic':                            'is_IS.ISO8859-1',
1127    'id':                                   'id_ID.ISO8859-1',
1128    'id_id':                                'id_ID.ISO8859-1',
1129    'ig_ng':                                'ig_NG.UTF-8',
1130    'ik_ca':                                'ik_CA.UTF-8',
1131    'in':                                   'id_ID.ISO8859-1',
1132    'in_id':                                'id_ID.ISO8859-1',
1133    'is':                                   'is_IS.ISO8859-1',
1134    'is_is':                                'is_IS.ISO8859-1',
1135    'iso-8859-1':                           'en_US.ISO8859-1',
1136    'iso-8859-15':                          'en_US.ISO8859-15',
1137    'iso8859-1':                            'en_US.ISO8859-1',
1138    'iso8859-15':                           'en_US.ISO8859-15',
1139    'iso_8859_1':                           'en_US.ISO8859-1',
1140    'iso_8859_15':                          'en_US.ISO8859-15',
1141    'it':                                   'it_IT.ISO8859-1',
1142    'it_ch':                                'it_CH.ISO8859-1',
1143    'it_it':                                'it_IT.ISO8859-1',
1144    'italian':                              'it_IT.ISO8859-1',
1145    'iu':                                   'iu_CA.NUNACOM-8',
1146    'iu_ca':                                'iu_CA.NUNACOM-8',
1147    'iu_ca.nunacom8':                       'iu_CA.NUNACOM-8',
1148    'iw':                                   'he_IL.ISO8859-8',
1149    'iw_il':                                'he_IL.ISO8859-8',
1150    'iw_il.utf8':                           'iw_IL.UTF-8',
1151    'ja':                                   'ja_JP.eucJP',
1152    'ja_jp':                                'ja_JP.eucJP',
1153    'ja_jp.euc':                            'ja_JP.eucJP',
1154    'ja_jp.mscode':                         'ja_JP.SJIS',
1155    'ja_jp.pck':                            'ja_JP.SJIS',
1156    'japan':                                'ja_JP.eucJP',
1157    'japanese':                             'ja_JP.eucJP',
1158    'japanese-euc':                         'ja_JP.eucJP',
1159    'japanese.euc':                         'ja_JP.eucJP',
1160    'jp_jp':                                'ja_JP.eucJP',
1161    'ka':                                   'ka_GE.GEORGIAN-ACADEMY',
1162    'ka_ge':                                'ka_GE.GEORGIAN-ACADEMY',
1163    'ka_ge.georgianacademy':                'ka_GE.GEORGIAN-ACADEMY',
1164    'ka_ge.georgianps':                     'ka_GE.GEORGIAN-PS',
1165    'ka_ge.georgianrs':                     'ka_GE.GEORGIAN-ACADEMY',
1166    'kab_dz':                               'kab_DZ.UTF-8',
1167    'kk_kz':                                'kk_KZ.ptcp154',
1168    'kl':                                   'kl_GL.ISO8859-1',
1169    'kl_gl':                                'kl_GL.ISO8859-1',
1170    'km_kh':                                'km_KH.UTF-8',
1171    'kn':                                   'kn_IN.UTF-8',
1172    'kn_in':                                'kn_IN.UTF-8',
1173    'ko':                                   'ko_KR.eucKR',
1174    'ko_kr':                                'ko_KR.eucKR',
1175    'ko_kr.euc':                            'ko_KR.eucKR',
1176    'kok_in':                               'kok_IN.UTF-8',
1177    'korean':                               'ko_KR.eucKR',
1178    'korean.euc':                           'ko_KR.eucKR',
1179    'ks':                                   'ks_IN.UTF-8',
1180    'ks_in':                                'ks_IN.UTF-8',
1181    'ks_in@devanagari.utf8':                'ks_IN.UTF-8@devanagari',
1182    'ku_tr':                                'ku_TR.ISO8859-9',
1183    'kw':                                   'kw_GB.ISO8859-1',
1184    'kw_gb':                                'kw_GB.ISO8859-1',
1185    'ky':                                   'ky_KG.UTF-8',
1186    'ky_kg':                                'ky_KG.UTF-8',
1187    'lb_lu':                                'lb_LU.UTF-8',
1188    'lg_ug':                                'lg_UG.ISO8859-10',
1189    'li_be':                                'li_BE.UTF-8',
1190    'li_nl':                                'li_NL.UTF-8',
1191    'lij_it':                               'lij_IT.UTF-8',
1192    'lithuanian':                           'lt_LT.ISO8859-13',
1193    'ln_cd':                                'ln_CD.UTF-8',
1194    'lo':                                   'lo_LA.MULELAO-1',
1195    'lo_la':                                'lo_LA.MULELAO-1',
1196    'lo_la.cp1133':                         'lo_LA.IBM-CP1133',
1197    'lo_la.ibmcp1133':                      'lo_LA.IBM-CP1133',
1198    'lo_la.mulelao1':                       'lo_LA.MULELAO-1',
1199    'lt':                                   'lt_LT.ISO8859-13',
1200    'lt_lt':                                'lt_LT.ISO8859-13',
1201    'lv':                                   'lv_LV.ISO8859-13',
1202    'lv_lv':                                'lv_LV.ISO8859-13',
1203    'lzh_tw':                               'lzh_TW.UTF-8',
1204    'mag_in':                               'mag_IN.UTF-8',
1205    'mai':                                  'mai_IN.UTF-8',
1206    'mai_in':                               'mai_IN.UTF-8',
1207    'mai_np':                               'mai_NP.UTF-8',
1208    'mfe_mu':                               'mfe_MU.UTF-8',
1209    'mg_mg':                                'mg_MG.ISO8859-15',
1210    'mhr_ru':                               'mhr_RU.UTF-8',
1211    'mi':                                   'mi_NZ.ISO8859-1',
1212    'mi_nz':                                'mi_NZ.ISO8859-1',
1213    'miq_ni':                               'miq_NI.UTF-8',
1214    'mjw_in':                               'mjw_IN.UTF-8',
1215    'mk':                                   'mk_MK.ISO8859-5',
1216    'mk_mk':                                'mk_MK.ISO8859-5',
1217    'ml':                                   'ml_IN.UTF-8',
1218    'ml_in':                                'ml_IN.UTF-8',
1219    'mn_mn':                                'mn_MN.UTF-8',
1220    'mni_in':                               'mni_IN.UTF-8',
1221    'mr':                                   'mr_IN.UTF-8',
1222    'mr_in':                                'mr_IN.UTF-8',
1223    'ms':                                   'ms_MY.ISO8859-1',
1224    'ms_my':                                'ms_MY.ISO8859-1',
1225    'mt':                                   'mt_MT.ISO8859-3',
1226    'mt_mt':                                'mt_MT.ISO8859-3',
1227    'my_mm':                                'my_MM.UTF-8',
1228    'nan_tw':                               'nan_TW.UTF-8',
1229    'nb':                                   'nb_NO.ISO8859-1',
1230    'nb_no':                                'nb_NO.ISO8859-1',
1231    'nds_de':                               'nds_DE.UTF-8',
1232    'nds_nl':                               'nds_NL.UTF-8',
1233    'ne_np':                                'ne_NP.UTF-8',
1234    'nhn_mx':                               'nhn_MX.UTF-8',
1235    'niu_nu':                               'niu_NU.UTF-8',
1236    'niu_nz':                               'niu_NZ.UTF-8',
1237    'nl':                                   'nl_NL.ISO8859-1',
1238    'nl_aw':                                'nl_AW.UTF-8',
1239    'nl_be':                                'nl_BE.ISO8859-1',
1240    'nl_nl':                                'nl_NL.ISO8859-1',
1241    'nn':                                   'nn_NO.ISO8859-1',
1242    'nn_no':                                'nn_NO.ISO8859-1',
1243    'no':                                   'no_NO.ISO8859-1',
1244    'no@nynorsk':                           'ny_NO.ISO8859-1',
1245    'no_no':                                'no_NO.ISO8859-1',
1246    'no_no.iso88591@bokmal':                'no_NO.ISO8859-1',
1247    'no_no.iso88591@nynorsk':               'no_NO.ISO8859-1',
1248    'norwegian':                            'no_NO.ISO8859-1',
1249    'nr':                                   'nr_ZA.ISO8859-1',
1250    'nr_za':                                'nr_ZA.ISO8859-1',
1251    'nso':                                  'nso_ZA.ISO8859-15',
1252    'nso_za':                               'nso_ZA.ISO8859-15',
1253    'ny':                                   'ny_NO.ISO8859-1',
1254    'ny_no':                                'ny_NO.ISO8859-1',
1255    'nynorsk':                              'nn_NO.ISO8859-1',
1256    'oc':                                   'oc_FR.ISO8859-1',
1257    'oc_fr':                                'oc_FR.ISO8859-1',
1258    'om_et':                                'om_ET.UTF-8',
1259    'om_ke':                                'om_KE.ISO8859-1',
1260    'or':                                   'or_IN.UTF-8',
1261    'or_in':                                'or_IN.UTF-8',
1262    'os_ru':                                'os_RU.UTF-8',
1263    'pa':                                   'pa_IN.UTF-8',
1264    'pa_in':                                'pa_IN.UTF-8',
1265    'pa_pk':                                'pa_PK.UTF-8',
1266    'pap_an':                               'pap_AN.UTF-8',
1267    'pap_aw':                               'pap_AW.UTF-8',
1268    'pap_cw':                               'pap_CW.UTF-8',
1269    'pd':                                   'pd_US.ISO8859-1',
1270    'pd_de':                                'pd_DE.ISO8859-1',
1271    'pd_us':                                'pd_US.ISO8859-1',
1272    'ph':                                   'ph_PH.ISO8859-1',
1273    'ph_ph':                                'ph_PH.ISO8859-1',
1274    'pl':                                   'pl_PL.ISO8859-2',
1275    'pl_pl':                                'pl_PL.ISO8859-2',
1276    'polish':                               'pl_PL.ISO8859-2',
1277    'portuguese':                           'pt_PT.ISO8859-1',
1278    'portuguese_brazil':                    'pt_BR.ISO8859-1',
1279    'posix':                                'C',
1280    'posix-utf2':                           'C',
1281    'pp':                                   'pp_AN.ISO8859-1',
1282    'pp_an':                                'pp_AN.ISO8859-1',
1283    'ps_af':                                'ps_AF.UTF-8',
1284    'pt':                                   'pt_PT.ISO8859-1',
1285    'pt_br':                                'pt_BR.ISO8859-1',
1286    'pt_pt':                                'pt_PT.ISO8859-1',
1287    'quz_pe':                               'quz_PE.UTF-8',
1288    'raj_in':                               'raj_IN.UTF-8',
1289    'ro':                                   'ro_RO.ISO8859-2',
1290    'ro_ro':                                'ro_RO.ISO8859-2',
1291    'romanian':                             'ro_RO.ISO8859-2',
1292    'ru':                                   'ru_RU.UTF-8',
1293    'ru_ru':                                'ru_RU.UTF-8',
1294    'ru_ua':                                'ru_UA.KOI8-U',
1295    'rumanian':                             'ro_RO.ISO8859-2',
1296    'russian':                              'ru_RU.KOI8-R',
1297    'rw':                                   'rw_RW.ISO8859-1',
1298    'rw_rw':                                'rw_RW.ISO8859-1',
1299    'sa_in':                                'sa_IN.UTF-8',
1300    'sat_in':                               'sat_IN.UTF-8',
1301    'sc_it':                                'sc_IT.UTF-8',
1302    'sd':                                   'sd_IN.UTF-8',
1303    'sd_in':                                'sd_IN.UTF-8',
1304    'sd_in@devanagari.utf8':                'sd_IN.UTF-8@devanagari',
1305    'sd_pk':                                'sd_PK.UTF-8',
1306    'se_no':                                'se_NO.UTF-8',
1307    'serbocroatian':                        'sr_RS.UTF-8@latin',
1308    'sgs_lt':                               'sgs_LT.UTF-8',
1309    'sh':                                   'sr_RS.UTF-8@latin',
1310    'sh_ba.iso88592@bosnia':                'sr_CS.ISO8859-2',
1311    'sh_hr':                                'sh_HR.ISO8859-2',
1312    'sh_hr.iso88592':                       'hr_HR.ISO8859-2',
1313    'sh_sp':                                'sr_CS.ISO8859-2',
1314    'sh_yu':                                'sr_RS.UTF-8@latin',
1315    'shn_mm':                               'shn_MM.UTF-8',
1316    'shs_ca':                               'shs_CA.UTF-8',
1317    'si':                                   'si_LK.UTF-8',
1318    'si_lk':                                'si_LK.UTF-8',
1319    'sid_et':                               'sid_ET.UTF-8',
1320    'sinhala':                              'si_LK.UTF-8',
1321    'sk':                                   'sk_SK.ISO8859-2',
1322    'sk_sk':                                'sk_SK.ISO8859-2',
1323    'sl':                                   'sl_SI.ISO8859-2',
1324    'sl_cs':                                'sl_CS.ISO8859-2',
1325    'sl_si':                                'sl_SI.ISO8859-2',
1326    'slovak':                               'sk_SK.ISO8859-2',
1327    'slovene':                              'sl_SI.ISO8859-2',
1328    'slovenian':                            'sl_SI.ISO8859-2',
1329    'sm_ws':                                'sm_WS.UTF-8',
1330    'so_dj':                                'so_DJ.ISO8859-1',
1331    'so_et':                                'so_ET.UTF-8',
1332    'so_ke':                                'so_KE.ISO8859-1',
1333    'so_so':                                'so_SO.ISO8859-1',
1334    'sp':                                   'sr_CS.ISO8859-5',
1335    'sp_yu':                                'sr_CS.ISO8859-5',
1336    'spanish':                              'es_ES.ISO8859-1',
1337    'spanish_spain':                        'es_ES.ISO8859-1',
1338    'sq':                                   'sq_AL.ISO8859-2',
1339    'sq_al':                                'sq_AL.ISO8859-2',
1340    'sq_mk':                                'sq_MK.UTF-8',
1341    'sr':                                   'sr_RS.UTF-8',
1342    'sr@cyrillic':                          'sr_RS.UTF-8',
1343    'sr@latn':                              'sr_CS.UTF-8@latin',
1344    'sr_cs':                                'sr_CS.UTF-8',
1345    'sr_cs.iso88592@latn':                  'sr_CS.ISO8859-2',
1346    'sr_cs@latn':                           'sr_CS.UTF-8@latin',
1347    'sr_me':                                'sr_ME.UTF-8',
1348    'sr_rs':                                'sr_RS.UTF-8',
1349    'sr_rs@latn':                           'sr_RS.UTF-8@latin',
1350    'sr_sp':                                'sr_CS.ISO8859-2',
1351    'sr_yu':                                'sr_RS.UTF-8@latin',
1352    'sr_yu.cp1251@cyrillic':                'sr_CS.CP1251',
1353    'sr_yu.iso88592':                       'sr_CS.ISO8859-2',
1354    'sr_yu.iso88595':                       'sr_CS.ISO8859-5',
1355    'sr_yu.iso88595@cyrillic':              'sr_CS.ISO8859-5',
1356    'sr_yu.microsoftcp1251@cyrillic':       'sr_CS.CP1251',
1357    'sr_yu.utf8':                           'sr_RS.UTF-8',
1358    'sr_yu.utf8@cyrillic':                  'sr_RS.UTF-8',
1359    'sr_yu@cyrillic':                       'sr_RS.UTF-8',
1360    'ss':                                   'ss_ZA.ISO8859-1',
1361    'ss_za':                                'ss_ZA.ISO8859-1',
1362    'st':                                   'st_ZA.ISO8859-1',
1363    'st_za':                                'st_ZA.ISO8859-1',
1364    'sv':                                   'sv_SE.ISO8859-1',
1365    'sv_fi':                                'sv_FI.ISO8859-1',
1366    'sv_se':                                'sv_SE.ISO8859-1',
1367    'sw_ke':                                'sw_KE.UTF-8',
1368    'sw_tz':                                'sw_TZ.UTF-8',
1369    'swedish':                              'sv_SE.ISO8859-1',
1370    'szl_pl':                               'szl_PL.UTF-8',
1371    'ta':                                   'ta_IN.TSCII-0',
1372    'ta_in':                                'ta_IN.TSCII-0',
1373    'ta_in.tscii':                          'ta_IN.TSCII-0',
1374    'ta_in.tscii0':                         'ta_IN.TSCII-0',
1375    'ta_lk':                                'ta_LK.UTF-8',
1376    'tcy_in.utf8':                          'tcy_IN.UTF-8',
1377    'te':                                   'te_IN.UTF-8',
1378    'te_in':                                'te_IN.UTF-8',
1379    'tg':                                   'tg_TJ.KOI8-C',
1380    'tg_tj':                                'tg_TJ.KOI8-C',
1381    'th':                                   'th_TH.ISO8859-11',
1382    'th_th':                                'th_TH.ISO8859-11',
1383    'th_th.tactis':                         'th_TH.TIS620',
1384    'th_th.tis620':                         'th_TH.TIS620',
1385    'thai':                                 'th_TH.ISO8859-11',
1386    'the_np':                               'the_NP.UTF-8',
1387    'ti_er':                                'ti_ER.UTF-8',
1388    'ti_et':                                'ti_ET.UTF-8',
1389    'tig_er':                               'tig_ER.UTF-8',
1390    'tk_tm':                                'tk_TM.UTF-8',
1391    'tl':                                   'tl_PH.ISO8859-1',
1392    'tl_ph':                                'tl_PH.ISO8859-1',
1393    'tn':                                   'tn_ZA.ISO8859-15',
1394    'tn_za':                                'tn_ZA.ISO8859-15',
1395    'to_to':                                'to_TO.UTF-8',
1396    'tpi_pg':                               'tpi_PG.UTF-8',
1397    'tr':                                   'tr_TR.ISO8859-9',
1398    'tr_cy':                                'tr_CY.ISO8859-9',
1399    'tr_tr':                                'tr_TR.ISO8859-9',
1400    'ts':                                   'ts_ZA.ISO8859-1',
1401    'ts_za':                                'ts_ZA.ISO8859-1',
1402    'tt':                                   'tt_RU.TATAR-CYR',
1403    'tt_ru':                                'tt_RU.TATAR-CYR',
1404    'tt_ru.tatarcyr':                       'tt_RU.TATAR-CYR',
1405    'tt_ru@iqtelif':                        'tt_RU.UTF-8@iqtelif',
1406    'turkish':                              'tr_TR.ISO8859-9',
1407    'ug_cn':                                'ug_CN.UTF-8',
1408    'uk':                                   'uk_UA.KOI8-U',
1409    'uk_ua':                                'uk_UA.KOI8-U',
1410    'univ':                                 'en_US.utf',
1411    'universal':                            'en_US.utf',
1412    'universal.utf8@ucs4':                  'en_US.UTF-8',
1413    'unm_us':                               'unm_US.UTF-8',
1414    'ur':                                   'ur_PK.CP1256',
1415    'ur_in':                                'ur_IN.UTF-8',
1416    'ur_pk':                                'ur_PK.CP1256',
1417    'uz':                                   'uz_UZ.UTF-8',
1418    'uz_uz':                                'uz_UZ.UTF-8',
1419    'uz_uz@cyrillic':                       'uz_UZ.UTF-8',
1420    've':                                   've_ZA.UTF-8',
1421    've_za':                                've_ZA.UTF-8',
1422    'vi':                                   'vi_VN.TCVN',
1423    'vi_vn':                                'vi_VN.TCVN',
1424    'vi_vn.tcvn':                           'vi_VN.TCVN',
1425    'vi_vn.tcvn5712':                       'vi_VN.TCVN',
1426    'vi_vn.viscii':                         'vi_VN.VISCII',
1427    'vi_vn.viscii111':                      'vi_VN.VISCII',
1428    'wa':                                   'wa_BE.ISO8859-1',
1429    'wa_be':                                'wa_BE.ISO8859-1',
1430    'wae_ch':                               'wae_CH.UTF-8',
1431    'wal_et':                               'wal_ET.UTF-8',
1432    'wo_sn':                                'wo_SN.UTF-8',
1433    'xh':                                   'xh_ZA.ISO8859-1',
1434    'xh_za':                                'xh_ZA.ISO8859-1',
1435    'yi':                                   'yi_US.CP1255',
1436    'yi_us':                                'yi_US.CP1255',
1437    'yo_ng':                                'yo_NG.UTF-8',
1438    'yue_hk':                               'yue_HK.UTF-8',
1439    'yuw_pg':                               'yuw_PG.UTF-8',
1440    'zh':                                   'zh_CN.eucCN',
1441    'zh_cn':                                'zh_CN.gb2312',
1442    'zh_cn.big5':                           'zh_TW.big5',
1443    'zh_cn.euc':                            'zh_CN.eucCN',
1444    'zh_hk':                                'zh_HK.big5hkscs',
1445    'zh_hk.big5hk':                         'zh_HK.big5hkscs',
1446    'zh_sg':                                'zh_SG.GB2312',
1447    'zh_sg.gbk':                            'zh_SG.GBK',
1448    'zh_tw':                                'zh_TW.big5',
1449    'zh_tw.euc':                            'zh_TW.eucTW',
1450    'zh_tw.euctw':                          'zh_TW.eucTW',
1451    'zu':                                   'zu_ZA.ISO8859-1',
1452    'zu_za':                                'zu_ZA.ISO8859-1',
1453}
1454
1455#
1456# This maps Windows language identifiers to locale strings.
1457#
1458# This list has been updated from
1459# http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_238z.asp
1460# to include every locale up to Windows Vista.
1461#
1462# NOTE: this mapping is incomplete.  If your language is missing, please
1463# submit a bug report as detailed in the Python devguide at:
1464#    https://devguide.python.org/triage/issue-tracker/
1465# Make sure you include the missing language identifier and the suggested
1466# locale code.
1467#
1468
1469windows_locale = {
1470    0x0436: "af_ZA", # Afrikaans
1471    0x041c: "sq_AL", # Albanian
1472    0x0484: "gsw_FR",# Alsatian - France
1473    0x045e: "am_ET", # Amharic - Ethiopia
1474    0x0401: "ar_SA", # Arabic - Saudi Arabia
1475    0x0801: "ar_IQ", # Arabic - Iraq
1476    0x0c01: "ar_EG", # Arabic - Egypt
1477    0x1001: "ar_LY", # Arabic - Libya
1478    0x1401: "ar_DZ", # Arabic - Algeria
1479    0x1801: "ar_MA", # Arabic - Morocco
1480    0x1c01: "ar_TN", # Arabic - Tunisia
1481    0x2001: "ar_OM", # Arabic - Oman
1482    0x2401: "ar_YE", # Arabic - Yemen
1483    0x2801: "ar_SY", # Arabic - Syria
1484    0x2c01: "ar_JO", # Arabic - Jordan
1485    0x3001: "ar_LB", # Arabic - Lebanon
1486    0x3401: "ar_KW", # Arabic - Kuwait
1487    0x3801: "ar_AE", # Arabic - United Arab Emirates
1488    0x3c01: "ar_BH", # Arabic - Bahrain
1489    0x4001: "ar_QA", # Arabic - Qatar
1490    0x042b: "hy_AM", # Armenian
1491    0x044d: "as_IN", # Assamese - India
1492    0x042c: "az_AZ", # Azeri - Latin
1493    0x082c: "az_AZ", # Azeri - Cyrillic
1494    0x046d: "ba_RU", # Bashkir
1495    0x042d: "eu_ES", # Basque - Russia
1496    0x0423: "be_BY", # Belarusian
1497    0x0445: "bn_IN", # Begali
1498    0x201a: "bs_BA", # Bosnian - Cyrillic
1499    0x141a: "bs_BA", # Bosnian - Latin
1500    0x047e: "br_FR", # Breton - France
1501    0x0402: "bg_BG", # Bulgarian
1502#    0x0455: "my_MM", # Burmese - Not supported
1503    0x0403: "ca_ES", # Catalan
1504    0x0004: "zh_CHS",# Chinese - Simplified
1505    0x0404: "zh_TW", # Chinese - Taiwan
1506    0x0804: "zh_CN", # Chinese - PRC
1507    0x0c04: "zh_HK", # Chinese - Hong Kong S.A.R.
1508    0x1004: "zh_SG", # Chinese - Singapore
1509    0x1404: "zh_MO", # Chinese - Macao S.A.R.
1510    0x7c04: "zh_CHT",# Chinese - Traditional
1511    0x0483: "co_FR", # Corsican - France
1512    0x041a: "hr_HR", # Croatian
1513    0x101a: "hr_BA", # Croatian - Bosnia
1514    0x0405: "cs_CZ", # Czech
1515    0x0406: "da_DK", # Danish
1516    0x048c: "gbz_AF",# Dari - Afghanistan
1517    0x0465: "div_MV",# Divehi - Maldives
1518    0x0413: "nl_NL", # Dutch - The Netherlands
1519    0x0813: "nl_BE", # Dutch - Belgium
1520    0x0409: "en_US", # English - United States
1521    0x0809: "en_GB", # English - United Kingdom
1522    0x0c09: "en_AU", # English - Australia
1523    0x1009: "en_CA", # English - Canada
1524    0x1409: "en_NZ", # English - New Zealand
1525    0x1809: "en_IE", # English - Ireland
1526    0x1c09: "en_ZA", # English - South Africa
1527    0x2009: "en_JA", # English - Jamaica
1528    0x2409: "en_CB", # English - Caribbean
1529    0x2809: "en_BZ", # English - Belize
1530    0x2c09: "en_TT", # English - Trinidad
1531    0x3009: "en_ZW", # English - Zimbabwe
1532    0x3409: "en_PH", # English - Philippines
1533    0x4009: "en_IN", # English - India
1534    0x4409: "en_MY", # English - Malaysia
1535    0x4809: "en_IN", # English - Singapore
1536    0x0425: "et_EE", # Estonian
1537    0x0438: "fo_FO", # Faroese
1538    0x0464: "fil_PH",# Filipino
1539    0x040b: "fi_FI", # Finnish
1540    0x040c: "fr_FR", # French - France
1541    0x080c: "fr_BE", # French - Belgium
1542    0x0c0c: "fr_CA", # French - Canada
1543    0x100c: "fr_CH", # French - Switzerland
1544    0x140c: "fr_LU", # French - Luxembourg
1545    0x180c: "fr_MC", # French - Monaco
1546    0x0462: "fy_NL", # Frisian - Netherlands
1547    0x0456: "gl_ES", # Galician
1548    0x0437: "ka_GE", # Georgian
1549    0x0407: "de_DE", # German - Germany
1550    0x0807: "de_CH", # German - Switzerland
1551    0x0c07: "de_AT", # German - Austria
1552    0x1007: "de_LU", # German - Luxembourg
1553    0x1407: "de_LI", # German - Liechtenstein
1554    0x0408: "el_GR", # Greek
1555    0x046f: "kl_GL", # Greenlandic - Greenland
1556    0x0447: "gu_IN", # Gujarati
1557    0x0468: "ha_NG", # Hausa - Latin
1558    0x040d: "he_IL", # Hebrew
1559    0x0439: "hi_IN", # Hindi
1560    0x040e: "hu_HU", # Hungarian
1561    0x040f: "is_IS", # Icelandic
1562    0x0421: "id_ID", # Indonesian
1563    0x045d: "iu_CA", # Inuktitut - Syllabics
1564    0x085d: "iu_CA", # Inuktitut - Latin
1565    0x083c: "ga_IE", # Irish - Ireland
1566    0x0410: "it_IT", # Italian - Italy
1567    0x0810: "it_CH", # Italian - Switzerland
1568    0x0411: "ja_JP", # Japanese
1569    0x044b: "kn_IN", # Kannada - India
1570    0x043f: "kk_KZ", # Kazakh
1571    0x0453: "kh_KH", # Khmer - Cambodia
1572    0x0486: "qut_GT",# K'iche - Guatemala
1573    0x0487: "rw_RW", # Kinyarwanda - Rwanda
1574    0x0457: "kok_IN",# Konkani
1575    0x0412: "ko_KR", # Korean
1576    0x0440: "ky_KG", # Kyrgyz
1577    0x0454: "lo_LA", # Lao - Lao PDR
1578    0x0426: "lv_LV", # Latvian
1579    0x0427: "lt_LT", # Lithuanian
1580    0x082e: "dsb_DE",# Lower Sorbian - Germany
1581    0x046e: "lb_LU", # Luxembourgish
1582    0x042f: "mk_MK", # FYROM Macedonian
1583    0x043e: "ms_MY", # Malay - Malaysia
1584    0x083e: "ms_BN", # Malay - Brunei Darussalam
1585    0x044c: "ml_IN", # Malayalam - India
1586    0x043a: "mt_MT", # Maltese
1587    0x0481: "mi_NZ", # Maori
1588    0x047a: "arn_CL",# Mapudungun
1589    0x044e: "mr_IN", # Marathi
1590    0x047c: "moh_CA",# Mohawk - Canada
1591    0x0450: "mn_MN", # Mongolian - Cyrillic
1592    0x0850: "mn_CN", # Mongolian - PRC
1593    0x0461: "ne_NP", # Nepali
1594    0x0414: "nb_NO", # Norwegian - Bokmal
1595    0x0814: "nn_NO", # Norwegian - Nynorsk
1596    0x0482: "oc_FR", # Occitan - France
1597    0x0448: "or_IN", # Oriya - India
1598    0x0463: "ps_AF", # Pashto - Afghanistan
1599    0x0429: "fa_IR", # Persian
1600    0x0415: "pl_PL", # Polish
1601    0x0416: "pt_BR", # Portuguese - Brazil
1602    0x0816: "pt_PT", # Portuguese - Portugal
1603    0x0446: "pa_IN", # Punjabi
1604    0x046b: "quz_BO",# Quechua (Bolivia)
1605    0x086b: "quz_EC",# Quechua (Ecuador)
1606    0x0c6b: "quz_PE",# Quechua (Peru)
1607    0x0418: "ro_RO", # Romanian - Romania
1608    0x0417: "rm_CH", # Romansh
1609    0x0419: "ru_RU", # Russian
1610    0x243b: "smn_FI",# Sami Finland
1611    0x103b: "smj_NO",# Sami Norway
1612    0x143b: "smj_SE",# Sami Sweden
1613    0x043b: "se_NO", # Sami Northern Norway
1614    0x083b: "se_SE", # Sami Northern Sweden
1615    0x0c3b: "se_FI", # Sami Northern Finland
1616    0x203b: "sms_FI",# Sami Skolt
1617    0x183b: "sma_NO",# Sami Southern Norway
1618    0x1c3b: "sma_SE",# Sami Southern Sweden
1619    0x044f: "sa_IN", # Sanskrit
1620    0x0c1a: "sr_SP", # Serbian - Cyrillic
1621    0x1c1a: "sr_BA", # Serbian - Bosnia Cyrillic
1622    0x081a: "sr_SP", # Serbian - Latin
1623    0x181a: "sr_BA", # Serbian - Bosnia Latin
1624    0x045b: "si_LK", # Sinhala - Sri Lanka
1625    0x046c: "ns_ZA", # Northern Sotho
1626    0x0432: "tn_ZA", # Setswana - Southern Africa
1627    0x041b: "sk_SK", # Slovak
1628    0x0424: "sl_SI", # Slovenian
1629    0x040a: "es_ES", # Spanish - Spain
1630    0x080a: "es_MX", # Spanish - Mexico
1631    0x0c0a: "es_ES", # Spanish - Spain (Modern)
1632    0x100a: "es_GT", # Spanish - Guatemala
1633    0x140a: "es_CR", # Spanish - Costa Rica
1634    0x180a: "es_PA", # Spanish - Panama
1635    0x1c0a: "es_DO", # Spanish - Dominican Republic
1636    0x200a: "es_VE", # Spanish - Venezuela
1637    0x240a: "es_CO", # Spanish - Colombia
1638    0x280a: "es_PE", # Spanish - Peru
1639    0x2c0a: "es_AR", # Spanish - Argentina
1640    0x300a: "es_EC", # Spanish - Ecuador
1641    0x340a: "es_CL", # Spanish - Chile
1642    0x380a: "es_UR", # Spanish - Uruguay
1643    0x3c0a: "es_PY", # Spanish - Paraguay
1644    0x400a: "es_BO", # Spanish - Bolivia
1645    0x440a: "es_SV", # Spanish - El Salvador
1646    0x480a: "es_HN", # Spanish - Honduras
1647    0x4c0a: "es_NI", # Spanish - Nicaragua
1648    0x500a: "es_PR", # Spanish - Puerto Rico
1649    0x540a: "es_US", # Spanish - United States
1650#    0x0430: "", # Sutu - Not supported
1651    0x0441: "sw_KE", # Swahili
1652    0x041d: "sv_SE", # Swedish - Sweden
1653    0x081d: "sv_FI", # Swedish - Finland
1654    0x045a: "syr_SY",# Syriac
1655    0x0428: "tg_TJ", # Tajik - Cyrillic
1656    0x085f: "tmz_DZ",# Tamazight - Latin
1657    0x0449: "ta_IN", # Tamil
1658    0x0444: "tt_RU", # Tatar
1659    0x044a: "te_IN", # Telugu
1660    0x041e: "th_TH", # Thai
1661    0x0851: "bo_BT", # Tibetan - Bhutan
1662    0x0451: "bo_CN", # Tibetan - PRC
1663    0x041f: "tr_TR", # Turkish
1664    0x0442: "tk_TM", # Turkmen - Cyrillic
1665    0x0480: "ug_CN", # Uighur - Arabic
1666    0x0422: "uk_UA", # Ukrainian
1667    0x042e: "wen_DE",# Upper Sorbian - Germany
1668    0x0420: "ur_PK", # Urdu
1669    0x0820: "ur_IN", # Urdu - India
1670    0x0443: "uz_UZ", # Uzbek - Latin
1671    0x0843: "uz_UZ", # Uzbek - Cyrillic
1672    0x042a: "vi_VN", # Vietnamese
1673    0x0452: "cy_GB", # Welsh
1674    0x0488: "wo_SN", # Wolof - Senegal
1675    0x0434: "xh_ZA", # Xhosa - South Africa
1676    0x0485: "sah_RU",# Yakut - Cyrillic
1677    0x0478: "ii_CN", # Yi - PRC
1678    0x046a: "yo_NG", # Yoruba - Nigeria
1679    0x0435: "zu_ZA", # Zulu
1680}
1681
1682def _print_locale():
1683
1684    """ Test function.
1685    """
1686    categories = {}
1687    def _init_categories(categories=categories):
1688        for k,v in globals().items():
1689            if k[:3] == 'LC_':
1690                categories[k] = v
1691    _init_categories()
1692    del categories['LC_ALL']
1693
1694    print('Locale defaults as determined by getdefaultlocale():')
1695    print('-'*72)
1696    lang, enc = getdefaultlocale()
1697    print('Language: ', lang or '(undefined)')
1698    print('Encoding: ', enc or '(undefined)')
1699    print()
1700
1701    print('Locale settings on startup:')
1702    print('-'*72)
1703    for name,category in categories.items():
1704        print(name, '...')
1705        lang, enc = getlocale(category)
1706        print('   Language: ', lang or '(undefined)')
1707        print('   Encoding: ', enc or '(undefined)')
1708        print()
1709
1710    try:
1711        setlocale(LC_ALL, "")
1712    except:
1713        print('NOTE:')
1714        print('setlocale(LC_ALL, "") does not support the default locale')
1715        print('given in the OS environment variables.')
1716    else:
1717        print()
1718        print('Locale settings after calling setlocale(LC_ALL, ""):')
1719        print('-'*72)
1720        for name,category in categories.items():
1721            print(name, '...')
1722            lang, enc = getlocale(category)
1723            print('   Language: ', lang or '(undefined)')
1724            print('   Encoding: ', enc or '(undefined)')
1725            print()
1726
1727###
1728
1729try:
1730    LC_MESSAGES
1731except NameError:
1732    pass
1733else:
1734    __all__.append("LC_MESSAGES")
1735
1736if __name__=='__main__':
1737    print('Locale aliasing:')
1738    print()
1739    _print_locale()
1740    print()
1741    print('Number formatting:')
1742    print()
1743    _test()
1744