jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/616170 )
Change subject: [4.0] Remove UnicodeType from several scripts ......................................................................
[4.0] Remove UnicodeType from several scripts
Change-Id: I65ecb79798cce36dd542acdad9cec46e448acfd8 --- M pywikibot/data/mysql.py M pywikibot/flow.py M pywikibot/login.py M pywikibot/specialbots/_upload.py M scripts/create_categories.py M scripts/misspelling.py M scripts/replace.py M tests/file_tests.py M tests/flow_edit_tests.py M tests/flow_tests.py M tests/http_tests.py M tests/logentries_tests.py M tests/wikistats_tests.py 13 files changed, 177 insertions(+), 258 deletions(-)
Approvals: Zhuyifei1999: Looks good to me, but someone else must approve D3r1ck01: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/data/mysql.py b/pywikibot/data/mysql.py index 2b40bf1..620d589 100644 --- a/pywikibot/data/mysql.py +++ b/pywikibot/data/mysql.py @@ -5,8 +5,6 @@ # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals - from contextlib import closing
import pywikibot @@ -18,11 +16,11 @@
from pywikibot import config2 as config -from pywikibot.tools import deprecated_args, UnicodeType +from pywikibot.tools import deprecated_args
@deprecated_args(encoding=None) -def mysql_query(query, params=None, dbname=None, verbose=None): +def mysql_query(query: str, params=None, dbname=None, verbose=None): """Yield rows from a MySQL query.
An example query that yields all ns0 pages might look like:: @@ -37,7 +35,6 @@ Cursor charset is utf8.
@param query: MySQL query to execute - @type query: str (unicode in py2) @param params: input parameters for the query, if needed if list or tuple, %s shall be used as placeholder in the query string. if a dict, %(key)s shall be used as placeholder in the query string. @@ -69,14 +66,12 @@ if verbose: _query = cursor.mogrify(query, params)
- if not isinstance(_query, UnicodeType): - _query = UnicodeType(_query, encoding='utf-8') + if not isinstance(_query, str): + _query = str(_query, encoding='utf-8') _query = _query.strip() _query = '\n'.join(' {0}'.format(line) for line in _query.splitlines()) pywikibot.output('Executing query:\n' + _query)
cursor.execute(query, params) - - for row in cursor: - yield row + yield from cursor diff --git a/pywikibot/flow.py b/pywikibot/flow.py index 74f9025..239e791 100644 --- a/pywikibot/flow.py +++ b/pywikibot/flow.py @@ -5,18 +5,12 @@ # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals - import logging
+from urllib.parse import urlparse, parse_qs + from pywikibot.exceptions import NoPage, UnknownExtension, LockedPage from pywikibot.page import BasePage, User -from pywikibot.tools import PY2, UnicodeType - -if not PY2: - from urllib.parse import urlparse, parse_qs -else: - from urlparse import urlparse, parse_qs
logger = logging.getLogger('pywiki.wiki.flow') @@ -45,7 +39,7 @@ @raises TypeError: incorrect use of parameters @raises ValueError: use of non-Flow-enabled Site """ - super(FlowPage, self).__init__(source, title) + super().__init__(source, title)
if not self.site.has_extension('Flow'): raise UnknownExtension('site is not Flow-enabled') @@ -199,7 +193,7 @@ """ if not isinstance(board, Board): raise TypeError('board must be a pywikibot.flow.Board object.') - if not isinstance(root_uuid, UnicodeType): + if not isinstance(root_uuid, str): raise TypeError('Topic/root UUID must be a string.')
topic = cls(board.site, 'Topic:' + root_uuid) @@ -305,7 +299,7 @@
# Flow non-page-like objects -class Post(object): +class Post:
"""A post to a Flow discussion topic."""
@@ -324,7 +318,7 @@ raise TypeError('Page must be a Topic object') if not page.exists(): raise NoPage(page, 'Topic must exist: %s') - if not isinstance(uuid, UnicodeType): + if not isinstance(uuid, str): raise TypeError('Post UUID must be a string')
self._page = page @@ -377,7 +371,7 @@ if 'content' in self._current_revision: content = self._current_revision.pop('content') assert isinstance(content, dict) - assert isinstance(content['content'], UnicodeType) + assert isinstance(content['content'], str) self._content[content['format']] = content['content']
def _load(self, format='wikitext', load_from_topic=False): diff --git a/pywikibot/login.py b/pywikibot/login.py index d9d5484..9a283d0 100644 --- a/pywikibot/login.py +++ b/pywikibot/login.py @@ -2,37 +2,36 @@ # -*- coding: utf-8 -*- """Library to log the bot in to a wiki account.""" # -# (C) Pywikibot team, 2003-2019 +# (C) Pywikibot team, 2003-2020 # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals - import codecs import os import webbrowser
-from pywikibot.tools import file_mode_checker - from warnings import warn
+import pywikibot + +from pywikibot import config, __url__ +from pywikibot.exceptions import NoUsername +from pywikibot.tools import ( + deprecated_args, file_mode_checker, normalize_username, remove_last_args, +) + try: import mwoauth except ImportError as e: mwoauth = e
-import pywikibot - -from pywikibot import config, __url__ -from pywikibot.exceptions import NoUsername -from pywikibot.tools import (deprecated_args, remove_last_args, - normalize_username, UnicodeType) -
class OAuthImpossible(ImportError):
"""OAuth authentication is not possible on your system."""
+ pass +
class _PasswordFileWarning(UserWarning):
@@ -55,7 +54,7 @@ }
-class LoginManager(object): +class LoginManager:
"""Site login manager."""
@@ -122,16 +121,15 @@ user = next(iter(data)) except pywikibot.data.api.APIError as e: if e.code == 'readapidenied': - pywikibot.warning('Could not check user %s exists on %s' - % (main_username, self.site)) + pywikibot.warning("Could not check user '{}' exists on {}" + .format(main_username, self.site)) return - else: - raise + raise
if user['name'] != main_username: # Report the same error as server error code NotExists - raise NoUsername("Username '%s' does not exist on %s" - % (main_username, self.site)) + raise NoUsername("Username '{}' does not exist on {}" + .format(main_username, self.site))
def botAllowed(self): """ @@ -139,10 +137,9 @@
This allows bots to comply with the policy on the respective wiki. """ - if self.site.family.name in botList \ - and self.site.code in botList[self.site.family.name]: - botlist_pagetitle, bot_template_title = botList[ - self.site.family.name][self.site.code] + code, fam = self.site.code, self.site.family.name + if code in botList.get(fam, []): + botlist_pagetitle, bot_template_title = botList[fam][code] botlist_page = pywikibot.Page(self.site, botlist_pagetitle) if bot_template_title: for template, params in botlist_page.templatesWithParams(): @@ -154,9 +151,9 @@ if linked_page.title(with_ns=False) == self.username: return True return False - else: - # No bot policies on other sites - return True + + # No bot policies on other sites + return True
@remove_last_args(['remember', 'captcha']) def getCookie(self): @@ -181,8 +178,7 @@ """ # THIS IS OVERRIDDEN IN data/api.py filename = config.datafilepath('pywikibot.lwp') - pywikibot.debug('Storing cookies to %s' % filename, - _logger) + pywikibot.debug('Storing cookies to {}'.format(filename), _logger) with open(filename, 'w') as f: f.write(data)
@@ -228,6 +224,7 @@ line_nr -= 1 if not line.strip() or line.startswith('#'): continue + try: entry = eval(line) except SyntaxError: @@ -248,15 +245,16 @@ if (normalize_username(username) == self.username and family == self.site.family.name and code == self.site.code): - if isinstance(password, UnicodeType): + if isinstance(password, str): self.password = password break - elif isinstance(password, BotPassword): + + if isinstance(password, BotPassword): self.password = password.password self.login_name = password.login_name(self.username) break - else: - warn('Invalid password format', _PasswordFileWarning) + + warn('Invalid password format', _PasswordFileWarning)
_api_error = { 'NotExists': 'does not exist', @@ -266,7 +264,7 @@ 'FAIL': 'does not have read permissions', }
- def login(self, retry=False, autocreate=False): + def login(self, retry=False, autocreate=False) -> bool: """ Attempt to log into the server.
@@ -291,12 +289,12 @@ # As we don't want the password to appear on the screen, we set # password = True self.password = pywikibot.input( - 'Password for user %(name)s on %(site)s (no characters will ' - 'be shown):' % {'name': self.login_name, 'site': self.site}, + 'Password for user {name} on {site} (no characters will be ' + 'shown):'.format(name=self.login_name, site=self.site), password=True)
- pywikibot.output('Logging in to %(site)s as %(name)s' - % {'name': self.login_name, 'site': self.site}) + pywikibot.output('Logging in to {site} as {name}' + .format(name=self.login_name, site=self.site)) try: cookiedata = self.getCookie() except pywikibot.data.api.APIError as e: @@ -320,11 +318,11 @@ return True
-class BotPassword(object): +class BotPassword:
"""BotPassword object for storage in password file."""
- def __init__(self, suffix, password): + def __init__(self, suffix: str, password: str): """ Initializer.
@@ -332,9 +330,7 @@ suffixed username of the form <username>@<suffix>.
@param suffix: Suffix of the login name - @type suffix: basestring @param password: bot password - @type password: basestring
@raises _PasswordFileWarning: suffix improperly specified """ @@ -344,13 +340,11 @@ self.suffix = suffix self.password = password
- def login_name(self, username): + def login_name(self, username: str) -> str: """ Construct the login name from the username and suffix.
@param user: username (without suffix) - @type user: basestring - @rtype: basestring """ return '{0}@{1}'.format(username, self.suffix)
@@ -372,9 +366,9 @@ @param site: Site object to log into @type site: BaseSite @param user: consumer key - @type user: basestring + @type user: str @param password: consumer secret - @type password: basestring + @type password: str
@raises pywikibot.exceptions.NoUsername: No username is configured for the requested site. @@ -383,12 +377,12 @@ if isinstance(mwoauth, ImportError): raise OAuthImpossible('mwoauth is not installed: %s.' % mwoauth) assert password is not None and user is not None - super(OauthLoginManager, self).__init__(password=None, site=site, - user=None) + super().__init__(password=None, site=site, user=None) if self.password: - pywikibot.warn('Password exists in password file for %s:%s.' - 'Password is unnecessary and should be removed ' - 'when OAuth enabled.' % (self.site, self.username)) + pywikibot.warn('Password exists in password file for {login.site}:' + '{login.username}. Password is unnecessary and ' + 'should be removed if OAuth enabled.' + .format(login=self)) self._consumer_token = (user, password) self._access_token = None
@@ -406,10 +400,9 @@ """ if self.access_token is None or force: pywikibot.output( - 'Logging in to %(site)s via OAuth consumer %(key)s' - % {'key': self.consumer_token[0], 'site': self.site}) - consumer_token = mwoauth.ConsumerToken(self.consumer_token[0], - self.consumer_token[1]) + 'Logging in to {site} via OAuth consumer {key}' + .format(key=self.consumer_token[0], site=self.site)) + consumer_token = mwoauth.ConsumerToken(*self.consumer_token) handshaker = mwoauth.Handshaker( self.site.base_url(self.site.path()), consumer_token) try: @@ -417,20 +410,19 @@ pywikibot.stdout('Authenticate via web browser..') webbrowser.open(redirect) pywikibot.stdout('If your web browser does not open ' - 'automatically, please point it to: %s' - % redirect) + 'automatically, please point it to: {}' + .format(redirect)) request_qs = pywikibot.input('Response query string: ') - access_token = handshaker.complete(request_token, - request_qs) + access_token = handshaker.complete(request_token, request_qs) self._access_token = (access_token.key, access_token.secret) except Exception as e: pywikibot.error(e) if retry: self.login(retry=True, force=force) else: - pywikibot.output('Logged in to %(site)s via consumer %(key)s' - % {'key': self.consumer_token[0], - 'site': self.site}) + pywikibot.output('Logged in to {site} via consumer {key}' + .format(key=self.consumer_token[0], + site=self.site))
@property def consumer_token(self): @@ -464,10 +456,9 @@ if self.access_token is None: pywikibot.error('Access token not set') return None - consumer_token = mwoauth.ConsumerToken(self.consumer_token[0], - self.consumer_token[1]) - access_token = mwoauth.AccessToken(self.access_token[0], - self.access_token[1]) + + consumer_token = mwoauth.ConsumerToken(*self.consumer_token) + access_token = mwoauth.AccessToken(*self.access_token) try: identity = mwoauth.identify(self.site.base_url(self.site.path()), consumer_token, access_token) diff --git a/pywikibot/specialbots/_upload.py b/pywikibot/specialbots/_upload.py index 56ff407..c30d1cf 100644 --- a/pywikibot/specialbots/_upload.py +++ b/pywikibot/specialbots/_upload.py @@ -9,12 +9,12 @@ # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals - import os import tempfile
from contextlib import closing +from urllib.parse import urlparse +from urllib.request import URLopener
import pywikibot import pywikibot.data.api @@ -22,16 +22,9 @@ from pywikibot import config
from pywikibot.bot import BaseBot, QuitKeyboardInterrupt -from pywikibot.tools import PY2, deprecated, deprecated_args, UnicodeType +from pywikibot.tools import deprecated, deprecated_args from pywikibot.tools.formatter import color_format
-if not PY2: - from urllib.parse import urlparse - from urllib.request import URLopener -else: - from urllib import URLopener - from urlparse import urlparse -
class UploadRobot(BaseBot):
@@ -41,7 +34,7 @@ useFilename='use_filename', keepFilename='keep_filename', verifyDescription='verify_description', ignoreWarning='ignore_warning', targetSite='target_site') - def __init__(self, url, url_encoding=None, description='', + def __init__(self, url: list, url_encoding=None, description='', use_filename=None, keep_filename=False, verify_description=True, ignore_warning=False, target_site=None, aborts=[], chunk_size=0, summary=None, @@ -51,7 +44,6 @@
@param url: path to url or local file (deprecated), or list of urls or paths to local files. - @type url: str (deprecated) or list @param description: Description of file for its page. If multiple files are uploading the same description is used for every file. @type description: str @@ -88,7 +80,7 @@ overwrites verify_description to False and keep_filename to True. @type always: bool """ - super(UploadRobot, self).__init__(**kwargs) + super().__init__(**kwargs) always = self.getOption('always') if (always and ignore_warning is not True and aborts is not True): raise ValueError('When always is set to True, either ' @@ -97,7 +89,7 @@ raise ValueError('When always is set to True, the description ' 'must be set.') self.url = url - if isinstance(self.url, UnicodeType): + if isinstance(self.url, str): pywikibot.warning('url as string is deprecated. ' 'Use an iterable instead.') self.url_encoding = url_encoding @@ -122,7 +114,7 @@ file_url = self.url pywikibot.warning('file_url is not given. ' 'Set to self.url by default.') - pywikibot.output('Reading file %s' % file_url) + pywikibot.output('Reading file {}'.format(file_url)) resume = False rlen = 0 _contents = None @@ -133,15 +125,12 @@ while not retrieved: if resume: pywikibot.output('Resume download...') - uo.addheader('Range', 'bytes=%s-' % rlen) + uo.addheader('Range', 'bytes={}-'.format(rlen))
with closing(uo.open(file_url)) as infile: info = infile.info()
- if PY2: - info_get = info.getheader - else: - info_get = info.get + info_get = info.get content_type = info_get('Content-Type') content_len = info_get('Content-Length') accept_ranges = info_get('Accept-Ranges') @@ -166,11 +155,11 @@ if rlen < content_len: retrieved = False pywikibot.output( - 'Connection closed at byte %s (%s left)' - % (rlen, content_len)) + 'Connection closed at byte {} ({} left)' + .format(rlen, content_len)) if valid_ranges and rlen > 0: resume = True - pywikibot.output('Sleeping for %d seconds...' % dt) + pywikibot.output('Sleeping for {} seconds...'.format(dt)) pywikibot.sleep(dt) if dt <= 60: dt += 15 @@ -461,7 +450,7 @@ return
try: - if isinstance(self.url, UnicodeType): + if isinstance(self.url, str): self._treat_counter = 1 return self.upload_file(self.url) for file_url in self.url: diff --git a/scripts/create_categories.py b/scripts/create_categories.py index ed77cb4..d5bd477 100755 --- a/scripts/create_categories.py +++ b/scripts/create_categories.py @@ -29,20 +29,16 @@ The page 'User:Multichill/Wallonia' on commons contains category links like [[Category:Hensies]], causing this script to create [[Category:Cultural heritage monuments in Hensies]]. - """ # -# (c) Pywikibot team, 2011-2019 +# (c) Pywikibot team, 2011-2020 # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals - import pywikibot from pywikibot.bot import AutomaticTWSummaryBot, SingleSiteBot from pywikibot import pagegenerators from pywikibot.site import Namespace -from pywikibot.tools import UnicodeType
class CreateCategoriesBot(SingleSiteBot, AutomaticTWSummaryBot): @@ -58,11 +54,11 @@ 'parent': None, 'overwrite': False, }) - super(CreateCategoriesBot, self).__init__(**kwargs) + super().__init__(**kwargs)
def init_page(self, item): """Create a category to be processed with the given page title.""" - page = super(CreateCategoriesBot, self).init_page(item) + page = super().init_page(item) title = page.title(with_ns=False) if page.namespace() != Namespace.CATEGORY: # return the page title to be skipped later within skip_page @@ -71,11 +67,11 @@ category = pywikibot.Category( page.site, '{} {}'.format(self.getOption('basename'), title))
- text = ('[[{namespace}:{parent}|{title}]]\n{category}\n' - .format(namespace=page.site.namespace(Namespace.CATEGORY), - parent=self.getOption('parent'), - title=title, - category=page.title(as_link=True))) + text = '[[{namespace}:{parent}|{title}]]\n{category}\n'.format( + namespace=page.site.namespace(Namespace.CATEGORY), + parent=self.getOption('parent'), + title=title, + category=page) category.text = text return category
@@ -87,13 +83,13 @@
def skip_page(self, page): """Skip page if it is not overwritten.""" - if isinstance(page, UnicodeType): + if isinstance(page, str): pywikibot.warning(page + ' is not a category, skipping') return True if page.exists() and not self.getOption('overwrite'): pywikibot.warning('{} already exists, skipping'.format(page)) return True - return super(CreateCategoriesBot, self).skip_page(page) + return super().skip_page(page)
def main(*args): diff --git a/scripts/misspelling.py b/scripts/misspelling.py index 897cf4c..85cba8e 100755 --- a/scripts/misspelling.py +++ b/scripts/misspelling.py @@ -31,7 +31,6 @@ import pywikibot
from pywikibot import i18n, pagegenerators -from pywikibot.tools import UnicodeType
from scripts.solve_disambiguation import DisambiguationRobot
@@ -77,7 +76,7 @@ mycode = self.site.code if mycode in self.misspellingCategory: categories = self.misspellingCategory[mycode] - if isinstance(categories, UnicodeType): + if isinstance(categories, str): categories = (categories, ) generators = ( pagegenerators.CategorizedPageGenerator( @@ -86,7 +85,7 @@ for misspellingCategoryTitle in categories) elif mycode in self.misspellingTemplate: templates = self.misspellingTemplate[mycode] - if isinstance(templates, UnicodeType): + if isinstance(templates, str): templates = (templates, ) generators = ( pagegenerators.ReferringPageGenerator( @@ -119,7 +118,7 @@ return True if self.misspellingTemplate.get(disambPage.site.code) is not None: templates = self.misspellingTemplate[disambPage.site.code] - if isinstance(templates, UnicodeType): + if isinstance(templates, str): templates = (templates, ) for template, params in disambPage.templatesWithParams(): if template.title(with_ns=False) in templates: diff --git a/scripts/replace.py b/scripts/replace.py index e9f1d68..c7d3609 100755 --- a/scripts/replace.py +++ b/scripts/replace.py @@ -140,16 +140,14 @@ # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals - import codecs -try: - from collections.abc import Sequence -except ImportError: # Python 2.7 - from collections import Sequence import re import warnings
+from collections.abc import Sequence +from contextlib import suppress +from queue import Queue + import pywikibot from pywikibot import editor from pywikibot.exceptions import ArgumentDeprecationWarning @@ -162,15 +160,8 @@ deprecated, deprecated_args, issue_deprecation_warning, - PY2, - UnicodeType )
-if not PY2: - from queue import Queue -else: - from Queue import Queue -
# This is required for the text that is shown when you run this script # with the parameter -help. @@ -199,7 +190,7 @@ return exceptions.get('inside-tags', []) + exceptions.get('inside', [])
-class ReplacementBase(object): +class ReplacementBase:
"""The replacement instructions."""
@@ -212,12 +203,12 @@ self.default_summary = default_summary
@property - def edit_summary(self): + def edit_summary(self) -> str: """Return the edit summary for this fix.""" return self._edit_summary
@property - def description(self): + def description(self) -> str: """Description of the changes that this replacement applies.
This description is used as the default summary of the replacement. If @@ -253,8 +244,6 @@ def compile(self, use_regex, flags): """Compile the search text.""" # Set the regular expression flags - flags |= re.UNICODE - if self.case_insensitive is False: flags &= ~re.IGNORECASE elif self.case_insensitive: @@ -273,8 +262,7 @@ case_insensitive=None, edit_summary=None, default_summary=True): """Create a single replacement entry unrelated to a fix.""" - super(Replacement, self).__init__(old, new, edit_summary, - default_summary) + super().__init__(old, new, edit_summary, default_summary) self._use_regex = use_regex self.exceptions = exceptions self._case_insensitive = case_insensitive @@ -300,7 +288,7 @@
def _compile(self, use_regex, flags): """Compile the search regex and exceptions.""" - super(Replacement, self)._compile(use_regex, flags) + super()._compile(use_regex, flags) precompile_exceptions(self.exceptions, use_regex, flags)
def get_inside_exceptions(self): @@ -325,7 +313,7 @@ def __init__(self, use_regex, exceptions, case_insensitive, edit_summary, name): """Create a fix list which can contain multiple replacements.""" - super(ReplacementList, self).__init__() + super().__init__() self.use_regex = use_regex self._exceptions = exceptions self.exceptions = None @@ -347,8 +335,7 @@ def __init__(self, old, new, fix_set, edit_summary=None, default_summary=True): """Create a replacement entry inside a fix set.""" - super(ReplacementListEntry, self).__init__(old, new, edit_summary, - default_summary) + super().__init__(old, new, edit_summary, default_summary) self.fix_set = fix_set
@property @@ -389,7 +376,7 @@
def _compile(self, use_regex, flags): """Compile the search regex and the fix's exceptions.""" - super(ReplacementListEntry, self)._compile(use_regex, flags) + super()._compile(use_regex, flags) self.fix_set._compile_exceptions(use_regex, flags)
def get_inside_exceptions(self): @@ -460,13 +447,11 @@ yield pywikibot.Page(self.site, entry.title)
except KeyboardInterrupt: - try: + with suppress(NameError): if not self.skipping: pywikibot.output( 'To resume, use "-xmlstart:{0}" on the command line.' .format(entry.title)) - except NameError: - pass
def isTitleExcepted(self, title): """ @@ -557,7 +542,7 @@ 'sleep': 0.0, 'summary': None, }) - super(ReplaceRobot, self).__init__(generator=generator, **kwargs) + super().__init__(generator=generator, **kwargs)
for i, replacement in enumerate(replacements): if isinstance(replacement, Sequence): @@ -575,17 +560,13 @@ self.summary = self.getOption('summary')
self.addcat = self.getOption('addcat') - if self.addcat and isinstance(self.addcat, UnicodeType): + if self.addcat and isinstance(self.addcat, str): self.addcat = pywikibot.Category(self.site, self.addcat)
self._pending_processed_titles = Queue()
- def isTitleExcepted(self, title, exceptions=None): - """ - Return True iff one of the exceptions applies for the given title. - - @rtype: bool - """ + def isTitleExcepted(self, title, exceptions=None) -> bool: + """Return True if one of the exceptions applies for the given title.""" if exceptions is None: exceptions = self.exceptions if 'title' in exceptions: @@ -598,12 +579,8 @@ return True return False
- def isTextExcepted(self, original_text): - """ - Return True iff one of the exceptions applies for the given text. - - @rtype: bool - """ + def isTextExcepted(self, original_text) -> bool: + """Return True iff one of the exceptions applies for the given text.""" if 'text-contains' in self.exceptions: for exc in self.exceptions['text-contains']: if exc.search(original_text): @@ -725,7 +702,7 @@ pywikibot.warning("You can't edit page {}".format(page)) return True
- return super(ReplaceRobot, self).skip_page(page) + return super().skip_page(page)
def treat(self, page): """Work on each page retrieved from generator.""" @@ -888,7 +865,7 @@ useSql = False sql_query = None # Set the default regular expression flags - flags = re.UNICODE + flags = 0 # Request manual replacements even if replacements are already defined manual_input = False # Replacements loaded from a file @@ -1041,7 +1018,7 @@ '"{0}"'.format(fix_name)) continue if 'msg' in fix: - if isinstance(fix['msg'], UnicodeType): + if isinstance(fix['msg'], str): set_summary = i18n.twtranslate(site, str(fix['msg'])) else: set_summary = i18n.translate(site, fix['msg'], fallback=True) @@ -1049,7 +1026,7 @@ set_summary = None if not generators_given and 'generator' in fix: gen_args = fix['generator'] - if isinstance(gen_args, UnicodeType): + if isinstance(gen_args, str): gen_args = [gen_args] for gen_arg in gen_args: genFactory.handleArg(gen_arg) diff --git a/tests/file_tests.py b/tests/file_tests.py index c96cae1..6100e6f 100644 --- a/tests/file_tests.py +++ b/tests/file_tests.py @@ -5,14 +5,12 @@ # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals - import os import re
-import pywikibot +from contextlib import suppress
-from pywikibot.tools import UnicodeType as unicode +import pywikibot
from tests import join_images_path
@@ -210,7 +208,7 @@
def setUp(self): """Create File page.""" - super(TestCase, self).setUp() + super().setUp() self.image = pywikibot.FilePage(self.site, self.file_name)
def test_get_file_url(self): @@ -272,8 +270,6 @@ first = page.getFirstUploader() self.assertOneDeprecation() self.assertEqual(first, ['Herbizid', '2011-03-18T10:04:48Z']) - self.assertIsInstance(first[0], unicode) - self.assertIsInstance(first[1], unicode)
def test_getLatestUploader(self): """Test getLatestUploader.""" @@ -281,8 +277,8 @@ latest = page.getLatestUploader() self.assertOneDeprecation() self.assertLength(latest, 2) - self.assertIsInstance(latest[0], unicode) - self.assertIsInstance(latest[1], unicode) + for item in latest: + self.assertIsInstance(item, str)
class TestFilePageDownload(TestCase): @@ -316,7 +312,5 @@
if __name__ == '__main__': # pragma: no cover - try: + with suppress(SystemExit): unittest.main() - except SystemExit: - pass diff --git a/tests/flow_edit_tests.py b/tests/flow_edit_tests.py index 330499a..bdf2797 100644 --- a/tests/flow_edit_tests.py +++ b/tests/flow_edit_tests.py @@ -1,15 +1,14 @@ # -*- coding: utf-8 -*- """Edit tests for the flow module.""" # -# (C) Pywikibot team, 2015-2019 +# (C) Pywikibot team, 2015-2020 # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals +from contextlib import suppress
from pywikibot.exceptions import LockedPage from pywikibot.flow import Board, Topic, Post -from pywikibot.tools import UnicodeType as unicode
from tests.aspects import TestCase from tests import unittest @@ -34,7 +33,7 @@ wikitext = first_post.get(format='wikitext') self.assertIn('wikitext', first_post._content) self.assertNotIn('html', first_post._content) - self.assertIsInstance(wikitext, unicode) + self.assertIsInstance(wikitext, str) self.assertEqual(wikitext, content)
@@ -51,7 +50,7 @@ @classmethod def setUpClass(cls): """Set up class.""" - super(TestFlowReply, cls).setUpClass() + super().setUpClass() cls._topic_title = 'Topic:Stf56oxx0sd4dkj1'
def test_reply_to_topic(self): @@ -66,7 +65,7 @@ wikitext = reply_post.get(format='wikitext') self.assertIn('wikitext', reply_post._content) self.assertNotIn('html', reply_post._content) - self.assertIsInstance(wikitext, unicode) + self.assertIsInstance(wikitext, str) self.assertEqual(wikitext, content) # Test reply list in topic new_replies = topic.replies(force=True) @@ -86,7 +85,7 @@ wikitext = reply_post.get(format='wikitext') self.assertIn('wikitext', reply_post._content) self.assertNotIn('html', reply_post._content) - self.assertIsInstance(wikitext, unicode) + self.assertIsInstance(wikitext, str) self.assertEqual(wikitext, content) # Test reply list in topic new_replies = topic_root.replies(force=True) @@ -105,7 +104,7 @@ wikitext = reply_post.get(format='wikitext') self.assertIn('wikitext', reply_post._content) self.assertNotIn('html', reply_post._content) - self.assertIsInstance(wikitext, unicode) + self.assertIsInstance(wikitext, str) self.assertEqual(wikitext, content) # Test reply list in topic new_replies = root_post.replies(force=True) @@ -126,7 +125,7 @@ first_wikitext = first_reply_post.get(format='wikitext') self.assertIn('wikitext', first_reply_post._content) self.assertNotIn('html', first_reply_post._content) - self.assertIsInstance(first_wikitext, unicode) + self.assertIsInstance(first_wikitext, str) self.assertEqual(first_wikitext, first_content) # Test reply list in topic new_root_replies = topic_root.replies(force=True) @@ -141,7 +140,7 @@ second_wikitext = second_reply_post.get(format='wikitext') self.assertIn('wikitext', second_reply_post._content) self.assertNotIn('html', second_reply_post._content) - self.assertIsInstance(second_wikitext, unicode) + self.assertIsInstance(second_wikitext, str) self.assertEqual(second_wikitext, second_content)
# Test reply list in first reply @@ -326,7 +325,5 @@
if __name__ == '__main__': # pragma: no cover - try: + with suppress(SystemExit): unittest.main() - except SystemExit: - pass diff --git a/tests/flow_tests.py b/tests/flow_tests.py index 62b3d96..60f644f 100644 --- a/tests/flow_tests.py +++ b/tests/flow_tests.py @@ -1,15 +1,14 @@ # -*- coding: utf-8 -*- """Tests for the flow module.""" # -# (C) Pywikibot team, 2015-2019 +# (C) Pywikibot team, 2015-2020 # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals +from contextlib import suppress
from pywikibot.exceptions import NoPage from pywikibot.flow import Board, Topic, Post -from pywikibot.tools import UnicodeType as unicode
from tests import unittest from tests.aspects import ( @@ -32,7 +31,7 @@ """Set up unit test.""" self._page = Board(self.site, 'Project talk:Sandbox/Structured_Discussions_test') - super(TestMediaWikiFlowSandbox, self).setUp() + super().setUp()
class TestBoardBasePageMethods(BasePageMethodsTestBase, @@ -61,7 +60,7 @@ def setUp(self): """Set up unit test.""" self._page = Topic(self.site, 'Topic:Sh6wgo5tu3qui1w2') - super(TestTopicBasePageMethods, self).setUp() + super().setUp()
def test_basepage_methods(self): """Test basic Page methods on a Flow topic page.""" @@ -122,24 +121,24 @@ wikitext = post.get(format='wikitext') self.assertIn('wikitext', post._content) self.assertNotIn('html', post._content) - self.assertIsInstance(wikitext, unicode) + self.assertIsInstance(wikitext, str) self.assertNotEqual(wikitext, '') # HTML html = post.get(format='html') self.assertIn('html', post._content) self.assertIn('wikitext', post._content) - self.assertIsInstance(html, unicode) + self.assertIsInstance(html, str) self.assertNotEqual(html, '') # Caching (hit) post._content['html'] = 'something' html = post.get(format='html') - self.assertIsInstance(html, unicode) + self.assertIsInstance(html, str) self.assertEqual(html, 'something') self.assertIn('html', post._content) # Caching (reload) post._content['html'] = 'something' html = post.get(format='html', force=True) - self.assertIsInstance(html, unicode) + self.assertIsInstance(html, str) self.assertNotEqual(html, 'something') self.assertIn('html', post._content)
@@ -247,7 +246,5 @@
if __name__ == '__main__': # pragma: no cover - try: + with suppress(SystemExit): unittest.main() - except SystemExit: - pass diff --git a/tests/http_tests.py b/tests/http_tests.py index 8bf693a..9a8b0b7 100644 --- a/tests/http_tests.py +++ b/tests/http_tests.py @@ -1,27 +1,23 @@ # -*- coding: utf-8 -*- """Tests for http module.""" # -# (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 - import json import re import warnings
+from contextlib import suppress + import requests
import pywikibot
from pywikibot import config2 as config from pywikibot.comms import http, threadedhttp -from pywikibot.tools import ( - PYTHON_VERSION, - suppress_warnings, - UnicodeType as unicode, -) +from pywikibot.tools import PYTHON_VERSION, suppress_warnings
from tests import join_images_path, patch from tests.aspects import ( @@ -49,7 +45,7 @@ self.assertIsInstance(r, threadedhttp.HttpRequest) self.assertEqual(r.status, 200) self.assertIn('<html lang="mul"', r.text) - self.assertIsInstance(r.text, unicode) + self.assertIsInstance(r.text, str) self.assertIsInstance(r.raw, bytes)
def test_fetch(self): @@ -58,7 +54,7 @@ self.assertIsInstance(r, threadedhttp.HttpRequest) self.assertEqual(r.status, 200) self.assertIn('<html lang="mul"', r.text) - self.assertIsInstance(r.text, unicode) + self.assertIsInstance(r.text, str) with suppress_warnings(r'.*HttpRequest.content is deprecated'): self.assertEqual(r.content, r.text) self.assertIsInstance(r.raw, bytes) @@ -80,7 +76,7 @@ def test_http(self): """Test http.request using http://www.wikipedia.org/.""" r = http.request(site=None, uri='http://www.wikipedia.org/') - self.assertIsInstance(r, unicode) + self.assertIsInstance(r, str) self.assertIn('<html lang="mul"', r) self.assertOneDeprecationParts( 'Invoking http.request without argument site', 'http.fetch()') @@ -88,7 +84,7 @@ def test_https(self): """Test http.request using https://www.wikiquote.org/.""" r = http.request(site=None, uri='https://www.wikiquote.org/') - self.assertIsInstance(r, unicode) + self.assertIsInstance(r, str) self.assertIn('<html lang="mul"', r) self.assertOneDeprecationParts( 'Invoking http.request without argument site', 'http.fetch()') @@ -102,7 +98,7 @@
def setUp(self): """Set up test by configuring config.authenticate.""" - super(TestGetAuthenticationConfig, self).setUp() + super().setUp() self._authenticate = config.authenticate config.authenticate = { 'zh.wikipedia.beta.wmflabs.org': ('1', '2'), @@ -113,7 +109,7 @@
def tearDown(self): """Tear down test by resetting config.authenticate.""" - super(TestGetAuthenticationConfig, self).tearDown() + super().tearDown() config.authenticate = self._authenticate
def test_url_based_authentication(self): @@ -153,7 +149,7 @@ uri='https://testssl-expire-r2i2.disig.sk/index.en.html', disable_ssl_certificate_validation=True) r = response.text - self.assertIsInstance(r, unicode) + self.assertIsInstance(r, str) self.assertTrue(re.search(r'<title>.*</title>', r)) http.session.close() # clear the connection
@@ -282,7 +278,7 @@
def setUp(self): """Set up unit test.""" - super(DefaultUserAgentTestCase, self).setUp() + super().setUp() self.orig_format = config.user_agent_format config.user_agent_format = ('{script_product} ({script_comments}) ' '{pwb} ({revision}) {http_backend} ' @@ -290,7 +286,7 @@
def tearDown(self): """Tear down unit test.""" - super(DefaultUserAgentTestCase, self).tearDown() + super().tearDown() config.user_agent_format = self.orig_format
def test_default_user_agent(self): @@ -314,13 +310,13 @@ """Set up the unit test.""" self.orig_fake_user_agent_exceptions = ( config.fake_user_agent_exceptions) - super(LiveFakeUserAgentTestCase, self).setUp() + super().setUp()
def tearDown(self): """Tear down unit test.""" config.fake_user_agent_exceptions = ( self.orig_fake_user_agent_exceptions) - super(LiveFakeUserAgentTestCase, self).tearDown() + super().tearDown()
def _test_fetch_use_fake_user_agent(self): """Test `use_fake_user_agent` argument of http.fetch.""" @@ -364,12 +360,12 @@ def setUp(self): """Set up unit test.""" self.orig_fake_user_agent = config.fake_user_agent - super(GetFakeUserAgentTestCase, self).setUp() + super().setUp()
def tearDown(self): """Tear down unit test.""" config.fake_user_agent = self.orig_fake_user_agent - super(GetFakeUserAgentTestCase, self).tearDown() + super().tearDown()
def _test_config_settings(self): """Test if method honours configuration toggle.""" @@ -562,7 +558,7 @@ @classmethod def setUpClass(cls): """Set up test class.""" - super(BinaryTestCase, cls).setUpClass() + super().setUpClass()
with open(join_images_path('MP_sounds.png'), 'rb') as f: cls.png = f.read() @@ -612,7 +608,7 @@
def setUp(self): """Set up tests.""" - super(QueryStringParamsTestCase, self).setUp() + super().setUp() self.url = self.get_httpbin_url('/get')
def test_no_params(self): @@ -689,7 +685,5 @@
if __name__ == '__main__': # pragma: no cover - try: + with suppress(SystemExit): unittest.main() - except SystemExit: - pass diff --git a/tests/logentries_tests.py b/tests/logentries_tests.py index 81fc48a..39f31d6 100644 --- a/tests/logentries_tests.py +++ b/tests/logentries_tests.py @@ -14,7 +14,6 @@ from pywikibot.exceptions import HiddenKeyError from pywikibot.logentries import ( LogEntryFactory, OtherLogEntry, UserTargetLogEntry) -from pywikibot.tools import UnicodeType
from tests import unittest_print from tests.aspects import ( @@ -75,10 +74,10 @@ else: self.assertNotIn(logentry.type(), logentry.data)
- self.assertIsInstance(logentry.action(), UnicodeType) + self.assertIsInstance(logentry.action(), str)
try: - self.assertIsInstance(logentry.comment(), UnicodeType) + self.assertIsInstance(logentry.comment(), str) except HiddenKeyError as e: self.assertRegex( str(e), @@ -115,7 +114,7 @@ self.assertRaises(KeyError, logentry.page)
self.assertEqual(logentry.type(), logtype) - self.assertIsInstance(logentry.user(), UnicodeType) + self.assertIsInstance(logentry.user(), str) self.assertGreaterEqual(logentry.logid(), 0)
# test new UserDict style @@ -144,7 +143,7 @@ cls.add_method(dct, 'test_{}Entry'.format(logtype.title()), test_method(logtype))
- return super(TestLogentriesMeta, cls).__new__(cls, name, bases, dct) + return super().__new__(cls, name, bases, dct)
class TestLogentries(TestLogentriesBase, metaclass=TestLogentriesMeta): @@ -212,7 +211,7 @@ self.assertIsInstance(logentry.target_ns, pywikibot.site.Namespace) self.assertEqual(logentry.target_page.namespace(), logentry.target_ns.id) - self.assertIsInstance(logentry.target_title, UnicodeType) + self.assertIsInstance(logentry.target_title, str) self.assertIsInstance(logentry.target_page, pywikibot.Page) self.assertIsInstance(logentry.suppressedredirect(), bool)
diff --git a/tests/wikistats_tests.py b/tests/wikistats_tests.py index 2af381e..a68926e 100644 --- a/tests/wikistats_tests.py +++ b/tests/wikistats_tests.py @@ -5,12 +5,9 @@ # # Distributed under the terms of the MIT license. # -from __future__ import absolute_import, division, unicode_literals - import sys
from pywikibot.data.wikistats import WikiStats, csv -from pywikibot.tools import UnicodeType
from tests.aspects import unittest, TestCase
@@ -35,13 +32,13 @@ self.assertIn(key, top) self.assertIn(key, bottom)
- self.assertTrue(all(isinstance(key, UnicodeType) + self.assertTrue(all(isinstance(key, str) for key in top.keys() if key is not None)) - self.assertIsInstance(top['good'], UnicodeType) - self.assertIsInstance(top['total'], UnicodeType) - self.assertIsInstance(bottom['good'], UnicodeType) - self.assertIsInstance(bottom['total'], UnicodeType) + self.assertIsInstance(top['good'], str) + self.assertIsInstance(top['total'], str) + self.assertIsInstance(bottom['good'], str) + self.assertIsInstance(bottom['total'], str)
self.assertGreater(int(top['total']), int(bottom['good'])) self.assertGreater(int(top['good']), int(bottom['good'])) @@ -74,10 +71,10 @@ self.assertIn('ht', data) self.assertGreater(int(data['en']['total']), int(data['en']['good'])) data = data['en'] - self.assertTrue(all(isinstance(key, UnicodeType) + self.assertTrue(all(isinstance(key, str) for key in data.keys() if key is not None)) - self.assertIsInstance(data['total'], UnicodeType) + self.assertIsInstance(data['total'], str) self.assertIn('prefix', data) self.assertIn('total', data)
@@ -90,10 +87,10 @@ self.assertIn('id', data) self.assertGreater(int(data['fr']['total']), int(data['fr']['good'])) data = data['fr'] - self.assertTrue(all(isinstance(key, UnicodeType) + self.assertTrue(all(isinstance(key, str) for key in data.keys() if key is not None)) - self.assertIsInstance(data['total'], UnicodeType) + self.assertIsInstance(data['total'], str) self.assertIn('prefix', data) self.assertIn('total', data)