Mercurial > babel > old > babel-test
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 |