""" Tests for the internal type cache in CPython. """
+import collections.abc
import dis
import unittest
import warnings
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
class TypeCacheWithSpecializationTests(unittest.TestCase):
def tearDown(self):
_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. In 3.14, invalidate first while holding TYPE_LOCK so readers
+ cannot assign a fresh tag from stale flags. Immutable types are skipped by
+ set_flags_recursive(). */
+ 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();
}