mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
gh-94673: Ensure Builtin Static Types are Readied Properly (gh-103940)
There were cases where we do unnecessary work for builtin static types. This also simplifies some work necessary for a per-interpreter GIL.
This commit is contained in:
parent
56c7176d1d
commit
d2e2e53f73
21 changed files with 89 additions and 169 deletions
|
|
@ -3090,25 +3090,6 @@ error:
|
|||
}
|
||||
|
||||
|
||||
PyStatus
|
||||
_PyBytes_InitTypes(PyInterpreterState *interp)
|
||||
{
|
||||
if (!_Py_IsMainInterpreter(interp)) {
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
if (PyType_Ready(&PyBytes_Type) < 0) {
|
||||
return _PyStatus_ERR("Can't initialize bytes type");
|
||||
}
|
||||
|
||||
if (PyType_Ready(&PyBytesIter_Type) < 0) {
|
||||
return _PyStatus_ERR("Can't initialize bytes iterator type");
|
||||
}
|
||||
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
|
||||
/*********************** Bytes Iterator ****************************/
|
||||
|
||||
typedef struct {
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ method_getattro(PyObject *obj, PyObject *name)
|
|||
PyObject *descr = NULL;
|
||||
|
||||
{
|
||||
if (tp->tp_dict == NULL) {
|
||||
if (!_PyType_IsReady(tp)) {
|
||||
if (PyType_Ready(tp) < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -395,7 +395,7 @@ instancemethod_getattro(PyObject *self, PyObject *name)
|
|||
PyTypeObject *tp = Py_TYPE(self);
|
||||
PyObject *descr = NULL;
|
||||
|
||||
if (tp->tp_dict == NULL) {
|
||||
if (!_PyType_IsReady(tp)) {
|
||||
if (PyType_Ready(tp) < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3596,10 +3596,6 @@ static struct static_exception static_exceptions[] = {
|
|||
int
|
||||
_PyExc_InitTypes(PyInterpreterState *interp)
|
||||
{
|
||||
if (!_Py_IsMainInterpreter(interp)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
|
||||
PyTypeObject *exc = static_exceptions[i].exc;
|
||||
if (_PyStaticType_InitBuiltin(exc) < 0) {
|
||||
|
|
|
|||
|
|
@ -1990,20 +1990,10 @@ _PyFloat_InitState(PyInterpreterState *interp)
|
|||
PyStatus
|
||||
_PyFloat_InitTypes(PyInterpreterState *interp)
|
||||
{
|
||||
if (!_Py_IsMainInterpreter(interp)) {
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
if (PyType_Ready(&PyFloat_Type) < 0) {
|
||||
return _PyStatus_ERR("Can't initialize float type");
|
||||
}
|
||||
|
||||
/* Init float info */
|
||||
if (FloatInfoType.tp_name == NULL) {
|
||||
if (_PyStructSequence_InitBuiltin(&FloatInfoType,
|
||||
&floatinfo_desc) < 0) {
|
||||
return _PyStatus_ERR("can't init float info type");
|
||||
}
|
||||
if (_PyStructSequence_InitBuiltin(&FloatInfoType,
|
||||
&floatinfo_desc) < 0) {
|
||||
return _PyStatus_ERR("can't init float info type");
|
||||
}
|
||||
|
||||
return _PyStatus_OK();
|
||||
|
|
|
|||
|
|
@ -6351,19 +6351,9 @@ PyLong_GetInfo(void)
|
|||
PyStatus
|
||||
_PyLong_InitTypes(PyInterpreterState *interp)
|
||||
{
|
||||
if (!_Py_IsMainInterpreter(interp)) {
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
if (PyType_Ready(&PyLong_Type) < 0) {
|
||||
return _PyStatus_ERR("Can't initialize int type");
|
||||
}
|
||||
|
||||
/* initialize int_info */
|
||||
if (Int_InfoType.tp_name == NULL) {
|
||||
if (_PyStructSequence_InitBuiltin(&Int_InfoType, &int_info_desc) < 0) {
|
||||
return _PyStatus_ERR("can't init int info type");
|
||||
}
|
||||
if (_PyStructSequence_InitBuiltin(&Int_InfoType, &int_info_desc) < 0) {
|
||||
return _PyStatus_ERR("can't init int info type");
|
||||
}
|
||||
|
||||
return _PyStatus_OK();
|
||||
|
|
|
|||
|
|
@ -890,7 +890,7 @@ PyObject_Hash(PyObject *v)
|
|||
* an explicit call to PyType_Ready, we implicitly call
|
||||
* PyType_Ready here and then check the tp_hash slot again
|
||||
*/
|
||||
if (tp->tp_dict == NULL) {
|
||||
if (!_PyType_IsReady(tp)) {
|
||||
if (PyType_Ready(tp) < 0)
|
||||
return -1;
|
||||
if (tp->tp_hash != NULL)
|
||||
|
|
@ -1385,7 +1385,7 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name,
|
|||
}
|
||||
Py_INCREF(name);
|
||||
|
||||
if (tp->tp_dict == NULL) {
|
||||
if (!_PyType_IsReady(tp)) {
|
||||
if (PyType_Ready(tp) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -1507,8 +1507,9 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (tp->tp_dict == NULL && PyType_Ready(tp) < 0)
|
||||
if (!_PyType_IsReady(tp) && PyType_Ready(tp) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Py_INCREF(name);
|
||||
Py_INCREF(tp);
|
||||
|
|
|
|||
|
|
@ -509,6 +509,13 @@ _PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type,
|
|||
PyStructSequence_Desc *desc,
|
||||
unsigned long tp_flags)
|
||||
{
|
||||
if (type->tp_flags & Py_TPFLAGS_READY) {
|
||||
if (_PyStaticType_InitBuiltin(type) < 0) {
|
||||
goto failed_init_builtin;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyMemberDef *members;
|
||||
Py_ssize_t n_members, n_unnamed_members;
|
||||
|
||||
|
|
@ -517,18 +524,25 @@ _PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type,
|
|||
return -1;
|
||||
}
|
||||
initialize_static_fields(type, desc, members, tp_flags);
|
||||
|
||||
Py_INCREF(type); // XXX It should be immortal.
|
||||
if (_PyStaticType_InitBuiltin(type) < 0) {
|
||||
PyMem_Free(members);
|
||||
PyErr_Format(PyExc_RuntimeError,
|
||||
"Can't initialize builtin type %s",
|
||||
desc->name);
|
||||
return -1;
|
||||
goto failed_init_builtin;
|
||||
}
|
||||
if (initialize_static_type(type, desc, n_members, n_unnamed_members) < 0) {
|
||||
|
||||
if (initialize_structseq_dict(
|
||||
desc, type->tp_dict, n_members, n_unnamed_members) < 0) {
|
||||
PyMem_Free(members);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
failed_init_builtin:
|
||||
PyErr_Format(PyExc_RuntimeError,
|
||||
"Can't initialize builtin type %s",
|
||||
desc->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -960,24 +960,6 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
|
|||
}
|
||||
|
||||
|
||||
PyStatus
|
||||
_PyTuple_InitTypes(PyInterpreterState *interp)
|
||||
{
|
||||
if (!_Py_IsMainInterpreter(interp)) {
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
if (PyType_Ready(&PyTuple_Type) < 0) {
|
||||
return _PyStatus_ERR("Can't initialize tuple type");
|
||||
}
|
||||
|
||||
if (PyType_Ready(&PyTupleIter_Type) < 0) {
|
||||
return _PyStatus_ERR("Can't initialize tuple iterator type");
|
||||
}
|
||||
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
static void maybe_freelist_clear(PyInterpreterState *, int);
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -6948,8 +6948,12 @@ type_ready_post_checks(PyTypeObject *type)
|
|||
static int
|
||||
type_ready(PyTypeObject *type)
|
||||
{
|
||||
_PyObject_ASSERT((PyObject *)type,
|
||||
(type->tp_flags & Py_TPFLAGS_READYING) == 0);
|
||||
type->tp_flags |= Py_TPFLAGS_READYING;
|
||||
|
||||
if (type_ready_pre_checks(type) < 0) {
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef Py_TRACE_REFS
|
||||
|
|
@ -6963,41 +6967,49 @@ type_ready(PyTypeObject *type)
|
|||
|
||||
/* Initialize tp_dict: _PyType_IsReady() tests if tp_dict != NULL */
|
||||
if (type_ready_set_dict(type) < 0) {
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
if (type_ready_set_bases(type) < 0) {
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
if (type_ready_mro(type) < 0) {
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
if (type_ready_set_new(type) < 0) {
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
if (type_ready_fill_dict(type) < 0) {
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
if (type_ready_inherit(type) < 0) {
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
if (type_ready_preheader(type) < 0) {
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
if (type_ready_set_hash(type) < 0) {
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
if (type_ready_add_subclasses(type) < 0) {
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
if (type_ready_managed_dict(type) < 0) {
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
if (type_ready_post_checks(type) < 0) {
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* All done -- set the ready flag */
|
||||
type->tp_flags = (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY;
|
||||
|
||||
assert(_PyType_CheckConsistency(type));
|
||||
return 0;
|
||||
|
||||
error:
|
||||
type->tp_flags &= ~Py_TPFLAGS_READYING;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
PyType_Ready(PyTypeObject *type)
|
||||
|
|
@ -7006,31 +7018,29 @@ PyType_Ready(PyTypeObject *type)
|
|||
assert(_PyType_CheckConsistency(type));
|
||||
return 0;
|
||||
}
|
||||
_PyObject_ASSERT((PyObject *)type,
|
||||
(type->tp_flags & Py_TPFLAGS_READYING) == 0);
|
||||
|
||||
type->tp_flags |= Py_TPFLAGS_READYING;
|
||||
assert(!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN));
|
||||
|
||||
/* Historically, all static types were immutable. See bpo-43908 */
|
||||
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
|
||||
type->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE;
|
||||
}
|
||||
|
||||
if (type_ready(type) < 0) {
|
||||
type->tp_flags &= ~Py_TPFLAGS_READYING;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* All done -- set the ready flag */
|
||||
type->tp_flags = (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY;
|
||||
assert(_PyType_CheckConsistency(type));
|
||||
return 0;
|
||||
return type_ready(type);
|
||||
}
|
||||
|
||||
int
|
||||
_PyStaticType_InitBuiltin(PyTypeObject *self)
|
||||
{
|
||||
assert(!(self->tp_flags & Py_TPFLAGS_HEAPTYPE));
|
||||
|
||||
if (self->tp_flags & Py_TPFLAGS_READY) {
|
||||
assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN);
|
||||
assert(_PyType_CheckConsistency(self));
|
||||
return 0;
|
||||
}
|
||||
|
||||
self->tp_flags |= _Py_TPFLAGS_STATIC_BUILTIN;
|
||||
self->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE;
|
||||
|
||||
assert(NEXT_GLOBAL_VERSION_TAG <= _Py_MAX_GLOBAL_TYPE_VERSION_TAG);
|
||||
self->tp_version_tag = NEXT_GLOBAL_VERSION_TAG++;
|
||||
|
|
@ -7038,7 +7048,7 @@ _PyStaticType_InitBuiltin(PyTypeObject *self)
|
|||
|
||||
static_builtin_state_init(self);
|
||||
|
||||
int res = PyType_Ready(self);
|
||||
int res = type_ready(self);
|
||||
if (res < 0) {
|
||||
static_builtin_state_clear(self);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14573,10 +14573,6 @@ _PyUnicode_InitGlobalObjects(PyInterpreterState *interp)
|
|||
PyStatus
|
||||
_PyUnicode_InitTypes(PyInterpreterState *interp)
|
||||
{
|
||||
if (!_Py_IsMainInterpreter(interp)) {
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
if (_PyStaticType_InitBuiltin(&EncodingMapType) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue