You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			267 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			267 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			Python
		
	
"""
 | 
						|
    babel.messages.plurals
 | 
						|
    ~~~~~~~~~~~~~~~~~~~~~~
 | 
						|
 | 
						|
    Plural form definitions.
 | 
						|
 | 
						|
    :copyright: (c) 2013-2025 by the Babel Team.
 | 
						|
    :license: BSD, see LICENSE for more details.
 | 
						|
"""
 | 
						|
from __future__ import annotations
 | 
						|
 | 
						|
from babel.core import Locale, default_locale
 | 
						|
 | 
						|
# XXX: remove this file, duplication with babel.plural
 | 
						|
 | 
						|
 | 
						|
LC_CTYPE: str | None = default_locale('LC_CTYPE')
 | 
						|
 | 
						|
 | 
						|
PLURALS: dict[str, tuple[int, str]] = {
 | 
						|
    # Afar
 | 
						|
    # 'aa': (),
 | 
						|
    # Abkhazian
 | 
						|
    # 'ab': (),
 | 
						|
    # Avestan
 | 
						|
    # 'ae': (),
 | 
						|
    # Afrikaans - From Pootle's PO's
 | 
						|
    'af': (2, '(n != 1)'),
 | 
						|
    # Akan
 | 
						|
    # 'ak': (),
 | 
						|
    # Amharic
 | 
						|
    # 'am': (),
 | 
						|
    # Aragonese
 | 
						|
    # 'an': (),
 | 
						|
    # Arabic - From Pootle's PO's
 | 
						|
    'ar': (6, '(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=0 && n%100<=2 ? 4 : 5)'),
 | 
						|
    # Assamese
 | 
						|
    # 'as': (),
 | 
						|
    # Avaric
 | 
						|
    # 'av': (),
 | 
						|
    # Aymara
 | 
						|
    # 'ay': (),
 | 
						|
    # Azerbaijani
 | 
						|
    # 'az': (),
 | 
						|
    # Bashkir
 | 
						|
    # 'ba': (),
 | 
						|
    # Belarusian
 | 
						|
    'be': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'),
 | 
						|
    # Bulgarian - From Pootle's PO's
 | 
						|
    'bg': (2, '(n != 1)'),
 | 
						|
    # Bihari
 | 
						|
    # 'bh': (),
 | 
						|
    # Bislama
 | 
						|
    # 'bi': (),
 | 
						|
    # Bambara
 | 
						|
    # 'bm': (),
 | 
						|
    # Bengali - From Pootle's PO's
 | 
						|
    'bn': (2, '(n != 1)'),
 | 
						|
    # Tibetan - as discussed in private with Andrew West
 | 
						|
    'bo': (1, '0'),
 | 
						|
    # Breton
 | 
						|
    'br': (
 | 
						|
        6,
 | 
						|
        '(n==1 ? 0 : n%10==1 && n%100!=11 && n%100!=71 && n%100!=91 ? 1 : n%10==2 && n%100!=12 && n%100!=72 && '
 | 
						|
        'n%100!=92 ? 2 : (n%10==3 || n%10==4 || n%10==9) && n%100!=13 && n%100!=14 && n%100!=19 && n%100!=73 && '
 | 
						|
        'n%100!=74 && n%100!=79 && n%100!=93 && n%100!=94 && n%100!=99 ? 3 : n%1000000==0 ? 4 : 5)',
 | 
						|
    ),
 | 
						|
    # Bosnian
 | 
						|
    'bs': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'),
 | 
						|
    # Catalan - From Pootle's PO's
 | 
						|
    'ca': (2, '(n != 1)'),
 | 
						|
    # Chechen
 | 
						|
    # 'ce': (),
 | 
						|
    # Chamorro
 | 
						|
    # 'ch': (),
 | 
						|
    # Corsican
 | 
						|
    # 'co': (),
 | 
						|
    # Cree
 | 
						|
    # 'cr': (),
 | 
						|
    # Czech
 | 
						|
    'cs': (3, '((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2)'),
 | 
						|
    # Church Slavic
 | 
						|
    # 'cu': (),
 | 
						|
    # Chuvash
 | 
						|
    'cv': (1, '0'),
 | 
						|
    # Welsh
 | 
						|
    'cy': (5, '(n==1 ? 1 : n==2 ? 2 : n==3 ? 3 : n==6 ? 4 : 0)'),
 | 
						|
    # Danish
 | 
						|
    'da': (2, '(n != 1)'),
 | 
						|
    # German
 | 
						|
    'de': (2, '(n != 1)'),
 | 
						|
    # Divehi
 | 
						|
    # 'dv': (),
 | 
						|
    # Dzongkha
 | 
						|
    'dz': (1, '0'),
 | 
						|
    # Greek
 | 
						|
    'el': (2, '(n != 1)'),
 | 
						|
    # English
 | 
						|
    'en': (2, '(n != 1)'),
 | 
						|
    # Esperanto
 | 
						|
    'eo': (2, '(n != 1)'),
 | 
						|
    # Spanish
 | 
						|
    'es': (2, '(n != 1)'),
 | 
						|
    # Estonian
 | 
						|
    'et': (2, '(n != 1)'),
 | 
						|
    # Basque - From Pootle's PO's
 | 
						|
    'eu': (2, '(n != 1)'),
 | 
						|
    # Persian - From Pootle's PO's
 | 
						|
    'fa': (1, '0'),
 | 
						|
    # Finnish
 | 
						|
    'fi': (2, '(n != 1)'),
 | 
						|
    # French
 | 
						|
    'fr': (2, '(n > 1)'),
 | 
						|
    # Friulian - From Pootle's PO's
 | 
						|
    'fur': (2, '(n > 1)'),
 | 
						|
    # Irish
 | 
						|
    'ga': (5, '(n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4)'),
 | 
						|
    # Galician - From Pootle's PO's
 | 
						|
    'gl': (2, '(n != 1)'),
 | 
						|
    # Hausa - From Pootle's PO's
 | 
						|
    'ha': (2, '(n != 1)'),
 | 
						|
    # Hebrew
 | 
						|
    'he': (2, '(n != 1)'),
 | 
						|
    # Hindi - From Pootle's PO's
 | 
						|
    'hi': (2, '(n != 1)'),
 | 
						|
    # Croatian
 | 
						|
    'hr': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'),
 | 
						|
    # Hungarian
 | 
						|
    'hu': (1, '0'),
 | 
						|
    # Armenian - From Pootle's PO's
 | 
						|
    'hy': (1, '0'),
 | 
						|
    # Icelandic - From Pootle's PO's
 | 
						|
    'is': (2, '(n%10==1 && n%100!=11 ? 0 : 1)'),
 | 
						|
    # Italian
 | 
						|
    'it': (2, '(n != 1)'),
 | 
						|
    # Japanese
 | 
						|
    'ja': (1, '0'),
 | 
						|
    # Georgian - From Pootle's PO's
 | 
						|
    'ka': (1, '0'),
 | 
						|
    # Kongo - From Pootle's PO's
 | 
						|
    'kg': (2, '(n != 1)'),
 | 
						|
    # Khmer - From Pootle's PO's
 | 
						|
    'km': (1, '0'),
 | 
						|
    # Korean
 | 
						|
    'ko': (1, '0'),
 | 
						|
    # Kurdish - From Pootle's PO's
 | 
						|
    'ku': (2, '(n != 1)'),
 | 
						|
    # Lao - Another member of the Tai language family, like Thai.
 | 
						|
    'lo': (1, '0'),
 | 
						|
    # Lithuanian
 | 
						|
    'lt': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2)'),
 | 
						|
    # Latvian
 | 
						|
    'lv': (3, '(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2)'),
 | 
						|
    # Maltese - From Pootle's PO's
 | 
						|
    'mt': (4, '(n==1 ? 0 : n==0 || ( n%100>=1 && n%100<=10) ? 1 : (n%100>10 && n%100<20 ) ? 2 : 3)'),
 | 
						|
    # Norwegian Bokmål
 | 
						|
    'nb': (2, '(n != 1)'),
 | 
						|
    # Dutch
 | 
						|
    'nl': (2, '(n != 1)'),
 | 
						|
    # Norwegian Nynorsk
 | 
						|
    'nn': (2, '(n != 1)'),
 | 
						|
    # Norwegian
 | 
						|
    'no': (2, '(n != 1)'),
 | 
						|
    # Punjabi - From Pootle's PO's
 | 
						|
    'pa': (2, '(n != 1)'),
 | 
						|
    # Polish
 | 
						|
    'pl': (3, '(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'),
 | 
						|
    # Portuguese
 | 
						|
    'pt': (2, '(n != 1)'),
 | 
						|
    # Brazilian
 | 
						|
    'pt_BR': (2, '(n > 1)'),
 | 
						|
    # Romanian - From Pootle's PO's
 | 
						|
    'ro': (3, '(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2)'),
 | 
						|
    # Russian
 | 
						|
    'ru': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'),
 | 
						|
    # Slovak
 | 
						|
    'sk': (3, '((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2)'),
 | 
						|
    # Slovenian
 | 
						|
    'sl': (4, '(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3)'),
 | 
						|
    # Serbian - From Pootle's PO's
 | 
						|
    'sr': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'),
 | 
						|
    # Southern Sotho - From Pootle's PO's
 | 
						|
    'st': (2, '(n != 1)'),
 | 
						|
    # Swedish
 | 
						|
    'sv': (2, '(n != 1)'),
 | 
						|
    # Thai
 | 
						|
    'th': (1, '0'),
 | 
						|
    # Turkish
 | 
						|
    'tr': (1, '0'),
 | 
						|
    # Ukrainian
 | 
						|
    'uk': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'),
 | 
						|
    # Venda - From Pootle's PO's
 | 
						|
    've': (2, '(n != 1)'),
 | 
						|
    # Vietnamese - From Pootle's PO's
 | 
						|
    'vi': (1, '0'),
 | 
						|
    # Xhosa - From Pootle's PO's
 | 
						|
    'xh': (2, '(n != 1)'),
 | 
						|
    # Chinese - From Pootle's PO's (modified)
 | 
						|
    'zh': (1, '0'),
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
DEFAULT_PLURAL: tuple[int, str] = (2, '(n != 1)')
 | 
						|
 | 
						|
 | 
						|
class _PluralTuple(tuple):
 | 
						|
    """A tuple with plural information."""
 | 
						|
 | 
						|
    __slots__ = ()
 | 
						|
 | 
						|
    @property
 | 
						|
    def num_plurals(self) -> int:
 | 
						|
        """The number of plurals used by the locale."""
 | 
						|
        return self[0]
 | 
						|
 | 
						|
    @property
 | 
						|
    def plural_expr(self) -> str:
 | 
						|
        """The plural expression used by the locale."""
 | 
						|
        return self[1]
 | 
						|
 | 
						|
    @property
 | 
						|
    def plural_forms(self) -> str:
 | 
						|
        """The plural expression used by the catalog or locale."""
 | 
						|
        return f'nplurals={self[0]}; plural={self[1]};'
 | 
						|
 | 
						|
    def __str__(self) -> str:
 | 
						|
        return self.plural_forms
 | 
						|
 | 
						|
 | 
						|
def get_plural(locale: Locale | str | None = None) -> _PluralTuple:
 | 
						|
    """A tuple with the information catalogs need to perform proper
 | 
						|
    pluralization.  The first item of the tuple is the number of plural
 | 
						|
    forms, the second the plural expression.
 | 
						|
 | 
						|
    :param locale: the `Locale` object or locale identifier. Defaults to the system character type locale.
 | 
						|
 | 
						|
    >>> get_plural(locale='en')
 | 
						|
    (2, '(n != 1)')
 | 
						|
    >>> get_plural(locale='ga')
 | 
						|
    (5, '(n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4)')
 | 
						|
 | 
						|
    The object returned is a special tuple with additional members:
 | 
						|
 | 
						|
    >>> tup = get_plural("ja")
 | 
						|
    >>> tup.num_plurals
 | 
						|
    1
 | 
						|
    >>> tup.plural_expr
 | 
						|
    '0'
 | 
						|
    >>> tup.plural_forms
 | 
						|
    'nplurals=1; plural=0;'
 | 
						|
 | 
						|
    Converting the tuple into a string prints the plural forms for a
 | 
						|
    gettext catalog:
 | 
						|
 | 
						|
    >>> str(tup)
 | 
						|
    'nplurals=1; plural=0;'
 | 
						|
    """
 | 
						|
    locale = Locale.parse(locale or LC_CTYPE)
 | 
						|
    try:
 | 
						|
        tup = PLURALS[str(locale)]
 | 
						|
    except KeyError:
 | 
						|
        try:
 | 
						|
            tup = PLURALS[locale.language]
 | 
						|
        except KeyError:
 | 
						|
            tup = DEFAULT_PLURAL
 | 
						|
    return _PluralTuple(tup)
 |