comparison babel/core.py @ 184:a0b5bfa17e4e stable-0.8.x

Ported [185:186] to 0.8.x branch.
author cmlenz
date Thu, 28 Jun 2007 11:51:26 +0000
parents dbad98f3dbf6
children 170cffc66554
comparison
equal deleted inserted replaced
180:b87343676bec 184:a0b5bfa17e4e
37 37
38 38
39 class Locale(object): 39 class Locale(object):
40 """Representation of a specific locale. 40 """Representation of a specific locale.
41 41
42 >>> locale = Locale('en', territory='US') 42 >>> locale = Locale('en', 'US')
43 >>> repr(locale) 43 >>> repr(locale)
44 '<Locale "en_US">' 44 '<Locale "en_US">'
45 >>> locale.display_name 45 >>> locale.display_name
46 u'English (United States)' 46 u'English (United States)'
47 47
54 `Locale` objects provide access to a collection of locale data, such as 54 `Locale` objects provide access to a collection of locale data, such as
55 territory and language names, number and date format patterns, and more: 55 territory and language names, number and date format patterns, and more:
56 56
57 >>> locale.number_symbols['decimal'] 57 >>> locale.number_symbols['decimal']
58 u'.' 58 u'.'
59 59
60 If a locale is requested for which no locale data is available, an 60 If a locale is requested for which no locale data is available, an
61 `UnknownLocaleError` is raised: 61 `UnknownLocaleError` is raised:
62 62
63 >>> Locale.parse('en_DE') 63 >>> Locale.parse('en_DE')
64 Traceback (most recent call last): 64 Traceback (most recent call last):
66 UnknownLocaleError: unknown locale 'en_DE' 66 UnknownLocaleError: unknown locale 'en_DE'
67 67
68 :see: `IETF RFC 3066 <http://www.ietf.org/rfc/rfc3066.txt>`_ 68 :see: `IETF RFC 3066 <http://www.ietf.org/rfc/rfc3066.txt>`_
69 """ 69 """
70 70
71 def __init__(self, language, territory=None, variant=None): 71 def __init__(self, language, territory=None, script=None, variant=None):
72 """Initialize the locale object from the given identifier components. 72 """Initialize the locale object from the given identifier components.
73 73
74 >>> locale = Locale('en', 'US') 74 >>> locale = Locale('en', 'US')
75 >>> locale.language 75 >>> locale.language
76 'en' 76 'en'
77 >>> locale.territory 77 >>> locale.territory
78 'US' 78 'US'
79 79
80 :param language: the language code 80 :param language: the language code
81 :param territory: the territory (country or region) code 81 :param territory: the territory (country or region) code
82 :param script: the script code
82 :param variant: the variant code 83 :param variant: the variant code
83 :raise `UnknownLocaleError`: if no locale data is available for the 84 :raise `UnknownLocaleError`: if no locale data is available for the
84 requested locale 85 requested locale
85 """ 86 """
86 self.language = language 87 self.language = language
87 self.territory = territory 88 self.territory = territory
89 self.script = script
88 self.variant = variant 90 self.variant = variant
89 self.__data = None 91 self.__data = None
90 92
91 identifier = str(self) 93 identifier = str(self)
92 if not localedata.exists(identifier): 94 if not localedata.exists(identifier):
168 170
169 def __repr__(self): 171 def __repr__(self):
170 return '<Locale "%s">' % str(self) 172 return '<Locale "%s">' % str(self)
171 173
172 def __str__(self): 174 def __str__(self):
173 return '_'.join(filter(None, [self.language, self.territory, 175 return '_'.join(filter(None, [self.language, self.script,
174 self.variant])) 176 self.territory, self.variant]))
175 177
176 def _data(self): 178 def _data(self):
177 if self.__data is None: 179 if self.__data is None:
178 self.__data = localedata.load(str(self)) 180 self.__data = localedata.load(str(self))
179 return self.__data 181 return self.__data
582 if len(parts) > 1 and parts[0].lower() in available: 584 if len(parts) > 1 and parts[0].lower() in available:
583 return parts[0] 585 return parts[0]
584 return None 586 return None
585 587
586 def parse_locale(identifier, sep='_'): 588 def parse_locale(identifier, sep='_'):
587 """Parse a locale identifier into a ``(language, territory, variant)`` 589 """Parse a locale identifier into a tuple of the form::
588 tuple. 590
591 ``(language, territory, script, variant)``
589 592
590 >>> parse_locale('zh_CN') 593 >>> parse_locale('zh_CN')
591 ('zh', 'CN', None) 594 ('zh', 'CN', None, None)
595 >>> parse_locale('zh_Hans_CN')
596 ('zh', 'CN', 'Hans', None)
592 597
593 The default component separator is "_", but a different separator can be 598 The default component separator is "_", but a different separator can be
594 specified using the `sep` parameter: 599 specified using the `sep` parameter:
595 600
596 >>> parse_locale('zh-CN', sep='-') 601 >>> parse_locale('zh-CN', sep='-')
597 ('zh', 'CN', None) 602 ('zh', 'CN', None, None)
603
604 If the identifier cannot be parsed into a locale, a `ValueError` exception
605 is raised:
606
607 >>> parse_locale('not_a_LOCALE_String')
608 Traceback (most recent call last):
609 ...
610 ValueError: 'not_a_LOCALE_String' is not a valid locale identifier
598 611
599 :param identifier: the locale identifier string 612 :param identifier: the locale identifier string
600 :param sep: character that separates the different parts of the locale 613 :param sep: character that separates the different components of the locale
601 string 614 identifier
602 :return: the ``(language, territory, variant)`` tuple 615 :return: the ``(language, territory, script, variant)`` tuple
603 :rtype: `tuple` 616 :rtype: `tuple`
604 :raise `ValueError`: if the string does not appear to be a valid locale 617 :raise `ValueError`: if the string does not appear to be a valid locale
605 identifier 618 identifier
606 619
607 :see: `IETF RFC 3066 <http://www.ietf.org/rfc/rfc3066.txt>`_ 620 :see: `IETF RFC 4646 <http://www.ietf.org/rfc/rfc4646.txt>`_
608 """ 621 """
609 if '.' in identifier: 622 if '.' in identifier:
610 # this is probably the charset/encoding, which we don't care about 623 # this is probably the charset/encoding, which we don't care about
611 identifier = identifier.split('.', 1)[0] 624 identifier = identifier.split('.', 1)[0]
625
612 parts = identifier.split(sep) 626 parts = identifier.split(sep)
613 lang, territory, variant = parts[0].lower(), None, None 627 lang = parts.pop(0).lower()
614 if not lang.isalpha(): 628 if not lang.isalpha():
615 raise ValueError('expected only letters, got %r' % lang) 629 raise ValueError('expected only letters, got %r' % lang)
616 if len(parts) > 1: 630
617 territory = parts[1].upper().split('.', 1)[0] 631 script = territory = variant = None
618 if not territory.isalpha(): 632 if parts:
619 raise ValueError('expected only letters, got %r' % territory) 633 if len(parts[0]) == 4 and parts[0].isalpha():
620 if len(parts) > 2: 634 script = parts.pop(0).title()
621 variant = parts[2].upper().split('.', 1)[0] 635
622 return lang, territory, variant 636 if parts:
637 if len(parts[0]) == 2 and parts[0].isalpha():
638 territory = parts.pop(0).upper()
639 elif len(parts[0]) == 3 and parts[0].isdigit():
640 territory = parts.pop(0)
641
642 if parts:
643 if len(parts[0]) == 4 and parts[0][0].isdigit() or \
644 len(parts[0]) >= 5 and parts[0][0].isalpha():
645 variant = parts.pop()
646
647 if parts:
648 raise ValueError('%r is not a valid locale identifier' % identifier)
649
650 return lang, territory, script, variant
Copyright (C) 2012-2017 Edgewall Software