diff options
Diffstat (limited to 'jython-tosca-parser/src/main/resources/Lib/site-packages/babel-2.3.4-py2.7.egg/babel/core.py')
-rw-r--r-- | jython-tosca-parser/src/main/resources/Lib/site-packages/babel-2.3.4-py2.7.egg/babel/core.py | 1135 |
1 files changed, 0 insertions, 1135 deletions
diff --git a/jython-tosca-parser/src/main/resources/Lib/site-packages/babel-2.3.4-py2.7.egg/babel/core.py b/jython-tosca-parser/src/main/resources/Lib/site-packages/babel-2.3.4-py2.7.egg/babel/core.py deleted file mode 100644 index 4e00ebf..0000000 --- a/jython-tosca-parser/src/main/resources/Lib/site-packages/babel-2.3.4-py2.7.egg/babel/core.py +++ /dev/null @@ -1,1135 +0,0 @@ -# -*- coding: utf-8 -*- -""" - babel.core - ~~~~~~~~~~ - - Core locale representation and locale data access. - - :copyright: (c) 2013 by the Babel Team. - :license: BSD, see LICENSE for more details. -""" - -import os - -from babel import localedata -from babel._compat import pickle, string_types -from babel.plural import PluralRule - -__all__ = ['UnknownLocaleError', 'Locale', 'default_locale', 'negotiate_locale', - 'parse_locale'] - - -_global_data = None -_default_plural_rule = PluralRule({}) - - -def _raise_no_data_error(): - raise RuntimeError('The babel data files are not available. ' - 'This usually happens because you are using ' - 'a source checkout from Babel and you did ' - 'not build the data files. Just make sure ' - 'to run "python setup.py import_cldr" before ' - 'installing the library.') - - -def get_global(key): - """Return the dictionary for the given key in the global data. - - The global data is stored in the ``babel/global.dat`` file and contains - information independent of individual locales. - - >>> get_global('zone_aliases')['UTC'] - u'Etc/GMT' - >>> get_global('zone_territories')['Europe/Berlin'] - u'DE' - - The keys available are: - - - ``currency_fractions`` - - ``language_aliases`` - - ``likely_subtags`` - - ``parent_exceptions`` - - ``script_aliases`` - - ``territory_aliases`` - - ``territory_currencies`` - - ``territory_languages`` - - ``territory_zones`` - - ``variant_aliases`` - - ``win_mapping`` - - ``zone_aliases`` - - ``zone_territories`` - - .. note:: The internal structure of the data may change between versions. - - .. versionadded:: 0.9 - - :param key: the data key - """ - global _global_data - if _global_data is None: - dirname = os.path.join(os.path.dirname(__file__)) - filename = os.path.join(dirname, 'global.dat') - if not os.path.isfile(filename): - _raise_no_data_error() - fileobj = open(filename, 'rb') - try: - _global_data = pickle.load(fileobj) - finally: - fileobj.close() - return _global_data.get(key, {}) - - -LOCALE_ALIASES = { - 'ar': 'ar_SY', 'bg': 'bg_BG', 'bs': 'bs_BA', 'ca': 'ca_ES', 'cs': 'cs_CZ', - 'da': 'da_DK', 'de': 'de_DE', 'el': 'el_GR', 'en': 'en_US', 'es': 'es_ES', - 'et': 'et_EE', 'fa': 'fa_IR', 'fi': 'fi_FI', 'fr': 'fr_FR', 'gl': 'gl_ES', - 'he': 'he_IL', 'hu': 'hu_HU', 'id': 'id_ID', 'is': 'is_IS', 'it': 'it_IT', - 'ja': 'ja_JP', 'km': 'km_KH', 'ko': 'ko_KR', 'lt': 'lt_LT', 'lv': 'lv_LV', - 'mk': 'mk_MK', 'nl': 'nl_NL', 'nn': 'nn_NO', 'no': 'nb_NO', 'pl': 'pl_PL', - 'pt': 'pt_PT', 'ro': 'ro_RO', 'ru': 'ru_RU', 'sk': 'sk_SK', 'sl': 'sl_SI', - 'sv': 'sv_SE', 'th': 'th_TH', 'tr': 'tr_TR', 'uk': 'uk_UA' -} - - -class UnknownLocaleError(Exception): - """Exception thrown when a locale is requested for which no locale data - is available. - """ - - def __init__(self, identifier): - """Create the exception. - - :param identifier: the identifier string of the unsupported locale - """ - Exception.__init__(self, 'unknown locale %r' % identifier) - - #: The identifier of the locale that could not be found. - self.identifier = identifier - - -class Locale(object): - """Representation of a specific locale. - - >>> locale = Locale('en', 'US') - >>> repr(locale) - "Locale('en', territory='US')" - >>> locale.display_name - u'English (United States)' - - A `Locale` object can also be instantiated from a raw locale string: - - >>> locale = Locale.parse('en-US', sep='-') - >>> repr(locale) - "Locale('en', territory='US')" - - `Locale` objects provide access to a collection of locale data, such as - territory and language names, number and date format patterns, and more: - - >>> locale.number_symbols['decimal'] - u'.' - - If a locale is requested for which no locale data is available, an - `UnknownLocaleError` is raised: - - >>> Locale.parse('en_XX') - Traceback (most recent call last): - ... - UnknownLocaleError: unknown locale 'en_XX' - - For more information see :rfc:`3066`. - """ - - def __init__(self, language, territory=None, script=None, variant=None): - """Initialize the locale object from the given identifier components. - - >>> locale = Locale('en', 'US') - >>> locale.language - 'en' - >>> locale.territory - 'US' - - :param language: the language code - :param territory: the territory (country or region) code - :param script: the script code - :param variant: the variant code - :raise `UnknownLocaleError`: if no locale data is available for the - requested locale - """ - #: the language code - self.language = language - #: the territory (country or region) code - self.territory = territory - #: the script code - self.script = script - #: the variant code - self.variant = variant - self.__data = None - - identifier = str(self) - if not localedata.exists(identifier): - raise UnknownLocaleError(identifier) - - @classmethod - def default(cls, category=None, aliases=LOCALE_ALIASES): - """Return the system default locale for the specified category. - - >>> for name in ['LANGUAGE', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES']: - ... os.environ[name] = '' - >>> os.environ['LANG'] = 'fr_FR.UTF-8' - >>> Locale.default('LC_MESSAGES') - Locale('fr', territory='FR') - - The following fallbacks to the variable are always considered: - - - ``LANGUAGE`` - - ``LC_ALL`` - - ``LC_CTYPE`` - - ``LANG`` - - :param category: one of the ``LC_XXX`` environment variable names - :param aliases: a dictionary of aliases for locale identifiers - """ - # XXX: use likely subtag expansion here instead of the - # aliases dictionary. - locale_string = default_locale(category, aliases=aliases) - return cls.parse(locale_string) - - @classmethod - def negotiate(cls, preferred, available, sep='_', aliases=LOCALE_ALIASES): - """Find the best match between available and requested locale strings. - - >>> Locale.negotiate(['de_DE', 'en_US'], ['de_DE', 'de_AT']) - Locale('de', territory='DE') - >>> Locale.negotiate(['de_DE', 'en_US'], ['en', 'de']) - Locale('de') - >>> Locale.negotiate(['de_DE', 'de'], ['en_US']) - - You can specify the character used in the locale identifiers to separate - the differnet components. This separator is applied to both lists. Also, - case is ignored in the comparison: - - >>> Locale.negotiate(['de-DE', 'de'], ['en-us', 'de-de'], sep='-') - Locale('de', territory='DE') - - :param preferred: the list of locale identifers preferred by the user - :param available: the list of locale identifiers available - :param aliases: a dictionary of aliases for locale identifiers - """ - identifier = negotiate_locale(preferred, available, sep=sep, - aliases=aliases) - if identifier: - return Locale.parse(identifier, sep=sep) - - @classmethod - def parse(cls, identifier, sep='_', resolve_likely_subtags=True): - """Create a `Locale` instance for the given locale identifier. - - >>> l = Locale.parse('de-DE', sep='-') - >>> l.display_name - u'Deutsch (Deutschland)' - - If the `identifier` parameter is not a string, but actually a `Locale` - object, that object is returned: - - >>> Locale.parse(l) - Locale('de', territory='DE') - - This also can perform resolving of likely subtags which it does - by default. This is for instance useful to figure out the most - likely locale for a territory you can use ``'und'`` as the - language tag: - - >>> Locale.parse('und_AT') - Locale('de', territory='AT') - - :param identifier: the locale identifier string - :param sep: optional component separator - :param resolve_likely_subtags: if this is specified then a locale will - have its likely subtag resolved if the - locale otherwise does not exist. For - instance ``zh_TW`` by itself is not a - locale that exists but Babel can - automatically expand it to the full - form of ``zh_hant_TW``. Note that this - expansion is only taking place if no - locale exists otherwise. For instance - there is a locale ``en`` that can exist - by itself. - :raise `ValueError`: if the string does not appear to be a valid locale - identifier - :raise `UnknownLocaleError`: if no locale data is available for the - requested locale - """ - if identifier is None: - return None - elif isinstance(identifier, Locale): - return identifier - elif not isinstance(identifier, string_types): - raise TypeError('Unxpected value for identifier: %r' % (identifier,)) - - parts = parse_locale(identifier, sep=sep) - input_id = get_locale_identifier(parts) - - def _try_load(parts): - try: - return cls(*parts) - except UnknownLocaleError: - return None - - def _try_load_reducing(parts): - # Success on first hit, return it. - locale = _try_load(parts) - if locale is not None: - return locale - - # Now try without script and variant - locale = _try_load(parts[:2]) - if locale is not None: - return locale - - locale = _try_load(parts) - if locale is not None: - return locale - if not resolve_likely_subtags: - raise UnknownLocaleError(input_id) - - # From here onwards is some very bad likely subtag resolving. This - # whole logic is not entirely correct but good enough (tm) for the - # time being. This has been added so that zh_TW does not cause - # errors for people when they upgrade. Later we should properly - # implement ICU like fuzzy locale objects and provide a way to - # maximize and minimize locale tags. - - language, territory, script, variant = parts - language = get_global('language_aliases').get(language, language) - territory = get_global('territory_aliases').get(territory, (territory,))[0] - script = get_global('script_aliases').get(script, script) - variant = get_global('variant_aliases').get(variant, variant) - - if territory == 'ZZ': - territory = None - if script == 'Zzzz': - script = None - - parts = language, territory, script, variant - - # First match: try the whole identifier - new_id = get_locale_identifier(parts) - likely_subtag = get_global('likely_subtags').get(new_id) - if likely_subtag is not None: - locale = _try_load_reducing(parse_locale(likely_subtag)) - if locale is not None: - return locale - - # If we did not find anything so far, try again with a - # simplified identifier that is just the language - likely_subtag = get_global('likely_subtags').get(language) - if likely_subtag is not None: - language2, _, script2, variant2 = parse_locale(likely_subtag) - locale = _try_load_reducing((language2, territory, script2, variant2)) - if locale is not None: - return locale - - raise UnknownLocaleError(input_id) - - def __eq__(self, other): - for key in ('language', 'territory', 'script', 'variant'): - if not hasattr(other, key): - return False - return (self.language == other.language) and \ - (self.territory == other.territory) and \ - (self.script == other.script) and \ - (self.variant == other.variant) - - def __ne__(self, other): - return not self.__eq__(other) - - def __hash__(self): - return hash((self.language, self.territory, self.script, self.variant)) - - def __repr__(self): - parameters = [''] - for key in ('territory', 'script', 'variant'): - value = getattr(self, key) - if value is not None: - parameters.append('%s=%r' % (key, value)) - parameter_string = '%r' % self.language + ', '.join(parameters) - return 'Locale(%s)' % parameter_string - - def __str__(self): - return get_locale_identifier((self.language, self.territory, - self.script, self.variant)) - - @property - def _data(self): - if self.__data is None: - self.__data = localedata.LocaleDataDict(localedata.load(str(self))) - return self.__data - - def get_display_name(self, locale=None): - """Return the display name of the locale using the given locale. - - The display name will include the language, territory, script, and - variant, if those are specified. - - >>> Locale('zh', 'CN', script='Hans').get_display_name('en') - u'Chinese (Simplified, China)' - - :param locale: the locale to use - """ - if locale is None: - locale = self - locale = Locale.parse(locale) - retval = locale.languages.get(self.language) - if self.territory or self.script or self.variant: - details = [] - if self.script: - details.append(locale.scripts.get(self.script)) - if self.territory: - details.append(locale.territories.get(self.territory)) - if self.variant: - details.append(locale.variants.get(self.variant)) - details = filter(None, details) - if details: - retval += ' (%s)' % u', '.join(details) - return retval - - display_name = property(get_display_name, doc="""\ - The localized display name of the locale. - - >>> Locale('en').display_name - u'English' - >>> Locale('en', 'US').display_name - u'English (United States)' - >>> Locale('sv').display_name - u'svenska' - - :type: `unicode` - """) - - def get_language_name(self, locale=None): - """Return the language of this locale in the given locale. - - >>> Locale('zh', 'CN', script='Hans').get_language_name('de') - u'Chinesisch' - - .. versionadded:: 1.0 - - :param locale: the locale to use - """ - if locale is None: - locale = self - locale = Locale.parse(locale) - return locale.languages.get(self.language) - - language_name = property(get_language_name, doc="""\ - The localized language name of the locale. - - >>> Locale('en', 'US').language_name - u'English' - """) - - def get_territory_name(self, locale=None): - """Return the territory name in the given locale.""" - if locale is None: - locale = self - locale = Locale.parse(locale) - return locale.territories.get(self.territory) - - territory_name = property(get_territory_name, doc="""\ - The localized territory name of the locale if available. - - >>> Locale('de', 'DE').territory_name - u'Deutschland' - """) - - def get_script_name(self, locale=None): - """Return the script name in the given locale.""" - if locale is None: - locale = self - locale = Locale.parse(locale) - return locale.scripts.get(self.script) - - script_name = property(get_script_name, doc="""\ - The localized script name of the locale if available. - - >>> Locale('sr', 'ME', script='Latn').script_name - u'latinica' - """) - - @property - def english_name(self): - """The english display name of the locale. - - >>> Locale('de').english_name - u'German' - >>> Locale('de', 'DE').english_name - u'German (Germany)' - - :type: `unicode`""" - return self.get_display_name(Locale('en')) - - # { General Locale Display Names - - @property - def languages(self): - """Mapping of language codes to translated language names. - - >>> Locale('de', 'DE').languages['ja'] - u'Japanisch' - - See `ISO 639 <http://www.loc.gov/standards/iso639-2/>`_ for - more information. - """ - return self._data['languages'] - - @property - def scripts(self): - """Mapping of script codes to translated script names. - - >>> Locale('en', 'US').scripts['Hira'] - u'Hiragana' - - See `ISO 15924 <http://www.evertype.com/standards/iso15924/>`_ - for more information. - """ - return self._data['scripts'] - - @property - def territories(self): - """Mapping of script codes to translated script names. - - >>> Locale('es', 'CO').territories['DE'] - u'Alemania' - - See `ISO 3166 <http://www.iso.org/iso/en/prods-services/iso3166ma/>`_ - for more information. - """ - return self._data['territories'] - - @property - def variants(self): - """Mapping of script codes to translated script names. - - >>> Locale('de', 'DE').variants['1901'] - u'Alte deutsche Rechtschreibung' - """ - return self._data['variants'] - - # { Number Formatting - - @property - def currencies(self): - """Mapping of currency codes to translated currency names. This - only returns the generic form of the currency name, not the count - specific one. If an actual number is requested use the - :func:`babel.numbers.get_currency_name` function. - - >>> Locale('en').currencies['COP'] - u'Colombian Peso' - >>> Locale('de', 'DE').currencies['COP'] - u'Kolumbianischer Peso' - """ - return self._data['currency_names'] - - @property - def currency_symbols(self): - """Mapping of currency codes to symbols. - - >>> Locale('en', 'US').currency_symbols['USD'] - u'$' - >>> Locale('es', 'CO').currency_symbols['USD'] - u'US$' - """ - return self._data['currency_symbols'] - - @property - def number_symbols(self): - """Symbols used in number formatting. - - .. note:: The format of the value returned may change between - Babel versions. - - >>> Locale('fr', 'FR').number_symbols['decimal'] - u',' - """ - return self._data['number_symbols'] - - @property - def decimal_formats(self): - """Locale patterns for decimal number formatting. - - .. note:: The format of the value returned may change between - Babel versions. - - >>> Locale('en', 'US').decimal_formats[None] - <NumberPattern u'#,##0.###'> - """ - return self._data['decimal_formats'] - - @property - def currency_formats(self): - """Locale patterns for currency number formatting. - - .. note:: The format of the value returned may change between - Babel versions. - - >>> Locale('en', 'US').currency_formats['standard'] - <NumberPattern u'\\xa4#,##0.00'> - >>> Locale('en', 'US').currency_formats['accounting'] - <NumberPattern u'\\xa4#,##0.00'> - """ - return self._data['currency_formats'] - - @property - def percent_formats(self): - """Locale patterns for percent number formatting. - - .. note:: The format of the value returned may change between - Babel versions. - - >>> Locale('en', 'US').percent_formats[None] - <NumberPattern u'#,##0%'> - """ - return self._data['percent_formats'] - - @property - def scientific_formats(self): - """Locale patterns for scientific number formatting. - - .. note:: The format of the value returned may change between - Babel versions. - - >>> Locale('en', 'US').scientific_formats[None] - <NumberPattern u'#E0'> - """ - return self._data['scientific_formats'] - - # { Calendar Information and Date Formatting - - @property - def periods(self): - """Locale display names for day periods (AM/PM). - - >>> Locale('en', 'US').periods['am'] - u'AM' - """ - try: - return self._data['day_periods']['stand-alone']['wide'] - except KeyError: - return {} - - @property - def day_periods(self): - """Locale display names for various day periods (not necessarily only AM/PM). - - These are not meant to be used without the relevant `day_period_rules`. - """ - return self._data['day_periods'] - - @property - def day_period_rules(self): - """Day period rules for the locale. Used by `get_period_id`. - """ - return self._data.get('day_period_rules', {}) - - @property - def days(self): - """Locale display names for weekdays. - - >>> Locale('de', 'DE').days['format']['wide'][3] - u'Donnerstag' - """ - return self._data['days'] - - @property - def months(self): - """Locale display names for months. - - >>> Locale('de', 'DE').months['format']['wide'][10] - u'Oktober' - """ - return self._data['months'] - - @property - def quarters(self): - """Locale display names for quarters. - - >>> Locale('de', 'DE').quarters['format']['wide'][1] - u'1. Quartal' - """ - return self._data['quarters'] - - @property - def eras(self): - """Locale display names for eras. - - .. note:: The format of the value returned may change between - Babel versions. - - >>> Locale('en', 'US').eras['wide'][1] - u'Anno Domini' - >>> Locale('en', 'US').eras['abbreviated'][0] - u'BC' - """ - return self._data['eras'] - - @property - def time_zones(self): - """Locale display names for time zones. - - .. note:: The format of the value returned may change between - Babel versions. - - >>> Locale('en', 'US').time_zones['Europe/London']['long']['daylight'] - u'British Summer Time' - >>> Locale('en', 'US').time_zones['America/St_Johns']['city'] - u'St. John\u2019s' - """ - return self._data['time_zones'] - - @property - def meta_zones(self): - """Locale display names for meta time zones. - - Meta time zones are basically groups of different Olson time zones that - have the same GMT offset and daylight savings time. - - .. note:: The format of the value returned may change between - Babel versions. - - >>> Locale('en', 'US').meta_zones['Europe_Central']['long']['daylight'] - u'Central European Summer Time' - - .. versionadded:: 0.9 - """ - return self._data['meta_zones'] - - @property - def zone_formats(self): - """Patterns related to the formatting of time zones. - - .. note:: The format of the value returned may change between - Babel versions. - - >>> Locale('en', 'US').zone_formats['fallback'] - u'%(1)s (%(0)s)' - >>> Locale('pt', 'BR').zone_formats['region'] - u'Hor\\xe1rio %s' - - .. versionadded:: 0.9 - """ - return self._data['zone_formats'] - - @property - def first_week_day(self): - """The first day of a week, with 0 being Monday. - - >>> Locale('de', 'DE').first_week_day - 0 - >>> Locale('en', 'US').first_week_day - 6 - """ - return self._data['week_data']['first_day'] - - @property - def weekend_start(self): - """The day the weekend starts, with 0 being Monday. - - >>> Locale('de', 'DE').weekend_start - 5 - """ - return self._data['week_data']['weekend_start'] - - @property - def weekend_end(self): - """The day the weekend ends, with 0 being Monday. - - >>> Locale('de', 'DE').weekend_end - 6 - """ - return self._data['week_data']['weekend_end'] - - @property - def min_week_days(self): - """The minimum number of days in a week so that the week is counted as - the first week of a year or month. - - >>> Locale('de', 'DE').min_week_days - 4 - """ - return self._data['week_data']['min_days'] - - @property - def date_formats(self): - """Locale patterns for date formatting. - - .. note:: The format of the value returned may change between - Babel versions. - - >>> Locale('en', 'US').date_formats['short'] - <DateTimePattern u'M/d/yy'> - >>> Locale('fr', 'FR').date_formats['long'] - <DateTimePattern u'd MMMM y'> - """ - return self._data['date_formats'] - - @property - def time_formats(self): - """Locale patterns for time formatting. - - .. note:: The format of the value returned may change between - Babel versions. - - >>> Locale('en', 'US').time_formats['short'] - <DateTimePattern u'h:mm a'> - >>> Locale('fr', 'FR').time_formats['long'] - <DateTimePattern u'HH:mm:ss z'> - """ - return self._data['time_formats'] - - @property - def datetime_formats(self): - """Locale patterns for datetime formatting. - - .. note:: The format of the value returned may change between - Babel versions. - - >>> Locale('en').datetime_formats['full'] - u"{1} 'at' {0}" - >>> Locale('th').datetime_formats['medium'] - u'{1} {0}' - """ - return self._data['datetime_formats'] - - @property - def datetime_skeletons(self): - """Locale patterns for formatting parts of a datetime. - - >>> Locale('en').datetime_skeletons['MEd'] - <DateTimePattern u'E, M/d'> - >>> Locale('fr').datetime_skeletons['MEd'] - <DateTimePattern u'E dd/MM'> - >>> Locale('fr').datetime_skeletons['H'] - <DateTimePattern u"HH 'h'"> - """ - return self._data['datetime_skeletons'] - - @property - def interval_formats(self): - """Locale patterns for interval formatting. - - .. note:: The format of the value returned may change between - Babel versions. - - How to format date intervals in Finnish when the day is the - smallest changing component: - - >>> Locale('fi_FI').interval_formats['MEd']['d'] - [u'E d. \u2013 ', u'E d.M.'] - - .. seealso:: - - The primary API to use this data is :py:func:`babel.dates.format_interval`. - - - :rtype: dict[str, dict[str, list[str]]] - """ - return self._data['interval_formats'] - - @property - def plural_form(self): - """Plural rules for the locale. - - >>> Locale('en').plural_form(1) - 'one' - >>> Locale('en').plural_form(0) - 'other' - >>> Locale('fr').plural_form(0) - 'one' - >>> Locale('ru').plural_form(100) - 'many' - """ - return self._data.get('plural_form', _default_plural_rule) - - @property - def list_patterns(self): - """Patterns for generating lists - - .. note:: The format of the value returned may change between - Babel versions. - - >>> Locale('en').list_patterns['start'] - u'{0}, {1}' - >>> Locale('en').list_patterns['end'] - u'{0}, and {1}' - >>> Locale('en_GB').list_patterns['end'] - u'{0} and {1}' - """ - return self._data['list_patterns'] - - @property - def ordinal_form(self): - """Plural rules for the locale. - - >>> Locale('en').ordinal_form(1) - 'one' - >>> Locale('en').ordinal_form(2) - 'two' - >>> Locale('en').ordinal_form(3) - 'few' - >>> Locale('fr').ordinal_form(2) - 'other' - >>> Locale('ru').ordinal_form(100) - 'other' - """ - return self._data.get('ordinal_form', _default_plural_rule) - - @property - def measurement_systems(self): - """Localized names for various measurement systems. - - >>> Locale('fr', 'FR').measurement_systems['US'] - u'am\\xe9ricain' - >>> Locale('en', 'US').measurement_systems['US'] - u'US' - - """ - return self._data['measurement_systems'] - - @property - def character_order(self): - """The text direction for the language. - - >>> Locale('de', 'DE').character_order - 'left-to-right' - >>> Locale('ar', 'SA').character_order - 'right-to-left' - """ - return self._data['character_order'] - - @property - def text_direction(self): - """The text direction for the language in CSS short-hand form. - - >>> Locale('de', 'DE').text_direction - 'ltr' - >>> Locale('ar', 'SA').text_direction - 'rtl' - """ - return ''.join(word[0] for word in self.character_order.split('-')) - - @property - def unit_display_names(self): - """Display names for units of measurement. - - .. seealso:: - - You may want to use :py:func:`babel.units.get_unit_name` instead. - - .. note:: The format of the value returned may change between - Babel versions. - - """ - return self._data['unit_display_names'] - - -def default_locale(category=None, aliases=LOCALE_ALIASES): - """Returns the system default locale for a given category, based on - environment variables. - - >>> for name in ['LANGUAGE', 'LC_ALL', 'LC_CTYPE']: - ... os.environ[name] = '' - >>> os.environ['LANG'] = 'fr_FR.UTF-8' - >>> default_locale('LC_MESSAGES') - 'fr_FR' - - The "C" or "POSIX" pseudo-locales are treated as aliases for the - "en_US_POSIX" locale: - - >>> os.environ['LC_MESSAGES'] = 'POSIX' - >>> default_locale('LC_MESSAGES') - 'en_US_POSIX' - - The following fallbacks to the variable are always considered: - - - ``LANGUAGE`` - - ``LC_ALL`` - - ``LC_CTYPE`` - - ``LANG`` - - :param category: one of the ``LC_XXX`` environment variable names - :param aliases: a dictionary of aliases for locale identifiers - """ - varnames = (category, 'LANGUAGE', 'LC_ALL', 'LC_CTYPE', 'LANG') - for name in filter(None, varnames): - locale = os.getenv(name) - if locale: - if name == 'LANGUAGE' and ':' in locale: - # the LANGUAGE variable may contain a colon-separated list of - # language codes; we just pick the language on the list - locale = locale.split(':')[0] - if locale.split('.')[0] in ('C', 'POSIX'): - locale = 'en_US_POSIX' - elif aliases and locale in aliases: - locale = aliases[locale] - try: - return get_locale_identifier(parse_locale(locale)) - except ValueError: - pass - - -def negotiate_locale(preferred, available, sep='_', aliases=LOCALE_ALIASES): - """Find the best match between available and requested locale strings. - - >>> negotiate_locale(['de_DE', 'en_US'], ['de_DE', 'de_AT']) - 'de_DE' - >>> negotiate_locale(['de_DE', 'en_US'], ['en', 'de']) - 'de' - - Case is ignored by the algorithm, the result uses the case of the preferred - locale identifier: - - >>> negotiate_locale(['de_DE', 'en_US'], ['de_de', 'de_at']) - 'de_DE' - - >>> negotiate_locale(['de_DE', 'en_US'], ['de_de', 'de_at']) - 'de_DE' - - By default, some web browsers unfortunately do not include the territory - in the locale identifier for many locales, and some don't even allow the - user to easily add the territory. So while you may prefer using qualified - locale identifiers in your web-application, they would not normally match - the language-only locale sent by such browsers. To workaround that, this - function uses a default mapping of commonly used langauge-only locale - identifiers to identifiers including the territory: - - >>> negotiate_locale(['ja', 'en_US'], ['ja_JP', 'en_US']) - 'ja_JP' - - Some browsers even use an incorrect or outdated language code, such as "no" - for Norwegian, where the correct locale identifier would actually be "nb_NO" - (Bokmål) or "nn_NO" (Nynorsk). The aliases are intended to take care of - such cases, too: - - >>> negotiate_locale(['no', 'sv'], ['nb_NO', 'sv_SE']) - 'nb_NO' - - You can override this default mapping by passing a different `aliases` - dictionary to this function, or you can bypass the behavior althogher by - setting the `aliases` parameter to `None`. - - :param preferred: the list of locale strings preferred by the user - :param available: the list of locale strings available - :param sep: character that separates the different parts of the locale - strings - :param aliases: a dictionary of aliases for locale identifiers - """ - available = [a.lower() for a in available if a] - for locale in preferred: - ll = locale.lower() - if ll in available: - return locale - if aliases: - alias = aliases.get(ll) - if alias: - alias = alias.replace('_', sep) - if alias.lower() in available: - return alias - parts = locale.split(sep) - if len(parts) > 1 and parts[0].lower() in available: - return parts[0] - return None - - -def parse_locale(identifier, sep='_'): - """Parse a locale identifier into a tuple of the form ``(language, - territory, script, variant)``. - - >>> parse_locale('zh_CN') - ('zh', 'CN', None, None) - >>> parse_locale('zh_Hans_CN') - ('zh', 'CN', 'Hans', None) - - The default component separator is "_", but a different separator can be - specified using the `sep` parameter: - - >>> parse_locale('zh-CN', sep='-') - ('zh', 'CN', None, None) - - If the identifier cannot be parsed into a locale, a `ValueError` exception - is raised: - - >>> parse_locale('not_a_LOCALE_String') - Traceback (most recent call last): - ... - ValueError: 'not_a_LOCALE_String' is not a valid locale identifier - - Encoding information and locale modifiers are removed from the identifier: - - >>> parse_locale('it_IT@euro') - ('it', 'IT', None, None) - >>> parse_locale('en_US.UTF-8') - ('en', 'US', None, None) - >>> parse_locale('de_DE.iso885915@euro') - ('de', 'DE', None, None) - - See :rfc:`4646` for more information. - - :param identifier: the locale identifier string - :param sep: character that separates the different components of the locale - identifier - :raise `ValueError`: if the string does not appear to be a valid locale - identifier - """ - if '.' in identifier: - # this is probably the charset/encoding, which we don't care about - identifier = identifier.split('.', 1)[0] - if '@' in identifier: - # this is a locale modifier such as @euro, which we don't care about - # either - identifier = identifier.split('@', 1)[0] - - parts = identifier.split(sep) - lang = parts.pop(0).lower() - if not lang.isalpha(): - raise ValueError('expected only letters, got %r' % lang) - - script = territory = variant = None - if parts: - if len(parts[0]) == 4 and parts[0].isalpha(): - script = parts.pop(0).title() - - if parts: - if len(parts[0]) == 2 and parts[0].isalpha(): - territory = parts.pop(0).upper() - elif len(parts[0]) == 3 and parts[0].isdigit(): - territory = parts.pop(0) - - if parts: - if len(parts[0]) == 4 and parts[0][0].isdigit() or \ - len(parts[0]) >= 5 and parts[0][0].isalpha(): - variant = parts.pop() - - if parts: - raise ValueError('%r is not a valid locale identifier' % identifier) - - return lang, territory, script, variant - - -def get_locale_identifier(tup, sep='_'): - """The reverse of :func:`parse_locale`. It creates a locale identifier out - of a ``(language, territory, script, variant)`` tuple. Items can be set to - ``None`` and trailing ``None``\s can also be left out of the tuple. - - >>> get_locale_identifier(('de', 'DE', None, '1999')) - 'de_DE_1999' - - .. versionadded:: 1.0 - - :param tup: the tuple as returned by :func:`parse_locale`. - :param sep: the separator for the identifier. - """ - tup = tuple(tup[:4]) - lang, territory, script, variant = tup + (None,) * (4 - len(tup)) - return sep.join(filter(None, (lang, script, territory, variant))) |