jenkins-bot submitted this change.

View Change

Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
[IMPR] Add backports to support older Python versions

- add typing backports
- add functools.cache backport
- add removeprefix and removesuffix functions backports

Import backports in several scripts

Change-Id: I366e5c7233ed927d17e7bf8127a6fd7920d7f11d
---
M docs/api_ref/pywikibot.rst
M pywikibot/CONTENT.rst
M pywikibot/__init__.py
A pywikibot/backports.py
M pywikibot/bot.py
M pywikibot/comms/http.py
M pywikibot/comms/threadedhttp.py
M pywikibot/config2.py
M pywikibot/data/api.py
M pywikibot/date.py
M pywikibot/family.py
M pywikibot/i18n.py
M pywikibot/logentries.py
M pywikibot/page/__init__.py
M pywikibot/pagegenerators.py
M pywikibot/site/__init__.py
M pywikibot/site/_namespace.py
M pywikibot/specialbots/_upload.py
M pywikibot/textlib.py
M pywikibot/userinterfaces/gui.py
M scripts/add_text.py
M scripts/archivebot.py
M scripts/basic.py
M scripts/capitalize_redirects.py
M scripts/catall.py
M scripts/category.py
M scripts/category_redirect.py
M scripts/checkimages.py
M scripts/clean_sandbox.py
M scripts/commons_link.py
M scripts/coordinate_import.py
M scripts/cosmetic_changes.py
M scripts/create_categories.py
M scripts/data_ingestion.py
M scripts/delete.py
M scripts/djvutext.py
M scripts/download_dump.py
M scripts/editarticle.py
M scripts/harvest_template.py
M scripts/interwikidata.py
M scripts/login.py
M scripts/newitem.py
M scripts/pagefromfile.py
M scripts/redirect.py
M scripts/solve_disambiguation.py
M scripts/templatecount.py
M scripts/weblinkchecker.py
M scripts/welcome.py
M tox.ini
49 files changed, 155 insertions(+), 305 deletions(-)

diff --git a/docs/api_ref/pywikibot.rst b/docs/api_ref/pywikibot.rst
index aaaf2f3..05b3f0b 100644
--- a/docs/api_ref/pywikibot.rst
+++ b/docs/api_ref/pywikibot.rst
@@ -20,6 +20,11 @@
Submodules
----------

+pywikibot.backports module
+--------------------------
+
+.. automodule:: pywikibot.backports
+
pywikibot.bot module
--------------------

diff --git a/pywikibot/CONTENT.rst b/pywikibot/CONTENT.rst
index 6df54ca..17f6e73 100644
--- a/pywikibot/CONTENT.rst
+++ b/pywikibot/CONTENT.rst
@@ -11,6 +11,8 @@
+----------------------------+------------------------------------------------------+
| _wbtypes.py | Wikibase data type classes |
+----------------------------+------------------------------------------------------+
+ | backports.py | Backports to support older Python versions |
+ +----------------------------+------------------------------------------------------+
| bot.py | User-interface related functions for building bots |
+----------------------------+------------------------------------------------------+
| bot_choice.py | Classes for input_choice |
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index 25a7100..b2dc8ff 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -23,6 +23,7 @@
__maintainer__, __maintainer_email__, __name__, __url__, __version__)

from pywikibot._wbtypes import WbRepresentation as _WbRepresentation
+from pywikibot.backports import cache
from pywikibot.bot import (
input, input_choice, input_yn, handle_args, show_help, ui,
calledModuleName, Bot, CurrentPageBot, WikidataBot,
@@ -59,17 +60,10 @@
normalize_username,
MediaWikiVersion as _MediaWikiVersion,
ModuleDeprecationWrapper as _ModuleDeprecationWrapper,
- PYTHON_VERSION,
redirect_func,
)
from pywikibot.tools.formatter import color_format

-if PYTHON_VERSION >= (3, 9, 0):
- from functools import cache
-else:
- from functools import lru_cache
- cache = lru_cache(None)
-

__all__ = (
'__copyright__', '__description__', '__download_url__', '__license__',
diff --git a/pywikibot/backports.py b/pywikibot/backports.py
new file mode 100644
index 0000000..433a685
--- /dev/null
+++ b/pywikibot/backports.py
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+"""This module contains backports to support older Python versions."""
+#
+# (C) Pywikibot team, 2020
+#
+# Distributed under the terms of the MIT license.
+#
+from pywikibot.tools import PYTHON_VERSION
+
+# functools.cache
+if PYTHON_VERSION >= (3, 9):
+ from functools import cache
+else:
+ from functools import lru_cache as _lru_cache
+ cache = _lru_cache(None)
+
+
+# typing
+if PYTHON_VERSION < (3, 5, 2):
+ from typing import Dict as DefaultDict
+elif PYTHON_VERSION < (3, 9):
+ from typing import DefaultDict
+else:
+ from collections import defaultdict as DefaultDict # noqa: N812
+
+if PYTHON_VERSION >= (3, 9):
+ from collections.abc import Iterable
+ Dict = dict
+ FrozenSet = frozenset
+ List = list
+ Set = set
+ Tuple = tuple
+else:
+ from typing import Dict, FrozenSet, Iterable, List, Set, Tuple
+
+
+# PEP 616 string methods
+if PYTHON_VERSION >= (3, 9):
+ removeprefix = str.removeprefix
+ removesuffix = str.removesuffix
+else:
+ def removeprefix(string: str, prefix: str) -> str:
+ """Remove prefix from a string or return a copy otherwise."""
+ if string.startswith(prefix):
+ return string[len(prefix):]
+ return string[:]
+
+ def removesuffix(string: str, suffix: str) -> str:
+ """Remove prefix from a string or return a copy otherwise."""
+ if string.endswith(suffix):
+ return string[:-len(suffix)]
+ return string[:]
diff --git a/pywikibot/bot.py b/pywikibot/bot.py
index 8920d7a..7a6942e 100644
--- a/pywikibot/bot.py
+++ b/pywikibot/bot.py
@@ -103,6 +103,7 @@
from warnings import warn

import pywikibot
+from pywikibot.backports import Dict, Iterable, List
from pywikibot import config2 as config
from pywikibot import daemonize
from pywikibot import i18n
@@ -128,12 +129,6 @@
from pywikibot.tools._logging import LoggingFormatter, RotatingFileHandler
from pywikibot.tools.formatter import color_format

-if PYTHON_VERSION >= (3, 9):
- from collections.abc import Iterable
- Dict = dict
- List = list
-else:
- from typing import Dict, Iterable, List

# Note: all output goes through python std library "logging" module
_logger = 'bot'
diff --git a/pywikibot/comms/http.py b/pywikibot/comms/http.py
index d526e34..a656bc5 100644
--- a/pywikibot/comms/http.py
+++ b/pywikibot/comms/http.py
@@ -29,6 +29,8 @@
import requests

import pywikibot
+
+from pywikibot.backports import Tuple
from pywikibot.comms import threadedhttp
from pywikibot import config2 as config
from pywikibot.exceptions import (
@@ -40,14 +42,8 @@
deprecated_args,
issue_deprecation_warning,
file_mode_checker,
- PYTHON_VERSION,
)

-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple
-
try:
import requests_oauthlib
except ImportError as e:
diff --git a/pywikibot/comms/threadedhttp.py b/pywikibot/comms/threadedhttp.py
index 1836e7b..9882c1d 100644
--- a/pywikibot/comms/threadedhttp.py
+++ b/pywikibot/comms/threadedhttp.py
@@ -12,17 +12,14 @@
from urllib.parse import urlparse

import pywikibot
+
+from pywikibot.backports import Dict
from pywikibot.tools import (
deprecated,
deprecated_args,
issue_deprecation_warning,
- PYTHON_VERSION,
)

-if PYTHON_VERSION >= (3, 9):
- Dict = dict
-else:
- from typing import Dict

_logger = 'comms.threadedhttp'

diff --git a/pywikibot/config2.py b/pywikibot/config2.py
index 5240a3b..0f8395f 100644
--- a/pywikibot/config2.py
+++ b/pywikibot/config2.py
@@ -54,15 +54,10 @@
from warnings import warn

from pywikibot.__metadata__ import __version__ as pwb_version
+from pywikibot.backports import Dict, List, Tuple
from pywikibot.logging import error, output, warning
-from pywikibot.tools import issue_deprecation_warning, PYTHON_VERSION
+from pywikibot.tools import issue_deprecation_warning

-if PYTHON_VERSION >= (3, 9):
- Dict = dict
- List = list
- Tuple = tuple
-else:
- from typing import Dict, List, Tuple

OSWIN32 = (sys.platform == 'win32')

diff --git a/pywikibot/data/api.py b/pywikibot/data/api.py
index 1abfcc9..9d644c2 100644
--- a/pywikibot/data/api.py
+++ b/pywikibot/data/api.py
@@ -30,6 +30,7 @@

from pywikibot import config, login

+from pywikibot.backports import FrozenSet, Set, Tuple
from pywikibot.comms import http
from pywikibot.exceptions import (
Server504Error, Server414Error, FatalServerError, NoUsername,
@@ -38,18 +39,14 @@
from pywikibot.family import SubdomainFamily
from pywikibot.login import LoginStatus
from pywikibot.tools import (
- deprecated, issue_deprecation_warning, itergroup, PYTHON_VERSION,
+ deprecated,
+ issue_deprecation_warning,
+ itergroup,
+ PYTHON_VERSION,
remove_last_args,
)
from pywikibot.tools.formatter import color_format

-if PYTHON_VERSION >= (3, 9):
- Set = set
- Tuple = tuple
- FrozenSet = frozenset
-else:
- from typing import Set, Tuple, FrozenSet
-

_logger = 'data.api'

diff --git a/pywikibot/date.py b/pywikibot/date.py
index 9419768..713af67 100644
--- a/pywikibot/date.py
+++ b/pywikibot/date.py
@@ -15,19 +15,10 @@
from functools import singledispatch
from string import digits as _decimalDigits # noqa: N812

+from pywikibot.backports import Tuple
from pywikibot import Site
from pywikibot.textlib import NON_LATIN_DIGITS
-from pywikibot.tools import (
- deprecated,
- first_lower,
- first_upper,
- PYTHON_VERSION,
-)
-
-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple
+from pywikibot.tools import deprecated, first_lower, first_upper

#
# Different collections of well known formats
diff --git a/pywikibot/family.py b/pywikibot/family.py
index 676871e..e13d49a 100644
--- a/pywikibot/family.py
+++ b/pywikibot/family.py
@@ -19,19 +19,19 @@
from typing import Optional

import pywikibot
+
+from pywikibot.backports import Dict, List, Tuple
from pywikibot import config
from pywikibot.exceptions import UnknownFamily, FamilyMaintenanceWarning
from pywikibot.tools import (
- classproperty, deprecated, deprecated_args, frozenmap,
- issue_deprecation_warning, ModuleDeprecationWrapper, PYTHON_VERSION,
+ classproperty,
+ deprecated,
+ deprecated_args,
+ frozenmap,
+ issue_deprecation_warning,
+ ModuleDeprecationWrapper,
)

-if PYTHON_VERSION >= (3, 9):
- Dict = dict
- List = list
- Tuple = tuple
-else:
- from typing import Dict, List, Tuple

logger = logging.getLogger('pywiki.wiki.family')

diff --git a/pywikibot/i18n.py b/pywikibot/i18n.py
index 33b6037..b10aceb 100644
--- a/pywikibot/i18n.py
+++ b/pywikibot/i18n.py
@@ -35,19 +35,13 @@
import pywikibot

from pywikibot import __url__
+from pywikibot.backports import cache, List
from pywikibot import config2 as config
from pywikibot.exceptions import Error
from pywikibot.plural import plural_rule
from pywikibot.tools import (
- deprecated, deprecated_args, issue_deprecation_warning, PYTHON_VERSION)
+ deprecated, deprecated_args, issue_deprecation_warning)

-if PYTHON_VERSION >= (3, 9, 0):
- from functools import cache
- List = list
-else:
- from functools import lru_cache
- from typing import List
- cache = lru_cache(None)

PLURAL_PATTERN = r'{{PLURAL:(?:%\()?([^\)]*?)(?:\)d)?\|(.*?)}}'

diff --git a/pywikibot/logentries.py b/pywikibot/logentries.py
index 8f9f3f1..167075d 100644
--- a/pywikibot/logentries.py
+++ b/pywikibot/logentries.py
@@ -9,13 +9,11 @@
from typing import Optional

import pywikibot
-from pywikibot.exceptions import Error, HiddenKeyError
-from pywikibot.tools import classproperty, deprecated, PYTHON_VERSION

-if PYTHON_VERSION >= (3, 9):
- List = list
-else:
- from typing import List
+from pywikibot.backports import List
+from pywikibot.exceptions import Error, HiddenKeyError
+from pywikibot.tools import classproperty, deprecated
+

_logger = 'wiki'

diff --git a/pywikibot/page/__init__.py b/pywikibot/page/__init__.py
index cc41edc..2b85139 100644
--- a/pywikibot/page/__init__.py
+++ b/pywikibot/page/__init__.py
@@ -31,6 +31,8 @@
from warnings import warn

import pywikibot
+
+from pywikibot.backports import cache, Dict, List
from pywikibot import config, i18n, textlib
from pywikibot.comms import http
from pywikibot.data.api import APIError
@@ -55,21 +57,11 @@
first_upper,
issue_deprecation_warning,
manage_wrapping,
- PYTHON_VERSION,
redirect_func,
remove_last_args,
)
from pywikibot.tools import is_IP

-if PYTHON_VERSION >= (3, 9):
- from functools import cache
- Dict = dict
- List = list
-else:
- from functools import lru_cache
- from typing import Dict, List
- cache = lru_cache(None)
-

PROTOCOL_REGEX = r'\Ahttps?://'

diff --git a/pywikibot/pagegenerators.py b/pywikibot/pagegenerators.py
index 9c3b365..cb20ea6 100644
--- a/pywikibot/pagegenerators.py
+++ b/pywikibot/pagegenerators.py
@@ -36,6 +36,13 @@

import pywikibot

+from pywikibot import date, config, i18n, xmlreader
+from pywikibot.backports import List
+from pywikibot.bot import ShowingListOption
+from pywikibot.comms import http
+from pywikibot.data import api
+from pywikibot.exceptions import ServerError, UnknownExtension
+from pywikibot.proofreadpage import ProofreadPage
from pywikibot.tools import (
deprecated,
deprecated_args,
@@ -47,18 +54,6 @@
redirect_func,
)

-from pywikibot import date, config, i18n, xmlreader
-from pywikibot.bot import ShowingListOption
-from pywikibot.comms import http
-from pywikibot.data import api
-from pywikibot.exceptions import ServerError, UnknownExtension
-from pywikibot.proofreadpage import ProofreadPage
-from pywikibot.tools import PYTHON_VERSION
-
-if PYTHON_VERSION >= (3, 9):
- List = list
-else:
- from typing import List

_logger = 'pagegenerators'

diff --git a/pywikibot/site/__init__.py b/pywikibot/site/__init__.py
index 5ea559b..4aaec96 100644
--- a/pywikibot/site/__init__.py
+++ b/pywikibot/site/__init__.py
@@ -34,6 +34,7 @@
import pywikibot
import pywikibot.family

+from pywikibot.backports import List
from pywikibot.comms.http import get_authentication
from pywikibot.data import api
from pywikibot.echo import Notification
@@ -80,14 +81,9 @@
itergroup,
MediaWikiVersion,
merge_unique_dicts,
- PYTHON_VERSION,
remove_last_args,
)

-if PYTHON_VERSION >= (3, 9):
- List = list
-else:
- from typing import List

__all__ = ('APISite', 'DataSite', 'Namespace', 'NamespacesDict', 'PageInUse',
'RemovedSite', 'Siteinfo', 'TokenWallet')
diff --git a/pywikibot/site/_namespace.py b/pywikibot/site/_namespace.py
index 51fc7c2..ec95ca5 100644
--- a/pywikibot/site/_namespace.py
+++ b/pywikibot/site/_namespace.py
@@ -8,19 +8,14 @@
from collections.abc import Iterable, Mapping
from typing import Optional, Union

+from pywikibot.backports import List
from pywikibot.tools import (
ComparableMixin,
deprecated_args,
issue_deprecation_warning,
- PYTHON_VERSION,
SelfCallMixin,
)

-if PYTHON_VERSION >= (3, 9):
- List = list
-else:
- from typing import List
-

class Namespace(Iterable, ComparableMixin):

diff --git a/pywikibot/specialbots/_upload.py b/pywikibot/specialbots/_upload.py
index 864339d..5161adb 100644
--- a/pywikibot/specialbots/_upload.py
+++ b/pywikibot/specialbots/_upload.py
@@ -22,19 +22,14 @@
import pywikibot.comms.http as http
import pywikibot.data.api

-
+from pywikibot.backports import List
from pywikibot import config
from pywikibot.bot import BaseBot, QuitKeyboardInterrupt
from pywikibot.data.api import APIError
from pywikibot.exceptions import FatalServerError
-from pywikibot.tools import deprecated_args, PYTHON_VERSION
+from pywikibot.tools import deprecated_args
from pywikibot.tools.formatter import color_format

-if PYTHON_VERSION >= (3, 9):
- List = list
-else:
- from typing import List
-

class UploadRobot(BaseBot):

diff --git a/pywikibot/textlib.py b/pywikibot/textlib.py
index 592a93c..6129681 100644
--- a/pywikibot/textlib.py
+++ b/pywikibot/textlib.py
@@ -21,21 +21,16 @@
from typing import NamedTuple, Optional, Union

import pywikibot
+
+from pywikibot.backports import List, Tuple
from pywikibot.exceptions import InvalidTitle, SiteDefinitionError
from pywikibot.family import Family
from pywikibot.tools import (
deprecate_arg,
deprecated,
issue_deprecation_warning,
- PYTHON_VERSION,
)

-if PYTHON_VERSION >= (3, 9):
- List = list
- Tuple = tuple
-else:
- from typing import List, Tuple
-
try:
import mwparserfromhell
except ImportError as e:
diff --git a/pywikibot/userinterfaces/gui.py b/pywikibot/userinterfaces/gui.py
index a32fa11..41b57c4 100644
--- a/pywikibot/userinterfaces/gui.py
+++ b/pywikibot/userinterfaces/gui.py
@@ -15,7 +15,9 @@
from typing import Optional

import pywikibot
+
from pywikibot import __url__
+from pywikibot.backports import Tuple
from pywikibot.tools import PYTHON_VERSION


@@ -34,11 +36,6 @@
from idlelib.configHandler import idleConf
from idlelib.MultiCall import MultiCallCreator

-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple
-

class TextEditor(ScrolledText):

diff --git a/scripts/add_text.py b/scripts/add_text.py
index f693faa..2296a85 100755
--- a/scripts/add_text.py
+++ b/scripts/add_text.py
@@ -66,15 +66,11 @@

import pywikibot

+from pywikibot.backports import Tuple
from pywikibot import config, i18n, pagegenerators, textlib
from pywikibot.bot_choice import QuitKeyboardInterrupt
from pywikibot.tools.formatter import color_format
-from pywikibot.tools import PYTHON_VERSION

-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple

docuReplacements = {'&params;': pagegenerators.parameterHelp} # noqa: N816

diff --git a/scripts/archivebot.py b/scripts/archivebot.py
index bb9783b..6c38f88 100755
--- a/scripts/archivebot.py
+++ b/scripts/archivebot.py
@@ -107,20 +107,15 @@

import pywikibot

+from pywikibot.backports import List, Set, Tuple
from pywikibot.date import apply_month_delta
from pywikibot import i18n
from pywikibot.textlib import (extract_sections, findmarker, TimeStripper,
to_local_digits)
from pywikibot.tools import (
- deprecated, frozenmap, issue_deprecation_warning, PYTHON_VERSION,
+ deprecated, frozenmap, issue_deprecation_warning,
)

-if PYTHON_VERSION >= (3, 9):
- List = list
- Set = set
- Tuple = tuple
-else:
- from typing import List, Set, Tuple

ShouldArchive = Tuple[str, str]
Size = Tuple[int, str]
diff --git a/scripts/basic.py b/scripts/basic.py
index 3549691..4645978 100755
--- a/scripts/basic.py
+++ b/scripts/basic.py
@@ -48,17 +48,14 @@
# Distributed under the terms of the MIT license.
#
import pywikibot
+
+from pywikibot.backports import Tuple
from pywikibot import pagegenerators

from pywikibot.bot import (
SingleSiteBot, ConfigParserBot, ExistingPageBot, NoRedirectPageBot,
AutomaticTWSummaryBot)
-from pywikibot.tools import PYTHON_VERSION

-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple

# This is required for the text that is shown when you run this script
# with the parameter -help.
diff --git a/scripts/capitalize_redirects.py b/scripts/capitalize_redirects.py
index a38f753..deb8eb9 100755
--- a/scripts/capitalize_redirects.py
+++ b/scripts/capitalize_redirects.py
@@ -31,16 +31,13 @@
# Automatically converted from compat branch by compat2core.py script
#
import pywikibot
+
from pywikibot import i18n, pagegenerators
+from pywikibot.backports import Tuple
from pywikibot.bot import (
MultipleSitesBot, FollowRedirectPageBot, ExistingPageBot
)
-from pywikibot.tools import PYTHON_VERSION

-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple

docuReplacements = {'&params;': pagegenerators.parameterHelp} # noqa: N816

diff --git a/scripts/catall.py b/scripts/catall.py
index 9fa5ced..c466e84 100755
--- a/scripts/catall.py
+++ b/scripts/catall.py
@@ -21,20 +21,15 @@
-onlynew : Only run on pages that do not yet have a category.
"""
#
-# (C) Pywikibot team, 2004-2019
+# (C) Pywikibot team, 2004-2020
#
# Distributed under the terms of the MIT license.
#
import pywikibot
-from pywikibot import i18n, textlib
-from pywikibot.bot import QuitKeyboardInterrupt
-from pywikibot.tools import PYTHON_VERSION

-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
- List = list
-else:
- from typing import List, Tuple
+from pywikibot import i18n, textlib
+from pywikibot.backports import List, Tuple
+from pywikibot.bot import QuitKeyboardInterrupt


def choosecats(pagetext: str) -> List[str]:
diff --git a/scripts/category.py b/scripts/category.py
index 83a459e..418a4ff 100755
--- a/scripts/category.py
+++ b/scripts/category.py
@@ -130,8 +130,8 @@

import pywikibot

-from pywikibot import config, pagegenerators
-from pywikibot import i18n, textlib
+from pywikibot import config, i18n, pagegenerators, textlib
+from pywikibot.backports import Set, Tuple
from pywikibot.bot import (
BaseBot,
Bot,
@@ -142,14 +142,9 @@
suggest_help,
)
from pywikibot.cosmetic_changes import moved_links
-from pywikibot.tools import deprecated_args, open_archive, PYTHON_VERSION
+from pywikibot.tools import deprecated_args, open_archive
from pywikibot.tools.formatter import color_format

-if PYTHON_VERSION >= (3, 9):
- Set = set
- Tuple = tuple
-else:
- from typing import Set, Tuple

# This is required for the text that is shown when you run this script
# with the parameter -help.
diff --git a/scripts/category_redirect.py b/scripts/category_redirect.py
index 42afd58..98fd0c6 100755
--- a/scripts/category_redirect.py
+++ b/scripts/category_redirect.py
@@ -38,14 +38,9 @@

import pywikibot

-from pywikibot import i18n, pagegenerators, config
+from pywikibot import config, i18n, pagegenerators
+from pywikibot.backports import Tuple
from pywikibot.bot import SingleSiteBot
-from pywikibot.tools import PYTHON_VERSION
-
-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple


class CategoryRedirectBot(SingleSiteBot):
diff --git a/scripts/checkimages.py b/scripts/checkimages.py
index 3f6148b..3aa2799 100755
--- a/scripts/checkimages.py
+++ b/scripts/checkimages.py
@@ -90,6 +90,7 @@

import pywikibot

+from pywikibot.backports import List, Tuple
from pywikibot.bot import suggest_help
from pywikibot import config2 as config
from pywikibot.exceptions import NotEmailableError
@@ -97,13 +98,7 @@
from pywikibot import i18n
from pywikibot import pagegenerators as pg
from pywikibot.site import Namespace
-from pywikibot.tools import PYTHON_VERSION

-if PYTHON_VERSION >= (3, 9):
- List = list
- Tuple = tuple
-else:
- from typing import List, Tuple

###############################################################################
# <--------------------------- Change only below! --------------------------->#
diff --git a/scripts/clean_sandbox.py b/scripts/clean_sandbox.py
index 4e9266f..6522866 100755
--- a/scripts/clean_sandbox.py
+++ b/scripts/clean_sandbox.py
@@ -49,13 +49,9 @@
import pywikibot

from pywikibot import i18n, pagegenerators
+from pywikibot.backports import Tuple
from pywikibot.bot import Bot, ConfigParserBot
-from pywikibot.tools import PYTHON_VERSION

-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple

content = {
'commons': '{{Sandbox}}\n<!-- Please edit only below this line. -->',
diff --git a/scripts/commons_link.py b/scripts/commons_link.py
index 481b52e..dccd99c 100755
--- a/scripts/commons_link.py
+++ b/scripts/commons_link.py
@@ -35,12 +35,8 @@
import pywikibot

from pywikibot import textlib, pagegenerators, i18n, Bot
-from pywikibot.tools import PYTHON_VERSION
+from pywikibot.backports import Tuple

-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple

docuReplacements = {'&params;': pagegenerators.parameterHelp} # noqa: N816

diff --git a/scripts/coordinate_import.py b/scripts/coordinate_import.py
index cccd77c..758b9f2 100755
--- a/scripts/coordinate_import.py
+++ b/scripts/coordinate_import.py
@@ -44,14 +44,11 @@
from typing import Optional

import pywikibot
-from pywikibot import pagegenerators, WikidataBot
-from pywikibot.exceptions import CoordinateGlobeUnknownException
-from pywikibot.tools import PYTHON_VERSION

-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple
+from pywikibot import pagegenerators, WikidataBot
+from pywikibot.backports import Tuple
+from pywikibot.exceptions import CoordinateGlobeUnknownException
+

docuReplacements = {'&params;': pagegenerators.parameterHelp} # noqa: N816

diff --git a/scripts/cosmetic_changes.py b/scripts/cosmetic_changes.py
index 02abc43..601eff1 100644
--- a/scripts/cosmetic_changes.py
+++ b/scripts/cosmetic_changes.py
@@ -35,17 +35,12 @@
import pywikibot

from pywikibot import config, i18n, pagegenerators
+from pywikibot.backports import Tuple
from pywikibot.bot import MultipleSitesBot, ExistingPageBot, NoRedirectPageBot
from pywikibot.cosmetic_changes import (
CANCEL_ALL, CANCEL_MATCH, CANCEL_METHOD, CANCEL_PAGE,
CosmeticChangesToolkit,
)
-from pywikibot.tools import PYTHON_VERSION
-
-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple


warning = """
diff --git a/scripts/create_categories.py b/scripts/create_categories.py
index a02ef6c..7d68442 100755
--- a/scripts/create_categories.py
+++ b/scripts/create_categories.py
@@ -36,15 +36,11 @@
# Distributed under the terms of the MIT license.
#
import pywikibot
+
+from pywikibot.backports import Tuple
from pywikibot.bot import AutomaticTWSummaryBot, SingleSiteBot
from pywikibot import pagegenerators
from pywikibot.site import Namespace
-from pywikibot.tools import PYTHON_VERSION
-
-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple


class CreateCategoriesBot(SingleSiteBot, AutomaticTWSummaryBot):
diff --git a/scripts/data_ingestion.py b/scripts/data_ingestion.py
index 754b0e5..d4ce7ad 100755
--- a/scripts/data_ingestion.py
+++ b/scripts/data_ingestion.py
@@ -111,15 +111,11 @@

import pywikibot

+from pywikibot.backports import Tuple
from pywikibot.comms.http import fetch
from pywikibot import pagegenerators
from pywikibot.specialbots import UploadRobot
-from pywikibot.tools import deprecated_args, PYTHON_VERSION
-
-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple
+from pywikibot.tools import deprecated_args


class Photo(pywikibot.FilePage):
diff --git a/scripts/delete.py b/scripts/delete.py
index f90664b..b5d001c 100755
--- a/scripts/delete.py
+++ b/scripts/delete.py
@@ -61,23 +61,11 @@
import pywikibot

from pywikibot import i18n, pagegenerators
+from pywikibot.backports import DefaultDict, Set, Tuple
from pywikibot.bot import MultipleSitesBot, CurrentPageBot
from pywikibot.page import Page
from pywikibot.site import Namespace
-from pywikibot.tools import islice_with_ellipsis, PYTHON_VERSION
-
-if PYTHON_VERSION < (3, 5, 2):
- from typing import Dict as DefaultDict
-elif PYTHON_VERSION < (3, 9):
- from typing import DefaultDict
-else:
- DefaultDict = collections.defaultdict
-
-if PYTHON_VERSION >= (3, 9):
- Set = set
- Tuple = tuple
-else:
- from typing import Set, Tuple
+from pywikibot.tools import islice_with_ellipsis


# This is required for the text that is shown when you run this script
diff --git a/scripts/djvutext.py b/scripts/djvutext.py
index 12ac019..73195ae 100644
--- a/scripts/djvutext.py
+++ b/scripts/djvutext.py
@@ -38,15 +38,10 @@

from pywikibot import i18n

+from pywikibot.backports import Tuple
from pywikibot.bot import SingleSiteBot
from pywikibot.proofreadpage import ProofreadPage
from pywikibot.tools.djvu import DjVuFile
-from pywikibot.tools import PYTHON_VERSION
-
-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple


class DjVuTextBot(SingleSiteBot):
diff --git a/scripts/download_dump.py b/scripts/download_dump.py
index fdb8dee..54931f9 100644
--- a/scripts/download_dump.py
+++ b/scripts/download_dump.py
@@ -24,14 +24,10 @@
from os import remove, replace, symlink, urandom

import pywikibot
+
+from pywikibot.backports import Tuple
from pywikibot import Bot
from pywikibot.comms.http import fetch
-from pywikibot.tools import PYTHON_VERSION
-
-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple


class DownloadDumpBot(Bot):
diff --git a/scripts/editarticle.py b/scripts/editarticle.py
index 8be8e5c..f974011 100755
--- a/scripts/editarticle.py
+++ b/scripts/editarticle.py
@@ -37,13 +37,8 @@

from pywikibot import i18n

+from pywikibot.backports import Tuple
from pywikibot.editor import TextEditor
-from pywikibot.tools import PYTHON_VERSION
-
-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple


class ArticleEditor(object):
diff --git a/scripts/harvest_template.py b/scripts/harvest_template.py
index 44c7af1..e213c79 100755
--- a/scripts/harvest_template.py
+++ b/scripts/harvest_template.py
@@ -99,14 +99,9 @@
import pywikibot

from pywikibot import pagegenerators as pg, textlib
+from pywikibot.backports import List
from pywikibot.bot import WikidataBot, OptionHandler

-from pywikibot.tools import PYTHON_VERSION
-
-if PYTHON_VERSION >= (3, 9):
- List = tuple
-else:
- from typing import List

willstop = False

diff --git a/scripts/interwikidata.py b/scripts/interwikidata.py
index 09a5a95..9c1517f 100644
--- a/scripts/interwikidata.py
+++ b/scripts/interwikidata.py
@@ -32,13 +32,9 @@
import pywikibot

from pywikibot import pagegenerators, output, warning
+from pywikibot.backports import Set
from pywikibot.bot import ExistingPageBot, SingleSiteBot, suggest_help
-from pywikibot.tools import PYTHON_VERSION

-if PYTHON_VERSION >= (3, 9):
- Set = set
-else:
- from typing import Set

# This is required for the text that is shown when you run this script
# with the parameter -help.
diff --git a/scripts/login.py b/scripts/login.py
index b67b09b..7227b21 100755
--- a/scripts/login.py
+++ b/scripts/login.py
@@ -63,15 +63,10 @@

import pywikibot

+from pywikibot.backports import Tuple
from pywikibot import config
from pywikibot.exceptions import SiteDefinitionError
from pywikibot.login import OauthLoginManager
-from pywikibot.tools import PYTHON_VERSION
-
-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple


def _get_consumer_token(site) -> Tuple[str, str]:
diff --git a/scripts/newitem.py b/scripts/newitem.py
index 49418ec..76e3ba1 100755
--- a/scripts/newitem.py
+++ b/scripts/newitem.py
@@ -29,16 +29,13 @@
from textwrap import fill

import pywikibot
+
from pywikibot import pagegenerators
+
+from pywikibot.backports import Set
from pywikibot.bot import NoRedirectPageBot, WikidataBot
from pywikibot.exceptions import (LockedPage, NoCreateError, NoPage,
PageSaveRelatedError)
-from pywikibot.tools import PYTHON_VERSION
-
-if PYTHON_VERSION >= (3, 9):
- Set = set
-else:
- from typing import Set


DELETION_TEMPLATES = ('Q4847311', 'Q6687153', 'Q21528265')
diff --git a/scripts/pagefromfile.py b/scripts/pagefromfile.py
index aa90124..0a85865 100755
--- a/scripts/pagefromfile.py
+++ b/scripts/pagefromfile.py
@@ -74,13 +74,8 @@
import pywikibot

from pywikibot import config, i18n
+from pywikibot.backports import Tuple
from pywikibot.bot import CurrentPageBot, OptionHandler, SingleSiteBot
-from pywikibot.tools import PYTHON_VERSION
-
-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple


class NoTitle(Exception):
diff --git a/scripts/redirect.py b/scripts/redirect.py
index 3628b4f..9b07caf 100755
--- a/scripts/redirect.py
+++ b/scripts/redirect.py
@@ -82,18 +82,10 @@
import pywikibot

from pywikibot import i18n, xmlreader
+from pywikibot.backports import Dict, List, Set, Tuple
from pywikibot.bot import (ExistingPageBot, MultipleSitesBot, OptionHandler,
RedirectPageBot)
from pywikibot.textlib import extract_templates_and_params_regex_simple
-from pywikibot.tools import PYTHON_VERSION
-
-if PYTHON_VERSION >= (3, 9):
- Dict = dict
- List = list
- Set = set
- Tuple = tuple
-else:
- from typing import Dict, List, Set, Tuple


def space_to_underscore(link) -> str:
diff --git a/scripts/solve_disambiguation.py b/scripts/solve_disambiguation.py
index fa6b8ff..a806836 100755
--- a/scripts/solve_disambiguation.py
+++ b/scripts/solve_disambiguation.py
@@ -89,19 +89,17 @@
from typing import Generator, Optional

import pywikibot
+
from pywikibot import config
from pywikibot import editor as editarticle
from pywikibot import i18n, pagegenerators
+from pywikibot.backports import List
from pywikibot.bot import (HighlightContextOption, ListOption,
OutputProxyOption, SingleSiteBot, StandardOption)
from pywikibot.tools import first_lower
-from pywikibot.tools import first_upper as firstcap, PYTHON_VERSION
+from pywikibot.tools import first_upper as firstcap
from pywikibot.tools.formatter import SequenceOutputter

-if PYTHON_VERSION >= (3, 9):
- List = list
-else:
- from typing import List

# Disambiguation Needed template
dn_template = {
diff --git a/scripts/templatecount.py b/scripts/templatecount.py
index 3ddafed..076d611 100755
--- a/scripts/templatecount.py
+++ b/scripts/templatecount.py
@@ -43,14 +43,8 @@
from typing import Generator

import pywikibot
-from pywikibot.tools import PYTHON_VERSION

-if PYTHON_VERSION >= (3, 9):
- Dict = dict
- List = list
- Tuple = tuple
-else:
- from typing import Dict, List, Tuple
+from pywikibot.backports import Dict, List, Tuple


class TemplateCountRobot:
diff --git a/scripts/weblinkchecker.py b/scripts/weblinkchecker.py
index 5f7ed34..bf96ee0 100755
--- a/scripts/weblinkchecker.py
+++ b/scripts/weblinkchecker.py
@@ -131,18 +131,14 @@
from pywikibot import comms, i18n, pagegenerators, textlib
from pywikibot import config2 as config

+from pywikibot.backports import Tuple
from pywikibot.bot import ExistingPageBot, SingleSiteBot, suggest_help
from pywikibot.pagegenerators import (
XMLDumpPageGenerator as _XMLDumpPageGenerator,
)
-from pywikibot.tools import deprecated, PYTHON_VERSION, ThreadList
+from pywikibot.tools import deprecated, ThreadList
from pywikibot.tools.formatter import color_format

-if PYTHON_VERSION >= (3, 9):
- Tuple = tuple
-else:
- from typing import Tuple
-
try:
import memento_client
from memento_client.memento_client import MementoClientException
diff --git a/scripts/welcome.py b/scripts/welcome.py
index 05d8aab..bb39b85 100755
--- a/scripts/welcome.py
+++ b/scripts/welcome.py
@@ -177,16 +177,11 @@
import pywikibot

from pywikibot import config, i18n
-
+from pywikibot.backports import List
from pywikibot.bot import SingleSiteBot
from pywikibot.exceptions import HiddenKeyError
from pywikibot.tools.formatter import color_format
-from pywikibot.tools import PYTHON_VERSION

-if PYTHON_VERSION >= (3, 9):
- List = list
-else:
- from typing import List

locale.setlocale(locale.LC_ALL, '')

diff --git a/tox.ini b/tox.ini
index e91424f..07db505 100644
--- a/tox.ini
+++ b/tox.ini
@@ -119,6 +119,7 @@
# pydocstyle cannot handle multiple __all__ variables
pywikibot/__init__.py : N802, N806, N815, N816
pywikibot/_wbtypes.py: N802
+ pywikibot/backports.py: F401
pywikibot/bot.py: N802, N815, N816
pywikibot/config2.py: N816
pywikibot/cosmetic_changes.py : N802, N803, N806, N816

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

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I366e5c7233ed927d17e7bf8127a6fd7920d7f11d
Gerrit-Change-Number: 651017
Gerrit-PatchSet: 10
Gerrit-Owner: Xqt <info@gno.de>
Gerrit-Reviewer: D3r1ck01 <xsavitar.wiki@aol.com>
Gerrit-Reviewer: Isaacandy <isaac@iznd.xyz>
Gerrit-Reviewer: Matěj Suchánek <matejsuchanek97@gmail.com>
Gerrit-Reviewer: Mpaa <mpaa.wiki@gmail.com>
Gerrit-Reviewer: Siebrand <siebrand@kitano.nl>
Gerrit-Reviewer: Xqt <info@gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged