Xqt has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/834550 )
Change subject: [PWB8] Drop Python 3.5 dependencies ......................................................................
[PWB8] Drop Python 3.5 dependencies
- update requirements - remove version warning - remove Python 3.5 code variants - remove win32_unicode.py - update documentation
Bug: T301908 Change-Id: I3a5183ca82e2c6595cfe0a9b9490319604330731 --- M .appveyor.yml M dev-requirements.txt M docs/api_ref/pywikibot.userinterfaces.rst M docs/index.rst M mypy.ini M pywikibot/README.rst M pywikibot/__init__.py M pywikibot/scripts/generate_user_files.py M pywikibot/specialbots/_upload.py M pywikibot/throttle.py M pywikibot/tools/collections.py M pywikibot/userinterfaces/gui.py M pywikibot/userinterfaces/terminal_interface_win32.py D pywikibot/userinterfaces/win32_unicode.py M requirements.txt M setup.py M tests/eventstreams_tests.py M tests/utils.py 18 files changed, 41 insertions(+), 468 deletions(-)
Approvals: Xqt: Verified; Looks good to me, approved
diff --git a/.appveyor.yml b/.appveyor.yml index 3d1cc5c..48e05d7 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -22,7 +22,6 @@
# Appveyor pre-installs these versions onto build machines
- - PYTHON: "C:\Python36-x64" PYTHON_VERSION: "3.6.x" PYTHON_ARCH: "64" diff --git a/dev-requirements.txt b/dev-requirements.txt index 94a3ad4..a90a4b5 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -2,9 +2,8 @@ #
pytest >= 5.3 -pytest-cov >= 2.11.1, < 3.0.0;python_version<"3.6" -pytest-cov >= 3.0.0;python_version>="3.10" -pytest-cov >= 2.11.1;python_version>="3.6" and python_version<"3.10" +pytest-cov >= 3.0.0; python_version>="3.10" +pytest-cov >= 2.11.1; python_version<"3.10" pytest-timeout pytest-runner pytest-subtests >= 0.3.2 @@ -14,13 +13,9 @@ # httpbin 0.7 fails with werkzeug 2.1.0/1 (T305124) werkzeug>=0.15.5, <2.1.0
-# T293440: pytest-httpbin needs cffi >=1.0.0 -# but Python 3.5 needs cffi < 1.15 which is not taken into account -cffi >= 1.0.0, < 1.15.0 ;python_version=="3.5" pytest-httpbin
pydocstyle>=4.0.0 -flake8==3.9.2; python_version < "3.6" flake8>=5.0.2; python_version >= "3.6" flake8-docstrings>=0.2.6 flake8-isort;python_version>="3.6" diff --git a/docs/api_ref/pywikibot.userinterfaces.rst b/docs/api_ref/pywikibot.userinterfaces.rst index bb1240b..576e61e 100644 --- a/docs/api_ref/pywikibot.userinterfaces.rst +++ b/docs/api_ref/pywikibot.userinterfaces.rst @@ -51,9 +51,3 @@
.. automodule:: userinterfaces.transliteration :synopsis: Module to transliterate text - -:mod:`win32_unicode` --- Unicode Interface for Python 3.5 ----------------------------------------------------------- - -.. automodule:: userinterfaces.win32_unicode - :synopsis: Unicode support for stdout, stderr and argv with Python 3.5. diff --git a/docs/index.rst b/docs/index.rst index e78b4bb..3a84893 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -19,8 +19,8 @@ whether you have Python installed and to find its version, just type ``python`` at the CMD or shell prompt.
-Python 3.5.3 or higher is currently required to run the bot, but Python 3.6 -or higher is recommended. Python 3.5 support will be dropped with Pywikibot 8. +Python 3.6.0 or higher is currently required to run the bot, but Python 3.7 +or higher is recommended. Python 3.6 support will be dropped with Pywikibot 9.
Pywikibot and this documentation are licensed under the :ref:`MIT license`; diff --git a/mypy.ini b/mypy.ini index 34102e5..4a36827 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,5 +1,5 @@ [mypy] -python_version = 3.5 +python_version = 3.6 check_untyped_defs = true disallow_any_generics = true disallow_incomplete_defs = true diff --git a/pywikibot/README.rst b/pywikibot/README.rst index f1cbab1..21f1f54 100644 --- a/pywikibot/README.rst +++ b/pywikibot/README.rst @@ -27,7 +27,7 @@ * python-tkinter (optional, used by some experimental GUI stuff)
-You need to have at least Python version `3.5.3 https://www.python.org/downloads/`_ +You need to have at least Python version `3.6.0 https://www.python.org/downloads/`_ or newer installed on your computer to be able to run any of the code in this package. Please refer the manual at mediawiki for further details and restrictions. diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py index a9f2a56..a8e8889 100644 --- a/pywikibot/__init__.py +++ b/pywikibot/__init__.py @@ -68,7 +68,7 @@ ) from pywikibot.site import APISite, BaseSite, DataSite from pywikibot.time import Timestamp -from pywikibot.tools import normalize_username, PYTHON_VERSION +from pywikibot.tools import normalize_username
ItemPageStrNoneType = Union[str, 'ItemPage', None] @@ -95,15 +95,6 @@ argvu = [] # type: List[str]
-if PYTHON_VERSION < (3, 6): - warn(""" -Python {version} will be dropped with release 8.0 soon. -It is recommended to use Python 3.6 or above. -See T301908 for further information. -""".format(version=sys.version.split(maxsplit=1)[0]), - FutureWarning) # adjust this line no in utils.execute() - - class Coordinate(_WbRepresentation):
"""Class for handling and storing Coordinates.""" diff --git a/pywikibot/scripts/generate_user_files.py b/pywikibot/scripts/generate_user_files.py index 443aa82..5882a80 100755 --- a/pywikibot/scripts/generate_user_files.py +++ b/pywikibot/scripts/generate_user_files.py @@ -231,9 +231,6 @@ ConfigSection = namedtuple('ConfigSection', 'head, info, section')
config_path = Path(__file__).resolve().parents[1].joinpath('config.py') - if PYTHON_VERSION < (3, 6): - config_path = str(config_path) - with codecs.open(config_path, 'r', 'utf-8') as config_f: config_file = config_f.read()
diff --git a/pywikibot/specialbots/_upload.py b/pywikibot/specialbots/_upload.py index 16e38e7..0764746 100644 --- a/pywikibot/specialbots/_upload.py +++ b/pywikibot/specialbots/_upload.py @@ -135,7 +135,7 @@ else: headers = {}
- with open(str(path), 'ab') as fd: # T272345: Python 3.5 needs str + with open(path, 'ab') as fd: os.lseek(handle, file_len, 0) try: response = http.fetch(file_url, stream=True, diff --git a/pywikibot/throttle.py b/pywikibot/throttle.py index 9df3846..1ac0cf7 100644 --- a/pywikibot/throttle.py +++ b/pywikibot/throttle.py @@ -10,18 +10,12 @@ import time from collections import Counter, namedtuple from contextlib import suppress +from hashlib import blake2b from typing import Optional, Union
import pywikibot from pywikibot import config -from pywikibot.tools import PYTHON_VERSION, deprecated - - -if PYTHON_VERSION < (3, 6): - from hashlib import md5 - blake2b = None -else: - from hashlib import blake2b +from pywikibot.tools import deprecated
FORMAT_LINE = '{module_id} {pid} {time} {site}\n' @@ -103,11 +97,8 @@ if module is None: module = pywikibot.calledModuleName() module = module.encode() - if blake2b: - hashobj = blake2b(module, digest_size=2) - else: - hashobj = md5(module) - return hashobj.hexdigest()[:4] # slice for Python 3.5 + hashobj = blake2b(module, digest_size=2) + return hashobj.hexdigest()
def _read_file(self, raise_exc: bool = False): """Yield process entries from file.""" diff --git a/pywikibot/tools/collections.py b/pywikibot/tools/collections.py index a4cd8a3..af9460a 100644 --- a/pywikibot/tools/collections.py +++ b/pywikibot/tools/collections.py @@ -7,14 +7,7 @@ import collections
from abc import abstractmethod, ABC -from collections.abc import ( - Container, - Generator, - Iterable, - Iterator, - Mapping, - Sized, -) +from collections.abc import Collection, Generator, Iterator, Mapping from contextlib import suppress from itertools import chain from typing import Any @@ -32,8 +25,7 @@ )
-# Collection is not provided with Python 3.5; use Container, Iterable, Sized -class SizedKeyCollection(Container, Iterable, Sized): +class SizedKeyCollection(Collection):
"""Structure to hold values where the key is given by the value itself.
diff --git a/pywikibot/userinterfaces/gui.py b/pywikibot/userinterfaces/gui.py index 395b06f..1dea42b 100644 --- a/pywikibot/userinterfaces/gui.py +++ b/pywikibot/userinterfaces/gui.py @@ -12,6 +12,11 @@ # Distributed under the terms of the MIT license. # import tkinter +from idlelib import replace as ReplaceDialog +from idlelib import search as SearchDialog +from idlelib.config import idleConf +from idlelib.configdialog import ConfigDialog +from idlelib.multicall import MultiCallCreator from tkinter import simpledialog as tkSimpleDialog from tkinter.scrolledtext import ScrolledText from typing import Optional @@ -22,20 +27,6 @@ from pywikibot.tools import PYTHON_VERSION
-# T164163: Fix idlelib import in Python 3.6 -if PYTHON_VERSION >= (3, 6): - from idlelib import replace as ReplaceDialog - from idlelib import search as SearchDialog - from idlelib.config import idleConf - from idlelib.configdialog import ConfigDialog - from idlelib.multicall import MultiCallCreator -else: - from idlelib import ReplaceDialog, SearchDialog - from idlelib.configDialog import ConfigDialog - from idlelib.configHandler import idleConf - from idlelib.MultiCall import MultiCallCreator - - class TextEditor(ScrolledText):
"""A text widget with some editing enhancements. @@ -562,15 +553,6 @@ @staticmethod def get_image(photo, width, height): """Take the BytesIO object and build an imageTK thumbnail.""" - if PYTHON_VERSION < (3, 6): - # vulnerability found in Pillow<8.1.1 - from sys import version - raise RuntimeError( - 'This script requires Python 3.6+ for GUI support.\n' - '{version} is not supported. Please update your Python.' - .format(version=version.split(maxsplit=1)[0]) - ) - try: from PIL import Image, ImageTk except ImportError: diff --git a/pywikibot/userinterfaces/terminal_interface_win32.py b/pywikibot/userinterfaces/terminal_interface_win32.py index c3a3454..4b25740 100644 --- a/pywikibot/userinterfaces/terminal_interface_win32.py +++ b/pywikibot/userinterfaces/terminal_interface_win32.py @@ -6,7 +6,6 @@ # import ctypes
-from pywikibot.tools import PYTHON_VERSION from pywikibot.userinterfaces import terminal_interface_base
@@ -35,19 +34,6 @@
"""User interface for Win32 terminals."""
- def __init__(self) -> None: - """Initializer.""" - super().__init__() - # issue1602 solved in Python 3.6 - if PYTHON_VERSION == (3, 5): # pragma: no cover - from pywikibot.userinterfaces import win32_unicode - stdin, stdout, stderr, argv = win32_unicode.get_unicode_console() - self.stdin = stdin - self.stdout = stdout - self.stderr = stderr - self.argv = argv - self.encoding = 'utf-8' - def support_color(self, target_stream): """Return whether the target stream supports actually color.""" return target_stream.isatty() diff --git a/pywikibot/userinterfaces/win32_unicode.py b/pywikibot/userinterfaces/win32_unicode.py deleted file mode 100644 index a135878..0000000 --- a/pywikibot/userinterfaces/win32_unicode.py +++ /dev/null @@ -1,335 +0,0 @@ -"""Unicode support for stdout, stderr and argv with Python 3.5. - -.. deprecated:: 7.1 - will be removed with Pywikibot 8 when Python 3.5 support is dropped. -""" -# -# (C) Pywikibot team, 2012-2022 -# -############################################## -# Support for unicode in Windows cmd.exe -# Posted on Stack Overflow [1], available under CC-BY-SA 3.0 [2] -# -# Question: "Windows cmd encoding change causes Python crash" [3] by Alex [4], -# Answered [5] by David-Sarah Hopwood [6]. -# -# [1] https://stackoverflow.com -# [2] https://creativecommons.org/licenses/by-sa/3.0/ -# [3] https://stackoverflow.com/questions/878972 -# [4] https://stackoverflow.com/users/85185 -# [5] https://stackoverflow.com/a/3259271/118671 -# [6] https://stackoverflow.com/users/393146 -# -################################################ -# -# Licensed under both CC-BY-SA and the MIT license. -# -################################################ -import sys -from contextlib import suppress -from ctypes import Structure, byref -from ctypes import c_void_p as LPVOID -from ctypes import create_unicode_buffer, sizeof -from io import IOBase, UnsupportedOperation -from typing import IO - -from pywikibot.backports import List, Tuple - - -OSWIN32 = (sys.platform == 'win32') - -stdin = sys.stdin -stdout = sys.stdout -stderr = sys.stderr -argv = sys.argv - -original_stderr = sys.stderr - -if OSWIN32: - from ctypes import POINTER, WINFUNCTYPE, WinError, windll - from ctypes.wintypes import ( - BOOL, - DWORD, - HANDLE, - LPWSTR, - SHORT, - UINT, - ULONG, - WCHAR, - ) - -try: - ReadConsoleW = WINFUNCTYPE(BOOL, HANDLE, LPVOID, DWORD, POINTER(DWORD), - LPVOID)(('ReadConsoleW', windll.kernel32)) - WriteConsoleW = WINFUNCTYPE(BOOL, HANDLE, LPWSTR, DWORD, POINTER(DWORD), - LPVOID)(('WriteConsoleW', windll.kernel32)) -except NameError: - ReadConsoleW = WriteConsoleW = None - - -class UnicodeInput(IOBase): - - """Unicode terminal input class.""" - - def __init__(self, hConsole, name, bufsize: int = 1024) -> None: - """Initialize the input stream.""" - self._hConsole = hConsole - self.bufsize = bufsize - self.buffer = create_unicode_buffer(bufsize) - self.name = name - self.encoding = 'utf-8' - - def readline(self): - """Read one line from the input.""" - maxnum = DWORD(self.bufsize - 1) - numrecv = DWORD(0) - result = ReadConsoleW(self._hConsole, self.buffer, maxnum, - byref(numrecv), None) - if not result: - raise Exception('stdin failure') - return self.buffer.value[:numrecv.value] - - -class UnicodeOutput(IOBase): - - """Unicode terminal output class.""" - - def __init__(self, hConsole, stream, fileno, name) -> None: - """Initialize the output stream.""" - self._hConsole = hConsole - self._stream = stream - self._fileno = fileno - self.softspace = False - self.mode = 'w' - self.encoding = 'utf-8' - self.name = name - self.flush() - - def fileno(self): - """Return the fileno.""" - return self._fileno - - def flush(self): - """Flush the stream.""" - if self._hConsole is None: - try: - self._stream.flush() - except Exception as e: - _complain('{}.flush: {!r} from {!r}' - .format(self.name, e, self._stream)) - raise - - def write(self, text): - """Write the text to the output.""" - try: - if self._hConsole is None: - self._stream.write(text) - else: - if not isinstance(text, str): - text = bytes(text).decode('utf-8') - remaining = len(text) - while remaining > 0: - n = DWORD(0) - # There is a shorter-than-documented limitation on the - # length of the string passed to WriteConsoleW (see - # https://tahoe-lafs.org/trac/tahoe-lafs/ticket/1232. - retval = WriteConsoleW(self._hConsole, text, - min(remaining, 10000), - byref(n), None) - if 0 in (retval, n.value): - msg = 'WriteConsoleW returned {!r}, n.value = {!r}' \ - .format(retval, n.value) - raise OSError(msg) - remaining -= n.value - if remaining == 0: - break - text = text[n.value:] - except Exception as e: - _complain('{}.write: {!r}'.format(self.name, e)) - raise - - def writelines(self, lines): - """Write a list of lines by using write.""" - try: - for line in lines: - self.write(line) - except Exception as e: - _complain('{}.writelines: {!r}'.format(self.name, e)) - raise - - def isatty(self): - """Return True if the stream is interactive.""" - return self._hConsole is not None - - -def old_fileno(std_name): - """Return the fileno or None if that doesn't work.""" - # some environments like IDLE don't support the fileno operation - # handle those like std streams which don't have fileno at all - std = getattr(sys, 'std{}'.format(std_name)) - if hasattr(std, 'fileno'): - with suppress(UnsupportedOperation): - return std.fileno() - return None - - -# If any exception occurs in this code, try to print it on stderr, -# which makes for frustrating debugging if stderr is directed to our wrapper. -# So be paranoid about catching errors and reporting them to original_stderr, -# so that we can at least see them. -def _complain(message) -> None: - print(isinstance(message, str) and message or repr(message), - file=original_stderr) - - -def force_truetype_console(h_stdout) -> None: - """Force the console to use a TrueType font (Vista+).""" - TMPF_TRUETYPE = 0x04 - LF_FACESIZE = 32 - - class COORD(Structure): - _fields_ = [('X', SHORT), - ('Y', SHORT)] - - class CONSOLE_FONT_INFOEX(Structure): - _fields_ = [('cbSize', ULONG), - ('nFont', DWORD), - ('dwFontSize', COORD), - ('FontFamily', UINT), - ('FontWeight', UINT), - ('FaceName', WCHAR * LF_FACESIZE)] - - try: - GetCurrentConsoleFontEx = WINFUNCTYPE( - BOOL, - HANDLE, # hConsoleOutput - BOOL, # bMaximumWindow - POINTER(CONSOLE_FONT_INFOEX), # lpConsoleCurrentFontEx - )(('GetCurrentConsoleFontEx', windll.kernel32)) - - SetCurrentConsoleFontEx = WINFUNCTYPE( - BOOL, - HANDLE, # hConsoleOutput - BOOL, # bMaximumWindow - POINTER(CONSOLE_FONT_INFOEX), # lpConsoleCurrentFontEx - )(('SetCurrentConsoleFontEx', windll.kernel32)) - except AttributeError: - # pre Windows Vista. Return without doing anything. - return - - current_font = CONSOLE_FONT_INFOEX() - current_font.cbSize = sizeof(CONSOLE_FONT_INFOEX) - - if not GetCurrentConsoleFontEx(h_stdout, True, byref(current_font)): - WinError() - - truetype_font = (current_font.FontFamily & TMPF_TRUETYPE) - - if not truetype_font: - new_font = CONSOLE_FONT_INFOEX() - new_font.cbSize = sizeof(CONSOLE_FONT_INFOEX) - new_font.FaceName = 'Lucida Console' - - if not SetCurrentConsoleFontEx(h_stdout, True, byref(new_font)): - WinError() - - -def get_unicode_console() -> Tuple[IO, IO, IO, List[str]]: - """ - Get Unicode console objects. - - :return: stdin, stdout, stderr, argv - """ - # Make Unicode console output work independently of the current code page. - # This also fixes https://bugs.python.org/issue1602 - # Credit to Michael Kaplan - # http://blogs.msdn.com/b/michkap/archive/2010/04/07/9989346.aspx - # and TZOmegaTZIOY - # https://stackoverflow.com/questions/878972/windows-cmd-encoding-change-cause... - - global stdin, stdout, stderr - - if not OSWIN32: - return stdin, stdout, stderr, argv - - try: - # https://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx - # HANDLE WINAPI GetStdHandle(DWORD nStdHandle); - # returns INVALID_HANDLE_VALUE, NULL, or a valid handle - # - # https://msdn.microsoft.com/en-us/library/aa364960(VS.85).aspx - # DWORD WINAPI GetFileType(DWORD hFile); - # - # https://msdn.microsoft.com/en-us/library/ms683167(VS.85).aspx - # BOOL WINAPI GetConsoleMode(HANDLE hConsole, LPDWORD lpMode); - - GetStdHandle = WINFUNCTYPE(HANDLE, DWORD)(('GetStdHandle', - windll.kernel32)) - STD_INPUT_HANDLE = DWORD(-10) - STD_OUTPUT_HANDLE = DWORD(-11) - STD_ERROR_HANDLE = DWORD(-12) - GetFileType = WINFUNCTYPE(DWORD, DWORD)(('GetFileType', - windll.kernel32)) - FILE_TYPE_CHAR = 0x0002 - FILE_TYPE_REMOTE = 0x8000 - GetConsoleMode = (WINFUNCTYPE(BOOL, HANDLE, POINTER(DWORD)) - (('GetConsoleMode', windll.kernel32))) - INVALID_HANDLE_VALUE = DWORD(-1).value - - def not_a_console(handle): - """Return whether the handle is not to a console.""" - if handle == INVALID_HANDLE_VALUE or handle is None: - return True - return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR - or GetConsoleMode(handle, byref(DWORD())) == 0) - - old_stdin_fileno = old_fileno('in') - old_stdout_fileno = old_fileno('out') - old_stderr_fileno = old_fileno('err') - - STDIN_FILENO = 0 - STDOUT_FILENO = 1 - STDERR_FILENO = 2 - real_stdin = (old_stdin_fileno == STDIN_FILENO) - real_stdout = (old_stdout_fileno == STDOUT_FILENO) - real_stderr = (old_stderr_fileno == STDERR_FILENO) - - if real_stdin: - hStdin = GetStdHandle(STD_INPUT_HANDLE) - if not_a_console(hStdin): - real_stdin = False - - if real_stdout: - hStdout = GetStdHandle(STD_OUTPUT_HANDLE) - force_truetype_console(hStdout) - if not_a_console(hStdout): - real_stdout = False - - if real_stderr: - hStderr = GetStdHandle(STD_ERROR_HANDLE) - force_truetype_console(hStderr) - if not_a_console(hStderr): - real_stderr = False - - if real_stdout or real_stderr: - if real_stdin: - stdin = UnicodeInput(hStdin, name='<Unicode console stdin>') - - if real_stdout: - stdout = UnicodeOutput(hStdout, sys.stdout, STDOUT_FILENO, - '<Unicode console stdout>') - else: - stdout = UnicodeOutput(None, sys.stdout, old_stdout_fileno, - '<Unicode redirected stdout>') - - if real_stderr: - stderr = UnicodeOutput(hStderr, sys.stderr, STDERR_FILENO, - '<Unicode console stderr>') - else: - stderr = UnicodeOutput(None, sys.stderr, old_stderr_fileno, - '<Unicode redirected stderr>') - except Exception as e: - _complain('exception {!r} while fixing up sys.stdout and sys.stderr' - .format(e)) - - return stdin, stdout, stderr, argv diff --git a/requirements.txt b/requirements.txt index 10eddfb..862c1cf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,13 +18,11 @@ # $ awk -F '[#>=]' '{print $1}' requirements.txt | xargs apt-cache search
# mandatory dependencies, others are optional -requests>=2.20.1, < 2.26.0; python_version < '3.6' -requests>=2.20.1, < 2.28.0; python_version >= '3.6' and python_version < '3.7' +requests>=2.20.1, < 2.28.0; python_version < '3.7' requests>=2.20.1; python_version >= '3.7' setuptools>=48.0.0 ; python_version >= '3.10' setuptools>=38.5.2 ; python_version >= '3.7' and python_version < '3.10' -setuptools>=20.8.1, <59.7.0 ; python_version >= '3.6' and python_version < '3.7' -setuptools>=20.8.1, !=50.0.0, <51.0.0 ; python_version < '3.6' +setuptools>=20.8.1, <59.7.0 ; python_version < '3.7'
# MediaWiki markup parser # mwparserfromhell is default, wikitextparser can be used instead @@ -44,15 +42,15 @@ python-stdnum >= 1.17
# GUI -Pillow >= 8.1.1 ; python_version >= '3.6' +Pillow >= 8.1.1
# core pagegenerators google >= 1.7 sseclient >= 0.0.18,< 0.0.23
# The mysql generator in pagegenerators depends on PyMySQL -PyMySQL >= 0.7.11, < 1.0.0 ; python_version < '3.6' -PyMySQL >= 1.0.0 ; python_version >= '3.6' +# toolforge uses 0.9.3 +PyMySQL >= 0.9.3
# core HTML comparison parser in diff module beautifulsoup4 diff --git a/setup.py b/setup.py index fe66a45..0f646a1 100755 --- a/setup.py +++ b/setup.py @@ -38,7 +38,7 @@ Pywikibot is not available on: {version}
-This version of Pywikibot only supports Python 3.5.3+. +This version of Pywikibot only supports Python 3.6+. """
try: @@ -49,7 +49,7 @@
def python_is_supported() -> bool: """Check that Python is supported.""" - return sys.version_info[:3] >= (3, 5, 3) + return sys.version_info[:3] >= (3, 6)
if not python_is_supported(): # pragma: no cover @@ -65,19 +65,15 @@ 'Google': ['google>=1.7'], 'memento': ['memento_client==0.6.1'], 'mwparserfromhell': ['mwparserfromhell>=0.5.0'], - 'wikitextparser': ['wikitextparser>=0.47.5; python_version < "3.6"', - 'wikitextparser>=0.47.0; python_version >= "3.6"'], - 'mysql': ['PyMySQL >= 0.7.11, < 1.0.0 ; python_version < "3.6"', - 'PyMySQL >= 1.0.0 ; python_version >= "3.6"'], - 'Tkinter': [ # vulnerability found in Pillow<8.1.1 - 'Pillow>=8.1.1;python_version>="3.6"', - ], + 'wikitextparser': ['wikitextparser>=0.47.0'], + 'mysql': ['PyMySQL >= 0.9.3'], # toolforge + # vulnerability found in Pillow<8.1.1 but toolforge uses 5.4.1 + 'Tkinter': ['Pillow>=8.1.1'], 'mwoauth': ['mwoauth!=0.3.1,>=0.2.4'], 'html': ['BeautifulSoup4'], 'http': ['fake_useragent'], 'flake8': [ # Due to incompatibilities between packages the order matters. - 'flake8==3.9.2,<5.0.0; python_version < "3.6"', - 'flake8>=5.0.2; python_version >= "3.6"', + 'flake8>=5.0.2', 'darglint', 'pydocstyle>=4.0.0', 'flake8-bugbear!=21.4.1,!=21.11.28', @@ -112,16 +108,12 @@ # ------- setup install_requires ------- # # packages which are mandatory dependencies = [ - 'requests>=2.20.1, <2.26.0; python_version < "3.6"', - 'requests>=2.20.1, <2.28.0; ' - 'python_version >= "3.6" and python_version < "3.7"', + 'requests>=2.20.1, <2.28.0; python_version < "3.7"', 'requests>=2.20.1; python_version>="3.7"', # PEP 440 'setuptools>=48.0.0 ; python_version >= "3.10"', 'setuptools>=38.5.2 ; python_version >= "3.7" and python_version < "3.10"', - 'setuptools>=20.8.1, <59.7.0 ' - '; python_version >= "3.6" and python_version < "3.7"', - 'setuptools>=20.8.1, !=50.0.0, <51.0.0 ; python_version < "3.6"', + 'setuptools>=20.8.1, <59.7.0 ; python_version < "3.7"', ] # in addition either mwparserfromhell or wikitextparser is required
@@ -277,7 +269,7 @@ # zip_safe install_requires=dependencies, extras_require=extra_deps, - python_requires='>=3.5.3', + python_requires='>=3.6', # namespace_packages test_suite='tests.collector', tests_require=test_deps, @@ -363,7 +355,6 @@ 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', diff --git a/tests/eventstreams_tests.py b/tests/eventstreams_tests.py index 873bfc7..bafe316 100755 --- a/tests/eventstreams_tests.py +++ b/tests/eventstreams_tests.py @@ -13,7 +13,6 @@ from pywikibot import config, Site from pywikibot.comms.eventstreams import EventSource, EventStreams from pywikibot.family import WikimediaFamily -from pywikibot.tools import PYTHON_VERSION
from tests.aspects import DefaultSiteTestCase, TestCase, require_modules from tests.utils import skipping @@ -45,10 +44,9 @@ self.assertEqual(e._url, e.sse_kwargs.get('url')) self.assertIsNone(e._total) self.assertIsNone(e._streams) - if PYTHON_VERSION >= (3, 6): - self.assertEqual(repr(e), - "EventStreams(url='{}')" - .format(self.sites[key]['hostname'])) + self.assertEqual(repr(e), + "EventStreams(url='{}')" + .format(self.sites[key]['hostname']))
def test_url_from_site(self, key): """Test EventStreams with url from site.""" @@ -61,12 +59,10 @@ self.assertEqual(e._url, e.sse_kwargs.get('url')) self.assertIsNone(e._total) self.assertEqual(e._streams, streams) - if PYTHON_VERSION >= (3, 6): - site_repr = 'site={}, '.format( - repr(site)) if site != Site() else '' - self.assertEqual(repr(e), - "EventStreams({}streams='{}')" - .format(site_repr, streams)) + site_repr = 'site={}, '.format(repr(site)) if site != Site() else '' + self.assertEqual(repr(e), + "EventStreams({}streams='{}')" + .format(site_repr, streams))
@mock.patch('pywikibot.comms.eventstreams.EventSource', new=mock.MagicMock()) diff --git a/tests/utils.py b/tests/utils.py index 5245dcc..e9031dc 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -21,7 +21,6 @@ from pywikibot.exceptions import APIError from pywikibot.login import LoginStatus from pywikibot.site import Namespace -from pywikibot.tools import PYTHON_VERSION
from tests import _pwb_py
@@ -450,9 +449,6 @@
:param command: executable to run and arguments to use """ - if PYTHON_VERSION < (3, 6): - command.insert(1, '-W ignore::FutureWarning:pywikibot:104') - env = os.environ.copy()
# Prevent output by test package; e.g. 'max_retries reduced from x to y'