jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/767200 )
Change subject: [IMPR] allow True/False/1/0 as -cosmeticchanges -cc value ......................................................................
[IMPR] allow True/False/1/0 as -cosmeticchanges -cc value
Currently -cc can be only switched but the current setting is deeply hidden in (user-)config.py. Enable direct setting like -cc:True or -cc:False respectivly -cc:1 or -cc:0 and some other variants.
- add a reimplementation fo distutils.util.strtobool due to PEP 632 - use strtobool to determine the -cc setting - add tests for tools string functions
Change-Id: I106e38becfdfe881c93e96e8535d931a20288331 --- M pywikibot/bot.py M pywikibot/tools/__init__.py M tests/tools_tests.py 3 files changed, 62 insertions(+), 5 deletions(-)
Approvals: Mpaa: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/bot.py b/pywikibot/bot.py index 16a02bf..1bd974d 100644 --- a/pywikibot/bot.py +++ b/pywikibot/bot.py @@ -85,7 +85,6 @@ 'WikidataBot', )
- import atexit import codecs import configparser @@ -177,6 +176,7 @@ PYTHON_VERSION, deprecated, issue_deprecation_warning, + strtobool, ) from pywikibot.tools._logging import LoggingFormatter from pywikibot.tools.formatter import color_format @@ -248,9 +248,13 @@ -verbose Have the bot provide additional console output that may be -v useful in debugging.
--cosmeticchanges Toggles the cosmetic_changes setting made in config.py or --cc user-config.py to its inverse and overrules it. All other - settings and restrictions are untouched. +-cosmeticchanges Toggles the cosmetic_changes setting made in config.py +-cc or user-config.py to its inverse and overrules it. All + other settings and restrictions are untouched. The + setting may also be given directly like `-cc:True`; + accepted values for the option are `1`, `yes`, `true`, + `on`, `y`, `t` for True and `0`, `no`, `false`, `off`, + `n`, `f` for False. Values are case-insensitive.
-simulate Disables writing to the server. Useful for testing and debugging of new code (if given, doesn't do any real @@ -899,7 +903,8 @@ elif option == '-nolog': config.log = [] elif option in ('-cosmeticchanges', '-cc'): - config.cosmetic_changes = not config.cosmetic_changes + config.cosmetic_changes = (strtobool(value) if value + else not config.cosmetic_changes) output('NOTE: option cosmetic_changes is {}\n' .format(config.cosmetic_changes)) elif option == '-simulate': diff --git a/pywikibot/tools/__init__.py b/pywikibot/tools/__init__.py index 9e19104..323ddf5 100644 --- a/pywikibot/tools/__init__.py +++ b/pywikibot/tools/__init__.py @@ -369,6 +369,26 @@ return (_first_upper_exception(first) or first.upper()) + string[1:]
+def strtobool(val: str) -> bool: + """Convert a string representation of truth to True or False. + + This is a reimplementation of distutils.util.strtobool due to + :pep:`632#Migration Advice` + + .. versionadded:: 7.1 + + :param val: True values are 'y', 'yes', 't', 'true', 'on', and '1'; + false values are 'n', 'no', 'f', 'false', 'off', and '0'. + :raises ValueError: `val` is not a valid truth value + """ + val = val.lower() + if val in ('y', 'yes', 't', 'true', 'on', '1'): + return True + if val in ('n', 'no', 'f', 'false', 'off', '0'): + return False + raise ValueError('invalid truth value {!r}'.format(val)) + + def normalize_username(username) -> Optional[str]: """Normalize the username.
diff --git a/tests/tools_tests.py b/tests/tools_tests.py index 30ec3b7..bc7751b 100644 --- a/tests/tools_tests.py +++ b/tests/tools_tests.py @@ -892,6 +892,38 @@ self.assertFalse(has_module('setuptools', '99999'))
+class TestStringFunctions(TestCase): + + """Unit test class for string functions.""" + + net = False + + def test_first_lower(self): + """Test first_lower function.""" + self.assertEqual(tools.first_lower('Foo Bar'), 'foo Bar') + self.assertEqual(tools.first_lower('FOO BAR'), 'fOO BAR') + self.assertEqual(tools.first_lower(''), '') + + def test_first_upper(self): + """Test first_upper function.""" + self.assertEqual(tools.first_upper('foo bar'), 'Foo bar') + self.assertEqual(tools.first_upper('foo BAR'), 'Foo BAR') + self.assertEqual(tools.first_upper(''), '') + self.assertEqual(tools.first_upper('ß'), 'ß') + self.assertNotEqual(tools.first_upper('ß'), str.upper('ß')) + + def test_strtobool(self): + """Test strtobool function.""" + for string in ('True', 'TRUE', 'true', 'T', 'Yes', 'y', 'on', '1'): + with self.subTest(truth=string): + self.assertTrue(tools.strtobool(string)) + for string in ('False', 'F', 'No', 'n', 'oFF', '0'): + with self.subTest(falsity=string): + self.assertFalse(tools.strtobool(string)) + with self.assertRaises(ValueError): + tools.strtobool('okay') + + if __name__ == '__main__': # pragma: no cover with suppress(SystemExit): unittest.main()
pywikibot-commits@lists.wikimedia.org