https://github.com/python/cpython/commit/5d03b24827e133874660082413906256b909e522
commit: 5d03b24827e133874660082413906256b909e522
branch: 3.13
author: Hai Zhu <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-05-23T17:20:16+05:30
summary:
[3.13] gh-148450: abc.register needs to update type_version when tp_flags is
changed (GH-148623) (#150307)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2026-05-23-09-55-50.gh-issue-148450.2MEVqH.rst
M Lib/test/test_type_cache.py
M Objects/typeobject.c
diff --git a/Lib/test/test_type_cache.py b/Lib/test/test_type_cache.py
index 8e2bb0c238257b3..a6a6e8cbdc1053b 100644
--- a/Lib/test/test_type_cache.py
+++ b/Lib/test/test_type_cache.py
@@ -1,4 +1,5 @@
""" Tests for the internal type cache in CPython. """
+import collections.abc
import unittest
import dis
from test import support
@@ -108,6 +109,25 @@ class HolderSub(Holder):
Holder.set_value()
HolderSub.value
+ def test_abc_register_invalidates_subclass_versions(self):
+ class Parent:
+ pass
+
+ class Child(Parent):
+ pass
+
+ type_assign_version(Parent)
+ type_assign_version(Child)
+ parent_version = type_get_version(Parent)
+ child_version = type_get_version(Child)
+ if parent_version == 0 or child_version == 0:
+ self.skipTest("Could not assign valid type versions")
+
+ collections.abc.Mapping.register(Parent)
+
+ self.assertEqual(type_get_version(Parent), 0)
+ self.assertEqual(type_get_version(Child), 0)
+
@support.cpython_only
@requires_specialization
class TypeCacheWithSpecializationTests(unittest.TestCase):
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-23-09-55-50.gh-issue-148450.2MEVqH.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-23-09-55-50.gh-issue-148450.2MEVqH.rst
new file mode 100644
index 000000000000000..2a7d0d9bb3a7f7e
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-23-09-55-50.gh-issue-148450.2MEVqH.rst
@@ -0,0 +1 @@
+Fix ``abc.register()`` so it invalidates type version tags for registered
classes.
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 51d1ce573d12e13..7ae4cce02cf6834 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -5398,6 +5398,15 @@ void
_PyType_SetFlagsRecursive(PyTypeObject *self, unsigned long mask, unsigned
long flags)
{
BEGIN_TYPE_LOCK();
+ /* Ideally, changing flags and invalidating the old version tag would
+ happen in one step. For this backport, keep it simple and invalidate
+ first while holding TYPE_LOCK. Immutable types are skipped because
+ set_flags_recursive() does not modify them. */
+ if (!PyType_HasFeature(self, Py_TPFLAGS_IMMUTABLETYPE) &&
+ (self->tp_flags & mask) != flags)
+ {
+ type_modified_unlocked(self);
+ }
set_flags_recursive(self, mask, flags);
END_TYPE_LOCK();
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]