GH-121832: Assert that the version number of static builtin types is not changed by PyType_Modified. (GH-122182)

Update datetime module and test_type_cache.py to not call PyType_Modified.
This commit is contained in:
Mark Shannon 2024-07-24 10:22:51 +01:00 committed by GitHub
parent b3b7b7d46a
commit e55b05f29e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 44 additions and 65 deletions

View file

@ -161,8 +161,8 @@ class TypeCacheWithSpecializationTests(unittest.TestCase):
self._check_specialization(load_foo_2, A, "LOAD_ATTR", should_specialize=False) self._check_specialization(load_foo_2, A, "LOAD_ATTR", should_specialize=False)
def test_class_load_attr_specialization_static_type(self): def test_class_load_attr_specialization_static_type(self):
self._assign_valid_version_or_skip(str) self.assertNotEqual(type_get_version(str), 0)
self._assign_valid_version_or_skip(bytes) self.assertNotEqual(type_get_version(bytes), 0)
def get_capitalize_1(type_): def get_capitalize_1(type_):
return type_.capitalize return type_.capitalize
@ -170,25 +170,6 @@ class TypeCacheWithSpecializationTests(unittest.TestCase):
self._check_specialization(get_capitalize_1, str, "LOAD_ATTR", should_specialize=True) self._check_specialization(get_capitalize_1, str, "LOAD_ATTR", should_specialize=True)
self.assertEqual(get_capitalize_1(str)('hello'), 'Hello') self.assertEqual(get_capitalize_1(str)('hello'), 'Hello')
self.assertEqual(get_capitalize_1(bytes)(b'hello'), b'Hello') self.assertEqual(get_capitalize_1(bytes)(b'hello'), b'Hello')
del get_capitalize_1
# Permanently overflow the static type version counter, and force str and bytes
# to have tp_version_tag == 0
for _ in range(2**16):
type_modified(str)
type_assign_version(str)
type_modified(bytes)
type_assign_version(bytes)
self.assertEqual(type_get_version(str), 0)
self.assertEqual(type_get_version(bytes), 0)
def get_capitalize_2(type_):
return type_.capitalize
self._check_specialization(get_capitalize_2, str, "LOAD_ATTR", should_specialize=False)
self.assertEqual(get_capitalize_2(str)('hello'), 'Hello')
self.assertEqual(get_capitalize_2(bytes)(b'hello'), b'Hello')
def test_property_load_attr_specialization_user_type(self): def test_property_load_attr_specialization_user_type(self):
class G: class G:

View file

@ -7256,6 +7256,7 @@ _datetime_exec(PyObject *module)
Py_DECREF(value); \ Py_DECREF(value); \
} while(0) } while(0)
if (!reloading) {
/* timedelta values */ /* timedelta values */
PyObject *d = _PyType_GetDict(&PyDateTime_DeltaType); PyObject *d = _PyType_GetDict(&PyDateTime_DeltaType);
DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0)); DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
@ -7299,6 +7300,7 @@ _datetime_exec(PyObject *module)
/* +23:59 */ /* +23:59 */
DATETIME_ADD_MACRO( DATETIME_ADD_MACRO(
d, "max", create_timezone_from_delta(0, (23 * 60 + 59) * 60, 0, 0)); d, "max", create_timezone_from_delta(0, (23 * 60 + 59) * 60, 0, 0));
}
#undef DATETIME_ADD_MACRO #undef DATETIME_ADD_MACRO
@ -7342,12 +7344,6 @@ _datetime_exec(PyObject *module)
static_assert(DI100Y == 25 * DI4Y - 1, "DI100Y"); static_assert(DI100Y == 25 * DI4Y - 1, "DI100Y");
assert(DI100Y == days_before_year(100+1)); assert(DI100Y == days_before_year(100+1));
if (reloading) {
for (size_t i = 0; i < Py_ARRAY_LENGTH(capi_types); i++) {
PyType_Modified(capi_types[i]);
}
}
if (set_current_module(interp, module) < 0) { if (set_current_module(interp, module) < 0) {
goto error; goto error;
} }

View file

@ -1026,6 +1026,8 @@ type_modified_unlocked(PyTypeObject *type)
if (type->tp_version_tag == 0) { if (type->tp_version_tag == 0) {
return; return;
} }
// Cannot modify static builtin types.
assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) == 0);
PyObject *subclasses = lookup_tp_subclasses(type); PyObject *subclasses = lookup_tp_subclasses(type);
if (subclasses != NULL) { if (subclasses != NULL) {