python313: 3.13.10 -> 3.13.11; python314: 3.14.1 -> 3.14.2 (#468254)

This commit is contained in:
Martin Weinelt
2025-12-06 13:10:14 +00:00
committed by GitHub
5 changed files with 4 additions and 257 deletions
@@ -1,66 +0,0 @@
From 1a75c0fb054db6910fc2b74c99911329b80e25b5 Mon Sep 17 00:00:00 2001
From: Sam Gross <colesbury@gmail.com>
Date: Thu, 4 Dec 2025 02:46:24 -0500
Subject: [PATCH] [3.13] gh-142218: Fix split table dictionary crash
(gh-142229) (gh-142245)
This fixes a regression introduced in gh-140558. The interpreter would
crash if we inserted a non `str` key into a split table that matches an
existing key.
(cherry picked from commit 547d8daf780646e2800bec598ed32085817c8606)
---
Lib/test/test_dict.py | 8 ++++++++
.../2025-12-03-11-03-35.gh-issue-142218.44Fq_J.rst | 2 ++
Objects/dictobject.c | 10 +++++++---
3 files changed, 17 insertions(+), 3 deletions(-)
create mode 100644 Misc/NEWS.d/next/Core and Builtins/2025-12-03-11-03-35.gh-issue-142218.44Fq_J.rst
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py
index 5c3889550953dd..c7b6f64b53b42f 100644
--- a/Lib/test/test_dict.py
+++ b/Lib/test/test_dict.py
@@ -1674,6 +1674,14 @@ def __eq__(self, other):
self.assertEqual(len(d), 1)
+ def test_split_table_update_with_str_subclass(self):
+ class MyStr(str): pass
+ class MyClass: pass
+ obj = MyClass()
+ obj.attr = 1
+ obj.__dict__[MyStr('attr')] = 2
+ self.assertEqual(obj.attr, 2)
+
class CAPITest(unittest.TestCase):
diff --git a/Misc/NEWS.d/next/Core and Builtins/2025-12-03-11-03-35.gh-issue-142218.44Fq_J.rst b/Misc/NEWS.d/next/Core and Builtins/2025-12-03-11-03-35.gh-issue-142218.44Fq_J.rst
new file mode 100644
index 00000000000000..a8ce0fc65267d5
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2025-12-03-11-03-35.gh-issue-142218.44Fq_J.rst
@@ -0,0 +1,2 @@
+Fix crash when inserting into a split table dictionary with a non
+:class:`str` key that matches an existing key.
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 4a88e08d1da52e..c987af31c45dd1 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -1873,10 +1873,14 @@ insertdict(PyInterpreterState *interp, PyDictObject *mp,
uint64_t new_version = _PyDict_NotifyEvent(
interp, PyDict_EVENT_MODIFIED, mp, key, value);
assert(old_value != NULL);
- assert(!_PyDict_HasSplitTable(mp));
if (DK_IS_UNICODE(mp->ma_keys)) {
- PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[ix];
- STORE_VALUE(ep, value);
+ if (_PyDict_HasSplitTable(mp)) {
+ STORE_SPLIT_VALUE(mp, ix, value);
+ }
+ else {
+ PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[ix];
+ STORE_VALUE(ep, value);
+ }
}
else {
PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[ix];
@@ -1,114 +0,0 @@
From 654e3c7435180d4aec8a2fcb16a16585cea7ab70 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Fri, 5 Dec 2025 09:08:15 +0100
Subject: [PATCH] [3.14] gh-142214: Fix two regressions in dataclasses
(GH-142223) (#142277)
gh-142214: Fix two regressions in dataclasses (GH-142223)
(cherry picked from commit 53ec7c8fc07eb6958869638a0cad70c52ad6fcf5)
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
---
Lib/dataclasses.py | 14 +++++++---
Lib/test/test_dataclasses/__init__.py | 28 +++++++++++++++++++
...-12-03-06-12-39.gh-issue-142214.appYNZ.rst | 12 ++++++++
3 files changed, 50 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/Library/2025-12-03-06-12-39.gh-issue-142214.appYNZ.rst
diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py
index fb7e1701cce0a4..c8dbb247745ab7 100644
--- a/Lib/dataclasses.py
+++ b/Lib/dataclasses.py
@@ -550,7 +550,12 @@ def __annotate__(format, /):
new_annotations = {}
for k in annotation_fields:
- new_annotations[k] = cls_annotations[k]
+ # gh-142214: The annotation may be missing in unusual dynamic cases.
+ # If so, just skip it.
+ try:
+ new_annotations[k] = cls_annotations[k]
+ except KeyError:
+ pass
if return_type is not MISSING:
if format == Format.STRING:
@@ -1398,9 +1403,10 @@ def _add_slots(cls, is_frozen, weakref_slot, defined_fields):
f.type = ann
# Fix the class reference in the __annotate__ method
- init_annotate = newcls.__init__.__annotate__
- if getattr(init_annotate, "__generated_by_dataclasses__", False):
- _update_func_cell_for__class__(init_annotate, cls, newcls)
+ init = newcls.__init__
+ if init_annotate := getattr(init, "__annotate__", None):
+ if getattr(init_annotate, "__generated_by_dataclasses__", False):
+ _update_func_cell_for__class__(init_annotate, cls, newcls)
return newcls
diff --git a/Lib/test/test_dataclasses/__init__.py b/Lib/test/test_dataclasses/__init__.py
index 513dd78c4381b4..3b335429b98500 100644
--- a/Lib/test/test_dataclasses/__init__.py
+++ b/Lib/test/test_dataclasses/__init__.py
@@ -927,6 +927,20 @@ class C:
validate_class(C)
+ def test_incomplete_annotations(self):
+ # gh-142214
+ @dataclass
+ class C:
+ "doc" # needed because otherwise we fetch the annotations at the wrong time
+ x: int
+
+ C.__annotate__ = lambda _: {}
+
+ self.assertEqual(
+ annotationlib.get_annotations(C.__init__),
+ {"return": None}
+ )
+
def test_missing_default(self):
# Test that MISSING works the same as a default not being
# specified.
@@ -2578,6 +2592,20 @@ def __init__(self, x: int) -> None:
self.assertFalse(hasattr(E.__init__.__annotate__, "__generated_by_dataclasses__"))
+ def test_slots_true_init_false(self):
+ # Test that slots=True and init=False work together and
+ # that __annotate__ is not added to __init__.
+
+ @dataclass(slots=True, init=False)
+ class F:
+ x: int
+
+ f = F()
+ f.x = 10
+ self.assertEqual(f.x, 10)
+
+ self.assertFalse(hasattr(F.__init__, "__annotate__"))
+
def test_init_false_forwardref(self):
# Test forward references in fields not required for __init__ annotations.
diff --git a/Misc/NEWS.d/next/Library/2025-12-03-06-12-39.gh-issue-142214.appYNZ.rst b/Misc/NEWS.d/next/Library/2025-12-03-06-12-39.gh-issue-142214.appYNZ.rst
new file mode 100644
index 00000000000000..b87430ec1a3d65
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-12-03-06-12-39.gh-issue-142214.appYNZ.rst
@@ -0,0 +1,12 @@
+Fix two regressions in :mod:`dataclasses` in Python 3.14.1 related to
+annotations.
+
+* An exception is no longer raised if ``slots=True`` is used and the
+ ``__init__`` method does not have an ``__annotate__`` attribute
+ (likely because ``init=False`` was used).
+
+* An exception is no longer raised if annotations are requested on the
+ ``__init__`` method and one of the fields is not present in the class
+ annotations. This can occur in certain dynamic scenarios.
+
+Patch by Jelle Zijlstra.
@@ -1,69 +0,0 @@
From 319c6a2ae1ea033d5aea09a43acbc8d451764869 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Thu, 4 Dec 2025 01:03:18 +0100
Subject: [PATCH] [3.14] gh-142218: Fix split table dictionary crash
(gh-142229) (gh-142244)
This fixes a regression introduced in gh-140558. The interpreter would
crash if we inserted a non `str` key into a split table that matches an
existing key.
(cherry picked from commit 547d8daf780646e2800bec598ed32085817c8606)
Co-authored-by: Sam Gross <colesbury@gmail.com>
---
Lib/test/test_dict.py | 8 ++++++++
.../2025-12-03-11-03-35.gh-issue-142218.44Fq_J.rst | 2 ++
Objects/dictobject.c | 10 +++++++---
3 files changed, 17 insertions(+), 3 deletions(-)
create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-12-03-11-03-35.gh-issue-142218.44Fq_J.rst
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py
index 2e6c2bbdf19409..665b3e843dd3a5 100644
--- a/Lib/test/test_dict.py
+++ b/Lib/test/test_dict.py
@@ -1621,6 +1621,14 @@ def __eq__(self, other):
self.assertEqual(len(d), 1)
+ def test_split_table_update_with_str_subclass(self):
+ class MyStr(str): pass
+ class MyClass: pass
+ obj = MyClass()
+ obj.attr = 1
+ obj.__dict__[MyStr('attr')] = 2
+ self.assertEqual(obj.attr, 2)
+
class CAPITest(unittest.TestCase):
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-03-11-03-35.gh-issue-142218.44Fq_J.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-03-11-03-35.gh-issue-142218.44Fq_J.rst
new file mode 100644
index 00000000000000..a8ce0fc65267d5
--- /dev/null
+++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-03-11-03-35.gh-issue-142218.44Fq_J.rst
@@ -0,0 +1,2 @@
+Fix crash when inserting into a split table dictionary with a non
+:class:`str` key that matches an existing key.
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 1b4640f9649569..0eb00410cf41eb 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -1863,10 +1863,14 @@ insertdict(PyInterpreterState *interp, PyDictObject *mp,
if (old_value != value) {
_PyDict_NotifyEvent(interp, PyDict_EVENT_MODIFIED, mp, key, value);
assert(old_value != NULL);
- assert(!_PyDict_HasSplitTable(mp));
if (DK_IS_UNICODE(mp->ma_keys)) {
- PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[ix];
- STORE_VALUE(ep, value);
+ if (_PyDict_HasSplitTable(mp)) {
+ STORE_SPLIT_VALUE(mp, ix, value);
+ }
+ else {
+ PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[ix];
+ STORE_VALUE(ep, value);
+ }
}
else {
PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[ix];
@@ -403,10 +403,6 @@ stdenv.mkDerivation (finalAttrs: {
# https://github.com/python/cpython/issues/142218
./${lib.versions.majorMinor version}/gh-142218.patch
]
++ optionals (version == "3.14.1") [
# https://github.com/python/cpython/issues/142214
./3.14/gh-142214.patch
]
++ optionals (stdenv.hostPlatform.isMinGW) (
let
# https://src.fedoraproject.org/rpms/mingw-python3
@@ -20,10 +20,10 @@
sourceVersion = {
major = "3";
minor = "13";
patch = "10";
patch = "11";
suffix = "";
};
hash = "sha256-vGc8BDdaGj8ICMJ7qPBBGrgRrTkKh0AxjMucYPrY/Xc=";
hash = "sha256-Fu3nu3zb+oldEbBkL6DlI/KR5khxlNU89tOzOMOhfqI=";
};
};
@@ -91,10 +91,10 @@
sourceVersion = {
major = "3";
minor = "14";
patch = "1";
patch = "2";
suffix = "";
};
hash = "sha256-jfoIsZWdnRWDihwtq3fcjY/0pVOh7QRt+svICVxtQvw=";
hash = "sha256-zlQ6uFS8JWthtx6bJ/gx/9G/1gpHnWOfi+f5dXz1c+k=";
inherit passthruFun;
};