diff --git a/CVE-2023-52425-libexpat-2.6.0-backport.patch b/CVE-2023-52425-libexpat-2.6.0-backport.patch
index b09aad4..b6358ae 100644
--- a/CVE-2023-52425-libexpat-2.6.0-backport.patch
+++ b/CVE-2023-52425-libexpat-2.6.0-backport.patch
@@ -4,11 +4,11 @@
Lib/test/test_xml_etree.py | 7 +++++++
3 files changed, 14 insertions(+)
-Index: Python-3.10.19/Lib/test/test_pyexpat.py
+Index: Python-3.10.20/Lib/test/test_pyexpat.py
===================================================================
---- Python-3.10.19.orig/Lib/test/test_pyexpat.py 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Lib/test/test_pyexpat.py 2025-12-19 23:10:22.001497953 +0100
-@@ -802,6 +802,10 @@
+--- Python-3.10.20.orig/Lib/test/test_pyexpat.py 2026-03-05 19:42:14.505101236 +0100
++++ Python-3.10.20/Lib/test/test_pyexpat.py 2026-03-05 19:42:23.343680667 +0100
+@@ -807,6 +807,10 @@
self.assertEqual(started, ['doc'])
def test_reparse_deferral_disabled(self):
@@ -19,10 +19,10 @@ Index: Python-3.10.19/Lib/test/test_pyexpat.py
started = []
def start_element(name, _):
-Index: Python-3.10.19/Lib/test/test_sax.py
+Index: Python-3.10.20/Lib/test/test_sax.py
===================================================================
---- Python-3.10.19.orig/Lib/test/test_sax.py 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Lib/test/test_sax.py 2025-12-19 23:10:22.002078897 +0100
+--- Python-3.10.20.orig/Lib/test/test_sax.py 2026-03-05 19:42:14.505101236 +0100
++++ Python-3.10.20/Lib/test/test_sax.py 2026-03-05 19:42:23.344649745 +0100
@@ -1240,6 +1240,9 @@
self.assertEqual(result.getvalue(), start + b"")
@@ -33,10 +33,10 @@ Index: Python-3.10.19/Lib/test/test_sax.py
def test_flush_reparse_deferral_disabled(self):
result = BytesIO()
xmlgen = XMLGenerator(result)
-Index: Python-3.10.19/Lib/test/test_xml_etree.py
+Index: Python-3.10.20/Lib/test/test_xml_etree.py
===================================================================
---- Python-3.10.19.orig/Lib/test/test_xml_etree.py 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Lib/test/test_xml_etree.py 2025-12-19 23:10:22.002413090 +0100
+--- Python-3.10.20.orig/Lib/test/test_xml_etree.py 2026-03-05 19:42:14.505101236 +0100
++++ Python-3.10.20/Lib/test/test_xml_etree.py 2026-03-05 19:42:23.345531779 +0100
@@ -1420,9 +1420,13 @@
self.assert_event_tags(parser, [('end', 'root')])
self.assertIsNone(parser.close())
diff --git a/CVE-2025-11468-email-hdr-fold-comment.patch b/CVE-2025-11468-email-hdr-fold-comment.patch
deleted file mode 100644
index 06d33ef..0000000
--- a/CVE-2025-11468-email-hdr-fold-comment.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From 2065aa5b8f2bcdea2f628686c57974793a62c42b Mon Sep 17 00:00:00 2001
-From: Seth Michael Larson
-Date: Mon, 19 Jan 2026 06:38:22 -0600
-Subject: [PATCH] [3.10] gh-143935: Email preserve parens when folding comments
- (GH-143936)
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Fix a bug in the folding of comments when flattening an email message
-using a modern email policy. Comments consisting of a very long sequence of
-non-foldable characters could trigger a forced line wrap that omitted the
-required leading space on the continuation line, causing the remainder of
-the comment to be interpreted as a new header field. This enabled header
-injection with carefully crafted inputs.
-(cherry picked from commit 17d1490)
-
-Co-authored-by: Seth Michael Larson seth@python.org
-Co-authored-by: Denis Ledoux dle@odoo.com
-
-- Issue: Fix folding of long comments of unfoldable characters in email headers #143935
-
-Signed-off-by: Edgar Ramírez Mondragón
----
- Lib/email/_header_value_parser.py | 15 +++++++++++-
- .../test_email/test__header_value_parser.py | 23 +++++++++++++++++++
- ...-01-16-14-40-31.gh-issue-143935.U2YtKl.rst | 6 +++++
- 3 files changed, 43 insertions(+), 1 deletion(-)
- create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-14-40-31.gh-issue-143935.U2YtKl.rst
-
-diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py
-index dbc0bd8196af52..2c05abeadea22b 100644
---- a/Lib/email/_header_value_parser.py
-+++ b/Lib/email/_header_value_parser.py
-@@ -101,6 +101,12 @@ def make_quoted_pairs(value):
- return str(value).replace('\\', '\\\\').replace('"', '\\"')
-
-
-+def make_parenthesis_pairs(value):
-+ """Escape parenthesis and backslash for use within a comment."""
-+ return str(value).replace('\\', '\\\\') \
-+ .replace('(', '\\(').replace(')', '\\)')
-+
-+
- def quote_string(value):
- escaped = make_quoted_pairs(value)
- return f'"{escaped}"'
-@@ -927,7 +933,7 @@ def value(self):
- return ' '
-
- def startswith_fws(self):
-- return True
-+ return self and self[0] in WSP
-
-
- class ValueTerminal(Terminal):
-@@ -2865,6 +2871,13 @@ def _refold_parse_tree(parse_tree, *, policy):
- [ValueTerminal(make_quoted_pairs(p), 'ptext')
- for p in newparts] +
- [ValueTerminal('"', 'ptext')])
-+ if part.token_type == 'comment':
-+ newparts = (
-+ [ValueTerminal('(', 'ptext')] +
-+ [ValueTerminal(make_parenthesis_pairs(p), 'ptext')
-+ if p.token_type == 'ptext' else p
-+ for p in newparts] +
-+ [ValueTerminal(')', 'ptext')])
- if not part.as_ew_allowed:
- wrap_as_ew_blocked += 1
- newparts.append(end_ew_not_allowed)
-diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py
-index 6a4ecafd68b4ab..2eaaaaef675284 100644
---- a/Lib/test/test_email/test__header_value_parser.py
-+++ b/Lib/test/test_email/test__header_value_parser.py
-@@ -2973,6 +2973,29 @@ def test_address_list_with_specials_in_long_quoted_string(self):
- with self.subTest(to=to):
- self._test(parser.get_address_list(to)[0], folded, policy=policy)
-
-+ def test_address_list_with_long_unwrapable_comment(self):
-+ policy = self.policy.clone(max_line_length=40)
-+ cases = [
-+ # (to, folded)
-+ ('(loremipsumdolorsitametconsecteturadipi)',
-+ '(loremipsumdolorsitametconsecteturadipi)\n'),
-+ ('(loremipsumdolorsitametconsecteturadipi)',
-+ '(loremipsumdolorsitametconsecteturadipi)\n'),
-+ ('(loremipsum dolorsitametconsecteturadipi)',
-+ '(loremipsum dolorsitametconsecteturadipi)\n'),
-+ ('(loremipsum dolorsitametconsecteturadipi)',
-+ '(loremipsum\n dolorsitametconsecteturadipi)\n'),
-+ ('(Escaped \\( \\) chars \\\\ in comments stay escaped)',
-+ '(Escaped \\( \\) chars \\\\ in comments stay\n escaped)\n'),
-+ ('((loremipsum)(loremipsum)(loremipsum)(loremipsum))',
-+ '((loremipsum)(loremipsum)(loremipsum)(loremipsum))\n'),
-+ ('((loremipsum)(loremipsum)(loremipsum) (loremipsum))',
-+ '((loremipsum)(loremipsum)(loremipsum)\n (loremipsum))\n'),
-+ ]
-+ for (to, folded) in cases:
-+ with self.subTest(to=to):
-+ self._test(parser.get_address_list(to)[0], folded, policy=policy)
-+
- def test_address_list_with_specials_in_encoded_word(self):
- # An encoded-word parsed from a structured header must remain
- # encoded when it contains specials. Regression for gh-121284.
-diff --git a/Misc/NEWS.d/next/Security/2026-01-16-14-40-31.gh-issue-143935.U2YtKl.rst b/Misc/NEWS.d/next/Security/2026-01-16-14-40-31.gh-issue-143935.U2YtKl.rst
-new file mode 100644
-index 00000000000000..c3d864936884ac
---- /dev/null
-+++ b/Misc/NEWS.d/next/Security/2026-01-16-14-40-31.gh-issue-143935.U2YtKl.rst
-@@ -0,0 +1,6 @@
-+Fixed a bug in the folding of comments when flattening an email message
-+using a modern email policy. Comments consisting of a very long sequence of
-+non-foldable characters could trigger a forced line wrap that omitted the
-+required leading space on the continuation line, causing the remainder of
-+the comment to be interpreted as a new header field. This enabled header
-+injection with carefully crafted inputs.
diff --git a/CVE-2025-12084-minidom-quad-search.patch b/CVE-2025-12084-minidom-quad-search.patch
deleted file mode 100644
index 171e52c..0000000
--- a/CVE-2025-12084-minidom-quad-search.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From f4eb9ab014545b521fb261b80adfa6d138e7e092 Mon Sep 17 00:00:00 2001
-From: Seth Michael Larson
-Date: Wed, 3 Dec 2025 01:16:37 -0600
-Subject: [PATCH] gh-142145: Remove quadratic behavior in node ID cache
- clearing (GH-142146)
-
-* Remove quadratic behavior in node ID cache clearing
-
-Co-authored-by: Jacob Walls <38668450+jacobtylerwalls@users.noreply.github.com>
-
-* Add news fragment
-
----------
-(cherry picked from commit 08d8e18ad81cd45bc4a27d6da478b51ea49486e4)
-
-Co-authored-by: Seth Michael Larson
-Co-authored-by: Jacob Walls <38668450+jacobtylerwalls@users.noreply.github.com>
----
- Lib/test/test_minidom.py | 18 ++++++++++
- Lib/xml/dom/minidom.py | 9 -----
- Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst | 1
- 3 files changed, 20 insertions(+), 8 deletions(-)
- create mode 100644 Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst
-
-Index: Python-3.10.19/Lib/test/test_minidom.py
-===================================================================
---- Python-3.10.19.orig/Lib/test/test_minidom.py 2025-12-19 23:10:45.263295780 +0100
-+++ Python-3.10.19/Lib/test/test_minidom.py 2025-12-19 23:10:50.342493590 +0100
-@@ -2,6 +2,7 @@
-
- import copy
- import pickle
-+import time
- import io
- from test import support
- import unittest
-@@ -176,6 +177,23 @@
- self.confirm(dom.documentElement.childNodes[-1].data == "Hello")
- dom.unlink()
-
-+ def testAppendChildNoQuadraticComplexity(self):
-+ impl = getDOMImplementation()
-+
-+ newdoc = impl.createDocument(None, "some_tag", None)
-+ top_element = newdoc.documentElement
-+ children = [newdoc.createElement(f"child-{i}") for i in range(1, 2 ** 15 + 1)]
-+ element = top_element
-+
-+ start = time.time()
-+ for child in children:
-+ element.appendChild(child)
-+ element = child
-+ end = time.time()
-+
-+ # This example used to take at least 30 seconds.
-+ self.assertLess(end - start, 1)
-+
- def testAppendChildFragment(self):
- dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes()
- dom.documentElement.appendChild(frag)
-Index: Python-3.10.19/Lib/xml/dom/minidom.py
-===================================================================
---- Python-3.10.19.orig/Lib/xml/dom/minidom.py 2025-12-19 23:10:45.263295780 +0100
-+++ Python-3.10.19/Lib/xml/dom/minidom.py 2025-12-19 23:10:50.342898393 +0100
-@@ -292,13 +292,6 @@
- childNodes.append(node)
- node.parentNode = self
-
--def _in_document(node):
-- # return True iff node is part of a document tree
-- while node is not None:
-- if node.nodeType == Node.DOCUMENT_NODE:
-- return True
-- node = node.parentNode
-- return False
-
- def _write_data(writer, data):
- "Writes datachars to writer."
-@@ -1539,7 +1532,7 @@
- if node.nodeType == Node.DOCUMENT_NODE:
- node._id_cache.clear()
- node._id_search_stack = None
-- elif _in_document(node):
-+ elif node.ownerDocument:
- node.ownerDocument._id_cache.clear()
- node.ownerDocument._id_search_stack= None
-
-Index: Python-3.10.19/Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ Python-3.10.19/Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst 2025-12-19 23:10:50.343161277 +0100
-@@ -0,0 +1 @@
-+Remove quadratic behavior in ``xml.minidom`` node ID cache clearing.
diff --git a/CVE-2025-13836-http-resp-cont-len.patch b/CVE-2025-13836-http-resp-cont-len.patch
deleted file mode 100644
index 36900a6..0000000
--- a/CVE-2025-13836-http-resp-cont-len.patch
+++ /dev/null
@@ -1,155 +0,0 @@
-From b3a7998115e195c40e00cfa662bcaa899d937c05 Mon Sep 17 00:00:00 2001
-From: Serhiy Storchaka
-Date: Mon, 1 Dec 2025 17:26:07 +0200
-Subject: [PATCH] gh-119451: Fix a potential denial of service in http.client
- (GH-119454)
-
-Reading the whole body of the HTTP response could cause OOM if
-the Content-Length value is too large even if the server does not send
-a large amount of data. Now the HTTP client reads large data by chunks,
-therefore the amount of consumed memory is proportional to the amount
-of sent data.
-(cherry picked from commit 5a4c4a033a4a54481be6870aa1896fad732555b5)
-
-Co-authored-by: Serhiy Storchaka
----
- Lib/http/client.py | 28 ++++++--
- Lib/test/test_httplib.py | 66 +++++++++++++++++++
- ...-05-23-11-47-48.gh-issue-119451.qkJe9-.rst | 5 ++
- 3 files changed, 95 insertions(+), 4 deletions(-)
- create mode 100644 Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst
-
-diff --git a/Lib/http/client.py b/Lib/http/client.py
-index d1b7b1048c9171..c8ab5b7662c334 100644
---- a/Lib/http/client.py
-+++ b/Lib/http/client.py
-@@ -111,6 +111,11 @@
- _MAXLINE = 65536
- _MAXHEADERS = 100
-
-+# Data larger than this will be read in chunks, to prevent extreme
-+# overallocation.
-+_MIN_READ_BUF_SIZE = 1 << 20
-+
-+
- # Header name/value ABNF (http://tools.ietf.org/html/rfc7230#section-3.2)
- #
- # VCHAR = %x21-7E
-@@ -628,10 +633,25 @@ def _safe_read(self, amt):
- reading. If the bytes are truly not available (due to EOF), then the
- IncompleteRead exception can be used to detect the problem.
- """
-- data = self.fp.read(amt)
-- if len(data) < amt:
-- raise IncompleteRead(data, amt-len(data))
-- return data
-+ cursize = min(amt, _MIN_READ_BUF_SIZE)
-+ data = self.fp.read(cursize)
-+ if len(data) >= amt:
-+ return data
-+ if len(data) < cursize:
-+ raise IncompleteRead(data, amt - len(data))
-+
-+ data = io.BytesIO(data)
-+ data.seek(0, 2)
-+ while True:
-+ # This is a geometric increase in read size (never more than
-+ # doubling out the current length of data per loop iteration).
-+ delta = min(cursize, amt - cursize)
-+ data.write(self.fp.read(delta))
-+ if data.tell() >= amt:
-+ return data.getvalue()
-+ cursize += delta
-+ if data.tell() < cursize:
-+ raise IncompleteRead(data.getvalue(), amt - data.tell())
-
- def _safe_readinto(self, b):
- """Same as _safe_read, but for reading into a buffer."""
-diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py
-index 77152cf64565e0..89ec5f6f1c5383 100644
---- a/Lib/test/test_httplib.py
-+++ b/Lib/test/test_httplib.py
-@@ -1226,6 +1226,72 @@ def run_server():
- thread.join()
- self.assertEqual(result, b"proxied data\n")
-
-+ def test_large_content_length(self):
-+ serv = socket.create_server((HOST, 0))
-+ self.addCleanup(serv.close)
-+
-+ def run_server():
-+ [conn, address] = serv.accept()
-+ with conn:
-+ while conn.recv(1024):
-+ conn.sendall(
-+ b"HTTP/1.1 200 Ok\r\n"
-+ b"Content-Length: %d\r\n"
-+ b"\r\n" % size)
-+ conn.sendall(b'A' * (size//3))
-+ conn.sendall(b'B' * (size - size//3))
-+
-+ thread = threading.Thread(target=run_server)
-+ thread.start()
-+ self.addCleanup(thread.join, 1.0)
-+
-+ conn = client.HTTPConnection(*serv.getsockname())
-+ try:
-+ for w in range(15, 27):
-+ size = 1 << w
-+ conn.request("GET", "/")
-+ with conn.getresponse() as response:
-+ self.assertEqual(len(response.read()), size)
-+ finally:
-+ conn.close()
-+ thread.join(1.0)
-+
-+ def test_large_content_length_truncated(self):
-+ serv = socket.create_server((HOST, 0))
-+ self.addCleanup(serv.close)
-+
-+ def run_server():
-+ while True:
-+ [conn, address] = serv.accept()
-+ with conn:
-+ conn.recv(1024)
-+ if not size:
-+ break
-+ conn.sendall(
-+ b"HTTP/1.1 200 Ok\r\n"
-+ b"Content-Length: %d\r\n"
-+ b"\r\n"
-+ b"Text" % size)
-+
-+ thread = threading.Thread(target=run_server)
-+ thread.start()
-+ self.addCleanup(thread.join, 1.0)
-+
-+ conn = client.HTTPConnection(*serv.getsockname())
-+ try:
-+ for w in range(18, 65):
-+ size = 1 << w
-+ conn.request("GET", "/")
-+ with conn.getresponse() as response:
-+ self.assertRaises(client.IncompleteRead, response.read)
-+ conn.close()
-+ finally:
-+ conn.close()
-+ size = 0
-+ conn.request("GET", "/")
-+ conn.close()
-+ thread.join(1.0)
-+
- def test_putrequest_override_domain_validation(self):
- """
- It should be possible to override the default validation
-diff --git a/Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst b/Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst
-new file mode 100644
-index 00000000000000..6d6f25cd2f8bf7
---- /dev/null
-+++ b/Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst
-@@ -0,0 +1,5 @@
-+Fix a potential memory denial of service in the :mod:`http.client` module.
-+When connecting to a malicious server, it could cause
-+an arbitrary amount of memory to be allocated.
-+This could have led to symptoms including a :exc:`MemoryError`, swapping, out
-+of memory (OOM) killed processes or containers, or even system crashes.
diff --git a/CVE-2025-13837-plistlib-mailicious-length.patch b/CVE-2025-13837-plistlib-mailicious-length.patch
deleted file mode 100644
index ed1ff99..0000000
--- a/CVE-2025-13837-plistlib-mailicious-length.patch
+++ /dev/null
@@ -1,160 +0,0 @@
-From e99059d800b741504ef18693803927a0dc062be4 Mon Sep 17 00:00:00 2001
-From: Serhiy Storchaka
-Date: Mon, 1 Dec 2025 17:28:15 +0200
-Subject: [PATCH] [3.10] gh-119342: Fix a potential denial of service in
- plistlib (GH-119343)
-
-Reading a specially prepared small Plist file could cause OOM because file's
-read(n) preallocates a bytes object for reading the specified amount of
-data. Now plistlib reads large data by chunks, therefore the upper limit of
-consumed memory is proportional to the size of the input file.
-(cherry picked from commit 694922cf40aa3a28f898b5f5ee08b71b4922df70)
-
-Co-authored-by: Serhiy Storchaka
----
- Lib/plistlib.py | 31 ++++++++++------
- Lib/test/test_plistlib.py | 37 +++++++++++++++++--
- ...-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst | 5 +++
- 3 files changed, 59 insertions(+), 14 deletions(-)
- create mode 100644 Misc/NEWS.d/next/Security/2024-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst
-
-diff --git a/Lib/plistlib.py b/Lib/plistlib.py
-index d6c997efe9c5f5..c80dfee02a3335 100644
---- a/Lib/plistlib.py
-+++ b/Lib/plistlib.py
-@@ -73,6 +73,9 @@
- PlistFormat = enum.Enum('PlistFormat', 'FMT_XML FMT_BINARY', module=__name__)
- globals().update(PlistFormat.__members__)
-
-+# Data larger than this will be read in chunks, to prevent extreme
-+# overallocation.
-+_MIN_READ_BUF_SIZE = 1 << 20
-
- class UID:
- def __init__(self, data):
-@@ -499,12 +502,24 @@ def _get_size(self, tokenL):
-
- return tokenL
-
-+ def _read(self, size):
-+ cursize = min(size, _MIN_READ_BUF_SIZE)
-+ data = self._fp.read(cursize)
-+ while True:
-+ if len(data) != cursize:
-+ raise InvalidFileException
-+ if cursize == size:
-+ return data
-+ delta = min(cursize, size - cursize)
-+ data += self._fp.read(delta)
-+ cursize += delta
-+
- def _read_ints(self, n, size):
-- data = self._fp.read(size * n)
-+ data = self._read(size * n)
- if size in _BINARY_FORMAT:
- return struct.unpack(f'>{n}{_BINARY_FORMAT[size]}', data)
- else:
-- if not size or len(data) != size * n:
-+ if not size:
- raise InvalidFileException()
- return tuple(int.from_bytes(data[i: i + size], 'big')
- for i in range(0, size * n, size))
-@@ -561,22 +576,16 @@ def _read_object(self, ref):
-
- elif tokenH == 0x40: # data
- s = self._get_size(tokenL)
-- result = self._fp.read(s)
-- if len(result) != s:
-- raise InvalidFileException()
-+ result = self._read(s)
-
- elif tokenH == 0x50: # ascii string
- s = self._get_size(tokenL)
-- data = self._fp.read(s)
-- if len(data) != s:
-- raise InvalidFileException()
-+ data = self._read(s)
- result = data.decode('ascii')
-
- elif tokenH == 0x60: # unicode string
- s = self._get_size(tokenL) * 2
-- data = self._fp.read(s)
-- if len(data) != s:
-- raise InvalidFileException()
-+ data = self._read(s)
- result = data.decode('utf-16be')
-
- elif tokenH == 0x80: # UID
-diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py
-index ef96c6ceda21a2..d3836991d212cd 100644
---- a/Lib/test/test_plistlib.py
-+++ b/Lib/test/test_plistlib.py
-@@ -838,8 +838,7 @@ def test_xml_plist_with_entity_decl(self):
-
- class TestBinaryPlistlib(unittest.TestCase):
-
-- @staticmethod
-- def decode(*objects, offset_size=1, ref_size=1):
-+ def build(self, *objects, offset_size=1, ref_size=1):
- data = [b'bplist00']
- offset = 8
- offsets = []
-@@ -851,7 +850,11 @@ def decode(*objects, offset_size=1, ref_size=1):
- len(objects), 0, offset)
- data.extend(offsets)
- data.append(tail)
-- return plistlib.loads(b''.join(data), fmt=plistlib.FMT_BINARY)
-+ return b''.join(data)
-+
-+ def decode(self, *objects, offset_size=1, ref_size=1):
-+ data = self.build(*objects, offset_size=offset_size, ref_size=ref_size)
-+ return plistlib.loads(data, fmt=plistlib.FMT_BINARY)
-
- def test_nonstandard_refs_size(self):
- # Issue #21538: Refs and offsets are 24-bit integers
-@@ -959,6 +962,34 @@ def test_invalid_binary(self):
- with self.assertRaises(plistlib.InvalidFileException):
- plistlib.loads(b'bplist00' + data, fmt=plistlib.FMT_BINARY)
-
-+ def test_truncated_large_data(self):
-+ self.addCleanup(os_helper.unlink, os_helper.TESTFN)
-+ def check(data):
-+ with open(os_helper.TESTFN, 'wb') as f:
-+ f.write(data)
-+ # buffered file
-+ with open(os_helper.TESTFN, 'rb') as f:
-+ with self.assertRaises(plistlib.InvalidFileException):
-+ plistlib.load(f, fmt=plistlib.FMT_BINARY)
-+ # unbuffered file
-+ with open(os_helper.TESTFN, 'rb', buffering=0) as f:
-+ with self.assertRaises(plistlib.InvalidFileException):
-+ plistlib.load(f, fmt=plistlib.FMT_BINARY)
-+ for w in range(20, 64):
-+ s = 1 << w
-+ # data
-+ check(self.build(b'\x4f\x13' + s.to_bytes(8, 'big')))
-+ # ascii string
-+ check(self.build(b'\x5f\x13' + s.to_bytes(8, 'big')))
-+ # unicode string
-+ check(self.build(b'\x6f\x13' + s.to_bytes(8, 'big')))
-+ # array
-+ check(self.build(b'\xaf\x13' + s.to_bytes(8, 'big')))
-+ # dict
-+ check(self.build(b'\xdf\x13' + s.to_bytes(8, 'big')))
-+ # number of objects
-+ check(b'bplist00' + struct.pack('>6xBBQQQ', 1, 1, s, 0, 8))
-+
-
- class TestKeyedArchive(unittest.TestCase):
- def test_keyed_archive_data(self):
-diff --git a/Misc/NEWS.d/next/Security/2024-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst b/Misc/NEWS.d/next/Security/2024-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst
-new file mode 100644
-index 00000000000000..04fd8faca4cf7e
---- /dev/null
-+++ b/Misc/NEWS.d/next/Security/2024-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst
-@@ -0,0 +1,5 @@
-+Fix a potential memory denial of service in the :mod:`plistlib` module.
-+When reading a Plist file received from untrusted source, it could cause
-+an arbitrary amount of memory to be allocated.
-+This could have led to symptoms including a :exc:`MemoryError`, swapping, out
-+of memory (OOM) killed processes or containers, or even system crashes.
diff --git a/CVE-2025-15282-urllib-ctrl-chars.patch b/CVE-2025-15282-urllib-ctrl-chars.patch
index 761803d..b5a9f6f 100644
--- a/CVE-2025-15282-urllib-ctrl-chars.patch
+++ b/CVE-2025-15282-urllib-ctrl-chars.patch
@@ -8,27 +8,19 @@ Subject: [PATCH] [3.10] gh-143925: Reject control characters in data: URL
Co-authored-by: Seth Michael Larson
---
- Lib/test/test_urllib.py | 8 ++++++++
+ Lib/test/test_urllib.py | 7 +++++++
Lib/urllib/request.py | 5 +++++
Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst | 1 +
- 3 files changed, 14 insertions(+)
+ 3 files changed, 13 insertions(+)
create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst
-Index: Python-3.10.19/Lib/test/test_urllib.py
+Index: Python-3.10.20/Lib/test/test_urllib.py
===================================================================
---- Python-3.10.19.orig/Lib/test/test_urllib.py 2026-02-12 01:05:56.127447144 +0100
-+++ Python-3.10.19/Lib/test/test_urllib.py 2026-02-12 01:08:02.226352573 +0100
-@@ -11,6 +11,7 @@
- from test import support
- from test.support import os_helper
- from test.support import warnings_helper
-+from test.support import control_characters_c0
- import os
- try:
- import ssl
-@@ -683,6 +684,13 @@
- # missing padding character
- self.assertRaises(ValueError,urllib.request.urlopen,'data:;base64,Cg=')
+--- Python-3.10.20.orig/Lib/test/test_urllib.py 2026-03-05 19:39:02.061358156 +0100
++++ Python-3.10.20/Lib/test/test_urllib.py 2026-03-05 23:19:43.575732909 +0100
+@@ -607,6 +607,13 @@
+ "https://localhost", cafile="/nonexistent/path", context=context
+ )
+ def test_invalid_mediatype(self):
+ for c0 in control_characters_c0():
@@ -38,15 +30,15 @@ Index: Python-3.10.19/Lib/test/test_urllib.py
+ self.assertRaises(ValueError,urllib.request.urlopen,
+ f'data:text/html{c0};base64,ZGF0YQ==')
- class urlretrieve_FileTests(unittest.TestCase):
- """Test urllib.urlretrieve() on local files"""
-Index: Python-3.10.19/Lib/urllib/request.py
+ class urlopen_DataTests(unittest.TestCase):
+ """Test urlopen() opening a data URL."""
+Index: Python-3.10.20/Lib/urllib/request.py
===================================================================
---- Python-3.10.19.orig/Lib/urllib/request.py 2026-02-12 01:05:56.627830069 +0100
-+++ Python-3.10.19/Lib/urllib/request.py 2026-02-12 01:08:02.226810828 +0100
-@@ -1654,6 +1654,11 @@
- scheme, data = url.split(":",1)
- mediatype, data = data.split(",",1)
+--- Python-3.10.20.orig/Lib/urllib/request.py 2026-03-05 19:39:02.551702670 +0100
++++ Python-3.10.20/Lib/urllib/request.py 2026-03-05 23:19:43.576415166 +0100
+@@ -1659,6 +1659,11 @@
+ raise ValueError(
+ "Control characters not allowed in data: mediatype")
+ # Disallow control characters within mediatype.
+ if re.search(r"[\x00-\x1F\x7F]", mediatype):
@@ -56,9 +48,9 @@ Index: Python-3.10.19/Lib/urllib/request.py
# even base64 encoded data URLs might be quoted so unquote in any case:
data = unquote_to_bytes(data)
if mediatype.endswith(";base64"):
-Index: Python-3.10.19/Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst
+Index: Python-3.10.20/Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ Python-3.10.19/Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst 2026-02-12 01:08:02.227192287 +0100
++++ Python-3.10.20/Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst 2026-03-05 23:19:43.576850667 +0100
@@ -0,0 +1 @@
+Reject control characters in ``data:`` URL media types.
diff --git a/CVE-2025-15366-imap-ctrl-chars.patch b/CVE-2025-15366-imap-ctrl-chars.patch
index ed45499..5f79815 100644
--- a/CVE-2025-15366-imap-ctrl-chars.patch
+++ b/CVE-2025-15366-imap-ctrl-chars.patch
@@ -9,10 +9,10 @@ Subject: [PATCH 1/2] Add 'test.support' fixture for C0 control characters
Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst | 1 +
3 files changed, 10 insertions(+), 1 deletion(-)
-Index: Python-3.10.19/Lib/imaplib.py
+Index: Python-3.10.20/Lib/imaplib.py
===================================================================
---- Python-3.10.19.orig/Lib/imaplib.py 2026-02-12 01:05:53.821319313 +0100
-+++ Python-3.10.19/Lib/imaplib.py 2026-02-12 01:06:28.558652908 +0100
+--- Python-3.10.20.orig/Lib/imaplib.py 2026-03-05 19:38:59.446918283 +0100
++++ Python-3.10.20/Lib/imaplib.py 2026-03-05 23:19:20.515035897 +0100
@@ -132,7 +132,7 @@
# We compile these in _mode_xxx.
_Literal = br'.*{(?P\d+)}$'
@@ -31,10 +31,10 @@ Index: Python-3.10.19/Lib/imaplib.py
data = data + b' ' + arg
literal = self.literal
-Index: Python-3.10.19/Lib/test/test_imaplib.py
+Index: Python-3.10.20/Lib/test/test_imaplib.py
===================================================================
---- Python-3.10.19.orig/Lib/test/test_imaplib.py 2026-02-12 01:05:55.293033311 +0100
-+++ Python-3.10.19/Lib/test/test_imaplib.py 2026-02-12 01:07:45.387053336 +0100
+--- Python-3.10.20.orig/Lib/test/test_imaplib.py 2026-03-05 19:39:01.155920382 +0100
++++ Python-3.10.20/Lib/test/test_imaplib.py 2026-03-05 23:19:20.517235411 +0100
@@ -538,6 +538,12 @@
self.assertEqual(data[0], b'Returned to authenticated state. (Success)')
self.assertEqual(client.state, 'AUTH')
@@ -48,9 +48,9 @@ Index: Python-3.10.19/Lib/test/test_imaplib.py
class NewIMAPTests(NewIMAPTestsMixin, unittest.TestCase):
imap_class = imaplib.IMAP4
-Index: Python-3.10.19/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst
+Index: Python-3.10.20/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ Python-3.10.19/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst 2026-02-12 01:06:28.559224837 +0100
++++ Python-3.10.20/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst 2026-03-05 23:19:20.517573599 +0100
@@ -0,0 +1 @@
+Reject control characters in IMAP commands.
diff --git a/CVE-2025-15367-poplib-ctrl-chars.patch b/CVE-2025-15367-poplib-ctrl-chars.patch
index 345f6b1..98bba05 100644
--- a/CVE-2025-15367-poplib-ctrl-chars.patch
+++ b/CVE-2025-15367-poplib-ctrl-chars.patch
@@ -9,10 +9,10 @@ Subject: [PATCH 1/2] Add 'test.support' fixture for C0 control characters
Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst | 1 +
3 files changed, 11 insertions(+)
-Index: Python-3.10.19/Lib/poplib.py
+Index: Python-3.10.20/Lib/poplib.py
===================================================================
---- Python-3.10.19.orig/Lib/poplib.py 2026-02-12 01:05:54.262197434 +0100
-+++ Python-3.10.19/Lib/poplib.py 2026-02-12 01:12:02.945762019 +0100
+--- Python-3.10.20.orig/Lib/poplib.py 2026-03-05 19:38:59.939747453 +0100
++++ Python-3.10.20/Lib/poplib.py 2026-03-05 23:21:23.043850896 +0100
@@ -122,6 +122,8 @@
def _putcmd(self, line):
if self._debugging: print('*cmd*', repr(line))
@@ -22,10 +22,10 @@ Index: Python-3.10.19/Lib/poplib.py
self._putline(line)
-Index: Python-3.10.19/Lib/test/test_poplib.py
+Index: Python-3.10.20/Lib/test/test_poplib.py
===================================================================
---- Python-3.10.19.orig/Lib/test/test_poplib.py 2026-02-12 01:05:55.796995175 +0100
-+++ Python-3.10.19/Lib/test/test_poplib.py 2026-02-12 01:12:32.837694637 +0100
+--- Python-3.10.20.orig/Lib/test/test_poplib.py 2026-03-05 19:39:01.686377763 +0100
++++ Python-3.10.20/Lib/test/test_poplib.py 2026-03-05 23:21:23.044538262 +0100
@@ -15,6 +15,7 @@
from test.support import hashlib_helper
from test.support import socket_helper
@@ -48,9 +48,9 @@ Index: Python-3.10.19/Lib/test/test_poplib.py
@requires_ssl
def test_stls_capa(self):
capa = self.client.capa()
-Index: Python-3.10.19/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst
+Index: Python-3.10.20/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ Python-3.10.19/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst 2026-02-12 01:12:02.946199975 +0100
++++ Python-3.10.20/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst 2026-03-05 23:21:23.044905845 +0100
@@ -0,0 +1 @@
+Reject control characters in POP3 commands.
diff --git a/CVE-2025-6075-expandvars-perf-degrad.patch b/CVE-2025-6075-expandvars-perf-degrad.patch
deleted file mode 100644
index cabfc9e..0000000
--- a/CVE-2025-6075-expandvars-perf-degrad.patch
+++ /dev/null
@@ -1,359 +0,0 @@
-From 20044636f0d9a802c42f907934c69d46e4019a0c Mon Sep 17 00:00:00 2001
-From: Serhiy Storchaka
-Date: Fri, 31 Oct 2025 15:49:51 +0200
-Subject: [PATCH] [3.10] gh-136065: Fix quadratic complexity in
- os.path.expandvars() (GH-134952) (cherry picked from commit
- f029e8db626ddc6e3a3beea4eff511a71aaceb5c)
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Co-authored-by: Serhiy Storchaka
-Co-authored-by: Łukasz Langa
----
- Lib/ntpath.py | 126 ++++++------------
- Lib/posixpath.py | 43 +++---
- Lib/test/test_genericpath.py | 14 ++
- Lib/test/test_ntpath.py | 20 ++-
- ...-05-30-22-33-27.gh-issue-136065.bu337o.rst | 1 +
- 5 files changed, 93 insertions(+), 111 deletions(-)
- create mode 100644 Misc/NEWS.d/next/Security/2025-05-30-22-33-27.gh-issue-136065.bu337o.rst
-
-diff --git a/Lib/ntpath.py b/Lib/ntpath.py
-index 9b0cca44727fd5..bd2b4e289c17b9 100644
---- a/Lib/ntpath.py
-+++ b/Lib/ntpath.py
-@@ -374,17 +374,23 @@ def expanduser(path):
- # XXX With COMMAND.COM you can use any characters in a variable name,
- # XXX except '^|<>='.
-
-+_varpattern = r"'[^']*'?|%(%|[^%]*%?)|\$(\$|[-\w]+|\{[^}]*\}?)"
-+_varsub = None
-+_varsubb = None
-+
- def expandvars(path):
- """Expand shell variables of the forms $var, ${var} and %var%.
-
- Unknown variables are left unchanged."""
- path = os.fspath(path)
-+ global _varsub, _varsubb
- if isinstance(path, bytes):
- if b'$' not in path and b'%' not in path:
- return path
-- import string
-- varchars = bytes(string.ascii_letters + string.digits + '_-', 'ascii')
-- quote = b'\''
-+ if not _varsubb:
-+ import re
-+ _varsubb = re.compile(_varpattern.encode(), re.ASCII).sub
-+ sub = _varsubb
- percent = b'%'
- brace = b'{'
- rbrace = b'}'
-@@ -393,94 +399,44 @@ def expandvars(path):
- else:
- if '$' not in path and '%' not in path:
- return path
-- import string
-- varchars = string.ascii_letters + string.digits + '_-'
-- quote = '\''
-+ if not _varsub:
-+ import re
-+ _varsub = re.compile(_varpattern, re.ASCII).sub
-+ sub = _varsub
- percent = '%'
- brace = '{'
- rbrace = '}'
- dollar = '$'
- environ = os.environ
-- res = path[:0]
-- index = 0
-- pathlen = len(path)
-- while index < pathlen:
-- c = path[index:index+1]
-- if c == quote: # no expansion within single quotes
-- path = path[index + 1:]
-- pathlen = len(path)
-- try:
-- index = path.index(c)
-- res += c + path[:index + 1]
-- except ValueError:
-- res += c + path
-- index = pathlen - 1
-- elif c == percent: # variable or '%'
-- if path[index + 1:index + 2] == percent:
-- res += c
-- index += 1
-- else:
-- path = path[index+1:]
-- pathlen = len(path)
-- try:
-- index = path.index(percent)
-- except ValueError:
-- res += percent + path
-- index = pathlen - 1
-- else:
-- var = path[:index]
-- try:
-- if environ is None:
-- value = os.fsencode(os.environ[os.fsdecode(var)])
-- else:
-- value = environ[var]
-- except KeyError:
-- value = percent + var + percent
-- res += value
-- elif c == dollar: # variable or '$$'
-- if path[index + 1:index + 2] == dollar:
-- res += c
-- index += 1
-- elif path[index + 1:index + 2] == brace:
-- path = path[index+2:]
-- pathlen = len(path)
-- try:
-- index = path.index(rbrace)
-- except ValueError:
-- res += dollar + brace + path
-- index = pathlen - 1
-- else:
-- var = path[:index]
-- try:
-- if environ is None:
-- value = os.fsencode(os.environ[os.fsdecode(var)])
-- else:
-- value = environ[var]
-- except KeyError:
-- value = dollar + brace + var + rbrace
-- res += value
-- else:
-- var = path[:0]
-- index += 1
-- c = path[index:index + 1]
-- while c and c in varchars:
-- var += c
-- index += 1
-- c = path[index:index + 1]
-- try:
-- if environ is None:
-- value = os.fsencode(os.environ[os.fsdecode(var)])
-- else:
-- value = environ[var]
-- except KeyError:
-- value = dollar + var
-- res += value
-- if c:
-- index -= 1
-+
-+ def repl(m):
-+ lastindex = m.lastindex
-+ if lastindex is None:
-+ return m[0]
-+ name = m[lastindex]
-+ if lastindex == 1:
-+ if name == percent:
-+ return name
-+ if not name.endswith(percent):
-+ return m[0]
-+ name = name[:-1]
- else:
-- res += c
-- index += 1
-- return res
-+ if name == dollar:
-+ return name
-+ if name.startswith(brace):
-+ if not name.endswith(rbrace):
-+ return m[0]
-+ name = name[1:-1]
-+
-+ try:
-+ if environ is None:
-+ return os.fsencode(os.environ[os.fsdecode(name)])
-+ else:
-+ return environ[name]
-+ except KeyError:
-+ return m[0]
-+
-+ return sub(repl, path)
-
-
- # Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B.
-diff --git a/Lib/posixpath.py b/Lib/posixpath.py
-index b8dd563ada3880..75020eef477b5e 100644
---- a/Lib/posixpath.py
-+++ b/Lib/posixpath.py
-@@ -279,42 +279,41 @@ def expanduser(path):
- # This expands the forms $variable and ${variable} only.
- # Non-existent variables are left unchanged.
-
--_varprog = None
--_varprogb = None
-+_varpattern = r'\$(\w+|\{[^}]*\}?)'
-+_varsub = None
-+_varsubb = None
-
- def expandvars(path):
- """Expand shell variables of form $var and ${var}. Unknown variables
- are left unchanged."""
- path = os.fspath(path)
-- global _varprog, _varprogb
-+ global _varsub, _varsubb
- if isinstance(path, bytes):
- if b'$' not in path:
- return path
-- if not _varprogb:
-+ if not _varsubb:
- import re
-- _varprogb = re.compile(br'\$(\w+|\{[^}]*\})', re.ASCII)
-- search = _varprogb.search
-+ _varsubb = re.compile(_varpattern.encode(), re.ASCII).sub
-+ sub = _varsubb
- start = b'{'
- end = b'}'
- environ = getattr(os, 'environb', None)
- else:
- if '$' not in path:
- return path
-- if not _varprog:
-+ if not _varsub:
- import re
-- _varprog = re.compile(r'\$(\w+|\{[^}]*\})', re.ASCII)
-- search = _varprog.search
-+ _varsub = re.compile(_varpattern, re.ASCII).sub
-+ sub = _varsub
- start = '{'
- end = '}'
- environ = os.environ
-- i = 0
-- while True:
-- m = search(path, i)
-- if not m:
-- break
-- i, j = m.span(0)
-- name = m.group(1)
-- if name.startswith(start) and name.endswith(end):
-+
-+ def repl(m):
-+ name = m[1]
-+ if name.startswith(start):
-+ if not name.endswith(end):
-+ return m[0]
- name = name[1:-1]
- try:
- if environ is None:
-@@ -322,13 +321,11 @@ def expandvars(path):
- else:
- value = environ[name]
- except KeyError:
-- i = j
-+ return m[0]
- else:
-- tail = path[j:]
-- path = path[:i] + value
-- i = len(path)
-- path += tail
-- return path
-+ return value
-+
-+ return sub(repl, path)
-
-
- # Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
-diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py
-index 1ff7f75ad3e614..b0a13265c98b4e 100644
---- a/Lib/test/test_genericpath.py
-+++ b/Lib/test/test_genericpath.py
-@@ -7,6 +7,7 @@
- import sys
- import unittest
- import warnings
-+from test import support
- from test.support import os_helper
- from test.support import warnings_helper
- from test.support.script_helper import assert_python_ok
-@@ -430,6 +431,19 @@ def check(value, expected):
- os.fsencode('$bar%s bar' % nonascii))
- check(b'$spam}bar', os.fsencode('%s}bar' % nonascii))
-
-+ @support.requires_resource('cpu')
-+ def test_expandvars_large(self):
-+ expandvars = self.pathmodule.expandvars
-+ with os_helper.EnvironmentVarGuard() as env:
-+ env.clear()
-+ env["A"] = "B"
-+ n = 100_000
-+ self.assertEqual(expandvars('$A'*n), 'B'*n)
-+ self.assertEqual(expandvars('${A}'*n), 'B'*n)
-+ self.assertEqual(expandvars('$A!'*n), 'B!'*n)
-+ self.assertEqual(expandvars('${A}A'*n), 'BA'*n)
-+ self.assertEqual(expandvars('${'*10*n), '${'*10*n)
-+
- def test_abspath(self):
- self.assertIn("foo", self.pathmodule.abspath("foo"))
- with warnings.catch_warnings():
-diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py
-index f790f771f2fb6d..161e57d62a06d3 100644
---- a/Lib/test/test_ntpath.py
-+++ b/Lib/test/test_ntpath.py
-@@ -5,8 +5,8 @@
- import unittest
- import warnings
- from ntpath import ALLOW_MISSING
-+from test import support
- from test.support import os_helper
--from test.support import TestFailed
- from test.support.os_helper import FakePath
- from test import test_genericpath
- from tempfile import TemporaryFile
-@@ -56,7 +56,7 @@ def tester(fn, wantResult):
- fn = fn.replace("\\", "\\\\")
- gotResult = eval(fn)
- if wantResult != gotResult and _norm(wantResult) != _norm(gotResult):
-- raise TestFailed("%s should return: %s but returned: %s" \
-+ raise support.TestFailed("%s should return: %s but returned: %s" \
- %(str(fn), str(wantResult), str(gotResult)))
-
- # then with bytes
-@@ -72,7 +72,7 @@ def tester(fn, wantResult):
- warnings.simplefilter("ignore", DeprecationWarning)
- gotResult = eval(fn)
- if _norm(wantResult) != _norm(gotResult):
-- raise TestFailed("%s should return: %s but returned: %s" \
-+ raise support.TestFailed("%s should return: %s but returned: %s" \
- %(str(fn), str(wantResult), repr(gotResult)))
-
-
-@@ -689,6 +689,19 @@ def check(value, expected):
- check('%spam%bar', '%sbar' % nonascii)
- check('%{}%bar'.format(nonascii), 'ham%sbar' % nonascii)
-
-+ @support.requires_resource('cpu')
-+ def test_expandvars_large(self):
-+ expandvars = ntpath.expandvars
-+ with os_helper.EnvironmentVarGuard() as env:
-+ env.clear()
-+ env["A"] = "B"
-+ n = 100_000
-+ self.assertEqual(expandvars('%A%'*n), 'B'*n)
-+ self.assertEqual(expandvars('%A%A'*n), 'BA'*n)
-+ self.assertEqual(expandvars("''"*n + '%%'), "''"*n + '%')
-+ self.assertEqual(expandvars("%%"*n), "%"*n)
-+ self.assertEqual(expandvars("$$"*n), "$"*n)
-+
- def test_expanduser(self):
- tester('ntpath.expanduser("test")', 'test')
-
-@@ -923,6 +936,7 @@ def test_nt_helpers(self):
- self.assertIsInstance(b_final_path, bytes)
- self.assertGreater(len(b_final_path), 0)
-
-+
- class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase):
- pathmodule = ntpath
- attributes = ['relpath']
-diff --git a/Misc/NEWS.d/next/Security/2025-05-30-22-33-27.gh-issue-136065.bu337o.rst b/Misc/NEWS.d/next/Security/2025-05-30-22-33-27.gh-issue-136065.bu337o.rst
-new file mode 100644
-index 00000000000000..1d152bb5318380
---- /dev/null
-+++ b/Misc/NEWS.d/next/Security/2025-05-30-22-33-27.gh-issue-136065.bu337o.rst
-@@ -0,0 +1 @@
-+Fix quadratic complexity in :func:`os.path.expandvars`.
diff --git a/CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch b/CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch
deleted file mode 100644
index f20c480..0000000
--- a/CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch
+++ /dev/null
@@ -1,184 +0,0 @@
-From 57c5ecd7e61fbb24e7de76eafd95332bd0ae4dea Mon Sep 17 00:00:00 2001
-From: Seth Michael Larson
-Date: Tue, 20 Jan 2026 15:23:42 -0600
-Subject: [PATCH] [3.10] gh-143919: Reject control characters in http cookies
- (cherry picked from commit 95746b3a13a985787ef53b977129041971ed7f70)
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Co-authored-by: Seth Michael Larson
-Co-authored-by: Bartosz Sławecki
-Co-authored-by: sobolevn
----
- Doc/library/http.cookies.rst | 4 +-
- Lib/http/cookies.py | 25 +++++++--
- Lib/test/test_http_cookies.py | 52 +++++++++++++++++--
- ...-01-16-11-13-15.gh-issue-143919.kchwZV.rst | 1 +
- 4 files changed, 73 insertions(+), 9 deletions(-)
- create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-13-15.gh-issue-143919.kchwZV.rst
-
-diff --git a/Doc/library/http.cookies.rst b/Doc/library/http.cookies.rst
-index a2c1eb00d8b33d..4cb563c230ea5e 100644
---- a/Doc/library/http.cookies.rst
-+++ b/Doc/library/http.cookies.rst
-@@ -270,9 +270,9 @@ The following example demonstrates how to use the :mod:`http.cookies` module.
- Set-Cookie: chips=ahoy
- Set-Cookie: vienna=finger
- >>> C = cookies.SimpleCookie()
-- >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
-+ >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=;";')
- >>> print(C)
-- Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
-+ Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=;"
- >>> C = cookies.SimpleCookie()
- >>> C["oreo"] = "doublestuff"
- >>> C["oreo"]["path"] = "/"
-diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py
-index 2c1f021d0abede..5cfa7a8072c7f7 100644
---- a/Lib/http/cookies.py
-+++ b/Lib/http/cookies.py
-@@ -87,9 +87,9 @@
- such trickeries do not confuse it.
-
- >>> C = cookies.SimpleCookie()
-- >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
-+ >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=;";')
- >>> print(C)
-- Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
-+ Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=;"
-
- Each element of the Cookie also supports all of the RFC 2109
- Cookie attributes. Here's an example which sets the Path
-@@ -170,6 +170,15 @@ class CookieError(Exception):
- })
-
- _is_legal_key = re.compile('[%s]+' % re.escape(_LegalChars)).fullmatch
-+_control_character_re = re.compile(r'[\x00-\x1F\x7F]')
-+
-+
-+def _has_control_character(*val):
-+ """Detects control characters within a value.
-+ Supports any type, as header values can be any type.
-+ """
-+ return any(_control_character_re.search(str(v)) for v in val)
-+
-
- def _quote(str):
- r"""Quote a string for use in a cookie header.
-@@ -292,12 +301,16 @@ def __setitem__(self, K, V):
- K = K.lower()
- if not K in self._reserved:
- raise CookieError("Invalid attribute %r" % (K,))
-+ if _has_control_character(K, V):
-+ raise CookieError(f"Control characters are not allowed in cookies {K!r} {V!r}")
- dict.__setitem__(self, K, V)
-
- def setdefault(self, key, val=None):
- key = key.lower()
- if key not in self._reserved:
- raise CookieError("Invalid attribute %r" % (key,))
-+ if _has_control_character(key, val):
-+ raise CookieError("Control characters are not allowed in cookies %r %r" % (key, val,))
- return dict.setdefault(self, key, val)
-
- def __eq__(self, morsel):
-@@ -333,6 +346,9 @@ def set(self, key, val, coded_val):
- raise CookieError('Attempt to set a reserved key %r' % (key,))
- if not _is_legal_key(key):
- raise CookieError('Illegal key %r' % (key,))
-+ if _has_control_character(key, val, coded_val):
-+ raise CookieError(
-+ "Control characters are not allowed in cookies %r %r %r" % (key, val, coded_val,))
-
- # It's a good key, so save it.
- self._key = key
-@@ -484,7 +500,10 @@ def output(self, attrs=None, header="Set-Cookie:", sep="\015\012"):
- result = []
- items = sorted(self.items())
- for key, value in items:
-- result.append(value.output(attrs, header))
-+ value_output = value.output(attrs, header)
-+ if _has_control_character(value_output):
-+ raise CookieError("Control characters are not allowed in cookies")
-+ result.append(value_output)
- return sep.join(result)
-
- __str__ = output
-diff --git a/Lib/test/test_http_cookies.py b/Lib/test/test_http_cookies.py
-index 644e75cd5b742e..1f2c049fa811fa 100644
---- a/Lib/test/test_http_cookies.py
-+++ b/Lib/test/test_http_cookies.py
-@@ -17,10 +17,10 @@ def test_basic(self):
- 'repr': "",
- 'output': 'Set-Cookie: chips=ahoy\nSet-Cookie: vienna=finger'},
-
-- {'data': 'keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"',
-- 'dict': {'keebler' : 'E=mc2; L="Loves"; fudge=\012;'},
-- 'repr': '''''',
-- 'output': 'Set-Cookie: keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"'},
-+ {'data': 'keebler="E=mc2; L=\\"Loves\\"; fudge=;"',
-+ 'dict': {'keebler' : 'E=mc2; L="Loves"; fudge=;'},
-+ 'repr': '''''',
-+ 'output': 'Set-Cookie: keebler="E=mc2; L=\\"Loves\\"; fudge=;"'},
-
- # Check illegal cookies that have an '=' char in an unquoted value
- {'data': 'keebler=E=mc2',
-@@ -517,6 +517,50 @@ def test_repr(self):
- r'Set-Cookie: key=coded_val; '
- r'expires=\w+, \d+ \w+ \d+ \d+:\d+:\d+ \w+')
-
-+ def test_control_characters(self):
-+ for c0 in support.control_characters_c0():
-+ morsel = cookies.Morsel()
-+
-+ # .__setitem__()
-+ with self.assertRaises(cookies.CookieError):
-+ morsel[c0] = "val"
-+ with self.assertRaises(cookies.CookieError):
-+ morsel["path"] = c0
-+
-+ # .setdefault()
-+ with self.assertRaises(cookies.CookieError):
-+ morsel.setdefault("path", c0)
-+ with self.assertRaises(cookies.CookieError):
-+ morsel.setdefault(c0, "val")
-+
-+ # .set()
-+ with self.assertRaises(cookies.CookieError):
-+ morsel.set(c0, "val", "coded-value")
-+ with self.assertRaises(cookies.CookieError):
-+ morsel.set("path", c0, "coded-value")
-+ with self.assertRaises(cookies.CookieError):
-+ morsel.set("path", "val", c0)
-+
-+ def test_control_characters_output(self):
-+ # Tests that even if the internals of Morsel are modified
-+ # that a call to .output() has control character safeguards.
-+ for c0 in support.control_characters_c0():
-+ morsel = cookies.Morsel()
-+ morsel.set("key", "value", "coded-value")
-+ morsel._key = c0 # Override private variable.
-+ cookie = cookies.SimpleCookie()
-+ cookie["cookie"] = morsel
-+ with self.assertRaises(cookies.CookieError):
-+ cookie.output()
-+
-+ morsel = cookies.Morsel()
-+ morsel.set("key", "value", "coded-value")
-+ morsel._coded_value = c0 # Override private variable.
-+ cookie = cookies.SimpleCookie()
-+ cookie["cookie"] = morsel
-+ with self.assertRaises(cookies.CookieError):
-+ cookie.output()
-+
- def test_main():
- run_unittest(CookieTests, MorselTests)
- run_doctest(cookies)
-diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-13-15.gh-issue-143919.kchwZV.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-13-15.gh-issue-143919.kchwZV.rst
-new file mode 100644
-index 00000000000000..788c3e4ac2ebf7
---- /dev/null
-+++ b/Misc/NEWS.d/next/Security/2026-01-16-11-13-15.gh-issue-143919.kchwZV.rst
-@@ -0,0 +1 @@
-+Reject control characters in :class:`http.cookies.Morsel` fields and values.
diff --git a/CVE-2026-0865-wsgiref-ctrl-chars.patch b/CVE-2026-0865-wsgiref-ctrl-chars.patch
deleted file mode 100644
index 702c81e..0000000
--- a/CVE-2026-0865-wsgiref-ctrl-chars.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 123bfbbe9074ef7fa28e1e7b25575665296560fa Mon Sep 17 00:00:00 2001
-From: "Gregory P. Smith" <68491+gpshead@users.noreply.github.com>
-Date: Sat, 17 Jan 2026 10:23:57 -0800
-Subject: [PATCH] [3.10] gh-143916: Reject control characters in
- wsgiref.headers.Headers (GH-143917) (GH-143973)
-
-gh-143916: Reject control characters in wsgiref.headers.Headers (GH-143917)
-
-* Add 'test.support' fixture for C0 control characters
-* gh-143916: Reject control characters in wsgiref.headers.Headers
-
-(cherry picked from commit f7fceed79ca1bceae8dbe5ba5bc8928564da7211)
-(cherry picked from commit 22e4d55285cee52bc4dbe061324e5f30bd4dee58)
-
-Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
-Co-authored-by: Seth Michael Larson
----
- Lib/test/support/__init__.py | 7 +++++++
- Lib/test/test_wsgiref.py | 12 +++++++++++-
- Lib/wsgiref/headers.py | 3 +++
- .../2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst | 2 ++
- 4 files changed, 23 insertions(+), 1 deletion(-)
- create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst
-
-diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
-index 0d3b9634f10248..d0492fe1914343 100644
---- a/Lib/test/support/__init__.py
-+++ b/Lib/test/support/__init__.py
-@@ -2157,3 +2157,10 @@ def adjust_int_max_str_digits(max_digits):
- yield
- finally:
- sys.set_int_max_str_digits(current)
-+
-+
-+def control_characters_c0() -> list[str]:
-+ """Returns a list of C0 control characters as strings.
-+ C0 control characters defined as the byte range 0x00-0x1F, and 0x7F.
-+ """
-+ return [chr(c) for c in range(0x00, 0x20)] + ["\x7F"]
-diff --git a/Lib/test/test_wsgiref.py b/Lib/test/test_wsgiref.py
-index 42094f467731d4..01ca51ba458587 100644
---- a/Lib/test/test_wsgiref.py
-+++ b/Lib/test/test_wsgiref.py
-@@ -1,6 +1,6 @@
- from unittest import mock
- from test import support
--from test.support import socket_helper
-+from test.support import socket_helper, control_characters_c0
- from test.support import warnings_helper
- from test.test_httpservers import NoLogRequestHandler
- from unittest import TestCase
-@@ -527,6 +527,16 @@ def testExtras(self):
- '\r\n'
- )
-
-+ def testRaisesControlCharacters(self):
-+ headers = Headers()
-+ for c0 in control_characters_c0():
-+ self.assertRaises(ValueError, headers.__setitem__, f"key{c0}", "val")
-+ self.assertRaises(ValueError, headers.__setitem__, "key", f"val{c0}")
-+ self.assertRaises(ValueError, headers.add_header, f"key{c0}", "val", param="param")
-+ self.assertRaises(ValueError, headers.add_header, "key", f"val{c0}", param="param")
-+ self.assertRaises(ValueError, headers.add_header, "key", "val", param=f"param{c0}")
-+
-+
- class ErrorHandler(BaseCGIHandler):
- """Simple handler subclass for testing BaseHandler"""
-
-diff --git a/Lib/wsgiref/headers.py b/Lib/wsgiref/headers.py
-index fab851c5a44430..fd98e85d75492b 100644
---- a/Lib/wsgiref/headers.py
-+++ b/Lib/wsgiref/headers.py
-@@ -9,6 +9,7 @@
- # existence of which force quoting of the parameter value.
- import re
- tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]')
-+_control_chars_re = re.compile(r'[\x00-\x1F\x7F]')
-
- def _formatparam(param, value=None, quote=1):
- """Convenience function to format and return a key=value pair.
-@@ -41,6 +42,8 @@ def __init__(self, headers=None):
- def _convert_string_type(self, value):
- """Convert/check value type."""
- if type(value) is str:
-+ if _control_chars_re.search(value):
-+ raise ValueError("Control characters not allowed in headers")
- return value
- raise AssertionError("Header names/values must be"
- " of type str (got {0})".format(repr(value)))
-diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst
-new file mode 100644
-index 00000000000000..44bd0b27059f94
---- /dev/null
-+++ b/Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst
-@@ -0,0 +1,2 @@
-+Reject C0 control characters within wsgiref.headers.Headers fields, values,
-+and parameters.
diff --git a/Python-3.10.19.tar.xz b/Python-3.10.19.tar.xz
deleted file mode 100644
index 4cd42b2..0000000
--- a/Python-3.10.19.tar.xz
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:c8f4a596572201d81dd7df91f70e177e19a70f1d489968b54b5fbbf29a97c076
-size 19873020
diff --git a/Python-3.10.19.tar.xz.sigstore b/Python-3.10.19.tar.xz.sigstore
deleted file mode 100644
index f88b5bd..0000000
--- a/Python-3.10.19.tar.xz.sigstore
+++ /dev/null
@@ -1 +0,0 @@
-{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICzjCCAlSgAwIBAgIUPLyAcJBqiNboHaWs7BHcTxLyk10wCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUxMDA5MTYwMzQ1WhcNMjUxMDA5MTYxMzQ1WjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/Ph0DALE7DyuLJPqS8zTKbHvI4d4FTFysDKBex9xr05SkjWCKLXNIrQmtHHOMQxZHtnLqlyGWc9C6R2a1cTbTaOCAXMwggFvMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUybzXPdm39+0wK3RSdJ45ttTJN3kwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wIgYDVR0RAQH/BBgwFoEUcGFibG9nc2FsQHB5dGhvbi5vcmcwKQYKKwYBBAGDvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgEHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGLBgorBgEEAdZ5AgQCBH0EewB5AHcA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGZybbSOQAABAMASDBGAiEAw9xx7UYivhAyYIxj8O/bRt/WdKL74c3MZDyXembfzTMCIQCDyspf74flglREl1yUs9/t+X2OhtzftOQdBPGH4ZWjbTAKBggqhkjOPQQDAwNoADBlAjBDE2ymGrMzZxRO+yRwzl1ujWuR6SeVI1Ty5+VVUW0QGikW9a4+3I+DB3TUxPNvh80CMQCGOyJMos1BBpAgiUyvb22OJ3BhzGgmC9dFSgcvzlyms5blKLAtBjf1+IlyFdEkBIc="}, "tlogEntries": [{"logIndex": "597674983", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1760025826", "inclusionPromise": {"signedEntryTimestamp": "MEUCIQDOhM/d61Xhr0Tn1mq0RFlu6kVvr+yr/OqE5ztg4LdI7AIgD6WPgOpn/1MgSp/XZ+ftU8wtZR32T+2wR03bkJOtQbE="}, "inclusionProof": {"logIndex": "475770721", "rootHash": "B1gv7JXRafrhEphKVN52yfrMBZ3YKQQELBICIGE0Xbk=", "treeSize": "475770722", "hashes": ["WK4RpC4pMLkEw8wOVJNRhaVH/LNHi65GwYW198mWnlA=", "opCnXnHA8HzxF/z3Qb6GpkzKVubqUgILN9729tSo7bk=", "81B2Ob5iKGTzITexeN47H++3/4QI6rNrwIp50yNjvYs=", "y24fAVX92cj3coVxwKg7azZlV2Oy7R0nwdY1HtepWQE=", "ojBgFF5g+M4hyxvL++Yi4mkmz2qJwkCl+1EpxEvLUdk=", "mZCvajPPCTqDtyHpKtXR1PctgiNLlTcGb/DjzXpA/eY=", "wCMog5TY7QnhcGa4vMQ8Scgr8Ti0zxV/CrgLR9sXadk=", "lU4SDoAFOyhGKqjcmr+9hlvgGNEuazsT3vZ4Hl7u4Sw=", "4fiFuSaFvn0p4uqLNF0ReEHj2uOks8Djwmd/wiJjI4I=", "WlOPUw/aSCRGCD82nA+ExVSdSAGkafb1nGxd3PAXPSk=", "V/aAsI+q3p5YLtfajhhBrAJmnMLh+6w/evHpWZ4yYJI=", "qXhJobQjWl6SO/pue3trUW2uL4jXx24Ip7lpd4hc5bU=", "56ObhlROm9L8Q4JyN+mxEQ5pZD5QdobB1xZFIeL0lVg=", "EGaD/cNavzxGYLx1Gl0uNNWBZvyXlSHSdlIeH7m+63A=", "2Wv4GiithwNukRKV06clevnQQYCzXmSS/+/OJtXgsXQ=", "1mfy94KpcItqshH9+gwqV6jccupcaMpVsF28New8zDY=", "vS7O4ozHIQZJWBiov+mkpI27GE8zAmVCEkRcP3NDyNE="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n475770722\nB1gv7JXRafrhEphKVN52yfrMBZ3YKQQELBICIGE0Xbk=\n\n\u2014 rekor.sigstore.dev wNI9ajBFAiEAi6W3v4n0hXFzBd/6jaKqBKmR6NSI62pITwqVgYWddeMCIG8EzMyqDkIyqMIi18EuboV6kml4tBJox32CvAaQHdnQ\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJjOGY0YTU5NjU3MjIwMWQ4MWRkN2RmOTFmNzBlMTc3ZTE5YTcwZjFkNDg5OTY4YjU0YjVmYmJmMjlhOTdjMDc2In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FUUNJQWltQ1ZnNTF3SzVCU2FoZVlGZFpNRWVPZUZrdEZJT2d3bUZRdnNEdVJ3NUFpQngzRTB5c0t5OEl5V3gyQk5KVzUrVG9GNmUxRmhaKzlNWEhoVGJnTVF6aGc9PSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjZha05EUVd4VFowRjNTVUpCWjBsVlVFeDVRV05LUW5GcFRtSnZTR0ZYY3pkQ1NHTlVlRXg1YXpFd2QwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZlRTFFUVRWTlZGbDNUWHBSTVZkb1kwNU5hbFY0VFVSQk5VMVVXWGhOZWxFeFYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVV2VUdnd1JFRk1SVGRFZVhWTVNsQnhVemg2VkV0aVNIWkpOR1EwUmxSR2VYTkVTMElLWlhnNWVISXdOVk5yYWxkRFMweFlUa2x5VVcxMFNFaFBUVkY0V2toMGJreHhiSGxIVjJNNVF6WlNNbUV4WTFSaVZHRlBRMEZZVFhkblowWjJUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlY1WW5wWUNsQmtiVE01S3pCM1N6TlNVMlJLTkRWMGRGUktUak5yZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBsbldVUldVakJTUVZGSUwwSkNaM2RHYjBWVlkwZEdhV0pIT1c1ak1rWnpVVWhDTldSSGFIWmlhVFYyWTIxamQwdFJXVXRMZDFsQ1FrRkhSQXAyZWtGQ1FWRlJZbUZJVWpCalNFMDJUSGs1YUZreVRuWmtWelV3WTNrMWJtSXlPVzVpUjFWMVdUSTVkRTFEYzBkRGFYTkhRVkZSUW1jM09IZEJVV2RGQ2toUmQySmhTRkl3WTBoTk5reDVPV2haTWs1MlpGYzFNR041Tlc1aU1qbHVZa2RWZFZreU9YUk5TVWRNUW1kdmNrSm5SVVZCWkZvMVFXZFJRMEpJTUVVS1pYZENOVUZJWTBFelZEQjNZWE5pU0VWVVNtcEhValJqYlZkak0wRnhTa3RZY21wbFVFc3pMMmcwY0hsblF6aHdOMjgwUVVGQlIxcDVZbUpUVDFGQlFRcENRVTFCVTBSQ1IwRnBSVUYzT1hoNE4xVlphWFpvUVhsWlNYaHFPRTh2WWxKMEwxZGtTMHczTkdNelRWcEVlVmhsYldKbWVsUk5RMGxSUTBSNWMzQm1DamMwWm14bmJGSkZiREY1VlhNNUwzUXJXREpQYUhSNlpuUlBVV1JDVUVkSU5GcFhhbUpVUVV0Q1oyZHhhR3RxVDFCUlVVUkJkMDV2UVVSQ2JFRnFRa1FLUlRKNWJVZHlUWHBhZUZKUEszbFNkM3BzTVhWcVYzVlNObE5sVmtreFZIazFLMVpXVlZjd1VVZHBhMWM1WVRRck0wa3JSRUl6VkZWNFVFNTJhRGd3UXdwTlVVTkhUM2xLVFc5ek1VSkNjRUZuYVZWNWRtSXlNazlLTTBKb2VrZG5iVU01WkVaVFoyTjJlbXg1YlhNMVlteExURUYwUW1wbU1TdEpiSGxHWkVWckNrSkpZejBLTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUW89In19fX0="}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "yPSlllciAdgd19+R9w4XfhmnDx1ImWi1S1+78pqXwHY="}, "signature": "MEQCIAimCVg51wK5BSaheYFdZMEeOeFktFIOgwmFQvsDuRw5AiBx3E0ysKy8IyWx2BNJW5+ToF6e1FhZ+9MXHhTbgMQzhg=="}}
diff --git a/Python-3.10.20.tar.xz b/Python-3.10.20.tar.xz
new file mode 100644
index 0000000..471a142
--- /dev/null
+++ b/Python-3.10.20.tar.xz
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:de6517421601e39a9a3bc3e1bc4c7b2f239297423ee05e282598c83ec0647505
+size 19868028
diff --git a/Python-3.10.20.tar.xz.sigstore b/Python-3.10.20.tar.xz.sigstore
new file mode 100644
index 0000000..8669499
--- /dev/null
+++ b/Python-3.10.20.tar.xz.sigstore
@@ -0,0 +1 @@
+{"mediaType":"application/vnd.dev.sigstore.bundle.v0.3+json","verificationMaterial":{"certificate":{"rawBytes":"MIICzTCCAlSgAwIBAgIUDhoArZLe6c38fDaopvK8CP875B4wCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjYwMzAzMDExMDAzWhcNMjYwMzAzMDEyMDAzWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE58F5Ofb9nq7EsHC961Pc/WJbCQHg7vxPfoArUfUv3Qo3pJkzcHjVgqEoxlYzGMnIl3I7FdbcaVO5USKsGWTWSaOCAXMwggFvMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUmeInD47KeQVcl6B0n3yUFZn0CsQwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wIgYDVR0RAQH/BBgwFoEUcGFibG9nc2FsQHB5dGhvbi5vcmcwKQYKKwYBBAGDvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgEHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGLBgorBgEEAdZ5AgQCBH0EewB5AHcA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGcsT62UwAABAMASDBGAiEAtmAUEzUXz6jJ8QB4+VdAL6ZSHbDoslJlXW4Fz8U5iiMCIQCRqOfH4T2l6gXe/yz23dy3jAHybVLLEGzPhtjhycLD5TAKBggqhkjOPQQDAwNnADBkAjArsGoXtWBUkzvNTvafksr/S9KDapVo2/g0JqCNLeC1B53SxybZ8wGaD0CdRucbXgwCME4LVWe8LENh87QijZI5AutcbF6SV/q8cZU4ApvM/EG67PD4y3Cq9mnfkSTmq0acaA=="},"tlogEntries":[{"logIndex":"1013523411","logId":{"keyId":"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="},"kindVersion":{"kind":"hashedrekord","version":"0.0.1"},"integratedTime":"1772500203","inclusionPromise":{"signedEntryTimestamp":"MEQCIQCo79CUmW825tPvDuDuktkD/8u2HdFtaXqGyvvn2Hwb3QIfJ2LlRVJv5J7RQpv5Ewgdj8eu0U0XNPmi8oGmNy52EQ=="},"inclusionProof":{"logIndex":"891619149","rootHash":"HNDps+Y1dPfxC24y65NMHyhhH8AsRJ9eavTYluKA0qE=","treeSize":"891619162","hashes":["SPHnI4ETb+r1yabvTNyY9wLxjGV+8XOHp95gEWG38Ik=","FeCim6GlixcSxMIWYhhHkPlDZw3gJyhnqdvIlobqO6Y=","TBjakqWuJID8vKIkxLbNFABPMhjI+4y07Ao8gWeqlPk=","P3GI25pQEMPpsTat9A2DB6hY9nnzGTg3sXhDR1zw+M8=","vofkJmHhhpNFFvVa5o8bQ3Jgs6jcBJ1EavajnxpIMJE=","EWYnCECJv0SafYTC7+J7Xyf0/XQdTjqUNIT8+hBO4K0=","mkxfyh3vx7bcSlqWpqeM0dDGBluMXwIuGhO9b91r7kQ=","wa+GBBGYEcG2IjHwMEZ+XaPwenxIPiNdhg03+jve2AE=","b+riDtYoB/vSd+NhQTMSxzu4K38oIYzGugTGUV9BT4o=","MhEKDSN20jNRzVYiOH1KqKscsycWpqtIWUHTSR1BW/0=","UfqWnx1YuXWnR6tQB8LboYpg7AuaUmwROEn7wJBVDjM=","HU7296NTl8Wek0AyCPeTMXdik0fZbtCiBDPDqVeye0E=","Xo5tam8gxbsWohATkFEqn5hvHpPFwBJ0SDjNE5DiI2A=","ZleKYeRKwUF3HP3HO0kxHMVeJgY3N/euGinVhlVWaq0=","fLAvE46NqCVV86EpB2pKkwJlFjjFk7ntX3lC+PiZuIo=","T4DqWD42hAtN+vX8jKCWqoC4meE4JekI9LxYGCcPy1M="],"checkpoint":{"envelope":"rekor.sigstore.dev - 1193050959916656506\n891619162\nHNDps+Y1dPfxC24y65NMHyhhH8AsRJ9eavTYluKA0qE=\n\n— rekor.sigstore.dev wNI9ajBGAiEA+cSb4NsHP9NGziDOeheM8Bad1rciubnFMcFINY5oszkCIQChlhjlB+qQtG2nfPvI+TY5sVkT2iqeT42vnRrNPhzpUQ==\n"}},"canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJkZTY1MTc0MjE2MDFlMzlhOWEzYmMzZTFiYzRjN2IyZjIzOTI5NzQyM2VlMDVlMjgyNTk4YzgzZWMwNjQ3NTA1In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FUUNJRXRnT0hlNXBLY3c2TTAyZVlSSDV2M25HMWdMSDhxZFVsVlRuRmhzK1kxNEFpQllpcFBoT3MxQW5RVHhyOXN2Q29zZWZtSjZXTExDanRQWmdkMWtnRzBubWc9PSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjZWRU5EUVd4VFowRjNTVUpCWjBsVlJHaHZRWEphVEdVMll6TTRaa1JoYjNCMlN6aERVRGczTlVJMGQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFpkMDE2UVhwTlJFVjRUVVJCZWxkb1kwNU5hbGwzVFhwQmVrMUVSWGxOUkVGNlYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVUxT0VZMVQyWmlPVzV4TjBWelNFTTVOakZRWXk5WFNtSkRVVWhuTjNaNFVHWnZRWElLVldaVmRqTlJiek53U210NlkwaHFWbWR4Ulc5NGJGbDZSMDF1U1d3elNUZEdaR0pqWVZaUE5WVlRTM05IVjFSWFUyRlBRMEZZVFhkblowWjJUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZ0WlVsdUNrUTBOMHRsVVZaamJEWkNNRzR6ZVZWR1dtNHdRM05SZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBsbldVUldVakJTUVZGSUwwSkNaM2RHYjBWVlkwZEdhV0pIT1c1ak1rWnpVVWhDTldSSGFIWmlhVFYyWTIxamQwdFJXVXRMZDFsQ1FrRkhSQXAyZWtGQ1FWRlJZbUZJVWpCalNFMDJUSGs1YUZreVRuWmtWelV3WTNrMWJtSXlPVzVpUjFWMVdUSTVkRTFEYzBkRGFYTkhRVkZSUW1jM09IZEJVV2RGQ2toUmQySmhTRkl3WTBoTk5reDVPV2haTWs1MlpGYzFNR041Tlc1aU1qbHVZa2RWZFZreU9YUk5TVWRNUW1kdmNrSm5SVVZCWkZvMVFXZFJRMEpJTUVVS1pYZENOVUZJWTBFelZEQjNZWE5pU0VWVVNtcEhValJqYlZkak0wRnhTa3RZY21wbFVFc3pMMmcwY0hsblF6aHdOMjgwUVVGQlIyTnpWRFl5VlhkQlFRcENRVTFCVTBSQ1IwRnBSVUYwYlVGVlJYcFZXSG8yYWtvNFVVSTBLMVprUVV3MldsTklZa1J2YzJ4S2JGaFhORVo2T0ZVMWFXbE5RMGxSUTFKeFQyWklDalJVTW13MloxaGxMM2w2TWpOa2VUTnFRVWg1WWxaTVRFVkhlbEJvZEdwb2VXTk1SRFZVUVV0Q1oyZHhhR3RxVDFCUlVVUkJkMDV1UVVSQ2EwRnFRWElLYzBkdldIUlhRbFZyZW5aT1ZIWmhabXR6Y2k5VE9VdEVZWEJXYnpJdlp6QktjVU5PVEdWRE1VSTFNMU40ZVdKYU9IZEhZVVF3UTJSU2RXTmlXR2QzUXdwTlJUUk1WbGRsT0V4RlRtZzROMUZwYWxwSk5VRjFkR05pUmpaVFZpOXhPR05hVlRSQmNIWk5MMFZITmpkUVJEUjVNME54T1cxdVptdFRWRzF4TUdGakNtRkJQVDBLTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUW89In19fX0="}],"timestampVerificationData":{"rfc3161Timestamps":[{"signedTimestamp":"MIIE6DADAgEAMIIE3wYJKoZIhvcNAQcCoIIE0DCCBMwCAQMxDTALBglghkgBZQMEAgEwgcEGCyqGSIb3DQEJEAEEoIGxBIGuMIGrAgEBBgkrBgEEAYO/MAIwMTANBglghkgBZQMEAgEFAAQgvi6FRn1Y7syA2BQYQwQMeiDUB+DL5pes7mPI7WdBRiUCFH5MbrWq5urNF2XQvNpdozZVH9J5GA8yMDI2MDMwMzAxMTAwM1owAwIBAQIIGLZG56CphR+gMqQwMC4xFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEVMBMGA1UEAxMMc2lnc3RvcmUtdHNhoIICFDCCAhAwggGWoAMCAQICFDoTVC8MkGHuvMFDL8uKjosqI4sMMAoGCCqGSM49BAMDMDkxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEgMB4GA1UEAxMXc2lnc3RvcmUtdHNhLXNlbGZzaWduZWQwHhcNMjUwNDA4MDY1OTQzWhcNMzUwNDA2MDY1OTQzWjAuMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxFTATBgNVBAMTDHNpZ3N0b3JlLXRzYTB2MBAGByqGSM49AgEGBSuBBAAiA2IABOK2tmfISjYoNk/ZBYwgE6Bht9I5MvlkL9wcy/pir4dUijUf1MLsLHzQoOLK8qGAHfBOorKL1QNzOGqDXZvUA4udGfJ0xMr6oHwz7UyMFyLX4lvwBX9Ve7sJG5AKI9McXKNqMGgwDgYDVR0PAQH/BAQDAgeAMB0GA1UdDgQWBBSJ/XlDh8/QZUbDAkbHLHNbfbTrAzAfBgNVHSMEGDAWgBSY7AHvf7tR/9SVHm+KiJhTB4nOvzAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAKBggqhkjOPQQDAwNoADBlAjA7abFf+imjtKshf1DLF9mklFykBXaBk6bUBnNH7atXLLpRzxhunbJsjDXdyQfhtxECMQDmo7wXI6SZim+Db/tk2qI/FHOfm+ooehVwgiq2kqrqXtO86rMDHFyU3tXBMbx775cxggHaMIIB1gIBATBRMDkxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEgMB4GA1UEAxMXc2lnc3RvcmUtdHNhLXNlbGZzaWduZWQCFDoTVC8MkGHuvMFDL8uKjosqI4sMMAsGCWCGSAFlAwQCAaCB/DAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTI2MDMwMzAxMTAwM1owLwYJKoZIhvcNAQkEMSIEIO+Yvw8NRuBPNFCci43mRe+yCz25yWCaTIc+x/wiuiCuMIGOBgsqhkiG9w0BCRACLzF/MH0wezB5BCCF+Se8B6tiysO0Q1bBDvyBssaIP9p6uebYcNnROs0FtzBVMD2kOzA5MRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxIDAeBgNVBAMTF3NpZ3N0b3JlLXRzYS1zZWxmc2lnbmVkAhQ6E1QvDJBh7rzBQy/Lio6LKiOLDDAKBggqhkjOPQQDAgRmMGQCMGAijQiYukXAs2IHeNMTctoahixAHWC4Pjmbd7F6wez2O+MUi/HvBHw4SofCAL3oTAIwdNjzO/9lbEjBtMKW0YSntWcPfT6sV9VVBzwel4nO9VqFuu4QrG7BkeMswVksJRCR"}]}},"messageSignature":{"messageDigest":{"algorithm":"SHA2_256","digest":"3mUXQhYB45qaO8PhvEx7LyOSl0I+4F4oJZjIPsBkdQU="},"signature":"MEQCIEtgOHe5pKcw6M02eYRH5v3nG1gLH8qdUlVTnFhs+Y14AiBYipPhOs1AnQTxr9svCosefmJ6WLLCjtPZgd1kgG0nmg=="}}
diff --git a/fix_configure_rst.patch b/fix_configure_rst.patch
index cf8b998..7daaf4b 100644
--- a/fix_configure_rst.patch
+++ b/fix_configure_rst.patch
@@ -3,10 +3,10 @@
Misc/NEWS | 2 +-
2 files changed, 1 insertion(+), 4 deletions(-)
-Index: Python-3.10.19/Doc/using/configure.rst
+Index: Python-3.10.20/Doc/using/configure.rst
===================================================================
---- Python-3.10.19.orig/Doc/using/configure.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/using/configure.rst 2025-12-19 23:10:08.779794344 +0100
+--- Python-3.10.20.orig/Doc/using/configure.rst 2026-03-03 01:49:35.000000000 +0100
++++ Python-3.10.20/Doc/using/configure.rst 2026-03-05 19:41:57.289556663 +0100
@@ -42,7 +42,6 @@
See :data:`sys.int_info.bits_per_digit `.
@@ -29,11 +29,11 @@ Index: Python-3.10.19/Doc/using/configure.rst
.. cmdoption:: --enable-framework=INSTALLDIR
Create a Python.framework rather than a traditional Unix install. Optional
-Index: Python-3.10.19/Misc/NEWS
+Index: Python-3.10.20/Misc/NEWS
===================================================================
---- Python-3.10.19.orig/Misc/NEWS 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Misc/NEWS 2025-12-19 23:10:08.784479751 +0100
-@@ -4018,7 +4018,7 @@
+--- Python-3.10.20.orig/Misc/NEWS 2026-03-03 01:49:35.000000000 +0100
++++ Python-3.10.20/Misc/NEWS 2026-03-05 19:41:57.302556681 +0100
+@@ -4112,7 +4112,7 @@
-----
- bpo-43795: The list in :ref:`stable-abi-list` now shows the public name
diff --git a/python310.changes b/python310.changes
index 22ddcfd..cad2c5b 100644
--- a/python310.changes
+++ b/python310.changes
@@ -1,3 +1,92 @@
+-------------------------------------------------------------------
+Thu Mar 5 18:38:39 UTC 2026 - Matej Cepl
+
+- Update to 3.10.20:
+ - Security
+ - gh-144125: BytesGenerator will now refuse to serialize
+ (write) headers that are unsafely folded or delimited; see
+ verify_generated_headers. (Contributed by Bas Bloemsaat and
+ Petr Viktorin in gh-121650).
+ - gh-143935: Fixed a bug in the folding of comments when
+ flattening an email message using a modern email policy.
+ Comments consisting of a very long sequence of non-foldable
+ characters could trigger a forced line wrap that omitted
+ the required leading space on the continuation line,
+ causing the remainder of the comment to be interpreted as
+ a new header field. This enabled header injection with
+ carefully crafted inputs (bsc#1257029 CVE-2025-11468).
+ - gh-143925: Reject control characters in data: URL media
+ types.
+ - gh-143919: Reject control characters in http.cookies.Morsel
+ fields and values (bsc#1257031, CVE-2026-0672).
+ - gh-143916: Reject C0 control characters within
+ wsgiref.headers.Headers fields, values, and parameters
+ (bsc#1257042, CVE-2026-0865).
+ - gh-142145: Remove quadratic behavior in xml.minidom node ID
+ cache clearing. In order to do this without breaking
+ existing users, we also add the ownerDocument attribute to
+ xml.dom.minidom elements and attributes created by directly
+ instantiating the Element or Attr class. Note that this way
+ of creating nodes is not supported; creator functions like
+ xml.dom.Document.documentElement() should be used instead
+ (bsc#1254997, CVE-2025-12084).
+ - gh-137836: Add support of the “plaintext” element, RAWTEXT
+ elements “xmp”, “iframe”, “noembed” and “noframes”, and
+ optionally RAWTEXT element “noscript” in
+ html.parser.HTMLParser.
+ - gh-136063: email.message: ensure linear complexity for
+ legacy HTTP parameters parsing. Patch by Bénédikt Tran.
+ - gh-136065: Fix quadratic complexity in
+ os.path.expandvars() (bsc#1252974, CVE-2025-6075).
+ - gh-119451: Fix a potential memory denial of service in the
+ http.client module. When connecting to a malicious server,
+ it could cause an arbitrary amount of memory to be
+ allocated. This could have led to symptoms including
+ a MemoryError, swapping, out of memory (OOM) killed
+ processes or containers, or even system crashes
+ (CVE-2025-13836, bsc#1254400).
+ - gh-119452: Fix a potential memory denial of service in the
+ http.server module. When a malicious user is connected to
+ the CGI server on Windows, it could cause an arbitrary
+ amount of memory to be allocated. This could have led to
+ symptoms including a MemoryError, swapping, out of memory
+ (OOM) killed processes or containers, or even system
+ crashes.
+ - gh-119342: Fix a potential memory denial of service in the
+ plistlib module. When reading a Plist file received from
+ untrusted source, it could cause an arbitrary amount of
+ memory to be allocated. This could have led to symptoms
+ including a MemoryError, swapping, out of memory (OOM)
+ killed processes or containers, or even system crashes
+ (bsc#1254401, CVE-2025-13837).
+ - Library
+ - gh-144833: Fixed a use-after-free in ssl when SSL_new()
+ returns NULL in newPySSLSocket(). The error was reported
+ via a dangling pointer after the object had already been
+ freed.
+ - gh-144363: Update bundled libexpat to 2.7.4
+ - gh-90949: Add SetAllocTrackerActivationThreshold() and
+ SetAllocTrackerMaximumAmplification() to xmlparser objects
+ to prevent use of disproportional amounts of dynamic memory
+ from within an Expat parser. Patch by Bénédikt Tran.
+ - Core and Builtins
+ - gh-120384: Fix an array out of bounds crash in
+ list_ass_subscript, which could be invoked via some
+ specificly tailored input: including concurrent
+ modification of a list object, where one thread assigns
+ a slice and another clears it.
+ - gh-120298: Fix use-after free in list_richcompare_impl
+ which can be invoked via some specificly tailored evil
+ input.
+- Remove upstreamed patches:
+ - CVE-2025-11468-email-hdr-fold-comment.patch
+ - CVE-2025-12084-minidom-quad-search.patch
+ - CVE-2025-13836-http-resp-cont-len.patch
+ - CVE-2025-13837-plistlib-mailicious-length.patch
+ - CVE-2025-6075-expandvars-perf-degrad.patch
+ - CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch
+ - CVE-2026-0865-wsgiref-ctrl-chars.patch
+
-------------------------------------------------------------------
Wed Feb 11 23:49:49 CET 2026 - Matej Cepl
diff --git a/python310.spec b/python310.spec
index b266f52..860845a 100644
--- a/python310.spec
+++ b/python310.spec
@@ -108,7 +108,7 @@ Obsoletes: python39%{?1:-%{1}}
# _md5.cpython-38m-x86_64-linux-gnu.so
%define dynlib() %{sitedir}/lib-dynload/%{1}.cpython-%{abi_tag}-%{archname}-%{_os}%{?_gnu}%{?armsuffix}.so
Name: %{python_pkg_name}%{psuffix}
-Version: 3.10.19
+Version: 3.10.20
Release: 0
Summary: Python 3 Interpreter
License: Python-2.0
diff --git a/sphinx-72.patch b/sphinx-72.patch
index 7245618..6fc7731 100644
--- a/sphinx-72.patch
+++ b/sphinx-72.patch
@@ -73,10 +73,10 @@
Doc/tutorial/stdlib.rst | 2
72 files changed, 458 insertions(+), 427 deletions(-)
-Index: Python-3.10.19/Doc/c-api/bytearray.rst
+Index: Python-3.10.20/Doc/c-api/bytearray.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/bytearray.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/bytearray.rst 2025-12-19 23:10:15.391446431 +0100
+--- Python-3.10.20.orig/Doc/c-api/bytearray.rst 2026-03-05 19:42:16.336584040 +0100
++++ Python-3.10.20/Doc/c-api/bytearray.rst 2026-03-05 19:42:18.969673759 +0100
@@ -5,7 +5,7 @@
Byte Array Objects
------------------
@@ -86,10 +86,10 @@ Index: Python-3.10.19/Doc/c-api/bytearray.rst
.. c:type:: PyByteArrayObject
-Index: Python-3.10.19/Doc/c-api/bytes.rst
+Index: Python-3.10.20/Doc/c-api/bytes.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/bytes.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/bytes.rst 2025-12-19 23:10:15.391922542 +0100
+--- Python-3.10.20.orig/Doc/c-api/bytes.rst 2026-03-05 19:42:16.336584040 +0100
++++ Python-3.10.20/Doc/c-api/bytes.rst 2026-03-05 19:42:18.970100765 +0100
@@ -8,7 +8,7 @@
These functions raise :exc:`TypeError` when expecting a bytes parameter and
called with a non-bytes parameter.
@@ -99,10 +99,10 @@ Index: Python-3.10.19/Doc/c-api/bytes.rst
.. c:type:: PyBytesObject
-Index: Python-3.10.19/Doc/c-api/capsule.rst
+Index: Python-3.10.20/Doc/c-api/capsule.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/capsule.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/capsule.rst 2025-12-19 23:10:15.392109858 +0100
+--- Python-3.10.20.orig/Doc/c-api/capsule.rst 2026-03-05 19:42:16.336584040 +0100
++++ Python-3.10.20/Doc/c-api/capsule.rst 2026-03-05 19:42:18.970312835 +0100
@@ -5,7 +5,7 @@
Capsules
--------
@@ -112,10 +112,10 @@ Index: Python-3.10.19/Doc/c-api/capsule.rst
Refer to :ref:`using-capsules` for more information on using these objects.
-Index: Python-3.10.19/Doc/c-api/complex.rst
+Index: Python-3.10.20/Doc/c-api/complex.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/complex.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/complex.rst 2025-12-19 23:10:15.392289421 +0100
+--- Python-3.10.20.orig/Doc/c-api/complex.rst 2026-03-05 19:42:16.336584040 +0100
++++ Python-3.10.20/Doc/c-api/complex.rst 2026-03-05 19:42:18.970503093 +0100
@@ -5,7 +5,7 @@
Complex Number Objects
----------------------
@@ -125,10 +125,10 @@ Index: Python-3.10.19/Doc/c-api/complex.rst
Python's complex number objects are implemented as two distinct types when
viewed from the C API: one is the Python object exposed to Python programs, and
-Index: Python-3.10.19/Doc/c-api/concrete.rst
+Index: Python-3.10.20/Doc/c-api/concrete.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/concrete.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/concrete.rst 2025-12-19 23:10:15.392466051 +0100
+--- Python-3.10.20.orig/Doc/c-api/concrete.rst 2026-03-05 19:42:16.336584040 +0100
++++ Python-3.10.20/Doc/c-api/concrete.rst 2026-03-05 19:42:18.970750049 +0100
@@ -40,7 +40,7 @@
Numeric Objects
===============
@@ -156,10 +156,10 @@ Index: Python-3.10.19/Doc/c-api/concrete.rst
.. toctree::
-Index: Python-3.10.19/Doc/c-api/dict.rst
+Index: Python-3.10.20/Doc/c-api/dict.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/dict.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/dict.rst 2025-12-19 23:10:15.392652110 +0100
+--- Python-3.10.20.orig/Doc/c-api/dict.rst 2026-03-05 19:42:16.336584040 +0100
++++ Python-3.10.20/Doc/c-api/dict.rst 2026-03-05 19:42:18.970944416 +0100
@@ -5,7 +5,7 @@
Dictionary Objects
------------------
@@ -178,10 +178,10 @@ Index: Python-3.10.19/Doc/c-api/dict.rst
Return the number of items in the dictionary. This is equivalent to
``len(p)`` on a dictionary.
-Index: Python-3.10.19/Doc/c-api/exceptions.rst
+Index: Python-3.10.20/Doc/c-api/exceptions.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/exceptions.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/exceptions.rst 2025-12-19 23:10:15.392896207 +0100
+--- Python-3.10.20.orig/Doc/c-api/exceptions.rst 2026-03-05 19:42:16.336584040 +0100
++++ Python-3.10.20/Doc/c-api/exceptions.rst 2026-03-05 19:42:18.971230595 +0100
@@ -503,7 +503,7 @@
.. c:function:: int PyErr_CheckSignals()
@@ -209,10 +209,10 @@ Index: Python-3.10.19/Doc/c-api/exceptions.rst
single: KeyboardInterrupt (built-in exception)
Simulate the effect of a signal arriving. The next time
-Index: Python-3.10.19/Doc/c-api/file.rst
+Index: Python-3.10.20/Doc/c-api/file.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/file.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/file.rst 2025-12-19 23:10:15.393159161 +0100
+--- Python-3.10.20.orig/Doc/c-api/file.rst 2026-03-05 19:42:16.336584040 +0100
++++ Python-3.10.20/Doc/c-api/file.rst 2026-03-05 19:42:18.971537043 +0100
@@ -5,7 +5,7 @@
File Objects
------------
@@ -222,10 +222,10 @@ Index: Python-3.10.19/Doc/c-api/file.rst
These APIs are a minimal emulation of the Python 2 C API for built-in file
objects, which used to rely on the buffered I/O (:c:expr:`FILE*`) support
-Index: Python-3.10.19/Doc/c-api/float.rst
+Index: Python-3.10.20/Doc/c-api/float.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/float.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/float.rst 2025-12-19 23:10:15.393330204 +0100
+--- Python-3.10.20.orig/Doc/c-api/float.rst 2026-03-05 19:42:16.336584040 +0100
++++ Python-3.10.20/Doc/c-api/float.rst 2026-03-05 19:42:18.971720008 +0100
@@ -5,7 +5,7 @@
Floating Point Objects
----------------------
@@ -235,10 +235,10 @@ Index: Python-3.10.19/Doc/c-api/float.rst
.. c:type:: PyFloatObject
-Index: Python-3.10.19/Doc/c-api/function.rst
+Index: Python-3.10.20/Doc/c-api/function.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/function.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/function.rst 2025-12-19 23:10:15.393493494 +0100
+--- Python-3.10.20.orig/Doc/c-api/function.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/function.rst 2026-03-05 19:42:18.971899246 +0100
@@ -5,7 +5,7 @@
Function Objects
----------------
@@ -248,10 +248,10 @@ Index: Python-3.10.19/Doc/c-api/function.rst
There are a few functions specific to Python functions.
-Index: Python-3.10.19/Doc/c-api/import.rst
+Index: Python-3.10.20/Doc/c-api/import.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/import.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/import.rst 2025-12-19 23:10:15.393679483 +0100
+--- Python-3.10.20.orig/Doc/c-api/import.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/import.rst 2026-03-05 19:42:18.972099725 +0100
@@ -41,7 +41,7 @@
.. c:function:: PyObject* PyImport_ImportModuleEx(const char *name, PyObject *globals, PyObject *locals, PyObject *fromlist)
@@ -270,10 +270,10 @@ Index: Python-3.10.19/Doc/c-api/import.rst
Given a module name (possibly of the form ``package.module``) and a code object
read from a Python bytecode file or obtained from the built-in function
-Index: Python-3.10.19/Doc/c-api/init.rst
+Index: Python-3.10.20/Doc/c-api/init.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/init.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/init.rst 2025-12-19 23:10:15.393955078 +0100
+--- Python-3.10.20.orig/Doc/c-api/init.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/init.rst 2026-03-05 19:42:18.972397676 +0100
@@ -233,9 +233,9 @@
single: PyEval_InitThreads()
single: modules (in module sys)
@@ -309,10 +309,10 @@ Index: Python-3.10.19/Doc/c-api/init.rst
single: stdout (in module sys)
single: stderr (in module sys)
single: stdin (in module sys)
-Index: Python-3.10.19/Doc/c-api/intro.rst
+Index: Python-3.10.20/Doc/c-api/intro.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/intro.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/intro.rst 2025-12-19 23:10:15.394470650 +0100
+--- Python-3.10.20.orig/Doc/c-api/intro.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/intro.rst 2026-03-05 19:42:18.972771231 +0100
@@ -226,7 +226,7 @@
Objects, Types and Reference Counts
===================================
@@ -335,10 +335,10 @@ Index: Python-3.10.19/Doc/c-api/intro.rst
triple: module; search; path
single: path (in module sys)
-Index: Python-3.10.19/Doc/c-api/list.rst
+Index: Python-3.10.20/Doc/c-api/list.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/list.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/list.rst 2025-12-19 23:10:15.394763148 +0100
+--- Python-3.10.20.orig/Doc/c-api/list.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/list.rst 2026-03-05 19:42:18.973088189 +0100
@@ -5,7 +5,7 @@
List Objects
------------
@@ -366,10 +366,10 @@ Index: Python-3.10.19/Doc/c-api/list.rst
Return a new tuple object containing the contents of *list*; equivalent to
``tuple(list)``.
-Index: Python-3.10.19/Doc/c-api/long.rst
+Index: Python-3.10.20/Doc/c-api/long.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/long.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/long.rst 2025-12-19 23:10:15.394948159 +0100
+--- Python-3.10.20.orig/Doc/c-api/long.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/long.rst 2026-03-05 19:42:18.973340364 +0100
@@ -5,8 +5,8 @@
Integer Objects
---------------
@@ -381,10 +381,10 @@ Index: Python-3.10.19/Doc/c-api/long.rst
All integers are implemented as "long" integer objects of arbitrary size.
-Index: Python-3.10.19/Doc/c-api/mapping.rst
+Index: Python-3.10.20/Doc/c-api/mapping.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/mapping.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/mapping.rst 2025-12-19 23:10:15.395138967 +0100
+--- Python-3.10.20.orig/Doc/c-api/mapping.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/mapping.rst 2026-03-05 19:42:18.973549118 +0100
@@ -20,7 +20,7 @@
.. c:function:: Py_ssize_t PyMapping_Size(PyObject *o)
Py_ssize_t PyMapping_Length(PyObject *o)
@@ -394,10 +394,10 @@ Index: Python-3.10.19/Doc/c-api/mapping.rst
Returns the number of keys in object *o* on success, and ``-1`` on failure.
This is equivalent to the Python expression ``len(o)``.
-Index: Python-3.10.19/Doc/c-api/memoryview.rst
+Index: Python-3.10.20/Doc/c-api/memoryview.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/memoryview.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/memoryview.rst 2025-12-19 23:10:15.395300231 +0100
+--- Python-3.10.20.orig/Doc/c-api/memoryview.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/memoryview.rst 2026-03-05 19:42:18.973728286 +0100
@@ -3,7 +3,7 @@
.. _memoryview-objects:
@@ -407,10 +407,10 @@ Index: Python-3.10.19/Doc/c-api/memoryview.rst
MemoryView objects
------------------
-Index: Python-3.10.19/Doc/c-api/method.rst
+Index: Python-3.10.20/Doc/c-api/method.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/method.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/method.rst 2025-12-19 23:10:15.395505706 +0100
+--- Python-3.10.20.orig/Doc/c-api/method.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/method.rst 2026-03-05 19:42:18.973936919 +0100
@@ -5,7 +5,7 @@
Instance Method Objects
-----------------------
@@ -429,10 +429,10 @@ Index: Python-3.10.19/Doc/c-api/method.rst
Methods are bound function objects. Methods are always bound to an instance of
a user-defined class. Unbound methods (methods bound to a class object) are
-Index: Python-3.10.19/Doc/c-api/module.rst
+Index: Python-3.10.20/Doc/c-api/module.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/module.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/module.rst 2025-12-19 23:10:15.395739397 +0100
+--- Python-3.10.20.orig/Doc/c-api/module.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/module.rst 2026-03-05 19:42:18.974150622 +0100
@@ -5,7 +5,7 @@
Module Objects
--------------
@@ -442,10 +442,10 @@ Index: Python-3.10.19/Doc/c-api/module.rst
.. c:var:: PyTypeObject PyModule_Type
-Index: Python-3.10.19/Doc/c-api/none.rst
+Index: Python-3.10.20/Doc/c-api/none.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/none.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/none.rst 2025-12-19 23:10:15.395955557 +0100
+--- Python-3.10.20.orig/Doc/c-api/none.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/none.rst 2026-03-05 19:42:18.974386076 +0100
@@ -5,7 +5,7 @@
The ``None`` Object
-------------------
@@ -455,10 +455,10 @@ Index: Python-3.10.19/Doc/c-api/none.rst
Note that the :c:type:`PyTypeObject` for ``None`` is not directly exposed in the
Python/C API. Since ``None`` is a singleton, testing for object identity (using
-Index: Python-3.10.19/Doc/c-api/number.rst
+Index: Python-3.10.20/Doc/c-api/number.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/number.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/number.rst 2025-12-19 23:10:15.396155514 +0100
+--- Python-3.10.20.orig/Doc/c-api/number.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/number.rst 2026-03-05 19:42:18.974581886 +0100
@@ -64,7 +64,7 @@
.. c:function:: PyObject* PyNumber_Divmod(PyObject *o1, PyObject *o2)
@@ -513,10 +513,10 @@ Index: Python-3.10.19/Doc/c-api/number.rst
Returns the *o* converted to a float object on success, or ``NULL`` on failure.
This is the equivalent of the Python expression ``float(o)``.
-Index: Python-3.10.19/Doc/c-api/object.rst
+Index: Python-3.10.20/Doc/c-api/object.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/object.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/object.rst 2025-12-19 23:10:15.396357217 +0100
+--- Python-3.10.20.orig/Doc/c-api/object.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/object.rst 2026-03-05 19:42:18.974799656 +0100
@@ -172,7 +172,7 @@
.. c:function:: PyObject* PyObject_Repr(PyObject *o)
@@ -571,10 +571,10 @@ Index: Python-3.10.19/Doc/c-api/object.rst
Return the length of object *o*. If the object *o* provides either the sequence
and mapping protocols, the sequence length is returned. On error, ``-1`` is
-Index: Python-3.10.19/Doc/c-api/sequence.rst
+Index: Python-3.10.20/Doc/c-api/sequence.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/sequence.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/sequence.rst 2025-12-19 23:10:15.396594610 +0100
+--- Python-3.10.20.orig/Doc/c-api/sequence.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/sequence.rst 2026-03-05 19:42:18.975049317 +0100
@@ -18,7 +18,7 @@
.. c:function:: Py_ssize_t PySequence_Size(PyObject *o)
Py_ssize_t PySequence_Length(PyObject *o)
@@ -593,10 +593,10 @@ Index: Python-3.10.19/Doc/c-api/sequence.rst
Return a tuple object with the same contents as the sequence or iterable *o*,
or ``NULL`` on failure. If *o* is a tuple, a new reference will be returned,
-Index: Python-3.10.19/Doc/c-api/set.rst
+Index: Python-3.10.20/Doc/c-api/set.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/set.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/set.rst 2025-12-19 23:10:15.396771519 +0100
+--- Python-3.10.20.orig/Doc/c-api/set.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/set.rst 2026-03-05 19:42:18.975306692 +0100
@@ -9,8 +9,8 @@
@@ -617,10 +617,10 @@ Index: Python-3.10.19/Doc/c-api/set.rst
Return the length of a :class:`set` or :class:`frozenset` object. Equivalent to
``len(anyset)``. Raises a :exc:`PyExc_SystemError` if *anyset* is not a
-Index: Python-3.10.19/Doc/c-api/structures.rst
+Index: Python-3.10.20/Doc/c-api/structures.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/structures.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/structures.rst 2025-12-19 23:10:15.396945495 +0100
+--- Python-3.10.20.orig/Doc/c-api/structures.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/structures.rst 2026-03-05 19:42:18.975635963 +0100
@@ -351,7 +351,7 @@
.. data:: METH_CLASS
@@ -639,10 +639,10 @@ Index: Python-3.10.19/Doc/c-api/structures.rst
The method will be passed ``NULL`` as the first parameter rather than an
instance of the type. This is used to create *static methods*, similar to
-Index: Python-3.10.19/Doc/c-api/tuple.rst
+Index: Python-3.10.20/Doc/c-api/tuple.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/tuple.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/tuple.rst 2025-12-19 23:10:15.397144544 +0100
+--- Python-3.10.20.orig/Doc/c-api/tuple.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/tuple.rst 2026-03-05 19:42:18.975888880 +0100
@@ -5,7 +5,7 @@
Tuple Objects
-------------
@@ -652,10 +652,10 @@ Index: Python-3.10.19/Doc/c-api/tuple.rst
.. c:type:: PyTupleObject
-Index: Python-3.10.19/Doc/c-api/type.rst
+Index: Python-3.10.20/Doc/c-api/type.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/type.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/type.rst 2025-12-19 23:10:15.397329764 +0100
+--- Python-3.10.20.orig/Doc/c-api/type.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/type.rst 2026-03-05 19:42:18.976188766 +0100
@@ -5,7 +5,7 @@
Type Objects
------------
@@ -665,10 +665,10 @@ Index: Python-3.10.19/Doc/c-api/type.rst
.. c:type:: PyTypeObject
-Index: Python-3.10.19/Doc/c-api/typeobj.rst
+Index: Python-3.10.20/Doc/c-api/typeobj.rst
===================================================================
---- Python-3.10.19.orig/Doc/c-api/typeobj.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/c-api/typeobj.rst 2025-12-19 23:10:15.397446400 +0100
+--- Python-3.10.20.orig/Doc/c-api/typeobj.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/c-api/typeobj.rst 2026-03-05 19:42:18.976565316 +0100
@@ -803,7 +803,7 @@
.. c:member:: reprfunc PyTypeObject.tp_repr
@@ -687,10 +687,10 @@ Index: Python-3.10.19/Doc/c-api/typeobj.rst
An optional pointer to a function that implements the built-in function
:func:`hash`.
-Index: Python-3.10.19/Doc/conf.py
+Index: Python-3.10.20/Doc/conf.py
===================================================================
---- Python-3.10.19.orig/Doc/conf.py 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/conf.py 2025-12-19 23:10:15.398083707 +0100
+--- Python-3.10.20.orig/Doc/conf.py 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/conf.py 2026-03-05 19:42:18.977099103 +0100
@@ -61,6 +61,11 @@
# Avoid a warning with Sphinx >= 2.0
master_doc = 'contents'
@@ -703,10 +703,10 @@ Index: Python-3.10.19/Doc/conf.py
# Options for HTML output
# -----------------------
-Index: Python-3.10.19/Doc/extending/newtypes.rst
+Index: Python-3.10.20/Doc/extending/newtypes.rst
===================================================================
---- Python-3.10.19.orig/Doc/extending/newtypes.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/extending/newtypes.rst 2025-12-19 23:10:15.398298470 +0100
+--- Python-3.10.20.orig/Doc/extending/newtypes.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/extending/newtypes.rst 2026-03-05 19:42:18.977417513 +0100
@@ -149,7 +149,7 @@
.. index::
@@ -716,10 +716,10 @@ Index: Python-3.10.19/Doc/extending/newtypes.rst
Object Presentation
-------------------
-Index: Python-3.10.19/Doc/library/_thread.rst
+Index: Python-3.10.20/Doc/library/_thread.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/_thread.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/_thread.rst 2025-12-19 23:10:15.398608428 +0100
+--- Python-3.10.20.orig/Doc/library/_thread.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/_thread.rst 2026-03-05 19:42:18.977812839 +0100
@@ -204,7 +204,7 @@
**Caveats:**
@@ -729,10 +729,10 @@ Index: Python-3.10.19/Doc/library/_thread.rst
* Threads interact strangely with interrupts: the :exc:`KeyboardInterrupt`
exception will be received by an arbitrary thread. (When the :mod:`signal`
-Index: Python-3.10.19/Doc/library/binascii.rst
+Index: Python-3.10.20/Doc/library/binascii.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/binascii.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/binascii.rst 2025-12-19 23:10:15.398847287 +0100
+--- Python-3.10.20.orig/Doc/library/binascii.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/binascii.rst 2026-03-05 19:42:18.978168049 +0100
@@ -6,9 +6,9 @@
representations.
@@ -746,10 +746,10 @@ Index: Python-3.10.19/Doc/library/binascii.rst
--------------
-Index: Python-3.10.19/Doc/library/cmath.rst
+Index: Python-3.10.20/Doc/library/cmath.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/cmath.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/cmath.rst 2025-12-19 23:10:15.399084959 +0100
+--- Python-3.10.20.orig/Doc/library/cmath.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/cmath.rst 2026-03-05 19:42:18.978445211 +0100
@@ -301,7 +301,7 @@
.. versionadded:: 3.6
@@ -759,10 +759,10 @@ Index: Python-3.10.19/Doc/library/cmath.rst
Note that the selection of functions is similar, but not identical, to that in
module :mod:`math`. The reason for having two modules is that some users aren't
-Index: Python-3.10.19/Doc/library/copy.rst
+Index: Python-3.10.20/Doc/library/copy.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/copy.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/copy.rst 2025-12-19 23:10:15.399270528 +0100
+--- Python-3.10.20.orig/Doc/library/copy.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/copy.rst 2026-03-05 19:42:18.978728956 +0100
@@ -68,7 +68,7 @@
of lists by assigning a slice of the entire list, for example,
``copied_list = original_list[:]``.
@@ -772,10 +772,10 @@ Index: Python-3.10.19/Doc/library/copy.rst
Classes can use the same interfaces to control copying that they use to control
pickling. See the description of module :mod:`pickle` for information on these
-Index: Python-3.10.19/Doc/library/copyreg.rst
+Index: Python-3.10.20/Doc/library/copyreg.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/copyreg.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/copyreg.rst 2025-12-19 23:10:15.399461755 +0100
+--- Python-3.10.20.orig/Doc/library/copyreg.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/copyreg.rst 2026-03-05 19:42:18.978924325 +0100
@@ -7,8 +7,8 @@
**Source code:** :source:`Lib/copyreg.py`
@@ -787,10 +787,10 @@ Index: Python-3.10.19/Doc/library/copyreg.rst
--------------
-Index: Python-3.10.19/Doc/library/dis.rst
+Index: Python-3.10.20/Doc/library/dis.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/dis.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/dis.rst 2025-12-19 23:10:15.399767732 +0100
+--- Python-3.10.20.orig/Doc/library/dis.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/dis.rst 2026-03-05 19:42:18.979174547 +0100
@@ -1207,7 +1207,7 @@
.. opcode:: BUILD_SLICE (argc)
@@ -800,10 +800,10 @@ Index: Python-3.10.19/Doc/library/dis.rst
Pushes a slice object on the stack. *argc* must be 2 or 3. If it is 2,
``slice(TOS1, TOS)`` is pushed; if it is 3, ``slice(TOS2, TOS1, TOS)`` is
-Index: Python-3.10.19/Doc/library/email.compat32-message.rst
+Index: Python-3.10.20/Doc/library/email.compat32-message.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/email.compat32-message.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/email.compat32-message.rst 2025-12-19 23:10:15.400042699 +0100
+--- Python-3.10.20.orig/Doc/library/email.compat32-message.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/email.compat32-message.rst 2026-03-05 19:42:18.979546769 +0100
@@ -7,6 +7,7 @@
:synopsis: The base class representing email messages in a fashion
backward compatible with Python 3.2
@@ -812,10 +812,10 @@ Index: Python-3.10.19/Doc/library/email.compat32-message.rst
The :class:`Message` class is very similar to the
-Index: Python-3.10.19/Doc/library/exceptions.rst
+Index: Python-3.10.20/Doc/library/exceptions.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/exceptions.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/exceptions.rst 2025-12-19 23:10:15.400305095 +0100
+--- Python-3.10.20.orig/Doc/library/exceptions.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/exceptions.rst 2026-03-05 19:42:18.979875649 +0100
@@ -4,8 +4,8 @@
===================
@@ -854,10 +854,10 @@ Index: Python-3.10.19/Doc/library/exceptions.rst
This exception is raised when a system function returns a system-related
error, including I/O failures such as "file not found" or "disk full"
-Index: Python-3.10.19/Doc/library/fnmatch.rst
+Index: Python-3.10.20/Doc/library/fnmatch.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/fnmatch.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/fnmatch.rst 2025-12-19 23:10:15.400595567 +0100
+--- Python-3.10.20.orig/Doc/library/fnmatch.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/fnmatch.rst 2026-03-05 19:42:18.980208527 +0100
@@ -8,7 +8,7 @@
.. index:: single: filenames; wildcard expansion
@@ -876,10 +876,10 @@ Index: Python-3.10.19/Doc/library/fnmatch.rst
Note that the filename separator (``'/'`` on Unix) is *not* special to this
module. See module :mod:`glob` for pathname expansion (:mod:`glob` uses
-Index: Python-3.10.19/Doc/library/functions.rst
+Index: Python-3.10.20/Doc/library/functions.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/functions.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/functions.rst 2025-12-19 23:10:15.400828071 +0100
+--- Python-3.10.20.orig/Doc/library/functions.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/functions.rst 2026-03-05 19:42:18.980496911 +0100
@@ -548,7 +548,7 @@
Raises an :ref:`auditing event ` ``exec`` with the code object
as the argument. Code compilation events may also be raised.
@@ -918,10 +918,10 @@ Index: Python-3.10.19/Doc/library/functions.rst
.. note::
-Index: Python-3.10.19/Doc/library/http.client.rst
+Index: Python-3.10.20/Doc/library/http.client.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/http.client.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/http.client.rst 2025-12-19 23:10:15.401177908 +0100
+--- Python-3.10.20.orig/Doc/library/http.client.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/http.client.rst 2026-03-05 19:42:18.980925559 +0100
@@ -10,7 +10,7 @@
pair: HTTP; protocol
single: HTTP; http.client (standard module)
@@ -931,10 +931,10 @@ Index: Python-3.10.19/Doc/library/http.client.rst
--------------
-Index: Python-3.10.19/Doc/library/imp.rst
+Index: Python-3.10.20/Doc/library/imp.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/imp.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/imp.rst 2025-12-19 23:10:15.401419561 +0100
+--- Python-3.10.20.orig/Doc/library/imp.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/imp.rst 2026-03-05 19:42:18.981246615 +0100
@@ -10,7 +10,7 @@
.. deprecated:: 3.4
The :mod:`imp` module is deprecated in favor of :mod:`importlib`.
@@ -944,10 +944,10 @@ Index: Python-3.10.19/Doc/library/imp.rst
--------------
-Index: Python-3.10.19/Doc/library/internet.rst
+Index: Python-3.10.20/Doc/library/internet.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/internet.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/internet.rst 2025-12-19 23:10:15.401643543 +0100
+--- Python-3.10.20.orig/Doc/library/internet.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/internet.rst 2026-03-05 19:42:18.981489052 +0100
@@ -9,7 +9,7 @@
single: Internet
single: World Wide Web
@@ -957,10 +957,10 @@ Index: Python-3.10.19/Doc/library/internet.rst
The modules described in this chapter implement internet protocols and support
for related technology. They are all implemented in Python. Most of these
-Index: Python-3.10.19/Doc/library/locale.rst
+Index: Python-3.10.20/Doc/library/locale.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/locale.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/locale.rst 2025-12-19 23:10:15.401831697 +0100
+--- Python-3.10.20.orig/Doc/library/locale.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/locale.rst 2026-03-05 19:42:18.981763630 +0100
@@ -16,7 +16,7 @@
certain cultural issues in an application, without requiring the programmer to
know all the specifics of each country where the software is executed.
@@ -979,10 +979,10 @@ Index: Python-3.10.19/Doc/library/locale.rst
Locale category for the character type functions. Depending on the settings of
this category, the functions of module :mod:`string` dealing with case change
-Index: Python-3.10.19/Doc/library/marshal.rst
+Index: Python-3.10.20/Doc/library/marshal.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/marshal.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/marshal.rst 2025-12-19 23:10:15.402080194 +0100
+--- Python-3.10.20.orig/Doc/library/marshal.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/marshal.rst 2026-03-05 19:42:18.982052574 +0100
@@ -15,8 +15,8 @@
rarely does). [#]_
@@ -994,11 +994,11 @@ Index: Python-3.10.19/Doc/library/marshal.rst
This is not a general "persistence" module. For general persistence and
transfer of Python objects through RPC calls, see the modules :mod:`pickle` and
-Index: Python-3.10.19/Doc/library/os.path.rst
+Index: Python-3.10.20/Doc/library/os.path.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/os.path.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/os.path.rst 2025-12-19 23:10:15.402271561 +0100
-@@ -159,7 +159,7 @@
+--- Python-3.10.20.orig/Doc/library/os.path.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/os.path.rst 2026-03-05 19:42:18.982385091 +0100
+@@ -161,7 +161,7 @@
On Unix and Windows, return the argument with an initial component of ``~`` or
``~user`` replaced by that *user*'s home directory.
@@ -1007,10 +1007,10 @@ Index: Python-3.10.19/Doc/library/os.path.rst
On Unix, an initial ``~`` is replaced by the environment variable :envvar:`HOME`
if it is set; otherwise the current user's home directory is looked up in the
-Index: Python-3.10.19/Doc/library/os.rst
+Index: Python-3.10.20/Doc/library/os.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/os.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/os.rst 2025-12-19 23:10:15.402446375 +0100
+--- Python-3.10.20.orig/Doc/library/os.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/os.rst 2026-03-05 19:42:18.982587843 +0100
@@ -1136,7 +1136,7 @@
.. function:: openpty()
@@ -1029,10 +1029,10 @@ Index: Python-3.10.19/Doc/library/os.rst
Example::
-Index: Python-3.10.19/Doc/library/pdb.rst
+Index: Python-3.10.20/Doc/library/pdb.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/pdb.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/pdb.rst 2025-12-19 23:10:15.403432541 +0100
+--- Python-3.10.20.orig/Doc/library/pdb.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/pdb.rst 2026-03-05 19:42:18.983778239 +0100
@@ -20,8 +20,8 @@
.. index::
@@ -1044,10 +1044,10 @@ Index: Python-3.10.19/Doc/library/pdb.rst
The debugger is extensible -- it is actually defined as the class :class:`Pdb`.
This is currently undocumented but easily understood by reading the source. The
-Index: Python-3.10.19/Doc/library/posix.rst
+Index: Python-3.10.20/Doc/library/posix.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/posix.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/posix.rst 2025-12-19 23:10:15.403681946 +0100
+--- Python-3.10.20.orig/Doc/library/posix.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/posix.rst 2026-03-05 19:42:18.984101268 +0100
@@ -11,7 +11,7 @@
standardized by the C Standard and the POSIX standard (a thinly disguised Unix
interface).
@@ -1057,10 +1057,10 @@ Index: Python-3.10.19/Doc/library/posix.rst
**Do not import this module directly.** Instead, import the module :mod:`os`,
which provides a *portable* version of this interface. On Unix, the :mod:`os`
-Index: Python-3.10.19/Doc/library/pprint.rst
+Index: Python-3.10.20/Doc/library/pprint.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/pprint.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/pprint.rst 2025-12-19 23:10:15.403862208 +0100
+--- Python-3.10.20.orig/Doc/library/pprint.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/pprint.rst 2026-03-05 19:42:18.984325922 +0100
@@ -171,7 +171,7 @@
.. function:: isreadable(object)
@@ -1079,10 +1079,10 @@ Index: Python-3.10.19/Doc/library/pprint.rst
Determine if the formatted representation of the object is "readable," or can be
used to reconstruct the value using :func:`eval`. Note that this returns
-Index: Python-3.10.19/Doc/library/pwd.rst
+Index: Python-3.10.20/Doc/library/pwd.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/pwd.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/pwd.rst 2025-12-19 23:10:15.404074457 +0100
+--- Python-3.10.20.orig/Doc/library/pwd.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/pwd.rst 2026-03-05 19:42:18.984577957 +0100
@@ -37,7 +37,7 @@
.. note::
@@ -1092,10 +1092,10 @@ Index: Python-3.10.19/Doc/library/pwd.rst
In traditional Unix the field ``pw_passwd`` usually contains a password
encrypted with a DES derived algorithm (see module :mod:`crypt`). However most
-Index: Python-3.10.19/Doc/library/pyexpat.rst
+Index: Python-3.10.20/Doc/library/pyexpat.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/pyexpat.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/pyexpat.rst 2025-12-19 23:10:15.404269595 +0100
+--- Python-3.10.20.orig/Doc/library/pyexpat.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/pyexpat.rst 2026-03-05 19:42:18.984818931 +0100
@@ -33,7 +33,7 @@
parser, the handler functions are called for the character data and markup in
the XML document.
@@ -1105,10 +1105,10 @@ Index: Python-3.10.19/Doc/library/pyexpat.rst
This module uses the :mod:`pyexpat` module to provide access to the Expat
parser. Direct use of the :mod:`pyexpat` module is deprecated.
-Index: Python-3.10.19/Doc/library/runpy.rst
+Index: Python-3.10.20/Doc/library/runpy.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/runpy.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/runpy.rst 2025-12-19 23:10:15.404446365 +0100
+--- Python-3.10.20.orig/Doc/library/runpy.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/runpy.rst 2026-03-05 19:42:18.985177187 +0100
@@ -30,7 +30,7 @@
.. function:: run_module(mod_name, init_globals=None, run_name=None, alter_sys=False)
@@ -1127,10 +1127,10 @@ Index: Python-3.10.19/Doc/library/runpy.rst
Execute the code at the named filesystem location and return the resulting
module globals dictionary. As with a script name supplied to the CPython
-Index: Python-3.10.19/Doc/library/shelve.rst
+Index: Python-3.10.20/Doc/library/shelve.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/shelve.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/shelve.rst 2025-12-19 23:10:15.404878127 +0100
+--- Python-3.10.20.orig/Doc/library/shelve.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/shelve.rst 2026-03-05 19:42:18.985415677 +0100
@@ -6,7 +6,7 @@
**Source code:** :source:`Lib/shelve.py`
@@ -1151,10 +1151,10 @@ Index: Python-3.10.19/Doc/library/shelve.rst
* The choice of which database package will be used (such as :mod:`dbm.ndbm` or
:mod:`dbm.gnu`) depends on which interface is available. Therefore it is not
-Index: Python-3.10.19/Doc/library/site.rst
+Index: Python-3.10.20/Doc/library/site.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/site.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/site.rst 2025-12-19 23:10:15.405113354 +0100
+--- Python-3.10.20.orig/Doc/library/site.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/site.rst 2026-03-05 19:42:18.985669245 +0100
@@ -51,7 +51,7 @@
.. index::
@@ -1182,10 +1182,10 @@ Index: Python-3.10.19/Doc/library/site.rst
After this, an attempt is made to import a module named :mod:`usercustomize`,
which can perform arbitrary user-specific customizations, if
-Index: Python-3.10.19/Doc/library/socket.rst
+Index: Python-3.10.20/Doc/library/socket.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/socket.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/socket.rst 2025-12-19 23:10:15.405446360 +0100
+--- Python-3.10.20.orig/Doc/library/socket.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/socket.rst 2026-03-05 19:42:18.986046306 +0100
@@ -16,7 +16,7 @@
Some behavior may be platform dependent, since calls are made to the operating
system socket APIs.
@@ -1204,10 +1204,10 @@ Index: Python-3.10.19/Doc/library/socket.rst
Set the value of the given socket option (see the Unix manual page
:manpage:`setsockopt(2)`). The needed symbolic constants are defined in the
-Index: Python-3.10.19/Doc/library/stdtypes.rst
+Index: Python-3.10.20/Doc/library/stdtypes.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/stdtypes.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/stdtypes.rst 2025-12-19 23:10:15.406446355 +0100
+--- Python-3.10.20.orig/Doc/library/stdtypes.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/stdtypes.rst 2026-03-05 19:42:18.986972964 +0100
@@ -32,8 +32,8 @@
===================
@@ -1583,10 +1583,10 @@ Index: Python-3.10.19/Doc/library/stdtypes.rst
Type objects represent the various object types. An object's type is accessed
by the built-in function :func:`type`. There are no special operations on
-Index: Python-3.10.19/Doc/library/sys.rst
+Index: Python-3.10.20/Doc/library/sys.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/sys.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/sys.rst 2025-12-19 23:10:15.406880072 +0100
+--- Python-3.10.20.orig/Doc/library/sys.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/sys.rst 2026-03-05 19:42:18.987990342 +0100
@@ -398,7 +398,7 @@
an except clause." For any stack frame, only information about the exception
being currently handled is accessible.
@@ -1596,10 +1596,10 @@ Index: Python-3.10.19/Doc/library/sys.rst
If no exception is being handled anywhere on the stack, a tuple containing
three ``None`` values is returned. Otherwise, the values returned are
-Index: Python-3.10.19/Doc/library/traceback.rst
+Index: Python-3.10.20/Doc/library/traceback.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/traceback.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/traceback.rst 2025-12-19 23:10:15.407220202 +0100
+--- Python-3.10.20.orig/Doc/library/traceback.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/traceback.rst 2026-03-05 19:42:18.988443998 +0100
@@ -14,7 +14,7 @@
stack traces under program control, such as in a "wrapper" around the
interpreter.
@@ -1609,10 +1609,10 @@ Index: Python-3.10.19/Doc/library/traceback.rst
The module uses traceback objects --- this is the object type that is stored in
the :data:`sys.last_traceback` variable and returned as the third item from
-Index: Python-3.10.19/Doc/library/types.rst
+Index: Python-3.10.20/Doc/library/types.rst
===================================================================
---- Python-3.10.19.orig/Doc/library/types.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/library/types.rst 2025-12-19 23:10:15.407463391 +0100
+--- Python-3.10.20.orig/Doc/library/types.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/library/types.rst 2026-03-05 19:42:18.988791784 +0100
@@ -146,7 +146,7 @@
.. class:: CodeType(**kwargs)
@@ -1622,10 +1622,10 @@ Index: Python-3.10.19/Doc/library/types.rst
The type for code objects such as returned by :func:`compile`.
-Index: Python-3.10.19/Doc/reference/compound_stmts.rst
+Index: Python-3.10.20/Doc/reference/compound_stmts.rst
===================================================================
---- Python-3.10.19.orig/Doc/reference/compound_stmts.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/reference/compound_stmts.rst 2025-12-19 23:10:15.407774397 +0100
+--- Python-3.10.20.orig/Doc/reference/compound_stmts.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/reference/compound_stmts.rst 2026-03-05 19:42:18.989240841 +0100
@@ -84,9 +84,9 @@
============================
@@ -1855,10 +1855,10 @@ Index: Python-3.10.19/Doc/reference/compound_stmts.rst
.. _`async with`:
The :keyword:`!async with` statement
-Index: Python-3.10.19/Doc/reference/datamodel.rst
+Index: Python-3.10.20/Doc/reference/datamodel.rst
===================================================================
---- Python-3.10.19.orig/Doc/reference/datamodel.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/reference/datamodel.rst 2025-12-19 23:10:15.408446345 +0100
+--- Python-3.10.20.orig/Doc/reference/datamodel.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/reference/datamodel.rst 2026-03-05 19:42:18.989869737 +0100
@@ -21,8 +21,8 @@
represented by objects.)
@@ -2371,10 +2371,10 @@ Index: Python-3.10.19/Doc/reference/datamodel.rst
single: context manager
Typical uses of context managers include saving and restoring various kinds of
-Index: Python-3.10.19/Doc/reference/executionmodel.rst
+Index: Python-3.10.20/Doc/reference/executionmodel.rst
===================================================================
---- Python-3.10.19.orig/Doc/reference/executionmodel.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/reference/executionmodel.rst 2025-12-19 23:10:15.408910164 +0100
+--- Python-3.10.20.orig/Doc/reference/executionmodel.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/reference/executionmodel.rst 2026-03-05 19:42:18.990617928 +0100
@@ -151,7 +151,7 @@
:exc:`SyntaxError` is raised at compile time if the given name does not
exist in any enclosing function scope.
@@ -2384,10 +2384,10 @@ Index: Python-3.10.19/Doc/reference/executionmodel.rst
The namespace for a module is automatically created the first time a module is
imported. The main module for a script is always called :mod:`__main__`.
-Index: Python-3.10.19/Doc/reference/expressions.rst
+Index: Python-3.10.20/Doc/reference/expressions.rst
===================================================================
---- Python-3.10.19.orig/Doc/reference/expressions.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/reference/expressions.rst 2025-12-19 23:10:15.409155938 +0100
+--- Python-3.10.20.orig/Doc/reference/expressions.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/reference/expressions.rst 2026-03-05 19:42:18.990933533 +0100
@@ -71,7 +71,7 @@
for lexical definition and section :ref:`naming` for documentation of naming and
binding.
@@ -2794,10 +2794,10 @@ Index: Python-3.10.19/Doc/reference/expressions.rst
Except when part of a list or set display, an expression list
containing at least one comma yields a tuple. The length of
-Index: Python-3.10.19/Doc/reference/simple_stmts.rst
+Index: Python-3.10.20/Doc/reference/simple_stmts.rst
===================================================================
---- Python-3.10.19.orig/Doc/reference/simple_stmts.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/reference/simple_stmts.rst 2025-12-19 23:10:15.409656983 +0100
+--- Python-3.10.20.orig/Doc/reference/simple_stmts.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/reference/simple_stmts.rst 2026-03-05 19:42:18.991596393 +0100
@@ -53,8 +53,8 @@
expression).
@@ -3039,10 +3039,10 @@ Index: Python-3.10.19/Doc/reference/simple_stmts.rst
single: , (comma); identifier list
.. productionlist:: python-grammar
-Index: Python-3.10.19/Doc/reference/toplevel_components.rst
+Index: Python-3.10.20/Doc/reference/toplevel_components.rst
===================================================================
---- Python-3.10.19.orig/Doc/reference/toplevel_components.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/reference/toplevel_components.rst 2025-12-19 23:10:15.409991385 +0100
+--- Python-3.10.20.orig/Doc/reference/toplevel_components.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/reference/toplevel_components.rst 2026-03-05 19:42:18.991994343 +0100
@@ -21,9 +21,9 @@
.. index:: single: program
@@ -3074,10 +3074,10 @@ Index: Python-3.10.19/Doc/reference/toplevel_components.rst
:func:`eval` is used for expression input. It ignores leading whitespace. The
string argument to :func:`eval` must have the following form:
-Index: Python-3.10.19/Doc/tools/extensions/pyspecific.py
+Index: Python-3.10.20/Doc/tools/extensions/pyspecific.py
===================================================================
---- Python-3.10.19.orig/Doc/tools/extensions/pyspecific.py 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/tools/extensions/pyspecific.py 2025-12-19 23:10:15.410328302 +0100
+--- Python-3.10.20.orig/Doc/tools/extensions/pyspecific.py 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/tools/extensions/pyspecific.py 2026-03-05 19:42:18.992268971 +0100
@@ -644,6 +644,30 @@
node.replace_self(table)
@@ -3117,10 +3117,10 @@ Index: Python-3.10.19/Doc/tools/extensions/pyspecific.py
app.connect('doctree-resolved', process_audit_events)
app.connect('env-merge-info', audit_events_merge)
app.connect('env-purge-doc', audit_events_purge)
-Index: Python-3.10.19/Doc/tutorial/classes.rst
+Index: Python-3.10.20/Doc/tutorial/classes.rst
===================================================================
---- Python-3.10.19.orig/Doc/tutorial/classes.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/tutorial/classes.rst 2025-12-19 23:10:15.410720534 +0100
+--- Python-3.10.20.orig/Doc/tutorial/classes.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/tutorial/classes.rst 2026-03-05 19:42:18.992758014 +0100
@@ -344,7 +344,7 @@
However, in the following discussion, we'll use the term method exclusively to
mean methods of class instance objects, unless explicitly stated otherwise.)
@@ -3130,10 +3130,10 @@ Index: Python-3.10.19/Doc/tutorial/classes.rst
Valid method names of an instance object depend on its class. By definition,
all attributes of a class that are function objects define corresponding
-Index: Python-3.10.19/Doc/tutorial/controlflow.rst
+Index: Python-3.10.20/Doc/tutorial/controlflow.rst
===================================================================
---- Python-3.10.19.orig/Doc/tutorial/controlflow.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/tutorial/controlflow.rst 2025-12-19 23:10:15.411043971 +0100
+--- Python-3.10.20.orig/Doc/tutorial/controlflow.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/tutorial/controlflow.rst 2026-03-05 19:42:18.993212891 +0100
@@ -46,7 +46,7 @@
==========================
@@ -3143,10 +3143,10 @@ Index: Python-3.10.19/Doc/tutorial/controlflow.rst
The :keyword:`for` statement in Python differs a bit from what you may be used
to in C or Pascal. Rather than always iterating over an arithmetic progression
-Index: Python-3.10.19/Doc/tutorial/inputoutput.rst
+Index: Python-3.10.20/Doc/tutorial/inputoutput.rst
===================================================================
---- Python-3.10.19.orig/Doc/tutorial/inputoutput.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/tutorial/inputoutput.rst 2025-12-19 23:10:15.411308183 +0100
+--- Python-3.10.20.orig/Doc/tutorial/inputoutput.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/tutorial/inputoutput.rst 2026-03-05 19:42:18.993527254 +0100
@@ -285,8 +285,8 @@
=========================
@@ -3167,10 +3167,10 @@ Index: Python-3.10.19/Doc/tutorial/inputoutput.rst
Strings can easily be written to and read from a file. Numbers take a bit more
effort, since the :meth:`read` method only returns strings, which will have to
-Index: Python-3.10.19/Doc/tutorial/modules.rst
+Index: Python-3.10.20/Doc/tutorial/modules.rst
===================================================================
---- Python-3.10.19.orig/Doc/tutorial/modules.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/tutorial/modules.rst 2025-12-19 23:10:15.411539499 +0100
+--- Python-3.10.20.orig/Doc/tutorial/modules.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/tutorial/modules.rst 2026-03-05 19:42:18.993796923 +0100
@@ -260,7 +260,7 @@
Standard Modules
================
@@ -3189,10 +3189,10 @@ Index: Python-3.10.19/Doc/tutorial/modules.rst
:func:`dir` does not list the names of built-in functions and variables. If you
want a list of those, they are defined in the standard module
-Index: Python-3.10.19/Doc/tutorial/stdlib.rst
+Index: Python-3.10.20/Doc/tutorial/stdlib.rst
===================================================================
---- Python-3.10.19.orig/Doc/tutorial/stdlib.rst 2025-10-09 17:25:03.000000000 +0200
-+++ Python-3.10.19/Doc/tutorial/stdlib.rst 2025-12-19 23:10:15.411769907 +0100
+--- Python-3.10.20.orig/Doc/tutorial/stdlib.rst 2026-03-05 19:42:16.337584041 +0100
++++ Python-3.10.20/Doc/tutorial/stdlib.rst 2026-03-05 19:42:18.994160168 +0100
@@ -24,7 +24,7 @@
will keep :func:`os.open` from shadowing the built-in :func:`open` function which
operates much differently.
diff --git a/support-expat-CVE-2022-25236-patched.patch b/support-expat-CVE-2022-25236-patched.patch
index 5b26c99..16eed53 100644
--- a/support-expat-CVE-2022-25236-patched.patch
+++ b/support-expat-CVE-2022-25236-patched.patch
@@ -27,17 +27,19 @@ Co-authored-by: Sebastian Pipping
1 file changed, 9 insertions(+), 14 deletions(-)
create mode 100644 Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst
---- a/Lib/test/test_minidom.py
-+++ b/Lib/test/test_minidom.py
-@@ -6,7 +6,6 @@ import io
+Index: Python-3.10.20/Lib/test/test_minidom.py
+===================================================================
+--- Python-3.10.20.orig/Lib/test/test_minidom.py 2026-03-05 19:39:01.567696516 +0100
++++ Python-3.10.20/Lib/test/test_minidom.py 2026-03-05 19:42:02.323563898 +0100
+@@ -7,7 +7,6 @@
from test import support
import unittest
-import pyexpat
import xml.dom.minidom
- from xml.dom.minidom import parse, Attr, Node, Document, parseString
-@@ -1163,13 +1162,11 @@ class MinidomTest(unittest.TestCase):
+ from xml.dom.minidom import parse, Attr, Node, Document, Element, parseString
+@@ -1194,13 +1193,11 @@
# Verify that character decoding errors raise exceptions instead
# of crashing
@@ -56,7 +58,7 @@ Co-authored-by: Sebastian Pipping
b'Comment \xe7a va ? Tr\xe8s bien ?')
doc.unlink()
-@@ -1631,12 +1628,10 @@ class MinidomTest(unittest.TestCase):
+@@ -1662,12 +1659,10 @@
self.confirm(doc2.namespaceURI == xml.dom.EMPTY_NAMESPACE)
def testExceptionOnSpacesInXMLNSValue(self):