Xqt has submitted this change. (
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1361161?usp=email )
Change subject: cleanup: Drop Python 3.9 code and update documentation
......................................................................
cleanup: Drop Python 3.9 code and update documentation
Bug: T423572
Change-Id: I78f7b48e486973d3c273d2874e84c4a3a14fd171
---
M .github/workflows/pywikibot-ci.yml
M dev-requirements.txt
M docs/compatibility.rst
M docs/index.rst
M pywikibot/README.rst
M pywikibot/__init__.py
M requirements.txt
M scripts/pyproject.toml
M setup.py
M tests/README.rst
M tests/login_tests.py
M tests/pwb_tests.py
M tests/tools_tests.py
M tests/utils.py
14 files changed, 17 insertions(+), 51 deletions(-)
Approvals:
Xqt: Verified; Looks good to me, approved
Mahveotm: Looks good to me, approved
diff --git a/.github/workflows/pywikibot-ci.yml
b/.github/workflows/pywikibot-ci.yml
index 2eec49f..36eac7a 100644
--- a/.github/workflows/pywikibot-ci.yml
+++ b/.github/workflows/pywikibot-ci.yml
@@ -139,10 +139,8 @@
NO_PROXY: ""
run: |
python pwb.py version
- if [ "${{ matrix.site }}" != "wikisource:zh" ] ||
- [ "${{ matrix.python-version }}" = "pypy3.9" ] ||
- [ "${{ matrix.python-version }}" = "3.9" ]; then
- coverage run -m unittest discover -vv -p \"*_tests.py\";
+ if [ "${{ matrix.site }}" != "wikisource:zh" ]; then
+ coverage run -m unittest discover -vv -p "*_tests.py"
else
coverage run -m pytest
fi
diff --git a/dev-requirements.txt b/dev-requirements.txt
index 2f034cf..cc4c6fa 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,6 +1,5 @@
# This is a requirements file for development dependencies.
#
-# Python 3.10 is required for pytest and pre-commit
pytest >= 9.2.0
pytest-attrib >= 0.1.3
pytest-xvfb >= 3.1.1
diff --git a/docs/compatibility.rst b/docs/compatibility.rst
index a54fb6e..384c5fa 100644
--- a/docs/compatibility.rst
+++ b/docs/compatibility.rst
@@ -13,7 +13,8 @@
================= ===================== ====== ==== =======
================= ================
Pywikibot version Python version No GIL PyPy GraalPy MediaWiki
version 1st Release Date
================= ===================== ====== ==== =======
================= ================
-11.0โ|version| 3.9โ3.15 ๐งช ๐ก๏ธ โ ๏ธ 1.31โ1.46
2026-02-09
+12.0โ|version| 3.10โ3.16 ๐งช ๐ก๏ธ ๐งช๏ธ 1.33โ1.48
2026/2027
+11.0โ11.10.0 3.9โ3.15 ๐งช ๐ก๏ธ โ ๏ธ 1.31โ1.46
2026-02-09
10.0โ10.7.4 3.8โ3.14 โ โ
โ 1.31โ1.44
2025-03-01
9.0โ9.6.3 3.7โ3.13 โ โ
โ 1.27โ1.42
2024-03-08
8.0โ8.6 3.6.1โ3.12 โ โ
โ 1.27โ1.41
2023-01-21
diff --git a/docs/index.rst b/docs/index.rst
index 2ea12d0..b78ca3b 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -21,8 +21,7 @@
whether you have Python installed and to find its version, just type
``python`` at the CMD or shell prompt.
-Python 3.9 or higher is currently required to run the bot but Python 3.10 or
-higher is strictly recommended.
+Python 3.10 or higher is currently required to run the bot.
Pywikibot and this documentation are licensed under the
:ref:`MIT license`;
diff --git a/pywikibot/README.rst b/pywikibot/README.rst
index 0ea442e..b3ac5d7 100644
--- a/pywikibot/README.rst
+++ b/pywikibot/README.rst
@@ -20,7 +20,7 @@
* googlesearch-python to access Google Web API for use with pagegenerators.py
-You need to have at least Python version `3.9
<https://www.python.org/downloads/>`_
+You need to have at least Python version `3.10
<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 a738738..67f083a 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -77,7 +77,7 @@
else:
class ShutDown(Exception):
- """Dummy exception for Python 3.9-3.12."""
+ """Dummy exception for Python 3.10-3.12."""
__all__ = (
diff --git a/requirements.txt b/requirements.txt
index 1fab7e6..43efee5 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -43,9 +43,9 @@
python-stdnum >= 2.2
# GUI
-# Pillow cannot be installed with GraalPy, Python 3.9 or PyPy < 3.11
+# Pillow cannot be installed with GraalPy or PyPy < 3.11
Pillow>=12.2.0; platform_python_implementation == "PyPy" and python_version >=
"3.11"
-Pillow>=12.2.0; platform_python_implementation == "CPython" and
python_version >= "3.10"
+Pillow>=12.2.0; platform_python_implementation == "CPython"
# core pagegenerators
googlesearch-python >= 1.3.0
diff --git a/scripts/pyproject.toml b/scripts/pyproject.toml
index f494477..18e6446 100644
--- a/scripts/pyproject.toml
+++ b/scripts/pyproject.toml
@@ -101,13 +101,13 @@
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
- "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: 3.15",
+ "Programming Language :: Python :: 3.16",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Wiki",
diff --git a/setup.py b/setup.py
index aa2f694..5e5a0a0 100755
--- a/setup.py
+++ b/setup.py
@@ -45,12 +45,11 @@
'memento': ['memento_client==0.6.1'],
'wikitextparser': ['wikitextparser>=0.56.4'],
'mysql': ['PyMySQL >= 1.1.2'],
- # Pillow cannot be installed with GraalPy, Python 3.9 or PyPy < 3.11
+ # Pillow cannot be installed with GraalPy or PyPy < 3.11
'Tkinter': [
'Pillow>=12.2.0; platform_python_implementation == "PyPy" '
'and python_version >= "3.11"',
- 'Pillow>=12.2.0; platform_python_implementation == "CPython" '
- 'and python_version >= "3.10"',
+ 'Pillow>=12.2.0; platform_python_implementation == "CPython"',
],
'mwoauth': [
'PyJWT != 2.10.0, != 2.10.1', # T380270
diff --git a/tests/README.rst b/tests/README.rst
index 3875a61..ab0a25b 100644
--- a/tests/README.rst
+++ b/tests/README.rst
@@ -30,8 +30,6 @@
**pytest**
-.. note:: Running the test suite with pytest requires Python 3.10 or higher.
-
::
pip install "pytest >= 9.0.3"
diff --git a/tests/login_tests.py b/tests/login_tests.py
index 73b776f..77554b7 100755
--- a/tests/login_tests.py
+++ b/tests/login_tests.py
@@ -13,7 +13,6 @@
import builtins
import datetime
import unittest
-import uuid
from collections import defaultdict
from io import StringIO
from pathlib import Path
@@ -235,23 +234,12 @@
def test_eval_security(self) -> None:
"""Test security that password file does not use eval() function."""
- # File-based checks are limited to Python 3.9 only.
- # On newer versions, self.stat patching in setUp() fails,
- # making the file appear to exist.
- use_file = PYTHON_VERSION[:2] == (3, 9)
-
+ # Note: File-based checks is not supportrd with Python 3.10+.
builtins.exploit_value = False
exploit_code = (
"__import__('builtins').__dict__"
".__setitem__('exploit_value', True)"
)
- if use_file:
- exploit_filename = f'pwb_rce_{uuid.uuid4().hex[:8]}.txt'
- exploit_file = Path(exploit_filename)
- exploit_code = (
- f"__import__('pathlib').Path('{exploit_filename}').touch() or "
- + exploit_code
- )
with self.subTest(test='Test ValueError'), \
self.assertRaisesRegex(ValueError,
@@ -263,13 +251,6 @@
with self.subTest(test='Test value was modified'):
self.assertFalse(exploit_value) # noqa: F821
- if use_file:
- with self.subTest(test='Test file exists'):
- self.assertFalse(exploit_file.exists())
-
- # cleanup file (should never happen)
- exploit_file.unlink(missing_ok=True)
-
if __name__ == '__main__':
unittest.main()
diff --git a/tests/pwb_tests.py b/tests/pwb_tests.py
index d279a45..09b4e7f 100755
--- a/tests/pwb_tests.py
+++ b/tests/pwb_tests.py
@@ -18,6 +18,7 @@
import pywikibot
from pywikibot import config
from pywikibot.scripts import wrapper
+from pywikibot.tools import PYTHON_VERSION
from tests import create_path_func, join_tests_path
from tests.aspects import PwbTestCase
from tests.utils import execute, execute_pwb
@@ -160,15 +161,12 @@
:func:`pywikibot.scripts.wrapper.run` (T420109).
"""
eps = entry_points()
- try:
- console = eps.select(group='console_scripts')
- except AttributeError: # Python < 3.10 compatibility path
- console = eps.get('console_scripts', []) # type: ignore[arg-type]
+ console = eps.select(group='console_scripts')
pwb_eps = [ep for ep in console if ep.name == 'pwb']
if not pwb_eps:
- if sys.version_info >= (3, 11):
+ if PYTHON_VERSION >= (3, 11):
import tomllib
else:
try:
diff --git a/tests/tools_tests.py b/tests/tools_tests.py
index 32f719c..ec4d46b 100755
--- a/tests/tools_tests.py
+++ b/tests/tools_tests.py
@@ -20,7 +20,6 @@
from pywikibot import config, tools
from pywikibot.tools import (
- PYTHON_VERSION,
SevenZipFile,
cached,
classproperty,
@@ -957,17 +956,13 @@
'a.b.c.d',
'192.168.0.1\n',
'256.0.0.1',
+ '01.02.03.04'
)
for address in invalid_addresses:
with self.subTest(ip_address=address):
self.assertFalse(is_ip_address(address))
- address = '01.02.03.04'
- with self.subTest(ip_address=address):
- self.assertEqual(is_ip_address(address),
- PYTHON_VERSION < (3, 9, 5))
-
def test_valid_ipv6_addresses(self) -> None:
"""Check with valid IPv6 addresses."""
valid_addresses = (
diff --git a/tests/utils.py b/tests/utils.py
index 532bba9..09bf200 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -665,8 +665,6 @@
):
page.save()
- .. note:: The last sample uses Python 3.10 syntax.
-
.. version-added:: 6.2
.. version-changed:: 9.3
*code* parameter was added
--
To view, visit
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1361161?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.wikimedia.org/r/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I78f7b48e486973d3c273d2874e84c4a3a14fd171
Gerrit-Change-Number: 1361161
Gerrit-PatchSet: 5
Gerrit-Owner: Xqt <[email protected]>
Gerrit-Reviewer: Mahveotm <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]