jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/323518 )
Change subject: login.py: Support specifying '*' for 'family' in user-config.py ......................................................................
login.py: Support specifying '*' for 'family' in user-config.py
- __init__.py: - Check the username and sysopname of family '*' if none is found in the specified family. - login_tests.py: - Use "import unittest.mock" instead of "import mock" when available. (mock has been part of the standard library since python 3.3) - FakeConfig.usernames should be a defaultdict. - Add a test for the new funtionality of LoginManager.
Bug: T120334 Change-Id: I23749a4035c7d27186a92e67c6d6206e10326ff0 --- M pywikibot/__init__.py M pywikibot/config2.py M pywikibot/login.py M tests/login_tests.py 4 files changed, 49 insertions(+), 17 deletions(-)
Approvals: jenkins-bot: Verified Sn1per: Looks good to me, approved
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py index 42b93ec..c68fcfe 100644 --- a/pywikibot/__init__.py +++ b/pywikibot/__init__.py @@ -825,13 +825,16 @@
interface = interface or fam.interface(code)
- # config.usernames is initialised with a dict for each family name + # config.usernames is initialised with a defaultdict for each family name family_name = str(fam) - if family_name in config.usernames: - user = user or config.usernames[family_name].get(code) \ - or config.usernames[family_name].get('*') - sysop = sysop or config.sysopnames[family_name].get(code) \ - or config.sysopnames[family_name].get('*') + + code_to_user = config.usernames['*'].copy() + code_to_user.update(config.usernames[family_name]) + user = user or code_to_user.get(code) or code_to_user.get('*') + + code_to_sysop = config.sysopnames['*'].copy() + code_to_sysop.update(config.sysopnames[family_name]) + sysop = sysop or code_to_sysop.get(code) or code_to_sysop.get('*')
if not isinstance(interface, type): # If it isnt a class, assume it is a string diff --git a/pywikibot/config2.py b/pywikibot/config2.py index 9451eb5..e1ab7dc 100644 --- a/pywikibot/config2.py +++ b/pywikibot/config2.py @@ -116,6 +116,7 @@ # If you have a unique username for all languages of a family, # you can use '*' # usernames['wikibooks']['*'] = 'mySingleUsername' +# You may use '*' for family name in a similar manner. # # If you have a sysop account on some wikis, this will be used to delete pages # or to edit locked pages if you add such lines to your diff --git a/pywikibot/login.py b/pywikibot/login.py index e110c47..01ebf6b 100644 --- a/pywikibot/login.py +++ b/pywikibot/login.py @@ -91,9 +91,12 @@ if user: self.username = user elif sysop: + config_names = config.sysopnames + family_sysopnames = ( + config_names[self.site.family.name] or config_names['*'] + ) + self.username = family_sysopnames.get(self.site.code, None) try: - family_sysopnames = config.sysopnames[self.site.family.name] - self.username = family_sysopnames.get(self.site.code, None) self.username = self.username or family_sysopnames['*'] except KeyError: raise NoUsername(u"""\ @@ -104,11 +107,14 @@ % {'fam_name': self.site.family.name, 'wiki_code': self.site.code}) else: + config_names = config.usernames + family_usernames = ( + config_names[self.site.family.name] or config_names['*'] + ) + self.username = family_usernames.get(self.site.code, None) try: - family_usernames = config.usernames[self.site.family.name] - self.username = family_usernames.get(self.site.code, None) self.username = self.username or family_usernames['*'] - except: + except KeyError: raise NoUsername(u"""\ ERROR: Username for %(fam_name)s:%(wiki_code)s is undefined. If you have an account for that site, please add a line to user-config.py: diff --git a/tests/login_tests.py b/tests/login_tests.py index 9c63bc3..b40ea7c 100644 --- a/tests/login_tests.py +++ b/tests/login_tests.py @@ -13,8 +13,13 @@
__version__ = '$Id$' # -import mock +from collections import defaultdict +try: + import unittest.mock as mock +except ImportError: + import mock
+from pywikibot.exceptions import NoUsername from pywikibot.login import LoginManager
from tests.aspects import ( @@ -35,17 +40,15 @@ code = "~FakeCode" family = FakeFamily
+ FakeUsername = "~FakeUsername"
class FakeConfig(object): """Mock."""
- usernames = { - FakeFamily.name: { - FakeSite.code: FakeUsername - } - } + usernames = defaultdict(dict) + usernames[FakeFamily.name] = {FakeSite.code: FakeUsername}
@mock.patch("pywikibot.Site", FakeSite) @@ -62,6 +65,24 @@ self.assertEqual(obj.username, FakeUsername) self.assertEqual(obj.login_name, FakeUsername) self.assertIsNone(obj.password) + + @mock.patch.dict( + FakeConfig.usernames, + {'*': {'*': FakeUsername}}, + clear=True + ) + def test_star_family(self): + """Test LoginManager with '*' as family.""" + lm = LoginManager() + self.assertEqual(lm.username, FakeUsername) + + del FakeConfig.usernames['*'] + FakeConfig.usernames['*']['en'] = FakeUsername + self.assertRaises(NoUsername, LoginManager) + + FakeConfig.usernames['*']['*'] = FakeUsername + lm = LoginManager() + self.assertEqual(lm.username, FakeUsername)
@mock.patch("pywikibot.Site", FakeSite) @@ -166,5 +187,6 @@ """, '~FakePassword') self.assertEqual(obj.login_name, "~FakeUsername@~FakeSuffix")
+ if __name__ == '__main__': # pragma: no cover unittest.main()
pywikibot-commits@lists.wikimedia.org