mirror of
https://github.com/python/cpython.git
synced 2025-10-12 09:53:19 +00:00
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:
parent
b3b7b7d46a
commit
e55b05f29e
3 changed files with 44 additions and 65 deletions
|
@ -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:
|
||||||
|
|
|
@ -7256,50 +7256,52 @@ _datetime_exec(PyObject *module)
|
||||||
Py_DECREF(value); \
|
Py_DECREF(value); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
/* timedelta values */
|
if (!reloading) {
|
||||||
PyObject *d = _PyType_GetDict(&PyDateTime_DeltaType);
|
/* timedelta values */
|
||||||
DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
|
PyObject *d = _PyType_GetDict(&PyDateTime_DeltaType);
|
||||||
DATETIME_ADD_MACRO(d, "min", new_delta(-MAX_DELTA_DAYS, 0, 0, 0));
|
DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
|
||||||
DATETIME_ADD_MACRO(d, "max",
|
DATETIME_ADD_MACRO(d, "min", new_delta(-MAX_DELTA_DAYS, 0, 0, 0));
|
||||||
new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0));
|
DATETIME_ADD_MACRO(d, "max",
|
||||||
|
new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0));
|
||||||
|
|
||||||
/* date values */
|
/* date values */
|
||||||
d = _PyType_GetDict(&PyDateTime_DateType);
|
d = _PyType_GetDict(&PyDateTime_DateType);
|
||||||
DATETIME_ADD_MACRO(d, "min", new_date(1, 1, 1));
|
DATETIME_ADD_MACRO(d, "min", new_date(1, 1, 1));
|
||||||
DATETIME_ADD_MACRO(d, "max", new_date(MAXYEAR, 12, 31));
|
DATETIME_ADD_MACRO(d, "max", new_date(MAXYEAR, 12, 31));
|
||||||
DATETIME_ADD_MACRO(d, "resolution", new_delta(1, 0, 0, 0));
|
DATETIME_ADD_MACRO(d, "resolution", new_delta(1, 0, 0, 0));
|
||||||
|
|
||||||
/* time values */
|
/* time values */
|
||||||
d = _PyType_GetDict(&PyDateTime_TimeType);
|
d = _PyType_GetDict(&PyDateTime_TimeType);
|
||||||
DATETIME_ADD_MACRO(d, "min", new_time(0, 0, 0, 0, Py_None, 0));
|
DATETIME_ADD_MACRO(d, "min", new_time(0, 0, 0, 0, Py_None, 0));
|
||||||
DATETIME_ADD_MACRO(d, "max", new_time(23, 59, 59, 999999, Py_None, 0));
|
DATETIME_ADD_MACRO(d, "max", new_time(23, 59, 59, 999999, Py_None, 0));
|
||||||
DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
|
DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
|
||||||
|
|
||||||
/* datetime values */
|
/* datetime values */
|
||||||
d = _PyType_GetDict(&PyDateTime_DateTimeType);
|
d = _PyType_GetDict(&PyDateTime_DateTimeType);
|
||||||
DATETIME_ADD_MACRO(d, "min",
|
DATETIME_ADD_MACRO(d, "min",
|
||||||
new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0));
|
new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0));
|
||||||
DATETIME_ADD_MACRO(d, "max", new_datetime(MAXYEAR, 12, 31, 23, 59, 59,
|
DATETIME_ADD_MACRO(d, "max", new_datetime(MAXYEAR, 12, 31, 23, 59, 59,
|
||||||
999999, Py_None, 0));
|
999999, Py_None, 0));
|
||||||
DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
|
DATETIME_ADD_MACRO(d, "resolution", new_delta(0, 0, 1, 0));
|
||||||
|
|
||||||
/* timezone values */
|
/* timezone values */
|
||||||
d = _PyType_GetDict(&PyDateTime_TimeZoneType);
|
d = _PyType_GetDict(&PyDateTime_TimeZoneType);
|
||||||
if (PyDict_SetItemString(d, "utc", (PyObject *)&utc_timezone) < 0) {
|
if (PyDict_SetItemString(d, "utc", (PyObject *)&utc_timezone) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bpo-37642: These attributes are rounded to the nearest minute for backwards
|
||||||
|
* compatibility, even though the constructor will accept a wider range of
|
||||||
|
* values. This may change in the future.*/
|
||||||
|
|
||||||
|
/* -23:59 */
|
||||||
|
DATETIME_ADD_MACRO(d, "min", create_timezone_from_delta(-1, 60, 0, 1));
|
||||||
|
|
||||||
|
/* +23:59 */
|
||||||
|
DATETIME_ADD_MACRO(
|
||||||
|
d, "max", create_timezone_from_delta(0, (23 * 60 + 59) * 60, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bpo-37642: These attributes are rounded to the nearest minute for backwards
|
|
||||||
* compatibility, even though the constructor will accept a wider range of
|
|
||||||
* values. This may change in the future.*/
|
|
||||||
|
|
||||||
/* -23:59 */
|
|
||||||
DATETIME_ADD_MACRO(d, "min", create_timezone_from_delta(-1, 60, 0, 1));
|
|
||||||
|
|
||||||
/* +23:59 */
|
|
||||||
DATETIME_ADD_MACRO(
|
|
||||||
d, "max", create_timezone_from_delta(0, (23 * 60 + 59) * 60, 0, 0));
|
|
||||||
|
|
||||||
#undef DATETIME_ADD_MACRO
|
#undef DATETIME_ADD_MACRO
|
||||||
|
|
||||||
/* Add module level attributes */
|
/* Add module level attributes */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue