jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/633292 )
Change subject: [IMPR] Add typing hints to i18n.py and plural.py ......................................................................
[IMPR] Add typing hints to i18n.py and plural.py
plural.py: - add typing hints - add a new plural_rule function which returns the PluralRule dict for a given lang or the default dict.
i18n.py: - add typing hints - rename code parameter of :extract_plural to lang - use plural_rule function - flatten input function
Change-Id: I5ba39767dbc13f69df11b72189f126661d370410 --- M pywikibot/i18n.py M pywikibot/plural.py 2 files changed, 41 insertions(+), 36 deletions(-)
Approvals: Hazard-SJ: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/i18n.py b/pywikibot/i18n.py index 287a86c..b9748f0 100644 --- a/pywikibot/i18n.py +++ b/pywikibot/i18n.py @@ -30,6 +30,7 @@ from collections import defaultdict from contextlib import suppress from textwrap import fill +from typing import List, Optional from warnings import warn
import pywikibot @@ -37,7 +38,7 @@ from pywikibot import __url__ from pywikibot import config2 as config from pywikibot.exceptions import Error -from pywikibot.plural import plural_rules +from pywikibot.plural import plural_rule from pywikibot.tools import ( deprecated, deprecated_args, issue_deprecation_warning, PYTHON_VERSION)
@@ -273,6 +274,7 @@ 'zh-min-nan': 'zh-min-nan', 'zh-tw': 'zh-classical', 'zh-yue': 'cdo'}) + _GROUP_NAME_TO_FALLBACKS = { '': [], 'aa': ['am'], @@ -358,7 +360,7 @@ 'cdo', 'zh', 'zh-hans', 'zh-tw', 'zh-cn', 'zh-classical', 'lzh']}
-def set_messages_package(package_name): +def set_messages_package(package_name: str): """Set the package name where i18n messages are located.""" global _messages_package_name global _messages_available @@ -366,15 +368,13 @@ _messages_available = None
-def messages_available(): +def messages_available() -> bool: """ Return False if there are no i18n messages available.
To determine if messages are available, it looks for the package name set using L{set_messages_package} for a message bundle called 'pywikibot' containing messages. - - @rtype: bool """ global _messages_available if _messages_available is not None: @@ -393,7 +393,7 @@ return True
-def _altlang(lang): +def _altlang(lang: str) -> List[str]: """Define fallback languages for particular languages.
If no translation is available to a specified language, translate() will @@ -406,9 +406,7 @@ This code is used by other translating methods below.
@param lang: The language code - @type lang: str @return: language codes - @rtype: list of str """ return _GROUP_NAME_TO_FALLBACKS[_LANG_TO_GROUP_NAME[lang]]
@@ -425,7 +423,7 @@
@cache -def _get_translation(lang, twtitle): +def _get_translation(lang: str, twtitle: str) -> Optional[str]: """ Return message of certain twtitle if exists.
@@ -443,15 +441,13 @@ return transdict.get(twtitle)
-def _extract_plural(code, message, parameters): +def _extract_plural(lang: str, message: str, parameters: Mapping) -> str: """Check for the plural variants in message and replace them.
@param message: the message to be replaced - @type message: str @param parameters: plural parameters passed from other methods @type parameters: Mapping of str to int @return: The message with the plural instances replaced - @rtype: str """ def static_plural_value(n): return rule['plural'] @@ -497,11 +493,9 @@ return plural_entries[index]
assert isinstance(parameters, Mapping), \ - 'parameters is not Mapping but {0}'.format(type(parameters)) - try: - rule = plural_rules[code] - except KeyError: - rule = plural_rules['_default'] + 'parameters is not Mapping but {}'.format(type(parameters)) + + rule = plural_rule(lang) plural_value = rule['plural'] if not callable(plural_value): assert rule['nplurals'] == 1 @@ -635,9 +629,11 @@
@deprecated_args(code='source') -def twtranslate( - source, twtitle, parameters=None, fallback=True, only_plural=False -): +def twtranslate(source, + twtitle: str, + parameters: Optional[Mapping] = None, + fallback: bool = True, + only_plural: bool = False) -> Optional[str]: r""" Translate a message using JSON files in messages_package_name.
@@ -698,7 +694,6 @@ plural instances. If this is False it will apply the parameters also to the resulting string. If this is True the placeholders must be manually applied afterwards. - @type only_plural: bool @raise IndexError: If the language supports and requires more plurals than defined for the given translation template. """ @@ -775,7 +770,8 @@
@deprecated('twtranslate', since='20151009', future_warning=True) @deprecated_args(code='source') -def twntranslate(source, twtitle, parameters=None): +def twntranslate(source, twtitle: str, + parameters: Optional[Mapping] = None) -> Optional[str]: """DEPRECATED: Get translated string for the key.""" if parameters is not None: parameters = _PluralMappingAlias(parameters) @@ -783,7 +779,7 @@
@deprecated_args(code='source') -def twhas_key(source, twtitle): +def twhas_key(source, twtitle: str) -> bool: """ Check if a message has a translation in the specified language code.
@@ -803,7 +799,7 @@ return transdict is not None
-def twget_keys(twtitle): +def twget_keys(twtitle: str) -> List[str]: """ Return all language codes for a special message.
@@ -827,7 +823,10 @@ if lang != 'qqq' and _get_translation(lang, twtitle)]
-def input(twtitle, parameters=None, password=False, fallback_prompt=None): +def input(twtitle: str, + parameters: Optional[Mapping] = None, + password: bool = False, + fallback_prompt: Optional[str] = None) -> str: """ Ask the user a question, return the user's answer.
@@ -838,17 +837,14 @@ @param parameters: The values which will be applied to the translated text @param password: Hides the user's input (for password entry) @param fallback_prompt: The English prompt if i18n is not available. - @rtype: str """ - if not messages_available(): - if not fallback_prompt: - raise TranslationError( - 'Unable to load messages package %s for bundle %s' - % (_messages_package_name, twtitle)) - else: - prompt = fallback_prompt - else: + if messages_available(): code = config.userinterface_lang - prompt = twtranslate(code, twtitle, parameters) + elif fallback_prompt: + prompt = fallback_prompt + else: + raise TranslationError( + 'Unable to load messages package {} for bundle {}' + .format(_messages_package_name, twtitle)) return pywikibot.input(prompt, password) diff --git a/pywikibot/plural.py b/pywikibot/plural.py index 70bc201..5dea038 100644 --- a/pywikibot/plural.py +++ b/pywikibot/plural.py @@ -5,6 +5,10 @@ # # Distributed under the terms of the MIT license. # +from typing import Callable, Dict, Union + +PluralRule = Dict[str, Union[int, Callable]] + plural_rules = { '_default': {'nplurals': 2, 'plural': lambda n: (n != 1)}, 'ar': {'nplurals': 6, 'plural': lambda n: @@ -77,7 +81,7 @@ 1 if (n % 100 == 2) else 2 if n % 100 in (3, 4) else 3}, -} +} # type: Dict[str, PluralRule]
plural_rules.update( dict.fromkeys( @@ -99,3 +103,8 @@ 0 if n % 10 == 1 and n % 100 != 11 else 1 if (2 <= (n % 10) <= 4) and (n % 100 < 10 or n % 100 >= 20) else 2})) + + +def plural_rule(lang: str) -> PluralRule: + """Return the plural rule for a given lang.""" + return plural_rules.get(lang, plural_rules['_default'])