jenkins-bot merged this change.

View Change

Approvals: Mpaa: Looks good to me, approved jenkins-bot: Verified
[IMPR] Provide mediawiki_messages for foreign language codes

mediawiki_messages can be retrieved with language code.
This patch enables messages to be independend from site.lang
by giving a lang parameter to mediawiki message methods.

- use a new site._mw_msg_cache cache which holds all messages
independend from a special Site object
- remove the all message fetching behaviour of '*' key
which was deprecated 5 years ago due to T111479
- add some test for the new behaviour
- use subTest for the test method
- remove tests for deprcated all message fetching with '*'

Change-Id: I24863cbf369a007404509a7bee19b4a36f9df881
---
M pywikibot/site.py
M tests/site_tests.py
2 files changed, 90 insertions(+), 63 deletions(-)

diff --git a/pywikibot/site.py b/pywikibot/site.py
index c2d20cb..c725868 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -30,7 +30,7 @@
from collections.abc import Iterable, Container, Mapping
except ImportError: # Python 2.7
from collections import Iterable, Container, Mapping
-from collections import namedtuple
+from collections import defaultdict, namedtuple
from enum import IntEnum
from warnings import warn

@@ -1845,6 +1845,9 @@
super(RemovedSite, self).__init__(code, fam, user)


+_mw_msg_cache = defaultdict(dict)
+
+
class APISite(BaseSite):

"""
@@ -2376,81 +2379,86 @@
except KeyError:
return False

- def mediawiki_messages(self, keys):
+ def mediawiki_messages(self, keys, lang=None):
"""Fetch the text of a set of MediaWiki messages.

- If keys is '*' or ['*'], all messages will be fetched. (deprecated)
-
The returned dict uses each key to store the associated message.

@see: U{https://www.mediawiki.org/wiki/API:Allmessages}

@param keys: MediaWiki messages to fetch
- @type keys: set of str, '*' or ['*']
+ @type keys: iterable of str
+ @param lang: a language code, default is self.lang
+ @type lang: str or None

@rtype dict
"""
- if keys == '*' or keys == ['*']:
- issue_deprecation_warning('mediawiki_messages("*")',
- 'specific messages', since='20150905')
-
- if not all(_key in self._msgcache for _key in keys):
+ amlang = lang or self.lang
+ if not all(amlang in _mw_msg_cache
+ and _key in _mw_msg_cache[amlang] for _key in keys):
parameters = {'meta': 'allmessages',
'ammessages': keys,
- 'amlang': self.lang,
+ 'amlang': amlang,
}
msg_query = api.QueryGenerator(site=self, parameters=parameters)

for msg in msg_query:
if 'missing' not in msg:
- self._msgcache[msg['name']] = msg['*']
+ _mw_msg_cache[amlang][msg['name']] = msg['*']

- # Return all messages
- if keys == '*' or keys == ['*']:
- return self._msgcache
+ # Check requested keys
+ result = {}
+ for key in keys:
+ try:
+ result[key] = _mw_msg_cache[amlang][key]
+ except KeyError:
+ raise KeyError("No message '{}' found for lang '{}'"
+ .format(key, amlang))
else:
- # Check requested keys
- for key in keys:
- if key not in self._msgcache:
- raise KeyError("Site %s has no message '%s'"
- % (self, key))
+ return result

- return {_key: self._msgcache[_key] for _key in keys}
+ return {_key: _mw_msg_cache[amlang][_key] for _key in keys}

@deprecated_args(forceReload=None)
- def mediawiki_message(self, key):
+ def mediawiki_message(self, key, lang=None):
"""Fetch the text for a MediaWiki message.

@param key: name of MediaWiki message
@type key: str
+ @param lang: a language code, default is self.lang
+ @type lang: str or None

@rtype unicode
"""
- return self.mediawiki_messages([key])[key]
+ return self.mediawiki_messages([key], lang=lang)[key]

- def has_mediawiki_message(self, key):
+ def has_mediawiki_message(self, key, lang=None):
"""Determine if the site defines a MediaWiki message.

@param key: name of MediaWiki message
@type key: str
+ @param lang: a language code, default is self.lang
+ @type lang: str or None

@rtype: bool
"""
- return self.has_all_mediawiki_messages([key])
+ return self.has_all_mediawiki_messages([key], lang=lang)

- def has_all_mediawiki_messages(self, keys):
+ def has_all_mediawiki_messages(self, keys, lang=None):
"""Confirm that the site defines a set of MediaWiki messages.

@param keys: names of MediaWiki messages
- @type keys: set of str
+ @type keys: iterable of str
+ @param lang: a language code, default is self.lang
+ @type lang: str or None

@rtype: bool
"""
try:
- self.mediawiki_messages(keys)
- return True
+ self.mediawiki_messages(keys, lang=lang)
except KeyError:
return False
+ return True

@property
def months_names(self):
diff --git a/tests/site_tests.py b/tests/site_tests.py
index 279b0f8..6fabc24 100644
--- a/tests/site_tests.py
+++ b/tests/site_tests.py
@@ -186,17 +186,6 @@
self.assertOneDeprecationParts('Calling the namespaces property',
'it directly')

- def test_messages_star(self):
- """Test that fetching all messages is deprecated."""
- # Load all messages and check that '*' is not a valid key.
- self.assertEqual(self.site.mediawiki_messages('*'),
- {'*': 'dummy entry'})
- self.assertOneDeprecationParts('mediawiki_messages("*")',
- 'specific messages')
- self.assertEqual(self.site.mediawiki_messages(['hello']),
- {'hello': 'world'})
- self.assertNoDeprecation()
-

class TestBaseSiteProperties(TestCase):

@@ -397,37 +386,67 @@
"""Test MediaWiki: messages."""
mysite = self.get_site()
for msg in ('about', 'aboutpage', 'aboutsite', 'accesskey-n-portal'):
- self.assertTrue(mysite.has_mediawiki_message(msg))
- self.assertIsInstance(mysite.mediawiki_message(msg), basestring)
- self.assertFalse(mysite.has_mediawiki_message('nosuchmessage'))
- self.assertRaises(KeyError, mysite.mediawiki_message, 'nosuchmessage')
+ with self.subTest(message=msg, lang=mysite.lang):
+ self.assertTrue(mysite.has_mediawiki_message(msg))
+ self.assertIsInstance(mysite.mediawiki_message(msg),
+ basestring)
+ self.assertEqual(
+ mysite.mediawiki_message(msg),
+ mysite.mediawiki_message(msg, lang=mysite.lang))
+
+ with self.subTest(message=msg, lang='de'):
+ self.assertTrue(mysite.has_mediawiki_message(msg, lang='de'))
+ self.assertIsInstance(mysite.mediawiki_message(msg, lang='de'),
+ basestring)
+
+ with self.subTest(message='nosuchmessage'):
+ self.assertFalse(mysite.has_mediawiki_message('nosuchmessage'))
+ self.assertRaises(KeyError, mysite.mediawiki_message,
+ 'nosuchmessage')

msg = ('about', 'aboutpage')
- about_msgs = self.site.mediawiki_messages(msg)
- self.assertIsInstance(mysite.mediawiki_messages(msg), dict)
- self.assertTrue(mysite.mediawiki_messages(msg))
- self.assertLength(about_msgs, 2)
- self.assertIn(msg[0], about_msgs)
+ with self.subTest(messages=msg):
+ about_msgs = self.site.mediawiki_messages(msg)
+ self.assertIsInstance(mysite.mediawiki_messages(msg), dict)
+ self.assertTrue(mysite.mediawiki_messages(msg))
+ self.assertLength(about_msgs, 2)
+ self.assertIn(msg[0], about_msgs)
+
+ months = ['january', 'february', 'march', 'april', 'may_long',
+ 'june', 'july', 'august', 'september', 'october',
+ 'november', 'december']
+ with self.subTest(messages=months, lang1='af', lang2='an'):
+ self.assertLength(mysite.mediawiki_messages(months, 'af'), 12)
+ self.assertLength(mysite.mediawiki_messages(months, 'an'), 12)
+ self.assertNotEqual(mysite.mediawiki_messages(months, 'af'),
+ mysite.mediawiki_messages(months, 'an'))

# mediawiki_messages must be given a list; using a string will split it
- self.assertRaises(KeyError, self.site.mediawiki_messages, 'about')
+ with self.subTest(messages='about'):
+ self.assertRaises(KeyError, self.site.mediawiki_messages, 'about')

msg = ('nosuchmessage1', 'about', 'aboutpage', 'nosuchmessage')
- self.assertFalse(mysite.has_all_mediawiki_messages(msg))
- self.assertRaises(KeyError, mysite.mediawiki_messages, msg)
+ with self.subTest(messages=msg):
+ self.assertFalse(mysite.has_all_mediawiki_messages(msg))
+ self.assertRaises(KeyError, mysite.mediawiki_messages, msg)

- self.assertIsInstance(mysite.server_time(), pywikibot.Timestamp)
- ts = mysite.getcurrenttimestamp()
- self.assertIsInstance(ts, basestring)
- self.assertRegex(ts, r'(19|20)\d\d[0-1]\d[0-3]\d[0-2]\d[0-5]\d[0-5]\d')
+ with self.subTest(test='server_time'):
+ self.assertIsInstance(mysite.server_time(), pywikibot.Timestamp)
+ ts = mysite.getcurrenttimestamp()
+ self.assertIsInstance(ts, basestring)
+ self.assertRegex(
+ ts, r'(19|20)\d\d[0-1]\d[0-3]\d[0-2]\d[0-5]\d[0-5]\d')

- self.assertIsInstance(mysite.months_names, list)
- self.assertLength(mysite.months_names, 12)
- self.assertTrue(all(isinstance(month, tuple)
- for month in mysite.months_names))
- for month in mysite.months_names:
- self.assertLength(month, 2)
- self.assertEqual(mysite.list_to_text(('pywikibot',)), 'pywikibot')
+ with self.subTest(test='months_names'):
+ self.assertIsInstance(mysite.months_names, list)
+ self.assertLength(mysite.months_names, 12)
+ self.assertTrue(all(isinstance(month, tuple)
+ for month in mysite.months_names))
+ for month in mysite.months_names:
+ self.assertLength(month, 2)
+
+ with self.subTest(test='list_to_text'):
+ self.assertEqual(mysite.list_to_text(('pywikibot',)), 'pywikibot')

def test_english_specific_methods(self):
"""Test Site methods using English specific inputs and outputs."""

To view, visit change 571927. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I24863cbf369a007404509a7bee19b4a36f9df881
Gerrit-Change-Number: 571927
Gerrit-PatchSet: 7
Gerrit-Owner: Xqt <info@gno.de>
Gerrit-Reviewer: Mpaa <mpaa.wiki@gmail.com>
Gerrit-Reviewer: Xqt <info@gno.de>
Gerrit-Reviewer: jenkins-bot (75)