jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/616047 )
Change subject: [4.0] replace StringTypes with str in several scripts ......................................................................
[4.0] replace StringTypes with str in several scripts
Change-Id: Ia3c8607bf13962d7ffcb169cf8963bee30e02e6d --- M pywikibot/i18n.py M pywikibot/textlib.py M pywikibot/tools/djvu.py M tests/archivebot_tests.py M tests/compat2core_tests.py M tests/family_tests.py M tests/i18n_tests.py M tests/user_tests.py 8 files changed, 79 insertions(+), 130 deletions(-)
Approvals: D3r1ck01: Looks good to me, but someone else must approve Zhuyifei1999: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/i18n.py b/pywikibot/i18n.py index cff155a..9779f83 100644 --- a/pywikibot/i18n.py +++ b/pywikibot/i18n.py @@ -21,18 +21,13 @@ # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals - import json import os import pkgutil import re
+from collections.abc import Mapping from collections import defaultdict -try: - from collections.abc import Mapping -except ImportError: # Python 2.7 - from collections import Mapping from textwrap import fill from warnings import warn
@@ -43,7 +38,7 @@ from pywikibot.exceptions import Error from pywikibot.plural import plural_rules from pywikibot.tools import ( - deprecated, deprecated_args, issue_deprecation_warning, StringTypes) + deprecated, deprecated_args, issue_deprecation_warning)
PLURAL_PATTERN = r'{{PLURAL:(?:%()?([^)]*?)(?:)d)?|(.*?)}}'
@@ -526,9 +521,10 @@ """
def __init__(self, source): - if isinstance(source, StringTypes): - source = int(source) - self.source = source + if isinstance(source, str): + self.source = int(source) + else: + self.source = source self.index = -1 super(_PluralMappingAlias, self).__init__()
@@ -536,13 +532,13 @@ self.index += 1 if isinstance(self.source, dict): return int(self.source[key]) - elif isinstance(self.source, (tuple, list)): + + if isinstance(self.source, (tuple, list)): if self.index < len(self.source): return int(self.source[self.index]) raise ValueError('Length of parameter does not match PLURAL ' 'occurrences.') - else: - return self.source + return self.source
def __iter__(self): raise NotImplementedError diff --git a/pywikibot/textlib.py b/pywikibot/textlib.py index 9c74eb2..dfd8486 100644 --- a/pywikibot/textlib.py +++ b/pywikibot/textlib.py @@ -11,12 +11,12 @@ # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals - import datetime import re
+from collections.abc import Sequence from collections import OrderedDict, namedtuple +from html.parser import HTMLParser
import pywikibot from pywikibot.exceptions import InvalidTitle, SiteDefinitionError @@ -25,20 +25,9 @@ deprecate_arg, deprecated, DeprecatedRegex, - StringTypes, - UnicodeType, issue_deprecation_warning, - PY2, )
-if not PY2: - from collections.abc import Sequence - from html.parser import HTMLParser -else: - from collections import Sequence - from future_builtins import zip - from HTMLParser import HTMLParser - try: import mwparserfromhell except ImportError as e: @@ -203,7 +192,7 @@ else: raise ValueError( '{0} is not a template Page object'.format(template)) - elif isinstance(template, StringTypes): + elif isinstance(template, str): old = template else: raise ValueError( @@ -311,7 +300,7 @@ result = []
for exc in keys: - if isinstance(exc, UnicodeType): + if isinstance(exc, str): # assume the string is a reference to a standard regex above, # which may not yet have a site specific re compiled. if exc in _regex_cache: @@ -373,11 +362,8 @@ @type count: int """ # if we got a string, compile it as a regular expression - if isinstance(old, UnicodeType): - if caseInsensitive: - old = re.compile(old, re.IGNORECASE | re.UNICODE) - else: - old = re.compile(old) + if isinstance(old, str): + old = re.compile(old, flags=re.IGNORECASE if caseInsensitive else 0)
# early termination if not relevant if not old.search(text): @@ -660,7 +646,7 @@ """Return the link from source when it's a Page otherwise itself.""" if isinstance(source, pywikibot.Page): return source._link - elif isinstance(source, UnicodeType): + elif isinstance(source, str): return pywikibot.Link(source, site) else: return source @@ -694,7 +680,7 @@ 'The original value must be either basestring, Link or Page ' 'but is "{0}"'.format(type(replace_list[0]))) if replace_list[1] is not False and replace_list[1] is not None: - if isinstance(replace_list[1], UnicodeType): + if isinstance(replace_list[1], str): replace_list[1] = pywikibot.Page(site, replace_list[1]) check_classes(replace_list[0]) replace = replace_callable @@ -778,10 +764,10 @@
if new_link is False: # unlink - we remove the section if there's any - assert isinstance(new_label, UnicodeType), \ - 'link text must be unicode.' + assert isinstance(new_label, str), \ + 'link text must be str.' new_link = new_label - if isinstance(new_link, UnicodeType): + if isinstance(new_link, str): # Nothing good can come out of the fact that bytes is returned so # force unicode text = text[:start] + new_link + text[end:] @@ -1550,7 +1536,7 @@
catLinks = [] for category in categories: - if isinstance(category, UnicodeType): + if isinstance(category, str): category, separator, sortKey = category.strip('[]').partition('|') sortKey = sortKey if separator else None # whole word if no ":" is present @@ -1698,14 +1684,14 @@ if not implicit_parameter: value = param.value.strip() else: - value = UnicodeType(param.value) + value = str(param.value) else: - key = UnicodeType(param.name) - value = UnicodeType(param.value) + key = str(param.name) + value = str(param.value)
params[key] = value
- result.append((UnicodeType(template.name.strip()), params)) + result.append((template.name.strip(), params)) return result
@@ -1831,7 +1817,7 @@ param_name, param_val = param.split('=', 1) implicit_parameter = False else: - param_name = UnicodeType(numbered_param) + param_name = str(numbered_param) param_val = param numbered_param += 1 implicit_parameter = True diff --git a/pywikibot/tools/djvu.py b/pywikibot/tools/djvu.py index 8f375ea..cf9f254 100644 --- a/pywikibot/tools/djvu.py +++ b/pywikibot/tools/djvu.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- """Wrapper around djvulibre to access djvu files properties and content.""" # -# (C) Pywikibot team, 2015-2019 +# (C) Pywikibot team, 2015-2020 # # Distributed under the terms of the MIT license. # @@ -15,11 +15,7 @@
import pywikibot
-from pywikibot.tools import ( - deprecated, deprecated_args, - StringTypes, - UnicodeType, -) +from pywikibot.tools import deprecated, deprecated_args
def _call_cmd(args, lib='djvulibre'): @@ -27,7 +23,7 @@ Tiny wrapper around subprocess.Popen().
@param args: same as Popen() - @type args: typing.Sequence[string] + @type args: str or typing.Sequence[string]
@param library: library to be logged in logging messages @type library: str @@ -39,10 +35,9 @@ @return: returns a tuple (res, stdoutdata), where res is True if dp.returncode != 0 else False """ - if not isinstance(args, StringTypes): - # upcast if any param in sequence args is not in StringTypes - args = [str(a) if not isinstance(a, StringTypes) else a for a in args] - cmd = ' '.join(args) + if not isinstance(args, str): + # upcast any param in sequence args to str + cmd = ' '.join(str(a) for a in args) else: cmd = args
@@ -59,7 +54,7 @@ return (True, stdoutdata)
-class DjVuFile(object): +class DjVuFile:
"""Wrapper around djvulibre to access djvu files properties and content.
@@ -72,12 +67,11 @@ """
@deprecated_args(file_djvu='file') - def __init__(self, file): + def __init__(self, file: str): """ Initializer.
@param file: filename (including path) to djvu file - @type file: str """ self._filename = file filename = os.path.expanduser(file) @@ -93,28 +87,15 @@ self._pat_info = re.compile( r'DjVu.*?(?P<size>\d+x\d+).*?(?P<dpi>\d+) dpi')
- def __repr__(self): + def __repr__(self) -> str: """Return a more complete string representation.""" - filename = self._filename - if not isinstance(filename, str): - filename = self._filename.encode('utf-8') return str("{0}.{1}('{2}')").format(self.__module__, self.__class__.__name__, - filename) + self._filename)
- def __str__(self): + def __str__(self) -> str: """Return a string representation.""" - filename = self._filename - if not isinstance(filename, str): - filename = self._filename.encode('utf-8') - return str("{0}('{1}')").format(self.__class__.__name__, filename) - - def __unicode__(self): - """Return a unicode representation.""" - _str = self.__str__() - if not isinstance(_str, UnicodeType): - _str = _str.decode('utf-8') - return _str + return str("{}('{}')").format(self.__class__.__name__, self._filename)
@property @deprecated('DjVuFile.file', since='2010222', future_warning=True) diff --git a/tests/archivebot_tests.py b/tests/archivebot_tests.py index c8b5bc3..32ffc39 100644 --- a/tests/archivebot_tests.py +++ b/tests/archivebot_tests.py @@ -1,19 +1,18 @@ # -*- coding: utf-8 -*- """Tests for archivebot scripts.""" # -# (C) Pywikibot team, 2014-2018 +# (C) Pywikibot team, 2014-2020 # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals - +from contextlib import suppress from datetime import datetime, timedelta
import pywikibot import pywikibot.page
from pywikibot.textlib import TimeStripper -from pywikibot.tools import suppress_warnings, StringTypes as basestring +from pywikibot.tools import suppress_warnings
from scripts import archivebot
@@ -139,7 +138,7 @@ self.assertIsInstance(talk.archives, dict) self.assertIsInstance(talk.archived_threads, int) self.assertTrue(talk.archiver is None) - self.assertIsInstance(talk.header, basestring) + self.assertIsInstance(talk.header, str) self.assertIsInstance(talk.timestripper, TimeStripper)
self.assertIsInstance(talk.threads, list) @@ -150,14 +149,14 @@
for thread in talk.threads: self.assertIsInstance(thread, archivebot.DiscussionThread) - self.assertIsInstance(thread.title, basestring) + self.assertIsInstance(thread.title, str) self.assertIsInstance(thread.now, datetime) self.assertEqual(thread.now, talk.now) self.assertIsInstance(thread.ts, TimeStripper) self.assertEqual(thread.ts, talk.timestripper) - self.assertIsInstance(thread.code, basestring) + self.assertIsInstance(thread.code, str) self.assertEqual(thread.code, talk.timestripper.site.code) - self.assertIsInstance(thread.content, basestring) + self.assertIsInstance(thread.content, str) try: self.assertIsInstance(thread.timestamp, datetime) except AssertionError: @@ -204,7 +203,7 @@ self.assertIsInstance(talk.archives, dict) self.assertIsInstance(talk.archived_threads, int) self.assertTrue(talk.archiver is None) - self.assertIsInstance(talk.header, basestring) + self.assertIsInstance(talk.header, str) self.assertIsInstance(talk.timestripper, TimeStripper)
self.assertIsInstance(talk.threads, list) @@ -216,14 +215,14 @@
for thread in talk.threads: self.assertIsInstance(thread, archivebot.DiscussionThread) - self.assertIsInstance(thread.title, basestring) + self.assertIsInstance(thread.title, str) self.assertIsInstance(thread.now, datetime) self.assertEqual(thread.now, talk.now) self.assertIsInstance(thread.ts, TimeStripper) self.assertEqual(thread.ts, talk.timestripper) - self.assertIsInstance(thread.code, basestring) + self.assertIsInstance(thread.code, str) self.assertEqual(thread.code, talk.timestripper.site.code) - self.assertIsInstance(thread.content, basestring) + self.assertIsInstance(thread.content, str) try: self.assertIsInstance(thread.timestamp, datetime) except AssertionError: @@ -363,7 +362,5 @@
if __name__ == '__main__': # pragma: no cover - try: + with suppress(SystemExit): unittest.main() - except SystemExit: - pass diff --git a/tests/compat2core_tests.py b/tests/compat2core_tests.py index 122c8c0..6147375 100644 --- a/tests/compat2core_tests.py +++ b/tests/compat2core_tests.py @@ -1,14 +1,10 @@ # -*- coding: utf-8 -*- """compat2core.py tests.""" # -# (C) Pywikibot team, 2019 +# (C) Pywikibot team, 2019-2020 # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals - -from pywikibot.tools import StringTypes - import scripts.maintenance.compat2core as c2c
from tests.aspects import unittest, TestCase @@ -24,15 +20,15 @@ """Test compat2core replacements.""" for item in c2c.replacements: self.assertLength(item, 2) - self.assertIsInstance(item[0], StringTypes) - self.assertIsInstance(item[1], StringTypes) + self.assertIsInstance(item[0], str) + self.assertIsInstance(item[1], str)
def test_warnings(self): """Test compat2core warnings.""" for item in c2c.warnings: self.assertLength(item, 2) - self.assertIsInstance(item[0], StringTypes) - self.assertIsInstance(item[1], StringTypes) + self.assertIsInstance(item[0], str) + self.assertIsInstance(item[1], str)
def test_bot(self): """Test compat2core bot.""" diff --git a/tests/family_tests.py b/tests/family_tests.py index c944d15..cba5a27 100644 --- a/tests/family_tests.py +++ b/tests/family_tests.py @@ -5,13 +5,13 @@ # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals +from contextlib import suppress
import pywikibot.site
from pywikibot.exceptions import UnknownFamily from pywikibot.family import Family, SingleSiteFamily -from pywikibot.tools import StringTypes as basestring, suppress_warnings +from pywikibot.tools import suppress_warnings
from tests.aspects import ( unittest, @@ -43,11 +43,11 @@ self.assertTrue(f.langs) self.assertTrue(f.codes) self.assertTrue(iter(f.codes)) - self.assertIsInstance(next(iter(f.codes)), basestring) + self.assertIsInstance(next(iter(f.codes)), str) self.assertTrue(f.domains) self.assertTrue(iter(f.domains)) for domain in f.domains: - self.assertIsInstance(domain, basestring) + self.assertIsInstance(domain, str) if domain.split(':', 1)[0] != 'localhost': self.assertIn('.', domain)
@@ -187,7 +187,7 @@
def setUp(self): """Setup default article path.""" - super(TestFamilyUrlRegex, self).setUp() + super().setUp() self.article_path = '/wiki/$1'
def test_from_url_wikipedia_extra(self): @@ -304,7 +304,5 @@
if __name__ == '__main__': # pragma: no cover - try: + with suppress(SystemExit): unittest.main() - except SystemExit: - pass diff --git a/tests/i18n_tests.py b/tests/i18n_tests.py index 2f0e164..9b4c515 100644 --- a/tests/i18n_tests.py +++ b/tests/i18n_tests.py @@ -1,16 +1,15 @@ # -*- coding: utf-8 -*- """Test i18n module.""" # -# (C) Pywikibot team, 2007-2019 +# (C) Pywikibot team, 2007-2020 # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals +from contextlib import suppress
import pywikibot
from pywikibot import i18n, bot, plural -from pywikibot.tools import StringTypes
from tests.aspects import ( unittest, TestCase, DefaultSiteTestCase, PwbTestCase, @@ -33,7 +32,7 @@ 'nl': 'test-semi-localized NL'} self.msg_non_localized = {'en': 'test-non-localized EN'} self.msg_no_english = {'ja': 'test-no-english JA'} - super(TestTranslate, self).setUp() + super().setUp()
def test_localized(self): """Test fully localized translations.""" @@ -76,14 +75,14 @@
def setUp(self): """Change the userinterface language to the site's code.""" - super(UserInterfaceLangTestCase, self).setUp() + super().setUp() self.orig_userinterface_lang = pywikibot.config.userinterface_lang pywikibot.config.userinterface_lang = self.get_site().code
def tearDown(self): """Reset the userinterface language.""" pywikibot.config.userinterface_lang = self.orig_userinterface_lang - super(UserInterfaceLangTestCase, self).tearDown() + super().tearDown()
class TWNSetMessagePackageBase(TestCase): @@ -96,11 +95,11 @@ """Load the test translations.""" self.orig_messages_package_name = i18n._messages_package_name i18n.set_messages_package(self.message_package) - super(TWNSetMessagePackageBase, self).setUp() + super().setUp()
def tearDown(self): """Load the original translations back.""" - super(TWNSetMessagePackageBase, self).tearDown() + super().tearDown() i18n.set_messages_package(self.orig_messages_package_name)
@@ -111,7 +110,7 @@ @classmethod def setUpClass(cls): """Verify that the test translations are not empty.""" - if not isinstance(cls.message_package, StringTypes): + if not isinstance(cls.message_package, str): raise TypeError('{}.message_package must be a package name' .format(cls.__name__)) # The call to set_messages_package below exists only to confirm @@ -124,7 +123,7 @@ if not has_messages: raise unittest.SkipTest("i18n messages package '{}' not available." .format(cls.message_package)) - super(TWNTestCaseBase, cls).setUpClass() + super().setUpClass()
class TestTWTranslate(TWNTestCaseBase): @@ -350,7 +349,7 @@ @classmethod def setUpClass(cls): """Verify that a translation does not yet exist.""" - super(InputTestCase, cls).setUpClass() + super().setUpClass()
if cls.code in i18n.twget_keys(cls.message): raise unittest.SkipTest( @@ -378,7 +377,7 @@
def setUp(self): """Patch the output and input methods.""" - super(MissingPackageTestCase, self).setUp() + super().setUp() self.output_text = '' self.orig_raw_input = bot.ui._raw_input self.orig_output = bot.ui.output @@ -389,7 +388,7 @@ """Restore the output and input methods.""" bot.ui._raw_input = self.orig_raw_input bot.ui.output = self.orig_output - super(MissingPackageTestCase, self).tearDown() + super().tearDown()
def test_pagegen_i18n_input(self): """Test i18n.input falls back with missing message package.""" @@ -472,7 +471,5 @@
if __name__ == '__main__': # pragma: no cover - try: + with suppress(SystemExit): unittest.main() - except SystemExit: - pass diff --git a/tests/user_tests.py b/tests/user_tests.py index 6b75116..3396be9 100644 --- a/tests/user_tests.py +++ b/tests/user_tests.py @@ -1,17 +1,17 @@ # -*- coding: utf-8 -*- """Tests for the User page.""" # -# (C) Pywikibot team, 2016-2019 +# (C) Pywikibot team, 2016-2020 # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals +from contextlib import suppress
import pywikibot
from pywikibot import Page, Timestamp, User from pywikibot.exceptions import AutoblockUser -from pywikibot.tools import StringTypes, suppress_warnings +from pywikibot.tools import suppress_warnings
from tests import patch from tests.aspects import DefaultSiteTestCase, TestCase, unittest @@ -183,7 +183,7 @@ self.assertIsInstance(p, Page) self.assertIsInstance(i, int) self.assertIsInstance(t, Timestamp) - self.assertIsInstance(c, StringTypes) + self.assertIsInstance(c, str) self.assertEqual(last, user.last_edit)
def test_logevents(self): @@ -201,7 +201,5 @@
if __name__ == '__main__': # pragma: no cover - try: + with suppress(SystemExit): unittest.main() - except SystemExit: - pass