Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit d2e2e53

Browse filesBrowse files
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.
1 parent 56c7176 commit d2e2e53
Copy full SHA for d2e2e53
Expand file treeCollapse file tree

21 files changed

+88
-168
lines changed

‎Include/internal/pycore_bytesobject.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_bytesobject.h
-5Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@ extern "C" {
99
#endif
1010

1111

12-
/* runtime lifecycle */
13-
14-
extern PyStatus _PyBytes_InitTypes(PyInterpreterState *);
15-
16-
1712
/* Substring Search.
1813
1914
Returns the index of the first occurrence of

‎Include/internal/pycore_tuple.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_tuple.h
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ extern "C" {
1414
/* runtime lifecycle */
1515

1616
extern PyStatus _PyTuple_InitGlobalObjects(PyInterpreterState *);
17-
extern PyStatus _PyTuple_InitTypes(PyInterpreterState *);
1817
extern void _PyTuple_Fini(PyInterpreterState *);
1918

2019

‎Modules/_io/_iomodule.c

Copy file name to clipboardExpand all lines: Modules/_io/_iomodule.c
+4-6Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -671,13 +671,11 @@ static PyTypeObject* static_types[] = {
671671
PyStatus
672672
_PyIO_InitTypes(PyInterpreterState *interp)
673673
{
674-
if (!_Py_IsMainInterpreter(interp)) {
675-
return _PyStatus_OK();
676-
}
677-
678-
// Set type base classes
679674
#ifdef HAVE_WINDOWS_CONSOLE_IO
680-
PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
675+
if (_Py_IsMainInterpreter(interp)) {
676+
// Set type base classes
677+
PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
678+
}
681679
#endif
682680

683681
for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {

‎Modules/mathmodule.c

Copy file name to clipboardExpand all lines: Modules/mathmodule.c
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2096,7 +2096,7 @@ math_trunc(PyObject *module, PyObject *x)
20962096
return PyFloat_Type.tp_as_number->nb_int(x);
20972097
}
20982098

2099-
if (Py_TYPE(x)->tp_dict == NULL) {
2099+
if (_PyType_IsReady(Py_TYPE(x))) {
21002100
if (PyType_Ready(Py_TYPE(x)) < 0)
21012101
return NULL;
21022102
}

‎Modules/symtablemodule.c

Copy file name to clipboardExpand all lines: Modules/symtablemodule.c
-7Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,6 @@ static PyMethodDef symtable_methods[] = {
6666
{NULL, NULL} /* sentinel */
6767
};
6868

69-
static int
70-
symtable_init_stentry_type(PyObject *m)
71-
{
72-
return PyType_Ready(&PySTEntry_Type);
73-
}
74-
7569
static int
7670
symtable_init_constants(PyObject *m)
7771
{
@@ -105,7 +99,6 @@ symtable_init_constants(PyObject *m)
10599
}
106100

107101
static PyModuleDef_Slot symtable_slots[] = {
108-
{Py_mod_exec, symtable_init_stentry_type},
109102
{Py_mod_exec, symtable_init_constants},
110103
{0, NULL}
111104
};

‎Objects/bytesobject.c

Copy file name to clipboardExpand all lines: Objects/bytesobject.c
-19Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3090,25 +3090,6 @@ _Py_COMP_DIAG_POP
30903090
}
30913091

30923092

3093-
PyStatus
3094-
_PyBytes_InitTypes(PyInterpreterState *interp)
3095-
{
3096-
if (!_Py_IsMainInterpreter(interp)) {
3097-
return _PyStatus_OK();
3098-
}
3099-
3100-
if (PyType_Ready(&PyBytes_Type) < 0) {
3101-
return _PyStatus_ERR("Can't initialize bytes type");
3102-
}
3103-
3104-
if (PyType_Ready(&PyBytesIter_Type) < 0) {
3105-
return _PyStatus_ERR("Can't initialize bytes iterator type");
3106-
}
3107-
3108-
return _PyStatus_OK();
3109-
}
3110-
3111-
31123093
/*********************** Bytes Iterator ****************************/
31133094

31143095
typedef struct {

‎Objects/classobject.c

Copy file name to clipboardExpand all lines: Objects/classobject.c
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ method_getattro(PyObject *obj, PyObject *name)
181181
PyObject *descr = NULL;
182182

183183
{
184-
if (tp->tp_dict == NULL) {
184+
if (!_PyType_IsReady(tp)) {
185185
if (PyType_Ready(tp) < 0)
186186
return NULL;
187187
}
@@ -395,7 +395,7 @@ instancemethod_getattro(PyObject *self, PyObject *name)
395395
PyTypeObject *tp = Py_TYPE(self);
396396
PyObject *descr = NULL;
397397

398-
if (tp->tp_dict == NULL) {
398+
if (!_PyType_IsReady(tp)) {
399399
if (PyType_Ready(tp) < 0)
400400
return NULL;
401401
}

‎Objects/exceptions.c

Copy file name to clipboardExpand all lines: Objects/exceptions.c
-4Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3596,10 +3596,6 @@ static struct static_exception static_exceptions[] = {
35963596
int
35973597
_PyExc_InitTypes(PyInterpreterState *interp)
35983598
{
3599-
if (!_Py_IsMainInterpreter(interp)) {
3600-
return 0;
3601-
}
3602-
36033599
for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
36043600
PyTypeObject *exc = static_exceptions[i].exc;
36053601
if (_PyStaticType_InitBuiltin(exc) < 0) {

‎Objects/floatobject.c

Copy file name to clipboardExpand all lines: Objects/floatobject.c
+3-13Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,20 +1990,10 @@ _PyFloat_InitState(PyInterpreterState *interp)
19901990
PyStatus
19911991
_PyFloat_InitTypes(PyInterpreterState *interp)
19921992
{
1993-
if (!_Py_IsMainInterpreter(interp)) {
1994-
return _PyStatus_OK();
1995-
}
1996-
1997-
if (PyType_Ready(&PyFloat_Type) < 0) {
1998-
return _PyStatus_ERR("Can't initialize float type");
1999-
}
2000-
20011993
/* Init float info */
2002-
if (FloatInfoType.tp_name == NULL) {
2003-
if (_PyStructSequence_InitBuiltin(&FloatInfoType,
2004-
&floatinfo_desc) < 0) {
2005-
return _PyStatus_ERR("can't init float info type");
2006-
}
1994+
if (_PyStructSequence_InitBuiltin(&FloatInfoType,
1995+
&floatinfo_desc) < 0) {
1996+
return _PyStatus_ERR("can't init float info type");
20071997
}
20081998

20091999
return _PyStatus_OK();

‎Objects/longobject.c

Copy file name to clipboardExpand all lines: Objects/longobject.c
+2-12Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6351,19 +6351,9 @@ PyLong_GetInfo(void)
63516351
PyStatus
63526352
_PyLong_InitTypes(PyInterpreterState *interp)
63536353
{
6354-
if (!_Py_IsMainInterpreter(interp)) {
6355-
return _PyStatus_OK();
6356-
}
6357-
6358-
if (PyType_Ready(&PyLong_Type) < 0) {
6359-
return _PyStatus_ERR("Can't initialize int type");
6360-
}
6361-
63626354
/* initialize int_info */
6363-
if (Int_InfoType.tp_name == NULL) {
6364-
if (_PyStructSequence_InitBuiltin(&Int_InfoType, &int_info_desc) < 0) {
6365-
return _PyStatus_ERR("can't init int info type");
6366-
}
6355+
if (_PyStructSequence_InitBuiltin(&Int_InfoType, &int_info_desc) < 0) {
6356+
return _PyStatus_ERR("can't init int info type");
63676357
}
63686358

63696359
return _PyStatus_OK();

‎Objects/object.c

Copy file name to clipboardExpand all lines: Objects/object.c
+4-3Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,7 @@ PyObject_Hash(PyObject *v)
890890
* an explicit call to PyType_Ready, we implicitly call
891891
* PyType_Ready here and then check the tp_hash slot again
892892
*/
893-
if (tp->tp_dict == NULL) {
893+
if (!_PyType_IsReady(tp)) {
894894
if (PyType_Ready(tp) < 0)
895895
return -1;
896896
if (tp->tp_hash != NULL)
@@ -1385,7 +1385,7 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name,
13851385
}
13861386
Py_INCREF(name);
13871387

1388-
if (tp->tp_dict == NULL) {
1388+
if (!_PyType_IsReady(tp)) {
13891389
if (PyType_Ready(tp) < 0)
13901390
goto done;
13911391
}
@@ -1507,8 +1507,9 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name,
15071507
return -1;
15081508
}
15091509

1510-
if (tp->tp_dict == NULL && PyType_Ready(tp) < 0)
1510+
if (!_PyType_IsReady(tp) && PyType_Ready(tp) < 0) {
15111511
return -1;
1512+
}
15121513

15131514
Py_INCREF(name);
15141515
Py_INCREF(tp);

‎Objects/structseq.c

Copy file name to clipboardExpand all lines: Objects/structseq.c
+19-5Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,13 @@ _PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type,
509509
PyStructSequence_Desc *desc,
510510
unsigned long tp_flags)
511511
{
512+
if (type->tp_flags & Py_TPFLAGS_READY) {
513+
if (_PyStaticType_InitBuiltin(type) < 0) {
514+
goto failed_init_builtin;
515+
}
516+
return 0;
517+
}
518+
512519
PyMemberDef *members;
513520
Py_ssize_t n_members, n_unnamed_members;
514521

@@ -517,18 +524,25 @@ _PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type,
517524
return -1;
518525
}
519526
initialize_static_fields(type, desc, members, tp_flags);
527+
528+
Py_INCREF(type); // XXX It should be immortal.
520529
if (_PyStaticType_InitBuiltin(type) < 0) {
521530
PyMem_Free(members);
522-
PyErr_Format(PyExc_RuntimeError,
523-
"Can't initialize builtin type %s",
524-
desc->name);
525-
return -1;
531+
goto failed_init_builtin;
526532
}
527-
if (initialize_static_type(type, desc, n_members, n_unnamed_members) < 0) {
533+
534+
if (initialize_structseq_dict(
535+
desc, type->tp_dict, n_members, n_unnamed_members) < 0) {
528536
PyMem_Free(members);
529537
return -1;
530538
}
531539
return 0;
540+
541+
failed_init_builtin:
542+
PyErr_Format(PyExc_RuntimeError,
543+
"Can't initialize builtin type %s",
544+
desc->name);
545+
return -1;
532546
}
533547

534548
int

‎Objects/tupleobject.c

Copy file name to clipboardExpand all lines: Objects/tupleobject.c
-18Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -960,24 +960,6 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
960960
}
961961

962962

963-
PyStatus
964-
_PyTuple_InitTypes(PyInterpreterState *interp)
965-
{
966-
if (!_Py_IsMainInterpreter(interp)) {
967-
return _PyStatus_OK();
968-
}
969-
970-
if (PyType_Ready(&PyTuple_Type) < 0) {
971-
return _PyStatus_ERR("Can't initialize tuple type");
972-
}
973-
974-
if (PyType_Ready(&PyTupleIter_Type) < 0) {
975-
return _PyStatus_ERR("Can't initialize tuple iterator type");
976-
}
977-
978-
return _PyStatus_OK();
979-
}
980-
981963
static void maybe_freelist_clear(PyInterpreterState *, int);
982964

983965
void

‎Objects/typeobject.c

Copy file name to clipboardExpand all lines: Objects/typeobject.c
+37-27Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6948,8 +6948,12 @@ type_ready_post_checks(PyTypeObject *type)
69486948
static int
69496949
type_ready(PyTypeObject *type)
69506950
{
6951+
_PyObject_ASSERT((PyObject *)type,
6952+
(type->tp_flags & Py_TPFLAGS_READYING) == 0);
6953+
type->tp_flags |= Py_TPFLAGS_READYING;
6954+
69516955
if (type_ready_pre_checks(type) < 0) {
6952-
return -1;
6956+
goto error;
69536957
}
69546958

69556959
#ifdef Py_TRACE_REFS
@@ -6963,41 +6967,49 @@ type_ready(PyTypeObject *type)
69636967

69646968
/* Initialize tp_dict: _PyType_IsReady() tests if tp_dict != NULL */
69656969
if (type_ready_set_dict(type) < 0) {
6966-
return -1;
6970+
goto error;
69676971
}
69686972
if (type_ready_set_bases(type) < 0) {
6969-
return -1;
6973+
goto error;
69706974
}
69716975
if (type_ready_mro(type) < 0) {
6972-
return -1;
6976+
goto error;
69736977
}
69746978
if (type_ready_set_new(type) < 0) {
6975-
return -1;
6979+
goto error;
69766980
}
69776981
if (type_ready_fill_dict(type) < 0) {
6978-
return -1;
6982+
goto error;
69796983
}
69806984
if (type_ready_inherit(type) < 0) {
6981-
return -1;
6985+
goto error;
69826986
}
69836987
if (type_ready_preheader(type) < 0) {
6984-
return -1;
6988+
goto error;
69856989
}
69866990
if (type_ready_set_hash(type) < 0) {
6987-
return -1;
6991+
goto error;
69886992
}
69896993
if (type_ready_add_subclasses(type) < 0) {
6990-
return -1;
6994+
goto error;
69916995
}
69926996
if (type_ready_managed_dict(type) < 0) {
6993-
return -1;
6997+
goto error;
69946998
}
69956999
if (type_ready_post_checks(type) < 0) {
6996-
return -1;
7000+
goto error;
69977001
}
7002+
7003+
/* All done -- set the ready flag */
7004+
type->tp_flags = (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY;
7005+
7006+
assert(_PyType_CheckConsistency(type));
69987007
return 0;
6999-
}
70007008

7009+
error:
7010+
type->tp_flags &= ~Py_TPFLAGS_READYING;
7011+
return -1;
7012+
}
70017013

70027014
int
70037015
PyType_Ready(PyTypeObject *type)
@@ -7006,39 +7018,37 @@ PyType_Ready(PyTypeObject *type)
70067018
assert(_PyType_CheckConsistency(type));
70077019
return 0;
70087020
}
7009-
_PyObject_ASSERT((PyObject *)type,
7010-
(type->tp_flags & Py_TPFLAGS_READYING) == 0);
7011-
7012-
type->tp_flags |= Py_TPFLAGS_READYING;
7021+
assert(!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN));
70137022

70147023
/* Historically, all static types were immutable. See bpo-43908 */
70157024
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
70167025
type->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE;
70177026
}
70187027

7019-
if (type_ready(type) < 0) {
7020-
type->tp_flags &= ~Py_TPFLAGS_READYING;
7021-
return -1;
7022-
}
7023-
7024-
/* All done -- set the ready flag */
7025-
type->tp_flags = (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY;
7026-
assert(_PyType_CheckConsistency(type));
7027-
return 0;
7028+
return type_ready(type);
70287029
}
70297030

70307031
int
70317032
_PyStaticType_InitBuiltin(PyTypeObject *self)
70327033
{
7034+
assert(!(self->tp_flags & Py_TPFLAGS_HEAPTYPE));
7035+
7036+
if (self->tp_flags & Py_TPFLAGS_READY) {
7037+
assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN);
7038+
assert(_PyType_CheckConsistency(self));
7039+
return 0;
7040+
}
7041+
70337042
self->tp_flags |= _Py_TPFLAGS_STATIC_BUILTIN;
7043+
self->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE;
70347044

70357045
assert(NEXT_GLOBAL_VERSION_TAG <= _Py_MAX_GLOBAL_TYPE_VERSION_TAG);
70367046
self->tp_version_tag = NEXT_GLOBAL_VERSION_TAG++;
70377047
self->tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG;
70387048

70397049
static_builtin_state_init(self);
70407050

7041-
int res = PyType_Ready(self);
7051+
int res = type_ready(self);
70427052
if (res < 0) {
70437053
static_builtin_state_clear(self);
70447054
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.