diff --git a/CVE-2023-52425-libexpat-2.6.0-backport-15.6.patch b/CVE-2023-52425-libexpat-2.6.0-backport-15.6.patch
index 7dc6a23..fe65839 100644
--- a/CVE-2023-52425-libexpat-2.6.0-backport-15.6.patch
+++ b/CVE-2023-52425-libexpat-2.6.0-backport-15.6.patch
@@ -4,11 +4,9 @@
Lib/test/test_xml_etree.py | 10 ++++++++++
3 files changed, 17 insertions(+)
-Index: Python-3.14.0a7/Lib/test/test_pyexpat.py
-===================================================================
---- Python-3.14.0a7.orig/Lib/test/test_pyexpat.py 2025-04-12 23:55:25.077318106 +0200
-+++ Python-3.14.0a7/Lib/test/test_pyexpat.py 2025-04-12 23:58:03.769944012 +0200
-@@ -791,6 +791,10 @@
+--- a/Lib/test/test_pyexpat.py
++++ b/Lib/test/test_pyexpat.py
+@@ -791,6 +791,10 @@ class ReparseDeferralTest(unittest.TestC
self.assertEqual(started, ['doc'])
def test_reparse_deferral_disabled(self):
@@ -19,11 +17,9 @@ Index: Python-3.14.0a7/Lib/test/test_pyexpat.py
started = []
def start_element(name, _):
-Index: Python-3.14.0a7/Lib/test/test_sax.py
-===================================================================
---- Python-3.14.0a7.orig/Lib/test/test_sax.py 2025-04-12 23:55:25.131274628 +0200
-+++ Python-3.14.0a7/Lib/test/test_sax.py 2025-04-12 23:58:03.770532570 +0200
-@@ -1241,6 +1241,9 @@
+--- a/Lib/test/test_sax.py
++++ b/Lib/test/test_sax.py
+@@ -1241,6 +1241,9 @@ class ExpatReaderTest(XmlTestBase):
self.assertEqual(result.getvalue(), start + b"")
@@ -33,11 +29,9 @@ Index: Python-3.14.0a7/Lib/test/test_sax.py
def test_flush_reparse_deferral_disabled(self):
result = BytesIO()
xmlgen = XMLGenerator(result)
-Index: Python-3.14.0a7/Lib/test/test_xml_etree.py
-===================================================================
---- Python-3.14.0a7.orig/Lib/test/test_xml_etree.py 2025-04-12 23:55:25.550207629 +0200
-+++ Python-3.14.0a7/Lib/test/test_xml_etree.py 2025-04-12 23:58:03.771265630 +0200
-@@ -138,6 +138,11 @@
+--- a/Lib/test/test_xml_etree.py
++++ b/Lib/test/test_xml_etree.py
+@@ -138,6 +138,11 @@ def equal_wrapper(cls):
return mock.patch.object(cls, "__eq__", autospec=True, wraps=eq)
@@ -49,7 +43,7 @@ Index: Python-3.14.0a7/Lib/test/test_xml_etree.py
def checkwarnings(*filters, quiet=False):
def decorator(test):
def newtest(*args, **kwargs):
-@@ -1521,9 +1526,11 @@
+@@ -1520,9 +1525,11 @@ class XMLPullParserTest(unittest.TestCas
self.assert_event_tags(parser, [('end', 'root')])
self.assertIsNone(parser.close())
@@ -61,7 +55,7 @@ Index: Python-3.14.0a7/Lib/test/test_xml_etree.py
def test_simple_xml_chunk_5(self):
self.test_simple_xml(chunk_size=5, flush=True)
-@@ -1748,6 +1755,9 @@
+@@ -1747,6 +1754,9 @@ class XMLPullParserTest(unittest.TestCas
self.assert_event_tags(parser, [('end', 'doc')])
diff --git a/CVE-2025-4516-DecodeError-handler.patch b/CVE-2025-4516-DecodeError-handler.patch
deleted file mode 100644
index 1aafbf7..0000000
--- a/CVE-2025-4516-DecodeError-handler.patch
+++ /dev/null
@@ -1,480 +0,0 @@
-From 3a939ff2298d147459116f98a09549d0f1954039 Mon Sep 17 00:00:00 2001
-From: Serhiy Storchaka
-Date: Tue, 4 Feb 2025 11:44:39 +0200
-Subject: Fix use-after-free in the unicode-escape decoder with error handler
-
-If the error handler is used, a new bytes object is created to set as
-the object attribute of UnicodeDecodeError, and that bytes object then
-replaces the original data. A pointer to the decoded data will became invalid
-after destroying that temporary bytes object. So we need other way to return
-the first invalid escape from _PyUnicode_DecodeUnicodeEscapeInternal().
-
-_PyBytes_DecodeEscape() does not have such issue, because it does not
-use the error handlers registry, but it should be changed for compatibility
-with _PyUnicode_DecodeUnicodeEscapeInternal().
----
- Include/internal/pycore_bytesobject.h | 5
- Include/internal/pycore_unicodeobject.h | 12 +-
- Lib/test/test_codeccallbacks.py | 39 +++++++
- Lib/test/test_codecs.py | 52 ++++++++--
- Misc/NEWS.d/next/Security/2025-05-09-20-22-54.gh-issue-133767.kN2i3Q.rst | 2
- Objects/bytesobject.c | 41 ++++---
- Objects/unicodeobject.c | 46 +++++---
- Parser/string_parser.c | 26 +++--
- 8 files changed, 160 insertions(+), 63 deletions(-)
-
-Index: Python-3.14.0b1/Include/internal/pycore_bytesobject.h
-===================================================================
---- Python-3.14.0b1.orig/Include/internal/pycore_bytesobject.h 2025-05-06 15:33:52.000000000 +0000
-+++ Python-3.14.0b1/Include/internal/pycore_bytesobject.h 2025-05-17 06:44:53.614667081 +0000
-@@ -20,8 +20,9 @@
-
- // Helper for PyBytes_DecodeEscape that detects invalid escape chars.
- // Export for test_peg_generator.
--PyAPI_FUNC(PyObject*) _PyBytes_DecodeEscape(const char *, Py_ssize_t,
-- const char *, const char **);
-+PyAPI_FUNC(PyObject*) _PyBytes_DecodeEscape2(const char *, Py_ssize_t,
-+ const char *,
-+ int *, const char **);
-
-
- // Substring Search.
-Index: Python-3.14.0b1/Include/internal/pycore_unicodeobject.h
-===================================================================
---- Python-3.14.0b1.orig/Include/internal/pycore_unicodeobject.h 2025-05-06 15:33:52.000000000 +0000
-+++ Python-3.14.0b1/Include/internal/pycore_unicodeobject.h 2025-05-17 06:44:53.614817134 +0000
-@@ -139,14 +139,18 @@
- // Helper for PyUnicode_DecodeUnicodeEscape that detects invalid escape
- // chars.
- // Export for test_peg_generator.
--PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal(
-+PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal2(
- const char *string, /* Unicode-Escape encoded string */
- Py_ssize_t length, /* size of string */
- const char *errors, /* error handling */
- Py_ssize_t *consumed, /* bytes consumed */
-- const char **first_invalid_escape); /* on return, points to first
-- invalid escaped char in
-- string. */
-+ int *first_invalid_escape_char, /* on return, if not -1, contain the first
-+ invalid escaped char (<= 0xff) or invalid
-+ octal escape (> 0xff) in string. */
-+ const char **first_invalid_escape_ptr); /* on return, if not NULL, may
-+ point to the first invalid escaped
-+ char in string.
-+ May be NULL if errors is not NULL. */
-
- /* --- Raw-Unicode-Escape Codecs ---------------------------------------------- */
-
-Index: Python-3.14.0b1/Lib/test/test_codeccallbacks.py
-===================================================================
---- Python-3.14.0b1.orig/Lib/test/test_codeccallbacks.py 2025-05-17 06:44:47.673341939 +0000
-+++ Python-3.14.0b1/Lib/test/test_codeccallbacks.py 2025-05-17 06:44:53.615018793 +0000
-@@ -2,6 +2,7 @@
- import codecs
- import html.entities
- import itertools
-+import re
- import sys
- import unicodedata
- import unittest
-@@ -1125,7 +1126,7 @@
- text = 'abcghi'*n
- text.translate(charmap)
-
-- def test_mutatingdecodehandler(self):
-+ def test_mutating_decode_handler(self):
- baddata = [
- ("ascii", b"\xff"),
- ("utf-7", b"++"),
-@@ -1160,6 +1161,42 @@
- for (encoding, data) in baddata:
- self.assertEqual(data.decode(encoding, "test.mutating"), "\u4242")
-
-+ def test_mutating_decode_handler_unicode_escape(self):
-+ decode = codecs.unicode_escape_decode
-+ def mutating(exc):
-+ if isinstance(exc, UnicodeDecodeError):
-+ r = data.get(exc.object[:exc.end])
-+ if r is not None:
-+ exc.object = r[0] + exc.object[exc.end:]
-+ return ('\u0404', r[1])
-+ raise AssertionError("don't know how to handle %r" % exc)
-+
-+ codecs.register_error('test.mutating2', mutating)
-+ data = {
-+ br'\x0': (b'\\', 0),
-+ br'\x3': (b'xxx\\', 3),
-+ br'\x5': (b'x\\', 1),
-+ }
-+ def check(input, expected, msg):
-+ with self.assertWarns(DeprecationWarning) as cm:
-+ self.assertEqual(decode(input, 'test.mutating2'), (expected, len(input)))
-+ self.assertIn(msg, str(cm.warning))
-+
-+ check(br'\x0n\z', '\u0404\n\\z', r'"\z" is an invalid escape sequence')
-+ check(br'\x0n\501', '\u0404\n\u0141', r'"\501" is an invalid octal escape sequence')
-+ check(br'\x0z', '\u0404\\z', r'"\z" is an invalid escape sequence')
-+
-+ check(br'\x3n\zr', '\u0404\n\\zr', r'"\z" is an invalid escape sequence')
-+ check(br'\x3zr', '\u0404\\zr', r'"\z" is an invalid escape sequence')
-+ check(br'\x3z5', '\u0404\\z5', r'"\z" is an invalid escape sequence')
-+ check(memoryview(br'\x3z5x')[:-1], '\u0404\\z5', r'"\z" is an invalid escape sequence')
-+ check(memoryview(br'\x3z5xy')[:-2], '\u0404\\z5', r'"\z" is an invalid escape sequence')
-+
-+ check(br'\x5n\z', '\u0404\n\\z', r'"\z" is an invalid escape sequence')
-+ check(br'\x5n\501', '\u0404\n\u0141', r'"\501" is an invalid octal escape sequence')
-+ check(br'\x5z', '\u0404\\z', r'"\z" is an invalid escape sequence')
-+ check(memoryview(br'\x5zy')[:-1], '\u0404\\z', r'"\z" is an invalid escape sequence')
-+
- # issue32583
- def test_crashing_decode_handler(self):
- # better generating one more character to fill the extra space slot
-Index: Python-3.14.0b1/Lib/test/test_codecs.py
-===================================================================
---- Python-3.14.0b1.orig/Lib/test/test_codecs.py 2025-05-17 06:44:47.696604117 +0000
-+++ Python-3.14.0b1/Lib/test/test_codecs.py 2025-05-17 06:44:53.615449954 +0000
-@@ -1196,23 +1196,39 @@
- check(br"[\1010]", b"[A0]")
- check(br"[\x41]", b"[A]")
- check(br"[\x410]", b"[A0]")
-+
-+ def test_warnings(self):
-+ decode = codecs.escape_decode
-+ check = coding_checker(self, decode)
- for i in range(97, 123):
- b = bytes([i])
- if b not in b'abfnrtvx':
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r'"\\%c" is an invalid escape sequence' % i):
- check(b"\\" + b, b"\\" + b)
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r'"\\%c" is an invalid escape sequence' % (i-32)):
- check(b"\\" + b.upper(), b"\\" + b.upper())
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r'"\\8" is an invalid escape sequence'):
- check(br"\8", b"\\8")
- with self.assertWarns(DeprecationWarning):
- check(br"\9", b"\\9")
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r'"\\\xfa" is an invalid escape sequence') as cm:
- check(b"\\\xfa", b"\\\xfa")
- for i in range(0o400, 0o1000):
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r'"\\%o" is an invalid octal escape sequence' % i):
- check(rb'\%o' % i, bytes([i & 0o377]))
-
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r'"\\z" is an invalid escape sequence'):
-+ self.assertEqual(decode(br'\x\z', 'ignore'), (b'\\z', 4))
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r'"\\501" is an invalid octal escape sequence'):
-+ self.assertEqual(decode(br'\x\501', 'ignore'), (b'A', 6))
-+
- def test_errors(self):
- decode = codecs.escape_decode
- self.assertRaises(ValueError, decode, br"\x")
-@@ -2661,24 +2677,40 @@
- check(br"[\x410]", "[A0]")
- check(br"\u20ac", "\u20ac")
- check(br"\U0001d120", "\U0001d120")
-+
-+ def test_decode_warnings(self):
-+ decode = codecs.unicode_escape_decode
-+ check = coding_checker(self, decode)
- for i in range(97, 123):
- b = bytes([i])
- if b not in b'abfnrtuvx':
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r'"\\%c" is an invalid escape sequence' % i):
- check(b"\\" + b, "\\" + chr(i))
- if b.upper() not in b'UN':
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r'"\\%c" is an invalid escape sequence' % (i-32)):
- check(b"\\" + b.upper(), "\\" + chr(i-32))
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r'"\\8" is an invalid escape sequence'):
- check(br"\8", "\\8")
- with self.assertWarns(DeprecationWarning):
- check(br"\9", "\\9")
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r'"\\\xfa" is an invalid escape sequence') as cm:
- check(b"\\\xfa", "\\\xfa")
- for i in range(0o400, 0o1000):
-- with self.assertWarns(DeprecationWarning):
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r'"\\%o" is an invalid octal escape sequence' % i):
- check(rb'\%o' % i, chr(i))
-
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r'"\\z" is an invalid escape sequence'):
-+ self.assertEqual(decode(br'\x\z', 'ignore'), ('\\z', 4))
-+ with self.assertWarnsRegex(DeprecationWarning,
-+ r'"\\501" is an invalid octal escape sequence'):
-+ self.assertEqual(decode(br'\x\501', 'ignore'), ('\u0141', 6))
-+
- def test_decode_errors(self):
- decode = codecs.unicode_escape_decode
- for c, d in (b'x', 2), (b'u', 4), (b'U', 4):
-Index: Python-3.14.0b1/Misc/NEWS.d/next/Security/2025-05-09-20-22-54.gh-issue-133767.kN2i3Q.rst
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ Python-3.14.0b1/Misc/NEWS.d/next/Security/2025-05-09-20-22-54.gh-issue-133767.kN2i3Q.rst 2025-05-17 06:44:53.615887918 +0000
-@@ -0,0 +1,2 @@
-+Fix use-after-free in the "unicode-escape" decoder with a non-"strict" error
-+handler.
-Index: Python-3.14.0b1/Objects/bytesobject.c
-===================================================================
---- Python-3.14.0b1.orig/Objects/bytesobject.c 2025-05-06 15:33:52.000000000 +0000
-+++ Python-3.14.0b1/Objects/bytesobject.c 2025-05-17 06:44:53.616354335 +0000
-@@ -1075,10 +1075,11 @@
- }
-
- /* Unescape a backslash-escaped string. */
--PyObject *_PyBytes_DecodeEscape(const char *s,
-+PyObject *_PyBytes_DecodeEscape2(const char *s,
- Py_ssize_t len,
- const char *errors,
-- const char **first_invalid_escape)
-+ int *first_invalid_escape_char,
-+ const char **first_invalid_escape_ptr)
- {
- int c;
- char *p;
-@@ -1092,7 +1093,8 @@
- return NULL;
- writer.overallocate = 1;
-
-- *first_invalid_escape = NULL;
-+ *first_invalid_escape_char = -1;
-+ *first_invalid_escape_ptr = NULL;
-
- end = s + len;
- while (s < end) {
-@@ -1130,9 +1132,10 @@
- c = (c<<3) + *s++ - '0';
- }
- if (c > 0377) {
-- if (*first_invalid_escape == NULL) {
-- *first_invalid_escape = s-3; /* Back up 3 chars, since we've
-- already incremented s. */
-+ if (*first_invalid_escape_char == -1) {
-+ *first_invalid_escape_char = c;
-+ /* Back up 3 chars, since we've already incremented s. */
-+ *first_invalid_escape_ptr = s - 3;
- }
- }
- *p++ = c;
-@@ -1173,9 +1176,10 @@
- break;
-
- default:
-- if (*first_invalid_escape == NULL) {
-- *first_invalid_escape = s-1; /* Back up one char, since we've
-- already incremented s. */
-+ if (*first_invalid_escape_char == -1) {
-+ *first_invalid_escape_char = (unsigned char)s[-1];
-+ /* Back up one char, since we've already incremented s. */
-+ *first_invalid_escape_ptr = s - 1;
- }
- *p++ = '\\';
- s--;
-@@ -1195,18 +1199,19 @@
- Py_ssize_t Py_UNUSED(unicode),
- const char *Py_UNUSED(recode_encoding))
- {
-- const char* first_invalid_escape;
-- PyObject *result = _PyBytes_DecodeEscape(s, len, errors,
-- &first_invalid_escape);
-+ int first_invalid_escape_char;
-+ const char *first_invalid_escape_ptr;
-+ PyObject *result = _PyBytes_DecodeEscape2(s, len, errors,
-+ &first_invalid_escape_char,
-+ &first_invalid_escape_ptr);
- if (result == NULL)
- return NULL;
-- if (first_invalid_escape != NULL) {
-- unsigned char c = *first_invalid_escape;
-- if ('4' <= c && c <= '7') {
-+ if (first_invalid_escape_char != -1) {
-+ if (first_invalid_escape_char > 0xff) {
- if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
-- "b\"\\%.3s\" is an invalid octal escape sequence. "
-+ "b\"\\%o\" is an invalid octal escape sequence. "
- "Such sequences will not work in the future. ",
-- first_invalid_escape) < 0)
-+ first_invalid_escape_char) < 0)
- {
- Py_DECREF(result);
- return NULL;
-@@ -1216,7 +1221,7 @@
- if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
- "b\"\\%c\" is an invalid escape sequence. "
- "Such sequences will not work in the future. ",
-- c) < 0)
-+ first_invalid_escape_char) < 0)
- {
- Py_DECREF(result);
- return NULL;
-Index: Python-3.14.0b1/Objects/unicodeobject.c
-===================================================================
---- Python-3.14.0b1.orig/Objects/unicodeobject.c 2025-05-06 15:33:52.000000000 +0000
-+++ Python-3.14.0b1/Objects/unicodeobject.c 2025-05-17 06:44:53.617547540 +0000
-@@ -6621,13 +6621,15 @@
- /* --- Unicode Escape Codec ----------------------------------------------- */
-
- PyObject *
--_PyUnicode_DecodeUnicodeEscapeInternal(const char *s,
-+_PyUnicode_DecodeUnicodeEscapeInternal2(const char *s,
- Py_ssize_t size,
- const char *errors,
- Py_ssize_t *consumed,
-- const char **first_invalid_escape)
-+ int *first_invalid_escape_char,
-+ const char **first_invalid_escape_ptr)
- {
- const char *starts = s;
-+ const char *initial_starts = starts;
- _PyUnicodeWriter writer;
- const char *end;
- PyObject *errorHandler = NULL;
-@@ -6635,7 +6637,8 @@
- _PyUnicode_Name_CAPI *ucnhash_capi;
-
- // so we can remember if we've seen an invalid escape char or not
-- *first_invalid_escape = NULL;
-+ *first_invalid_escape_char = -1;
-+ *first_invalid_escape_ptr = NULL;
-
- if (size == 0) {
- if (consumed) {
-@@ -6723,9 +6726,12 @@
- }
- }
- if (ch > 0377) {
-- if (*first_invalid_escape == NULL) {
-- *first_invalid_escape = s-3; /* Back up 3 chars, since we've
-- already incremented s. */
-+ if (*first_invalid_escape_char == -1) {
-+ *first_invalid_escape_char = ch;
-+ if (starts == initial_starts) {
-+ /* Back up 3 chars, since we've already incremented s. */
-+ *first_invalid_escape_ptr = s - 3;
-+ }
- }
- }
- WRITE_CHAR(ch);
-@@ -6820,9 +6826,12 @@
- goto error;
-
- default:
-- if (*first_invalid_escape == NULL) {
-- *first_invalid_escape = s-1; /* Back up one char, since we've
-- already incremented s. */
-+ if (*first_invalid_escape_char == -1) {
-+ *first_invalid_escape_char = c;
-+ if (starts == initial_starts) {
-+ /* Back up one char, since we've already incremented s. */
-+ *first_invalid_escape_ptr = s - 1;
-+ }
- }
- WRITE_ASCII_CHAR('\\');
- WRITE_CHAR(c);
-@@ -6867,19 +6876,20 @@
- const char *errors,
- Py_ssize_t *consumed)
- {
-- const char *first_invalid_escape;
-- PyObject *result = _PyUnicode_DecodeUnicodeEscapeInternal(s, size, errors,
-+ int first_invalid_escape_char;
-+ const char *first_invalid_escape_ptr;
-+ PyObject *result = _PyUnicode_DecodeUnicodeEscapeInternal2(s, size, errors,
- consumed,
-- &first_invalid_escape);
-+ &first_invalid_escape_char,
-+ &first_invalid_escape_ptr);
- if (result == NULL)
- return NULL;
-- if (first_invalid_escape != NULL) {
-- unsigned char c = *first_invalid_escape;
-- if ('4' <= c && c <= '7') {
-+ if (first_invalid_escape_char != -1) {
-+ if (first_invalid_escape_char > 0xff) {
- if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
-- "\"\\%.3s\" is an invalid octal escape sequence. "
-+ "\"\\%o\" is an invalid octal escape sequence. "
- "Such sequences will not work in the future. ",
-- first_invalid_escape) < 0)
-+ first_invalid_escape_char) < 0)
- {
- Py_DECREF(result);
- return NULL;
-@@ -6889,7 +6899,7 @@
- if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
- "\"\\%c\" is an invalid escape sequence. "
- "Such sequences will not work in the future. ",
-- c) < 0)
-+ first_invalid_escape_char) < 0)
- {
- Py_DECREF(result);
- return NULL;
-Index: Python-3.14.0b1/Parser/string_parser.c
-===================================================================
---- Python-3.14.0b1.orig/Parser/string_parser.c 2025-05-06 15:33:52.000000000 +0000
-+++ Python-3.14.0b1/Parser/string_parser.c 2025-05-17 06:44:53.618734552 +0000
-@@ -196,15 +196,18 @@
- len = (size_t)(p - buf);
- s = buf;
-
-- const char *first_invalid_escape;
-- v = _PyUnicode_DecodeUnicodeEscapeInternal(s, (Py_ssize_t)len, NULL, NULL, &first_invalid_escape);
-+ int first_invalid_escape_char;
-+ const char *first_invalid_escape_ptr;
-+ v = _PyUnicode_DecodeUnicodeEscapeInternal2(s, (Py_ssize_t)len, NULL, NULL,
-+ &first_invalid_escape_char,
-+ &first_invalid_escape_ptr);
-
- // HACK: later we can simply pass the line no, since we don't preserve the tokens
- // when we are decoding the string but we preserve the line numbers.
-- if (v != NULL && first_invalid_escape != NULL && t != NULL) {
-- if (warn_invalid_escape_sequence(parser, s, first_invalid_escape, t) < 0) {
-- /* We have not decref u before because first_invalid_escape points
-- inside u. */
-+ if (v != NULL && first_invalid_escape_ptr != NULL && t != NULL) {
-+ if (warn_invalid_escape_sequence(parser, s, first_invalid_escape_ptr, t) < 0) {
-+ /* We have not decref u before because first_invalid_escape_ptr
-+ points inside u. */
- Py_XDECREF(u);
- Py_DECREF(v);
- return NULL;
-@@ -217,14 +220,17 @@
- static PyObject *
- decode_bytes_with_escapes(Parser *p, const char *s, Py_ssize_t len, Token *t)
- {
-- const char *first_invalid_escape;
-- PyObject *result = _PyBytes_DecodeEscape(s, len, NULL, &first_invalid_escape);
-+ int first_invalid_escape_char;
-+ const char *first_invalid_escape_ptr;
-+ PyObject *result = _PyBytes_DecodeEscape2(s, len, NULL,
-+ &first_invalid_escape_char,
-+ &first_invalid_escape_ptr);
- if (result == NULL) {
- return NULL;
- }
-
-- if (first_invalid_escape != NULL) {
-- if (warn_invalid_escape_sequence(p, s, first_invalid_escape, t) < 0) {
-+ if (first_invalid_escape_ptr != NULL) {
-+ if (warn_invalid_escape_sequence(p, s, first_invalid_escape_ptr, t) < 0) {
- Py_DECREF(result);
- return NULL;
- }
diff --git a/Python-3.14.0b1.tar.xz b/Python-3.14.0b1.tar.xz
deleted file mode 100644
index 06eecfa..0000000
--- a/Python-3.14.0b1.tar.xz
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:2ddd30a77c9f62e065ce648664a254b9b0c011bcdaa8c1c2787087e644cbeb39
-size 23358200
diff --git a/Python-3.14.0b1.tar.xz.sigstore b/Python-3.14.0b1.tar.xz.sigstore
deleted file mode 100644
index 980ba6b..0000000
--- a/Python-3.14.0b1.tar.xz.sigstore
+++ /dev/null
@@ -1 +0,0 @@
-{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICzTCCAlSgAwIBAgIULIy4li9CnyoD5VMYqVRBX2xhl6YwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUwNTA3MTYwMzMzWhcNMjUwNTA3MTYxMzMzWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0JmJhID7cDpz+w6ZeMYNR449Q09ObTq/rJoA8ZEElRyZ3PMOtxR2ddPssyVyssw08b+petEPGdB0JJPO3WEnlKOCAXMwggFvMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUGQo//6O9UwWERnXDGRKGEoQUbu0wHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHQYDVR0RAQH/BBMwEYEPaHVnb0BweXRob24ub3JnMCwGCisGAQQBg78wAQEEHmh0dHBzOi8vZ2l0aHViLmNvbS9sb2dpbi9vYXV0aDAuBgorBgEEAYO/MAEIBCAMHmh0dHBzOi8vZ2l0aHViLmNvbS9sb2dpbi9vYXV0aDCBigYKKwYBBAHWeQIEAgR8BHoAeAB2AN09MGrGxxEyYxkeHJlnNwKiSl643jyt/4eKcoAvKe6OAAABlqt88AUAAAQDAEcwRQIhAInVh3hc5tWxnOQJ5h7UJrc5APbRKH8LJqAxkOV+WKm0AiBGJm7a5cYa/zbL5Luuv9tjz8KHnWbROq6oKklEHKGvZjAKBggqhkjOPQQDAwNnADBkAjBtvTe9/f6rAve+EkBvvIop4WNK5iMcokC8IgzjxL6wriEBnFYdWYSwK7VBR2cH/ZECMAyKRlLPH9eUprwyKQUdRlTo0Yy8vrHwvnPCYDSy3haOb6o63L6aBc3a3+ZFL3JN8w=="}, "tlogEntries": [{"logIndex": "207983201", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1746633814", "inclusionPromise": {"signedEntryTimestamp": "MEYCIQDJuNzTYOUa0MGipv/REIMeMqMDDKZD7kC7VFMz9Ti4MQIhAI80PJYQgmc4IVvjyaOuoII3FWAcpXMAFxDwWIuK9cCW"}, "inclusionProof": {"logIndex": "86078939", "rootHash": "w3YK957NYJEEdmCkJePI4YPkL/m/o3MzbbnwWWhs7GA=", "treeSize": "86078940", "hashes": ["CBhgCT1rFez/Jf74ZwQ61/iJi+GdFNlGCXP8UBJxoB4=", "DpoDp5RYO3Q9T5lacpgLmaHF2bn+FkquEGFozf+sp1Q=", "2TglKxclAzNtphRi2WpqJF5uopsc4Iuu9Z71MpI9v4o=", "RPllLfj9XtJJgiVxHlAL6ebrSaxG+KeQXTLR4Cm8XQo=", "pf8d3Uj/L5VdDspWOfvrpwpDewiwud0CgEhkiG5MKkQ=", "kxK8IY0R+juQTVgVA5V+1SBt2dxu46s7J69sMRfNyn4=", "cjIv9wp+qUQ2SskcyJj01uOcSf/AthrVrFWD3YRhRFA=", "JOXEdAzR1hHM95VAQqRSOvJ7fA/w50P0X9a/WzIuhdc=", "YkX6Zh7rNaOAk3CNse8gzKpbsS+KDU79Fw1cGoFJILE=", "tvDDknRU/Rmet2xJVgoUiHqZA5/dG20d2t0zsoSIpRw=", "1SRCIie0eK46oBmaYPSw8Zuo3poDMoEhwGV+1UGlkGo=", "fZPSgZk/M4toaT6mV3CvNCRz647SBlRiOzrdRNQw70A=", "ZFYJDX8rdSh0CP8oZVy/Ik2B+hMkbZEF46EgoAFxDZ4=", "++1LMuz3tIdW1/pfEfhPfXC4ot1AwDAXDcPyfibzGyc=", "7v8qPHNDLerpduaMx06eb/MwgoQwczTn/cYGKX/9wZ4="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n86078940\nw3YK957NYJEEdmCkJePI4YPkL/m/o3MzbbnwWWhs7GA=\n\n\u2014 rekor.sigstore.dev wNI9ajBFAiBFm3XirGA9d16WEyelP3qBi1diHR2aD6H/1qfpU/GKjQIhAMuUjS7iJZNNLMp1Aj8gzrI8IfIGPzpzjW5wdOsYQuPY\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiIyZGRkMzBhNzdjOWY2MmUwNjVjZTY0ODY2NGEyNTRiOWIwYzAxMWJjZGFhOGMxYzI3ODcwODdlNjQ0Y2JlYjM5In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FWUNJUUMyV2hQWE9HY2FkVmk5a0lYUWIyMVBJYTJDcWIvOVJvVzhTRHNBUnA2cGhBSWhBUDJNeGxoNERBY0gyalRBRXYvK0dmM3dySkRWZXBBZlJuSytTSmxyU21DbyIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjZWRU5EUVd4VFowRjNTVUpCWjBsVlRFbDVOR3hwT1VOdWVXOUVOVlpOV1hGV1VrSllNbmhvYkRaWmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZkMDVVUVROTlZGbDNUWHBOZWxkb1kwNU5hbFYzVGxSQk0wMVVXWGhOZWsxNlYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVV3U20xS2FFbEVOMk5FY0hvcmR6WmFaVTFaVGxJME5EbFJNRGxQWWxSeEwzSktiMEVLT0ZwRlJXeFNlVm96VUUxUGRIaFNNbVJrVUhOemVWWjVjM04zTURoaUszQmxkRVZRUjJSQ01FcEtVRTh6VjBWdWJFdFBRMEZZVFhkblowWjJUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZIVVc4dkNpODJUemxWZDFkRlVtNVlSRWRTUzBkRmIxRlZZblV3ZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoUldVUldVakJTUVZGSUwwSkNUWGRGV1VWUVlVaFdibUl3UW5kbFdGSnZZakkwZFdJelNtNU5RM2RIUTJselIwRlJVVUpuTnpoM1FWRkZSUXBJYldnd1pFaENlazlwT0haYU1td3dZVWhXYVV4dFRuWmlVemx6WWpKa2NHSnBPWFpaV0ZZd1lVUkJkVUpuYjNKQ1owVkZRVmxQTDAxQlJVbENRMEZOQ2todGFEQmtTRUo2VDJrNGRsb3liREJoU0ZacFRHMU9kbUpUT1hOaU1tUndZbWs1ZGxsWVZqQmhSRU5DYVdkWlMwdDNXVUpDUVVoWFpWRkpSVUZuVWpnS1FraHZRV1ZCUWpKQlRqQTVUVWR5UjNoNFJYbFplR3RsU0Vwc2JrNTNTMmxUYkRZME0ycDVkQzgwWlV0amIwRjJTMlUyVDBGQlFVSnNjWFE0T0VGVlFRcEJRVkZFUVVWamQxSlJTV2hCU1c1V2FETm9ZelYwVjNodVQxRktOV2czVlVweVl6VkJVR0pTUzBnNFRFcHhRWGhyVDFZclYwdHRNRUZwUWtkS2JUZGhDalZqV1dFdmVtSk1OVXgxZFhZNWRHcDZPRXRJYmxkaVVrOXhObTlMYTJ4RlNFdEhkbHBxUVV0Q1oyZHhhR3RxVDFCUlVVUkJkMDV1UVVSQ2EwRnFRblFLZGxSbE9TOW1ObkpCZG1VclJXdENkblpKYjNBMFYwNUxOV2xOWTI5clF6aEpaM3BxZUV3MmQzSnBSVUp1Umxsa1YxbFRkMHMzVmtKU01tTklMMXBGUXdwTlFYbExVbXhNVUVnNVpWVndjbmQ1UzFGVlpGSnNWRzh3V1hrNGRuSklkM1p1VUVOWlJGTjVNMmhoVDJJMmJ6WXpURFpoUW1NellUTXJXa1pNTTBwT0NqaDNQVDBLTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUW89In19fX0="}]}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "Ld0wp3yfYuBlzmSGZKJUubDAEbzaqMHCeHCH5kTL6zk="}, "signature": "MEYCIQC2WhPXOGcadVi9kIXQb21PIa2Cqb/9RoW8SDsARp6phAIhAP2Mxlh4DAcH2jTAEv/+Gf3wrJDVepAfRnK+SJlrSmCo"}}
diff --git a/Python-3.14.0b2.tar.xz b/Python-3.14.0b2.tar.xz
new file mode 100644
index 0000000..3dffd23
--- /dev/null
+++ b/Python-3.14.0b2.tar.xz
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7ac9e84844bbc0a5a8f1f79a37a68b3b8caf2a58b4aa5999c49227cb36e70ea6
+size 23579860
diff --git a/Python-3.14.0b2.tar.xz.sigstore b/Python-3.14.0b2.tar.xz.sigstore
new file mode 100644
index 0000000..8048698
--- /dev/null
+++ b/Python-3.14.0b2.tar.xz.sigstore
@@ -0,0 +1 @@
+{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICzzCCAlWgAwIBAgIUChCDgQHRA1Igh/Ojbrpft+lgXo0wCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUwNTI2MTg1MjQ2WhcNMjUwNTI2MTkwMjQ2WjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECYjq5SRuvoZAvtJJ46ssKwhHC3HccF4i89/Q+yVu7kRlvttqzyjIgGeGI9WktRWOg78H0sIyvrEPScz7oHDVoaOCAXQwggFwMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUkCdI16aHO1xp5qoJifJvbKtEQKkwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHQYDVR0RAQH/BBMwEYEPaHVnb0BweXRob24ub3JnMCwGCisGAQQBg78wAQEEHmh0dHBzOi8vZ2l0aHViLmNvbS9sb2dpbi9vYXV0aDAuBgorBgEEAYO/MAEIBCAMHmh0dHBzOi8vZ2l0aHViLmNvbS9sb2dpbi9vYXV0aDCBiwYKKwYBBAHWeQIEAgR9BHsAeQB3AN09MGrGxxEyYxkeHJlnNwKiSl643jyt/4eKcoAvKe6OAAABlw3wr2IAAAQDAEgwRgIhAJdMsBp/pjt043ZGHTzWw0gKmESRde7hNMQAb01FgjLIAiEA1T1YubIaj37yqL2pr/U12BLz9AraMLX2kSq9hw/Qg3swCgYIKoZIzj0EAwMDaAAwZQIxAIJo6hW9immJWSAGq0HPgKR+1b6KlIyJFosJp0ZocowP6VRr/OwQiuEXSRLwSLdI6gIwPP9ftNP5ikQCEhH6HDonHHb9HnHr/oAlYM+ivbRH+0x6HkYz8K1SH60Emy3sHBxT"}, "tlogEntries": [{"logIndex": "220085169", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1748285567", "inclusionPromise": {"signedEntryTimestamp": "MEUCIQCyGbx3XopZRmq6mmrCkhoQJvuRqR62giVmWtPvosANigIger0MkeXASzno5NKaUJwaTXlh4abtGBPsBsCDDmTV/38="}, "inclusionProof": {"logIndex": "98180907", "rootHash": "llBJk8Br31u8BNoIfOK++L8lwcRZXa0BM5VW7xu6HCE=", "treeSize": "98180908", "hashes": ["42WGfIQDj3m2U/fVjB7Kyjv8Yf1A1/k7HgcVf667qN8=", "cFUMpcTRO5yJiqUSGH0W+rx8e6FmwwwQMYk9HXcMF50=", "5cl6PeGOxk8ylkXyrKi8eGCyPTUAl8vlR0mhpWokrSY=", "3pI6V71WkxutIHjM0WkuBRhQdfcH4rIgtz/Eg3NETUo=", "VO/ynlJFyNcbFD02zmJvM2Mm5UzEqpS9xgM8dZx4JF0=", "r2VV9zsLHKN1LyQmhqsyIMIF3MZsuxC3Geh/oidHzjk=", "qFks5wqXYAN2/6NiWw9BmDqOK85OYWocXHq2CabxWUg=", "1CSYp0Uxm7lUrq9j7DuYJ9ShY9P8tJVIf9mb9ubOsBs=", "lCWSLVZukVJwp1i7tSNta774H8uCYwvFZoiU+IG48HA=", "TN3oG+6KnCkr9fBEaBUHHyghBPa5AYM2QmDIhyd7PP8=", "yeJj3pYQkMFCH/OfTlCSZvGxI+sDQOuuH20/lxLt7gs=", "tp5gt2QgBd2gmRM5Vhz5vhEC//9CyS41WCVQRpJm/dk=", "+jKVBl9RI6O7U6XYJ+AwciNKMCW+hkgk3R4JtuB+FJA=", "h5VTNNCORtYrwvf9h5wlAx+k3+9SY5/VIETuNnly6Xk=", "++1LMuz3tIdW1/pfEfhPfXC4ot1AwDAXDcPyfibzGyc=", "7v8qPHNDLerpduaMx06eb/MwgoQwczTn/cYGKX/9wZ4="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n98180908\nllBJk8Br31u8BNoIfOK++L8lwcRZXa0BM5VW7xu6HCE=\n\n\u2014 rekor.sigstore.dev wNI9ajBFAiEA2i4Ql6CVpt7gnMTP5tWrN6p+mx3YIs8VZCuZ9nAr2csCIBGzsWrMsQCjhbOwLP6ZgHRCkv/eHf1lzgG/B8EmO6ck\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI3YWM5ZTg0ODQ0YmJjMGE1YThmMWY3OWEzN2E2OGIzYjhjYWYyYTU4YjRhYTU5OTljNDkyMjdjYjM2ZTcwZWE2In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJUURzVmF2REhzWnRkc3cyRk9jZGVvS2g0QWdxSlBkVHVaKy9WdjNBdWdIQ3dnSWdPT3dQK3B3dzFoaHlwUkE5QlYrS1c5bHJIeHNhWWJmbEhjZGgyTUd0ODZzPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjZla05EUVd4WFowRjNTVUpCWjBsVlEyaERSR2RSU0ZKQk1VbG5hQzlQYW1KeWNHWjBLMnhuV0c4d2QwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZkMDVVU1RKTlZHY3hUV3BSTWxkb1kwNU5hbFYzVGxSSk1rMVVhM2ROYWxFeVYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZEV1dweE5WTlNkWFp2V2tGMmRFcEtORFp6YzB0M2FFaERNMGhqWTBZMGFUZzVMMUVLSzNsV2RUZHJVbXgyZEhSeGVubHFTV2RIWlVkSk9WZHJkRkpYVDJjM09FZ3djMGw1ZG5KRlVGTmplamR2U0VSV2IyRlBRMEZZVVhkblowWjNUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZyUTJSSkNqRTJZVWhQTVhod05YRnZTbWxtU25aaVMzUkZVVXRyZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoUldVUldVakJTUVZGSUwwSkNUWGRGV1VWUVlVaFdibUl3UW5kbFdGSnZZakkwZFdJelNtNU5RM2RIUTJselIwRlJVVUpuTnpoM1FWRkZSUXBJYldnd1pFaENlazlwT0haYU1td3dZVWhXYVV4dFRuWmlVemx6WWpKa2NHSnBPWFpaV0ZZd1lVUkJkVUpuYjNKQ1owVkZRVmxQTDAxQlJVbENRMEZOQ2todGFEQmtTRUo2VDJrNGRsb3liREJoU0ZacFRHMU9kbUpUT1hOaU1tUndZbWs1ZGxsWVZqQmhSRU5DYVhkWlMwdDNXVUpDUVVoWFpWRkpSVUZuVWprS1FraHpRV1ZSUWpOQlRqQTVUVWR5UjNoNFJYbFplR3RsU0Vwc2JrNTNTMmxUYkRZME0ycDVkQzgwWlV0amIwRjJTMlUyVDBGQlFVSnNkek4zY2pKSlFRcEJRVkZFUVVWbmQxSm5TV2hCU21STmMwSndMM0JxZERBME0xcEhTRlI2VjNjd1owdHRSVk5TWkdVM2FFNU5VVUZpTURGR1oycE1TVUZwUlVFeFZERlpDblZpU1dGcU16ZDVjVXd5Y0hJdlZURXlRa3g2T1VGeVlVMU1XREpyVTNFNWFIY3ZVV2N6YzNkRFoxbEpTMjlhU1hwcU1FVkJkMDFFWVVGQmQxcFJTWGdLUVVsS2J6Wm9WemxwYlcxS1YxTkJSM0V3U0ZCblMxSXJNV0kyUzJ4SmVVcEdiM05LY0RCYWIyTnZkMUEyVmxKeUwwOTNVV2wxUlZoVFVreDNVMHhrU1FvMlowbDNVRkE1Wm5ST1VEVnBhMUZEUldoSU5raEViMjVJU0dJNVNHNUljaTl2UVd4WlRTdHBkbUpTU0Nzd2VEWklhMWw2T0VzeFUwZzJNRVZ0ZVROekNraENlRlFLTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUW89In19fX0="}]}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "esnoSES7wKWo8feaN6aLO4yvKli0qlmZxJInyzbnDqY="}, "signature": "MEUCIQDsVavDHsZtdsw2FOcdeoKh4AgqJPdTuZ+/Vv3AugHCwgIgOOwP+pww1hhypRA9BV+KW9lrHxsaYbflHcdh2MGt86s="}}
diff --git a/bpo-31046_ensurepip_honours_prefix.patch b/bpo-31046_ensurepip_honours_prefix.patch
index f45e929..ff87448 100644
--- a/bpo-31046_ensurepip_honours_prefix.patch
+++ b/bpo-31046_ensurepip_honours_prefix.patch
@@ -13,11 +13,9 @@ Co-Authored-By: Xavier de Gaye
5 files changed, 37 insertions(+), 9 deletions(-)
create mode 100644 Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst
-Index: Python-3.14.0b1/Doc/library/ensurepip.rst
-===================================================================
---- Python-3.14.0b1.orig/Doc/library/ensurepip.rst 2025-05-12 10:59:00.152603111 +0000
-+++ Python-3.14.0b1/Doc/library/ensurepip.rst 2025-05-12 10:59:06.662087113 +0000
-@@ -61,7 +61,11 @@
+--- a/Doc/library/ensurepip.rst
++++ b/Doc/library/ensurepip.rst
+@@ -61,7 +61,11 @@ is at least as recent as the one availab
By default, ``pip`` is installed into the current virtual environment
(if one is active) or into the system site packages (if there is no
active virtual environment). The installation location can be controlled
@@ -30,7 +28,7 @@ Index: Python-3.14.0b1/Doc/library/ensurepip.rst
.. option:: --root
-@@ -102,7 +106,7 @@
+@@ -102,7 +106,7 @@ Module API
Returns a string specifying the available version of pip that will be
installed when bootstrapping an environment.
@@ -39,7 +37,7 @@ Index: Python-3.14.0b1/Doc/library/ensurepip.rst
altinstall=False, default_pip=False, \
verbosity=0)
-@@ -112,6 +116,8 @@
+@@ -112,6 +116,8 @@ Module API
If *root* is ``None``, then installation uses the default install location
for the current environment.
@@ -48,7 +46,7 @@ Index: Python-3.14.0b1/Doc/library/ensurepip.rst
*upgrade* indicates whether or not to upgrade an existing installation
of an earlier version of ``pip`` to the available version.
-@@ -132,6 +138,8 @@
+@@ -132,6 +138,8 @@ Module API
*verbosity* controls the level of output to :data:`sys.stdout` from the
bootstrapping operation.
@@ -57,11 +55,9 @@ Index: Python-3.14.0b1/Doc/library/ensurepip.rst
.. audit-event:: ensurepip.bootstrap root ensurepip.bootstrap
.. note::
-Index: Python-3.14.0b1/Lib/ensurepip/__init__.py
-===================================================================
---- Python-3.14.0b1.orig/Lib/ensurepip/__init__.py 2025-05-12 10:59:00.152603111 +0000
-+++ Python-3.14.0b1/Lib/ensurepip/__init__.py 2025-05-12 10:59:06.662530889 +0000
-@@ -106,27 +106,27 @@
+--- a/Lib/ensurepip/__init__.py
++++ b/Lib/ensurepip/__init__.py
+@@ -106,27 +106,27 @@ def _disable_pip_configuration_settings(
os.environ['PIP_CONFIG_FILE'] = os.devnull
@@ -94,7 +90,7 @@ Index: Python-3.14.0b1/Lib/ensurepip/__init__.py
Note that calling this function will alter both sys.path and os.environ.
"""
-@@ -162,6 +162,8 @@
+@@ -162,6 +162,8 @@ def _bootstrap(*, root=None, upgrade=Fal
args = ["install", "--no-cache-dir", "--no-index", "--find-links", tmpdir]
if root:
args += ["--root", root]
@@ -103,7 +99,7 @@ Index: Python-3.14.0b1/Lib/ensurepip/__init__.py
if upgrade:
args += ["--upgrade"]
if user:
-@@ -238,6 +240,11 @@
+@@ -238,6 +240,11 @@ def _main(argv=None):
help="Install everything relative to this alternate root directory.",
)
parser.add_argument(
@@ -115,7 +111,7 @@ Index: Python-3.14.0b1/Lib/ensurepip/__init__.py
"--altinstall",
action="store_true",
default=False,
-@@ -256,6 +263,7 @@
+@@ -256,6 +263,7 @@ def _main(argv=None):
return _bootstrap(
root=args.root,
@@ -123,11 +119,9 @@ Index: Python-3.14.0b1/Lib/ensurepip/__init__.py
upgrade=args.upgrade,
user=args.user,
verbosity=args.verbosity,
-Index: Python-3.14.0b1/Lib/test/test_ensurepip.py
-===================================================================
---- Python-3.14.0b1.orig/Lib/test/test_ensurepip.py 2025-05-12 10:59:00.152603111 +0000
-+++ Python-3.14.0b1/Lib/test/test_ensurepip.py 2025-05-12 10:59:06.662803061 +0000
-@@ -100,6 +100,17 @@
+--- a/Lib/test/test_ensurepip.py
++++ b/Lib/test/test_ensurepip.py
+@@ -100,6 +100,17 @@ class TestBootstrap(EnsurepipMixin, unit
unittest.mock.ANY,
)
@@ -145,11 +139,9 @@ Index: Python-3.14.0b1/Lib/test/test_ensurepip.py
def test_bootstrapping_with_user(self):
ensurepip.bootstrap(user=True)
-Index: Python-3.14.0b1/Makefile.pre.in
-===================================================================
---- Python-3.14.0b1.orig/Makefile.pre.in 2025-05-12 10:59:05.200858322 +0000
-+++ Python-3.14.0b1/Makefile.pre.in 2025-05-12 10:59:06.663191503 +0000
-@@ -2335,7 +2335,7 @@
+--- a/Makefile.pre.in
++++ b/Makefile.pre.in
+@@ -2341,7 +2341,7 @@ install: @FRAMEWORKINSTALLFIRST@ @INSTAL
install|*) ensurepip="" ;; \
esac; \
$(RUNSHARED) $(PYTHON_FOR_BUILD) -m ensurepip \
@@ -158,7 +150,7 @@ Index: Python-3.14.0b1/Makefile.pre.in
fi
.PHONY: altinstall
-@@ -2346,7 +2346,7 @@
+@@ -2352,7 +2352,7 @@ altinstall: commoninstall
install|*) ensurepip="--altinstall" ;; \
esac; \
$(RUNSHARED) $(PYTHON_FOR_BUILD) -m ensurepip \
@@ -167,9 +159,7 @@ Index: Python-3.14.0b1/Makefile.pre.in
fi
.PHONY: commoninstall
-Index: Python-3.14.0b1/Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ Python-3.14.0b1/Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst 2025-05-12 10:59:06.663664734 +0000
+--- /dev/null
++++ b/Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst
@@ -0,0 +1 @@
+A directory prefix can now be specified when using :mod:`ensurepip`.
diff --git a/python-3.3.0b1-fix_date_time_compiler.patch b/python-3.3.0b1-fix_date_time_compiler.patch
index c93792b..b0812c0 100644
--- a/python-3.3.0b1-fix_date_time_compiler.patch
+++ b/python-3.3.0b1-fix_date_time_compiler.patch
@@ -2,11 +2,9 @@
Makefile.pre.in | 5 +++++
1 file changed, 5 insertions(+)
-Index: Python-3.14.0b1/Makefile.pre.in
-===================================================================
---- Python-3.14.0b1.orig/Makefile.pre.in 2025-05-12 10:57:03.566724942 +0000
-+++ Python-3.14.0b1/Makefile.pre.in 2025-05-12 10:57:41.504010702 +0000
-@@ -1874,6 +1874,11 @@
+--- a/Makefile.pre.in
++++ b/Makefile.pre.in
+@@ -1880,6 +1880,11 @@ Modules/getbuildinfo.o: $(PARSER_OBJS) \
-DGITBRANCH="\"`LC_ALL=C $(GITBRANCH)`\"" \
-o $@ $(srcdir)/Modules/getbuildinfo.c
diff --git a/python-3.3.0b1-localpath.patch b/python-3.3.0b1-localpath.patch
index 00d6dba..3dffb30 100644
--- a/python-3.3.0b1-localpath.patch
+++ b/python-3.3.0b1-localpath.patch
@@ -1,9 +1,11 @@
-Index: Python-3.13.0a3/Lib/site.py
-===================================================================
---- Python-3.13.0a3.orig/Lib/site.py
-+++ Python-3.13.0a3/Lib/site.py
-@@ -77,7 +77,7 @@ import io
- import stat
+---
+ Lib/site.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/Lib/site.py
++++ b/Lib/site.py
+@@ -78,7 +78,7 @@ import stat
+ import errno
# Prefixes for site-packages; add additional prefixes like /usr/local here
-PREFIXES = [sys.prefix, sys.exec_prefix]
diff --git a/python314.changes b/python314.changes
index f408ad0..19058ad 100644
--- a/python314.changes
+++ b/python314.changes
@@ -1,3 +1,221 @@
+-------------------------------------------------------------------
+Thu May 29 11:42:15 UTC 2025 - Matej Cepl
+
+- Update to 3.14.0~b2:
+ - Tools/Demos
+ - gh-134215: REPL import autocomplete only suggests private
+ modules when explicitly specified.
+ - Tests
+ - gh-133744: Fix multiprocessing interrupt test. Add an event
+ to synchronize the parent process with the child process:
+ wait until the child process starts sleeping. Patch by
+ Victor Stinner.
+ - gh-133682: Fixed test case
+ test.test_annotationlib.TestStringFormat.test_displays
+ which ensures proper handling of complex data structures
+ (lists, sets, dictionaries, and tuples) in string
+ annotations.
+ - gh-133639: Fix
+ TestPyReplAutoindent.test_auto_indent_default() doesn’t run
+ input_code.
+ - Security
+ - gh-133767: Fix use-after-free in the “unicode-escape”
+ decoder with a non-“strict” error handler (CVE-2025-4516
+ bsc#1243273).
+ - gh-128840: Short-circuit the processing of long IPv6
+ addresses early in ipaddress to prevent excessive memory
+ consumption and a minor denial-of-service.
+ - Library
+ - gh-132710: If possible, ensure that uuid.getnode()
+ returns the same result even across different
+ processes. Previously, the result was constant only within
+ the same process. Patch by Bénédikt Tran.
+ - gh-80334: multiprocessing.freeze_support() now checks for
+ work on any “spawn” start method platform rather than only
+ on Windows.
+ - gh-134582: Fix tokenize.untokenize() round-trip errors
+ related to t-strings braces escaping
+ - gh-134546: Ensure pdb remote debugging script is readable
+ by remote Python process.
+ - gh-134451: Converted asyncio.tools.CycleFoundException from
+ dataclass to a regular exception type.
+ - gh-114177: Fix asyncio to not close subprocess pipes which
+ would otherwise error out when the event loop is already
+ closed.
+ - gh-90871: Fixed an off by one error concerning the backlog
+ parameter in create_unix_server(). Contributed by Christian
+ Harries.
+ - gh-134323: Fix the threading.RLock.locked() method.
+ - gh-86802: Fixed asyncio memory leak in cancelled
+ shield tasks. For shielded tasks where the shield was
+ cancelled, log potential exceptions through the exception
+ handler. Contributed by Christian Harries.
+ - gh-134209: curses: The curses.window.instr() and
+ curses.window.getstr() methods now allocate their internal
+ buffer on the heap instead of the stack; in addition, the
+ max buffer size is increased from 1023 to 2047.
+ - gh-134235: Updated tab completion on REPL to include
+ builtin modules. Contributed by Tom Wang, Hunter Young
+ - gh-134152: Fixed UnboundLocalError that could occur during
+ email header parsing if an expected trailing delimiter is
+ missing in some contexts.
+ - gh-134168: http.server: Fix IPv6 address binding and
+ --directory handling when using HTTPS.
+ - gh-62184: Remove import of C implementation of io.FileIO
+ from Python implementation which has its own implementation
+ - gh-133982: Emit RuntimeWarning in the Python implementation
+ of io when the file-like object is not closed explicitly in
+ the presence of multiple I/O layers.
+ - gh-133890: The tarfile module now handles
+ UnicodeEncodeError in the same way as OSError when cannot
+ extract a member.
+ - gh-134097: Fix interaction of the new REPL and -X
+ showrefcount command line option.
+ - gh-133889: The generated directory listing page in
+ http.server.SimpleHTTPRequestHandler now only shows the
+ decoded path component of the requested URL, and not the
+ query and fragment.
+ - gh-134098: Fix handling paths that end with
+ a percent-encoded slash (%2f or %2F) in
+ http.server.SimpleHTTPRequestHandler.
+ - gh-132124: On POSIX-compliant systems,
+ multiprocessing.util.get_temp_dir() now ignores TMPDIR
+ (and similar environment variables) if the path length of
+ AF_UNIX socket files exceeds the platform-specific maximum
+ length when using the forkserver start method. Patch by
+ Bénédikt Tran.
+ - gh-134062: ipaddress: fix collisions in __hash__() for
+ IPv4Network and IPv6Network objects.
+ - gh-133970: Make string.templatelib.Template and
+ string.templatelib.Interpolation generic.
+ - gh-71253: Raise ValueError in open() if opener returns a
+ negative file-descriptor in the Python implementation of io
+ to match the C implementation.
+ - gh-133960: Simplify and improve
+ typing.evaluate_forward_ref(). It now no longer raises
+ errors on certain invalid types. In several situations,
+ it is now able to evaluate forward references that were
+ previously unsupported.
+ - gh-133925: Make the private class typing._UnionGenericAlias
+ hashable.
+ - gh-133653: Fix argparse.ArgumentParser with the
+ formatter_class argument. Fix TypeError when
+ formatter_class is a custom subclass of HelpFormatter. Fix
+ TypeError when formatter_class is not a subclass of
+ HelpFormatter and non-standard prefix_char is used. Fix
+ support of colorizing when formatter_class is not a
+ subclass of HelpFormatter.
+ - gh-132641: Fixed a race in functools.lru_cache() under
+ free-threading.
+ - gh-133783: Fix bug with applying copy.replace() to ast
+ objects. Attributes that default to None were incorrectly
+ treated as required for manually created AST nodes.
+ - gh-133684: Fix bug where annotationlib.get_annotations()
+ would return the wrong result for certain classes that are
+ part of a class hierarchy where from __future__ import
+ annotations is used.
+ - gh-77057: Fix handling of invalid markup declarations in
+ html.parser.HTMLParser.
+ - gh-130328: Speedup pasting in PyREPL on Windows in a legacy
+ console. Patch by Chris Eibl.
+ - gh-133701: Fix bug where typing.TypedDict classes defined
+ under from __future__ import annotations and inheriting
+ from another TypedDict had an incorrect __annotations__
+ attribute.
+ - gh-133581: Improve unparsing of t-strings in ast.unparse()
+ and from __future__ import annotations. Empty t-strings now
+ round-trip correctly and formatting in interpolations is
+ preserved. Patch by Jelle Zijlstra.
+ - gh-133551: Support t-strings (PEP 750) in
+ annotationlib. Patch by Jelle Zijlstra.
+ - gh-133439: Fix dot commands with trailing spaces are
+ mistaken for multi-line SQL statements in the sqlite3
+ command-line interface.
+ - gh-132493: Avoid accessing __annotations__ unnecessarily in
+ inspect.signature().
+ - gh-132876: ldexp() on Windows doesn’t round subnormal
+ results before Windows 11, but should. Python’s
+ math.ldexp() wrapper now does round them, so results may
+ change slightly, in rare cases of very small results, on
+ Windows versions before 11.
+ - gh-133009: xml.etree.ElementTree: Fix a crash in
+ Element.__deepcopy__ when the element is concurrently
+ mutated. Patch by Bénédikt Tran.
+ - gh-91555: Ignore log messages generated during handling of
+ log messages, to avoid deadlock or infinite recursion.
+ - gh-125028: functools.Placeholder cannot be passed to
+ functools.partial() as a keyword argument.
+ - gh-62824: Fix aliases for iso8859_8 encoding. Patch by Dave
+ Goncalves.
+ - gh-86155: html.parser.HTMLParser.close() no longer loses
+ data when the