From 38e19bd96642a77e43c7d6feda56b01ae1b08d71 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 4 Sep 2025 18:00:21 +0300 Subject: [PATCH 1/9] Deprecate __version__ attribute --- Doc/deprecations/pending-removal-in-3.17.rst | 21 +++++++++++++ Doc/whatsnew/3.15.rst | 31 +++++++++++++++++++ Lib/argparse.py | 10 +++++- Lib/csv.py | 11 +++++-- Lib/ctypes/macholib/__init__.py | 8 ++++- Lib/ipaddress.py | 12 +++++-- Lib/json/__init__.py | 10 +++++- Lib/logging/__init__.py | 16 ++++++++-- Lib/optparse.py | 11 +++++-- Lib/pickle.py | 1 - Lib/platform.py | 11 +++++-- Lib/re/__init__.py | 11 +++++-- Lib/socketserver.py | 12 +++++-- Lib/tabnanny.py | 11 +++++-- Lib/test/test_argparse.py | 10 ++++++ Lib/test/test_csv.py | 11 +++++++ Lib/test/test_ctypes/test_macholib.py | 12 +++++++ Lib/test/test_ipaddress.py | 10 ++++++ Lib/test/test_json/__init__.py | 10 ++++++ Lib/test/test_logging.py | 10 ++++++ Lib/test/test_optparse.py | 10 ++++++ Lib/test/test_re.py | 10 ++++++ Lib/test/test_socketserver.py | 9 ++++++ Lib/test/test_tabnanny.py | 17 +++++++++- Lib/test/test_tkinter/test_font.py | 10 ++++++ Lib/test/test_ttk/__init__.py | 10 ++++++ Lib/tkinter/font.py | 10 +++++- Lib/tkinter/ttk.py | 11 +++++-- ...5-09-08-17-32-02.gh-issue-76007.peEgcr.rst | 2 ++ 29 files changed, 301 insertions(+), 27 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-09-08-17-32-02.gh-issue-76007.peEgcr.rst diff --git a/Doc/deprecations/pending-removal-in-3.17.rst b/Doc/deprecations/pending-removal-in-3.17.rst index 370b98307e5228..5c94621497f9c7 100644 --- a/Doc/deprecations/pending-removal-in-3.17.rst +++ b/Doc/deprecations/pending-removal-in-3.17.rst @@ -8,3 +8,24 @@ Pending removal in Python 3.17 but it has been retained for backward compatibility, with removal scheduled for Python 3.17. Users should use documented introspection helpers like :func:`typing.get_origin` and :func:`typing.get_args` instead of relying on private implementation details. + +* The ``__version__`` attribute has been deprecated in these standard library + modules and will be removed in Python 3.17. + Use :py:data:`sys.version_info` instead. + + - :mod:`argparse` + - :mod:`csv` + - :mod:`!ctypes.macholib` + - :mod:`ipaddress` + - :mod:`json` + - :mod:`logging` (``__date__`` also deprecated) + - :mod:`optparse` + - :mod:`pickle` + - :mod:`platform` + - :mod:`re` + - :mod:`socketserver` + - :mod:`tabnanny` + - :mod:`tkinter.font` + - :mod:`tkinter.ttk` + + (Contributed by Hugo van Kemenade in :gh:`76007`.) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 01f1f31647f5e3..3a7ade46c82e59 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -550,9 +550,40 @@ hashlib (Contributed by Bénédikt Tran in :gh:`134978`.) +__version__ +----------- + +* The ``__version__`` attribute has been deprecated in these standard library + modules and will be removed in Python 3.17. + Use :py:data:`sys.version_info` instead. + + - :mod:`argparse` + - :mod:`csv` + - :mod:`!ctypes.macholib` + - :mod:`ipaddress` + - :mod:`json` + - :mod:`logging` (``__date__`` also deprecated) + - :mod:`optparse` + - :mod:`pickle` + - :mod:`platform` + - :mod:`re` + - :mod:`socketserver` + - :mod:`tabnanny` + - :mod:`tkinter.font` + - :mod:`tkinter.ttk` + + (Contributed by Hugo van Kemenade in :gh:`76007`.) .. Add deprecations above alphabetically, not here at the end. +.. include:: ../deprecations/pending-removal-in-3.16.rst + +.. include:: ../deprecations/pending-removal-in-3.17.rst + +.. include:: ../deprecations/pending-removal-in-3.19.rst + +.. include:: ../deprecations/pending-removal-in-future.rst + Removed ======= diff --git a/Lib/argparse.py b/Lib/argparse.py index 2144c81886ad19..16ddf8469ba77a 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -64,7 +64,6 @@ still considered an implementation detail.) """ -__version__ = '1.1' __all__ = [ 'ArgumentParser', 'ArgumentError', @@ -2773,3 +2772,12 @@ def error(self, message): def _warning(self, message): args = {'prog': self.prog, 'message': message} self._print_message(_('%(prog)s: warning: %(message)s\n') % args, _sys.stderr) + + +def __getattr__(name): + if name == "__version__": + from warnings import _deprecated + + _deprecated("__version__", remove=(3, 17)) + return "1.1" # Do not change + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/csv.py b/Lib/csv.py index 0a627ba7a512fa..81d8f06690bff0 100644 --- a/Lib/csv.py +++ b/Lib/csv.py @@ -81,8 +81,6 @@ class excel: "unregister_dialect", "DictReader", "DictWriter", "unix_dialect"] -__version__ = "1.0" - class Dialect: """Describe a CSV dialect. @@ -511,3 +509,12 @@ def has_header(self, sample): hasHeader -= 1 return hasHeader > 0 + + +def __getattr__(name): + if name == "__version__": + from warnings import _deprecated + + _deprecated("__version__", remove=(3, 17)) + return "1.0" # Do not change + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/ctypes/macholib/__init__.py b/Lib/ctypes/macholib/__init__.py index 5621defccd61d1..2fc535abe105ba 100644 --- a/Lib/ctypes/macholib/__init__.py +++ b/Lib/ctypes/macholib/__init__.py @@ -6,4 +6,10 @@ And also Apple's documentation. """ -__version__ = '1.0' +def __getattr__(name): + if name == "__version__": + from warnings import _deprecated + + _deprecated("__version__", remove=(3, 17)) + return "1.0" # Do not change + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index 7470dc6c52d3a8..6e4dc7abc0f09a 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -8,9 +8,6 @@ """ -__version__ = '1.0' - - import functools IPV4LENGTH = 32 @@ -2419,3 +2416,12 @@ class _IPv6Constants: IPv6Address._constants = _IPv6Constants IPv6Network._constants = _IPv6Constants + + +def __getattr__(name): + if name == "__version__": + from warnings import _deprecated + + _deprecated("__version__", remove=(3, 17)) + return "1.0" # Do not change + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/json/__init__.py b/Lib/json/__init__.py index 1d972d22ded072..669f5635bdeb29 100644 --- a/Lib/json/__init__.py +++ b/Lib/json/__init__.py @@ -95,7 +95,6 @@ $ echo '{ 1.2:3.4}' | python -m json Expecting property name enclosed in double quotes: line 1 column 3 (char 2) """ -__version__ = '2.0.9' __all__ = [ 'dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder', @@ -357,3 +356,12 @@ def loads(s, *, cls=None, object_hook=None, parse_float=None, if parse_constant is not None: kw['parse_constant'] = parse_constant return cls(**kw).decode(s) + + +def __getattr__(name): + if name == "__version__": + from warnings import _deprecated + + _deprecated("__version__", remove=(3, 17)) + return "2.0.9" # Do not change + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index c5860d53b1bdff..1367bb5a7860de 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -45,9 +45,6 @@ __author__ = "Vinay Sajip " __status__ = "production" -# The following module attributes are no longer updated. -__version__ = "0.5.1.2" -__date__ = "07 February 2010" #--------------------------------------------------------------------------- # Miscellaneous module data @@ -2341,3 +2338,16 @@ def captureWarnings(capture): if _warnings_showwarning is not None: warnings.showwarning = _warnings_showwarning _warnings_showwarning = None + + +def __getattr__(name): + if name in ("__version__", "__date__"): + from warnings import _deprecated + + _deprecated(name, remove=(3, 17)) + return { # Do not change + "__version__": "0.5.1.2", + "__date__": "07 February 2010", + }[name] + + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/optparse.py b/Lib/optparse.py index 38cf16d21efffa..3f2fe7322bc279 100644 --- a/Lib/optparse.py +++ b/Lib/optparse.py @@ -21,8 +21,6 @@ (options, args) = parser.parse_args() """ -__version__ = "1.5.3" - __all__ = ['Option', 'make_option', 'SUPPRESS_HELP', @@ -1669,3 +1667,12 @@ def _match_abbrev(s, wordmap): # which will become a factory function when there are many Option # classes. make_option = Option + + +def __getattr__(name): + if name == "__version__": + from warnings import _deprecated + + _deprecated("__version__", remove=(3, 17)) + return "1.5.3" # Do not change + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/pickle.py b/Lib/pickle.py index beaefae0479d3c..729c215514ad24 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -17,7 +17,6 @@ Misc variables: - __version__ format_version compatible_formats diff --git a/Lib/platform.py b/Lib/platform.py index 4028012dc3ce6a..fd1fe8a29c5ed1 100644 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -110,8 +110,6 @@ """ -__version__ = '1.1.0' - import collections import os import re @@ -1436,5 +1434,14 @@ def _main(args: list[str] | None = None): print(platform(aliased, terse)) +def __getattr__(name): + if name == "__version__": + from warnings import _deprecated + + _deprecated("__version__", remove=(3, 17)) + return "1.1.0" # Do not change + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + + if __name__ == "__main__": _main() diff --git a/Lib/re/__init__.py b/Lib/re/__init__.py index af2808a77da691..a1d8a050884dfc 100644 --- a/Lib/re/__init__.py +++ b/Lib/re/__init__.py @@ -137,8 +137,6 @@ "UNICODE", "NOFLAG", "RegexFlag", "PatternError" ] -__version__ = "2.2.1" - @enum.global_enum @enum._simple_enum(enum.IntFlag, boundary=enum.KEEP) class RegexFlag: @@ -426,3 +424,12 @@ def scan(self, string): append(action) i = j return result, string[i:] + + +def __getattr__(name): + if name == "__version__": + from warnings import _deprecated + + _deprecated("__version__", remove=(3, 17)) + return "2.2.1" # Do not change + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/socketserver.py b/Lib/socketserver.py index 93b0a23be27f68..8c03a319a7a663 100644 --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -120,9 +120,6 @@ class will essentially render the service "deaf" while one request is # Author of the BaseServer patch: Luke Kenneth Casson Leighton -__version__ = "0.4" - - import socket import selectors import os @@ -861,3 +858,12 @@ def setup(self): def finish(self): self.socket.sendto(self.wfile.getvalue(), self.client_address) + + +def __getattr__(name): + if name == "__version__": + from warnings import _deprecated + + _deprecated("__version__", remove=(3, 17)) + return "0.4" # Do not change + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/tabnanny.py b/Lib/tabnanny.py index c0097351b269f2..dc72b0e672481e 100644 --- a/Lib/tabnanny.py +++ b/Lib/tabnanny.py @@ -16,8 +16,6 @@ # XXX The API needs to undergo changes however; the current code is too # XXX script-like. This will be addressed later. -__version__ = "6" - import os import sys import tokenize @@ -334,5 +332,14 @@ def _process_tokens(tokens): raise NannyNag(start[0], msg, line) +def __getattr__(name): + if name == "__version__": + from warnings import _deprecated + + _deprecated("__version__", remove=(3, 17)) + return "6" # Do not change + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + + if __name__ == '__main__': main() diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index fc73174d98cd6f..6e8201d1352875 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -7356,6 +7356,16 @@ def __init__(self, prog): ''')) +class TestModule(unittest.TestCase): + def test_deprecated__version__(self): + with self.assertWarnsRegex( + DeprecationWarning, + "'__version__' is deprecated and slated for removal in Python 3.17", + ) as cm: + getattr(argparse, "__version__") + self.assertEqual(cm.filename, __file__) + + def tearDownModule(): # Remove global references to avoid looking like we have refleaks. RFile.seen = {} diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index 60feab225a107c..03293670a1e356 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -1603,5 +1603,16 @@ def test_disallow_instantiation(self): with self.subTest(tp=tp): check_disallow_instantiation(self, tp) + +class TestModule(unittest.TestCase): + def test_deprecated__version__(self): + with self.assertWarnsRegex( + DeprecationWarning, + "'__version__' is deprecated and slated for removal in Python 3.17", + ) as cm: + getattr(csv, "__version__") + self.assertEqual(cm.filename, __file__) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_ctypes/test_macholib.py b/Lib/test/test_ctypes/test_macholib.py index 9d90617995623d..0fc8716e085c30 100644 --- a/Lib/test/test_ctypes/test_macholib.py +++ b/Lib/test/test_ctypes/test_macholib.py @@ -108,5 +108,17 @@ def test_framework_info(self): d('P', 'F.framework/Versions/A/F_debug', 'F', 'A', 'debug')) +class TestModule(unittest.TestCase): + def test_deprecated__version__(self): + import ctypes.macholib + + with self.assertWarnsRegex( + DeprecationWarning, + "'__version__' is deprecated and slated for removal in Python 3.17", + ) as cm: + getattr(ctypes.macholib, "__version__") + self.assertEqual(cm.filename, __file__) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py index 62929f9dd68b5a..b896465b9245fd 100644 --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -2821,5 +2821,15 @@ def testNetworkV6HashCollisions(self): ) +class TestModule(unittest.TestCase): + def test_deprecated__version__(self): + with self.assertWarnsRegex( + DeprecationWarning, + "'__version__' is deprecated and slated for removal in Python 3.17", + ) as cm: + getattr(ipaddress, "__version__") + self.assertEqual(cm.filename, __file__) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_json/__init__.py b/Lib/test/test_json/__init__.py index 74b64ed86a3183..ceaf356f9f47e0 100644 --- a/Lib/test/test_json/__init__.py +++ b/Lib/test/test_json/__init__.py @@ -47,6 +47,16 @@ def test_cjson(self): '_json') +class TestModule(unittest.TestCase): + def test_deprecated__version__(self): + with self.assertWarnsRegex( + DeprecationWarning, + "'__version__' is deprecated and slated for removal in Python 3.17", + ) as cm: + getattr(json, "__version__") + self.assertEqual(cm.filename, __file__) + + def load_tests(loader, _, pattern): suite = unittest.TestSuite() for mod in (json, json.encoder, json.decoder): diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 7a08f9ec9de9fb..593f08d7d817bb 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -7236,6 +7236,16 @@ def test__all__(self): support.check__all__(self, logging, not_exported=not_exported) +class TestModule(unittest.TestCase): + def test_deprecated__version__and__date__(self): + msg = "is deprecated and slated for removal in Python 3.17" + for attr in ("__version__", "__date__"): + with self.subTest(attr=attr): + with self.assertWarnsRegex(DeprecationWarning, msg) as cm: + getattr(logging, attr) + self.assertEqual(cm.filename, __file__) + + # Set the locale to the platform-dependent default. I have no idea # why the test does this, but in any case we save the current locale # first and restore it at the end. diff --git a/Lib/test/test_optparse.py b/Lib/test/test_optparse.py index e476e4727803e5..810f74bb3389f1 100644 --- a/Lib/test/test_optparse.py +++ b/Lib/test/test_optparse.py @@ -1666,6 +1666,16 @@ def test_translations(self): self.assertMsgidsEqual(optparse) +class TestModule(unittest.TestCase): + def test_deprecated__version__(self): + with self.assertWarnsRegex( + DeprecationWarning, + "'__version__' is deprecated and slated for removal in Python 3.17", + ) as cm: + getattr(optparse, "__version__") + self.assertEqual(cm.filename, __file__) + + if __name__ == '__main__': # To regenerate translation snapshots if len(sys.argv) > 1 and sys.argv[1] == '--snapshot-update': diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index d4a2863728e1f8..f211e68af9715e 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -3116,5 +3116,15 @@ def test_re_tests(self): self.assertTrue(obj.search(s)) +class TestModule(unittest.TestCase): + def test_deprecated__version__(self): + with self.assertWarnsRegex( + DeprecationWarning, + "'__version__' is deprecated and slated for removal in Python 3.17", + ) as cm: + getattr(re, "__version__") + self.assertEqual(cm.filename, __file__) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index 893372cbbd0be9..bdeeb158d06bbf 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -511,5 +511,14 @@ class MyServer(socketserver.ThreadingMixIn, socketserver.TCPServer): server.server_close() +class TestModule(unittest.TestCase): + def test_deprecated__version__(self): + with self.assertWarnsRegex( + DeprecationWarning, + "'__version__' is deprecated and slated for removal in Python 3.17", + ) as cm: + getattr(socketserver, "__version__") + self.assertEqual(cm.filename, __file__) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_tabnanny.py b/Lib/test/test_tabnanny.py index 30dcb3e3c4f4f9..d1ad53f85db726 100644 --- a/Lib/test/test_tabnanny.py +++ b/Lib/test/test_tabnanny.py @@ -3,7 +3,8 @@ Glossary: * errored : Whitespace related problems present in file. """ -from unittest import TestCase, mock + +from unittest import TestCase, main, mock import errno import os import tabnanny @@ -352,3 +353,17 @@ def test_double_verbose_mode(self): "offending line: '\\tprint(\"world\")'" ).strip() self.validate_cmd("-vv", path, stdout=stdout, partial=True) + + +class TestModule(TestCase): + def test_deprecated__version__(self): + with self.assertWarnsRegex( + DeprecationWarning, + "'__version__' is deprecated and slated for removal in Python 3.17", + ) as cm: + getattr(tabnanny, "__version__") + self.assertEqual(cm.filename, __file__) + + +if __name__ == "__main__": + main() diff --git a/Lib/test/test_tkinter/test_font.py b/Lib/test/test_tkinter/test_font.py index 563707ddd2fa9b..ac68de5efa10eb 100644 --- a/Lib/test/test_tkinter/test_font.py +++ b/Lib/test/test_tkinter/test_font.py @@ -159,5 +159,15 @@ def test_nametofont(self): self.assertRaises(RuntimeError, font.nametofont, fontname) +class TestModule(unittest.TestCase): + def test_deprecated__version__(self): + with self.assertWarnsRegex( + DeprecationWarning, + "'__version__' is deprecated and slated for removal in Python 3.17", + ) as cm: + getattr(font, "__version__") + self.assertEqual(cm.filename, __file__) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_ttk/__init__.py b/Lib/test/test_ttk/__init__.py index 7ee7ffbd6d7408..c0294ef12400f9 100644 --- a/Lib/test/test_ttk/__init__.py +++ b/Lib/test/test_ttk/__init__.py @@ -19,6 +19,16 @@ from tkinter import ttk +class TestModule(unittest.TestCase): + def test_deprecated__version__(self): + with self.assertWarnsRegex( + DeprecationWarning, + "'__version__' is deprecated and slated for removal in Python 3.17", + ) as cm: + getattr(ttk, "__version__") + self.assertEqual(cm.filename, __file__) + + def setUpModule(): root = None try: diff --git a/Lib/tkinter/font.py b/Lib/tkinter/font.py index 3e24e28ef58cde..d2d59e8d658e3b 100644 --- a/Lib/tkinter/font.py +++ b/Lib/tkinter/font.py @@ -6,7 +6,6 @@ import itertools import tkinter -__version__ = "0.9" __all__ = ["NORMAL", "ROMAN", "BOLD", "ITALIC", "nametofont", "Font", "families", "names"] @@ -198,6 +197,15 @@ def names(root=None): return root.tk.splitlist(root.tk.call("font", "names")) +def __getattr__(name): + if name == "__version__": + from warnings import _deprecated + + _deprecated("__version__", remove=(3, 17)) + return "0.9" # Do not change + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + + # -------------------------------------------------------------------- # test stuff diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py index ef2b91dfbb6638..538d4ae019c3ff 100644 --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -12,8 +12,6 @@ of the widgets appearance lies at Themes. """ -__version__ = "0.3.1" - __author__ = "Guilherme Polo " __all__ = ["Button", "Checkbutton", "Combobox", "Entry", "Frame", "Label", @@ -1648,3 +1646,12 @@ def destroy(self): except AttributeError: pass super().destroy() + + +def __getattr__(name): + if name == "__version__": + from warnings import _deprecated + + _deprecated("__version__", remove=(3, 17)) + return "0.3.1" # Do not change + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Misc/NEWS.d/next/Library/2025-09-08-17-32-02.gh-issue-76007.peEgcr.rst b/Misc/NEWS.d/next/Library/2025-09-08-17-32-02.gh-issue-76007.peEgcr.rst new file mode 100644 index 00000000000000..c6476f029cee47 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-09-08-17-32-02.gh-issue-76007.peEgcr.rst @@ -0,0 +1,2 @@ +Deprecate ``__version__`` from a number of standard library modules. Patch +by Hugo van Kemenade. From c23ee78b3c9eb3e667e04ec9402c559a99496105 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Sep 2025 17:48:37 +0300 Subject: [PATCH 2/9] Update SBOM checksums for Lib/ctypes/macholib/__init__.py --- Misc/sbom.spdx.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/sbom.spdx.json b/Misc/sbom.spdx.json index 738b33908857a8..6e1b79733aa5f5 100644 --- a/Misc/sbom.spdx.json +++ b/Misc/sbom.spdx.json @@ -944,11 +944,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "0fbc026a9771d9675e7094790b5b945334d3cb53" + "checksumValue": "873215c0c94112070d8123bcbea4f5d3bacc7a79" }, { "algorithm": "SHA256", - "checksumValue": "1e77c01eec8f167ed10b754f153c0c743c8e5196ae9c81dffc08f129ab56dbfd" + "checksumValue": "14c8a80ceb5bda789e7059992aa9e1c24b4069db26e7d21b365ea6fedb0f85bb" } ], "fileName": "Lib/ctypes/macholib/__init__.py" From 6e015340cc52f5cfd30667fc5da52e12bd28257e Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 15 Sep 2025 13:43:15 +0300 Subject: [PATCH 3/9] Whitespace Co-authored-by: AN Long --- Lib/test/test_socketserver.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index bdeeb158d06bbf..1fa9746729672d 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -520,5 +520,6 @@ def test_deprecated__version__(self): getattr(socketserver, "__version__") self.assertEqual(cm.filename, __file__) + if __name__ == "__main__": unittest.main() From 7b13a13a1be2124adaa4245ac8a5c7e71365405d Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 17 Sep 2025 12:35:16 +0300 Subject: [PATCH 4/9] Deprecate for recommended five years Co-authored-by: Petr Viktorin --- Lib/ctypes/macholib/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/ctypes/macholib/__init__.py b/Lib/ctypes/macholib/__init__.py index 2fc535abe105ba..f00e55f8131c9d 100644 --- a/Lib/ctypes/macholib/__init__.py +++ b/Lib/ctypes/macholib/__init__.py @@ -10,6 +10,6 @@ def __getattr__(name): if name == "__version__": from warnings import _deprecated - _deprecated("__version__", remove=(3, 17)) + _deprecated("__version__", remove=(3, 20)) return "1.0" # Do not change raise AttributeError(f"module {__name__!r} has no attribute {name!r}") From bfbe4b7f4673bc8efe067e8e2472ae390433a3da Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 17 Sep 2025 10:45:47 +0100 Subject: [PATCH 5/9] Deprecate for recommended five years --- Doc/deprecations/index.rst | 4 ++++ Doc/deprecations/pending-removal-in-3.17.rst | 21 ------------------ Doc/deprecations/pending-removal-in-3.20.rst | 23 ++++++++++++++++++++ Doc/whatsnew/3.12.rst | 6 +++++ Doc/whatsnew/3.13.rst | 6 +++++ Doc/whatsnew/3.14.rst | 2 ++ Doc/whatsnew/3.15.rst | 4 +++- Lib/argparse.py | 2 +- Lib/csv.py | 2 +- Lib/ipaddress.py | 2 +- Lib/json/__init__.py | 2 +- Lib/logging/__init__.py | 2 +- Lib/optparse.py | 2 +- Lib/platform.py | 2 +- Lib/re/__init__.py | 2 +- Lib/socketserver.py | 2 +- Lib/tabnanny.py | 2 +- Lib/tkinter/font.py | 2 +- Lib/tkinter/ttk.py | 2 +- 19 files changed, 56 insertions(+), 34 deletions(-) create mode 100644 Doc/deprecations/pending-removal-in-3.20.rst diff --git a/Doc/deprecations/index.rst b/Doc/deprecations/index.rst index c6e05c176b2aa1..c91c64a1092457 100644 --- a/Doc/deprecations/index.rst +++ b/Doc/deprecations/index.rst @@ -7,8 +7,12 @@ Deprecations .. include:: pending-removal-in-3.17.rst +.. include:: pending-removal-in-3.18.rst + .. include:: pending-removal-in-3.19.rst +.. include:: pending-removal-in-3.20.rst + .. include:: pending-removal-in-future.rst C API deprecations diff --git a/Doc/deprecations/pending-removal-in-3.17.rst b/Doc/deprecations/pending-removal-in-3.17.rst index ab7cad5d1615f3..cbad85868c32f9 100644 --- a/Doc/deprecations/pending-removal-in-3.17.rst +++ b/Doc/deprecations/pending-removal-in-3.17.rst @@ -21,24 +21,3 @@ Pending removal in Python 3.17 :class:`~collections.abc.Buffer`. For use in type annotations, prefer a union, like ``bytes | bytearray``, or :class:`collections.abc.Buffer`. (Contributed by Shantanu Jain in :gh:`91896`.) - -* The ``__version__`` attribute has been deprecated in these standard library - modules and will be removed in Python 3.17. - Use :py:data:`sys.version_info` instead. - - - :mod:`argparse` - - :mod:`csv` - - :mod:`!ctypes.macholib` - - :mod:`ipaddress` - - :mod:`json` - - :mod:`logging` (``__date__`` also deprecated) - - :mod:`optparse` - - :mod:`pickle` - - :mod:`platform` - - :mod:`re` - - :mod:`socketserver` - - :mod:`tabnanny` - - :mod:`tkinter.font` - - :mod:`tkinter.ttk` - - (Contributed by Hugo van Kemenade in :gh:`76007`.) \ No newline at end of file diff --git a/Doc/deprecations/pending-removal-in-3.20.rst b/Doc/deprecations/pending-removal-in-3.20.rst new file mode 100644 index 00000000000000..8bc863b185d921 --- /dev/null +++ b/Doc/deprecations/pending-removal-in-3.20.rst @@ -0,0 +1,23 @@ +Pending removal in Python 3.20 +------------------------------ + +* The ``__version__`` attribute has been deprecated in these standard library + modules and will be removed in Python 3.20. + Use :py:data:`sys.version_info` instead. + + - :mod:`argparse` + - :mod:`csv` + - :mod:`!ctypes.macholib` + - :mod:`ipaddress` + - :mod:`json` + - :mod:`logging` (``__date__`` also deprecated) + - :mod:`optparse` + - :mod:`pickle` + - :mod:`platform` + - :mod:`re` + - :mod:`socketserver` + - :mod:`tabnanny` + - :mod:`tkinter.font` + - :mod:`tkinter.ttk` + + (Contributed by Hugo van Kemenade in :gh:`76007`.) diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 8e0cb652a73b03..5eb6adf99841c2 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -1349,6 +1349,12 @@ Deprecated .. include:: ../deprecations/pending-removal-in-3.17.rst +.. include:: ../deprecations/pending-removal-in-3.18.rst + +.. include:: ../deprecations/pending-removal-in-3.19.rst + +.. include:: ../deprecations/pending-removal-in-3.20.rst + .. include:: ../deprecations/pending-removal-in-future.rst .. _whatsnew312-removed: diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 67fec4ebc4a234..2028d9e04c8af0 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -2026,6 +2026,12 @@ New Deprecations .. include:: ../deprecations/pending-removal-in-3.17.rst +.. include:: ../deprecations/pending-removal-in-3.18.rst + +.. include:: ../deprecations/pending-removal-in-3.19.rst + +.. include:: ../deprecations/pending-removal-in-3.20.rst + .. include:: ../deprecations/pending-removal-in-future.rst CPython Bytecode Changes diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index e8695f1db33281..dbfc1009e14bd1 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -2794,6 +2794,8 @@ Deprecated .. include:: ../deprecations/pending-removal-in-3.19.rst +.. include:: ../deprecations/pending-removal-in-3.20.rst + .. include:: ../deprecations/pending-removal-in-future.rst diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 4860571b079d66..f4dae40c5815e5 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -573,7 +573,7 @@ __version__ ----------- * The ``__version__`` attribute has been deprecated in these standard library - modules and will be removed in Python 3.17. + modules and will be removed in Python 3.20. Use :py:data:`sys.version_info` instead. - :mod:`argparse` @@ -601,6 +601,8 @@ __version__ .. include:: ../deprecations/pending-removal-in-3.19.rst +.. include:: ../deprecations/pending-removal-in-3.20.rst + .. include:: ../deprecations/pending-removal-in-future.rst Removed diff --git a/Lib/argparse.py b/Lib/argparse.py index 16ddf8469ba77a..863e951528b6d0 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2778,6 +2778,6 @@ def __getattr__(name): if name == "__version__": from warnings import _deprecated - _deprecated("__version__", remove=(3, 17)) + _deprecated("__version__", remove=(3, 20)) return "1.1" # Do not change raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/csv.py b/Lib/csv.py index 81d8f06690bff0..98eab01429a8ec 100644 --- a/Lib/csv.py +++ b/Lib/csv.py @@ -515,6 +515,6 @@ def __getattr__(name): if name == "__version__": from warnings import _deprecated - _deprecated("__version__", remove=(3, 17)) + _deprecated("__version__", remove=(3, 20)) return "1.0" # Do not change raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index 6e4dc7abc0f09a..aa0cf4a0620cd0 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -2422,6 +2422,6 @@ def __getattr__(name): if name == "__version__": from warnings import _deprecated - _deprecated("__version__", remove=(3, 17)) + _deprecated("__version__", remove=(3, 20)) return "1.0" # Do not change raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/json/__init__.py b/Lib/json/__init__.py index 669f5635bdeb29..c8fdd0d99a0efc 100644 --- a/Lib/json/__init__.py +++ b/Lib/json/__init__.py @@ -362,6 +362,6 @@ def __getattr__(name): if name == "__version__": from warnings import _deprecated - _deprecated("__version__", remove=(3, 17)) + _deprecated("__version__", remove=(3, 20)) return "2.0.9" # Do not change raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 1367bb5a7860de..431ff41b352048 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -2344,7 +2344,7 @@ def __getattr__(name): if name in ("__version__", "__date__"): from warnings import _deprecated - _deprecated(name, remove=(3, 17)) + _deprecated(name, remove=(3, 20)) return { # Do not change "__version__": "0.5.1.2", "__date__": "07 February 2010", diff --git a/Lib/optparse.py b/Lib/optparse.py index 3f2fe7322bc279..02ff7140882ed6 100644 --- a/Lib/optparse.py +++ b/Lib/optparse.py @@ -1673,6 +1673,6 @@ def __getattr__(name): if name == "__version__": from warnings import _deprecated - _deprecated("__version__", remove=(3, 17)) + _deprecated("__version__", remove=(3, 20)) return "1.5.3" # Do not change raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/platform.py b/Lib/platform.py index fd1fe8a29c5ed1..4db93bea2a39e1 100644 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -1438,7 +1438,7 @@ def __getattr__(name): if name == "__version__": from warnings import _deprecated - _deprecated("__version__", remove=(3, 17)) + _deprecated("__version__", remove=(3, 20)) return "1.1.0" # Do not change raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/re/__init__.py b/Lib/re/__init__.py index a1d8a050884dfc..a5316391297f4c 100644 --- a/Lib/re/__init__.py +++ b/Lib/re/__init__.py @@ -430,6 +430,6 @@ def __getattr__(name): if name == "__version__": from warnings import _deprecated - _deprecated("__version__", remove=(3, 17)) + _deprecated("__version__", remove=(3, 20)) return "2.2.1" # Do not change raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/socketserver.py b/Lib/socketserver.py index 8c03a319a7a663..ec389457ef5b1c 100644 --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -864,6 +864,6 @@ def __getattr__(name): if name == "__version__": from warnings import _deprecated - _deprecated("__version__", remove=(3, 17)) + _deprecated("__version__", remove=(3, 20)) return "0.4" # Do not change raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/tabnanny.py b/Lib/tabnanny.py index dc72b0e672481e..272e8e33e0c46a 100644 --- a/Lib/tabnanny.py +++ b/Lib/tabnanny.py @@ -336,7 +336,7 @@ def __getattr__(name): if name == "__version__": from warnings import _deprecated - _deprecated("__version__", remove=(3, 17)) + _deprecated("__version__", remove=(3, 20)) return "6" # Do not change raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/tkinter/font.py b/Lib/tkinter/font.py index d2d59e8d658e3b..7aed523cce3784 100644 --- a/Lib/tkinter/font.py +++ b/Lib/tkinter/font.py @@ -201,7 +201,7 @@ def __getattr__(name): if name == "__version__": from warnings import _deprecated - _deprecated("__version__", remove=(3, 17)) + _deprecated("__version__", remove=(3, 20)) return "0.9" # Do not change raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py index 538d4ae019c3ff..5c5ef11ae05ba6 100644 --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -1652,6 +1652,6 @@ def __getattr__(name): if name == "__version__": from warnings import _deprecated - _deprecated("__version__", remove=(3, 17)) + _deprecated("__version__", remove=(3, 20)) return "0.3.1" # Do not change raise AttributeError(f"module {__name__!r} has no attribute {name!r}") From 6bb4cbe8d464cc3d18fd72f0ea7400386b38776e Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 17 Sep 2025 12:49:47 +0300 Subject: [PATCH 6/9] Deprecate for recommended five years --- Doc/deprecations/pending-removal-in-3.17.rst | 15 +++++++-------- Lib/test/test_argparse.py | 2 +- Lib/test/test_csv.py | 2 +- Lib/test/test_ctypes/test_macholib.py | 2 +- Lib/test/test_ipaddress.py | 2 +- Lib/test/test_json/__init__.py | 2 +- Lib/test/test_logging.py | 2 +- Lib/test/test_optparse.py | 2 +- Lib/test/test_re.py | 2 +- Lib/test/test_socketserver.py | 2 +- Lib/test/test_tabnanny.py | 2 +- Lib/test/test_tkinter/test_font.py | 2 +- Lib/test/test_ttk/__init__.py | 2 +- 13 files changed, 19 insertions(+), 20 deletions(-) diff --git a/Doc/deprecations/pending-removal-in-3.17.rst b/Doc/deprecations/pending-removal-in-3.17.rst index cbad85868c32f9..4fd4bde24d42b3 100644 --- a/Doc/deprecations/pending-removal-in-3.17.rst +++ b/Doc/deprecations/pending-removal-in-3.17.rst @@ -1,13 +1,6 @@ Pending removal in Python 3.17 ------------------------------ -* :mod:`collections.abc`: - - - :class:`collections.abc.ByteString` is scheduled for removal in Python 3.17. Prefer - :class:`~collections.abc.Sequence` or :class:`~collections.abc.Buffer`. For use in - type annotations, prefer a union, like ``bytes | bytearray``, or - :class:`collections.abc.Buffer`. (Contributed by Shantanu Jain in :gh:`91896`.) - * :mod:`typing`: - Before Python 3.14, old-style unions were implemented using the private class @@ -15,9 +8,15 @@ Pending removal in Python 3.17 but it has been retained for backward compatibility, with removal scheduled for Python 3.17. Users should use documented introspection helpers like :func:`typing.get_origin` and :func:`typing.get_args` instead of relying on private implementation details. - - :class:`typing.ByteString`, deprecated since Python 3.9, is scheduled for removal in Python 3.17. Prefer :class:`~collections.abc.Sequence` or :class:`~collections.abc.Buffer`. For use in type annotations, prefer a union, like ``bytes | bytearray``, or :class:`collections.abc.Buffer`. (Contributed by Shantanu Jain in :gh:`91896`.) + +* :mod:`collections.abc`: + + - :class:`collections.abc.ByteString` is scheduled for removal in Python 3.17. Prefer + :class:`~collections.abc.Sequence` or :class:`~collections.abc.Buffer`. For use in + type annotations, prefer a union, like ``bytes | bytearray``, or + :class:`collections.abc.Buffer`. (Contributed by Shantanu Jain in :gh:`91896`.) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 6e8201d1352875..90bfcd0ae3e29b 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -7360,7 +7360,7 @@ class TestModule(unittest.TestCase): def test_deprecated__version__(self): with self.assertWarnsRegex( DeprecationWarning, - "'__version__' is deprecated and slated for removal in Python 3.17", + "'__version__' is deprecated and slated for removal in Python 3.20", ) as cm: getattr(argparse, "__version__") self.assertEqual(cm.filename, __file__) diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index 03293670a1e356..50431b562f90ba 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -1608,7 +1608,7 @@ class TestModule(unittest.TestCase): def test_deprecated__version__(self): with self.assertWarnsRegex( DeprecationWarning, - "'__version__' is deprecated and slated for removal in Python 3.17", + "'__version__' is deprecated and slated for removal in Python 3.20", ) as cm: getattr(csv, "__version__") self.assertEqual(cm.filename, __file__) diff --git a/Lib/test/test_ctypes/test_macholib.py b/Lib/test/test_ctypes/test_macholib.py index 0fc8716e085c30..9a5e18ed589d44 100644 --- a/Lib/test/test_ctypes/test_macholib.py +++ b/Lib/test/test_ctypes/test_macholib.py @@ -114,7 +114,7 @@ def test_deprecated__version__(self): with self.assertWarnsRegex( DeprecationWarning, - "'__version__' is deprecated and slated for removal in Python 3.17", + "'__version__' is deprecated and slated for removal in Python 3.20", ) as cm: getattr(ctypes.macholib, "__version__") self.assertEqual(cm.filename, __file__) diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py index b896465b9245fd..11721a59972672 100644 --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -2825,7 +2825,7 @@ class TestModule(unittest.TestCase): def test_deprecated__version__(self): with self.assertWarnsRegex( DeprecationWarning, - "'__version__' is deprecated and slated for removal in Python 3.17", + "'__version__' is deprecated and slated for removal in Python 3.20", ) as cm: getattr(ipaddress, "__version__") self.assertEqual(cm.filename, __file__) diff --git a/Lib/test/test_json/__init__.py b/Lib/test/test_json/__init__.py index ceaf356f9f47e0..e58fbee41af3e6 100644 --- a/Lib/test/test_json/__init__.py +++ b/Lib/test/test_json/__init__.py @@ -51,7 +51,7 @@ class TestModule(unittest.TestCase): def test_deprecated__version__(self): with self.assertWarnsRegex( DeprecationWarning, - "'__version__' is deprecated and slated for removal in Python 3.17", + "'__version__' is deprecated and slated for removal in Python 3.20", ) as cm: getattr(json, "__version__") self.assertEqual(cm.filename, __file__) diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 593f08d7d817bb..1f7a4d9e197f9c 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -7238,7 +7238,7 @@ def test__all__(self): class TestModule(unittest.TestCase): def test_deprecated__version__and__date__(self): - msg = "is deprecated and slated for removal in Python 3.17" + msg = "is deprecated and slated for removal in Python 3.20" for attr in ("__version__", "__date__"): with self.subTest(attr=attr): with self.assertWarnsRegex(DeprecationWarning, msg) as cm: diff --git a/Lib/test/test_optparse.py b/Lib/test/test_optparse.py index 810f74bb3389f1..fc8ef9520b3c0f 100644 --- a/Lib/test/test_optparse.py +++ b/Lib/test/test_optparse.py @@ -1670,7 +1670,7 @@ class TestModule(unittest.TestCase): def test_deprecated__version__(self): with self.assertWarnsRegex( DeprecationWarning, - "'__version__' is deprecated and slated for removal in Python 3.17", + "'__version__' is deprecated and slated for removal in Python 3.20", ) as cm: getattr(optparse, "__version__") self.assertEqual(cm.filename, __file__) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index f211e68af9715e..5fc95087f2b6ad 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -3120,7 +3120,7 @@ class TestModule(unittest.TestCase): def test_deprecated__version__(self): with self.assertWarnsRegex( DeprecationWarning, - "'__version__' is deprecated and slated for removal in Python 3.17", + "'__version__' is deprecated and slated for removal in Python 3.20", ) as cm: getattr(re, "__version__") self.assertEqual(cm.filename, __file__) diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index 1fa9746729672d..a5e03020e5bd57 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -515,7 +515,7 @@ class TestModule(unittest.TestCase): def test_deprecated__version__(self): with self.assertWarnsRegex( DeprecationWarning, - "'__version__' is deprecated and slated for removal in Python 3.17", + "'__version__' is deprecated and slated for removal in Python 3.20", ) as cm: getattr(socketserver, "__version__") self.assertEqual(cm.filename, __file__) diff --git a/Lib/test/test_tabnanny.py b/Lib/test/test_tabnanny.py index d1ad53f85db726..e575aac037e917 100644 --- a/Lib/test/test_tabnanny.py +++ b/Lib/test/test_tabnanny.py @@ -359,7 +359,7 @@ class TestModule(TestCase): def test_deprecated__version__(self): with self.assertWarnsRegex( DeprecationWarning, - "'__version__' is deprecated and slated for removal in Python 3.17", + "'__version__' is deprecated and slated for removal in Python 3.20", ) as cm: getattr(tabnanny, "__version__") self.assertEqual(cm.filename, __file__) diff --git a/Lib/test/test_tkinter/test_font.py b/Lib/test/test_tkinter/test_font.py index ac68de5efa10eb..3616da54cf7075 100644 --- a/Lib/test/test_tkinter/test_font.py +++ b/Lib/test/test_tkinter/test_font.py @@ -163,7 +163,7 @@ class TestModule(unittest.TestCase): def test_deprecated__version__(self): with self.assertWarnsRegex( DeprecationWarning, - "'__version__' is deprecated and slated for removal in Python 3.17", + "'__version__' is deprecated and slated for removal in Python 3.20", ) as cm: getattr(font, "__version__") self.assertEqual(cm.filename, __file__) diff --git a/Lib/test/test_ttk/__init__.py b/Lib/test/test_ttk/__init__.py index c0294ef12400f9..4a077a0f966fbb 100644 --- a/Lib/test/test_ttk/__init__.py +++ b/Lib/test/test_ttk/__init__.py @@ -23,7 +23,7 @@ class TestModule(unittest.TestCase): def test_deprecated__version__(self): with self.assertWarnsRegex( DeprecationWarning, - "'__version__' is deprecated and slated for removal in Python 3.17", + "'__version__' is deprecated and slated for removal in Python 3.20", ) as cm: getattr(ttk, "__version__") self.assertEqual(cm.filename, __file__) From d352594920623ea140e36151f71778e44ff14d54 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 17 Sep 2025 11:00:03 +0100 Subject: [PATCH 7/9] Re-update SBOM checksums for Lib/ctypes/macholib/__init__.py --- Misc/sbom.spdx.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/sbom.spdx.json b/Misc/sbom.spdx.json index 6e1b79733aa5f5..17526b7650c469 100644 --- a/Misc/sbom.spdx.json +++ b/Misc/sbom.spdx.json @@ -944,11 +944,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "873215c0c94112070d8123bcbea4f5d3bacc7a79" + "checksumValue": "0d83ed429ede0a2c6617cd2f24490be16d8393f4" }, { "algorithm": "SHA256", - "checksumValue": "14c8a80ceb5bda789e7059992aa9e1c24b4069db26e7d21b365ea6fedb0f85bb" + "checksumValue": "876f4486d08d3eac3581a8681d7fb3cec2fe5b823d1bef27cca15e755510365c" } ], "fileName": "Lib/ctypes/macholib/__init__.py" From d17235d617cb940f3a69c4cd766d1f4a9250e000 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 17 Sep 2025 11:03:25 +0100 Subject: [PATCH 8/9] Fix Sphinx --- Doc/whatsnew/3.12.rst | 2 -- Doc/whatsnew/3.13.rst | 2 -- 2 files changed, 4 deletions(-) diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 5eb6adf99841c2..7bc89ffb5bf8ea 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -1349,8 +1349,6 @@ Deprecated .. include:: ../deprecations/pending-removal-in-3.17.rst -.. include:: ../deprecations/pending-removal-in-3.18.rst - .. include:: ../deprecations/pending-removal-in-3.19.rst .. include:: ../deprecations/pending-removal-in-3.20.rst diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 2028d9e04c8af0..416e6ca50597ed 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -2026,8 +2026,6 @@ New Deprecations .. include:: ../deprecations/pending-removal-in-3.17.rst -.. include:: ../deprecations/pending-removal-in-3.18.rst - .. include:: ../deprecations/pending-removal-in-3.19.rst .. include:: ../deprecations/pending-removal-in-3.20.rst From 134c8beac9595c6557b430b8113f6a1af0fe8508 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 17 Sep 2025 11:06:44 +0100 Subject: [PATCH 9/9] Fix Sphinx --- Doc/deprecations/index.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/Doc/deprecations/index.rst b/Doc/deprecations/index.rst index c91c64a1092457..f3cecb321d633f 100644 --- a/Doc/deprecations/index.rst +++ b/Doc/deprecations/index.rst @@ -7,8 +7,6 @@ Deprecations .. include:: pending-removal-in-3.17.rst -.. include:: pending-removal-in-3.18.rst - .. include:: pending-removal-in-3.19.rst .. include:: pending-removal-in-3.20.rst