@@ -433,12 +433,10 @@ initialize_structseq_dict(PyStructSequence_Desc *desc, PyObject* dict,
433
433
434
434
static PyMemberDef *
435
435
initialize_members (PyStructSequence_Desc * desc ,
436
- Py_ssize_t * pn_members , Py_ssize_t * pn_unnamed_members )
436
+ Py_ssize_t n_members , Py_ssize_t n_unnamed_members )
437
437
{
438
438
PyMemberDef * members ;
439
- Py_ssize_t n_members , n_unnamed_members ;
440
439
441
- n_members = count_members (desc , & n_unnamed_members );
442
440
members = PyMem_NEW (PyMemberDef , n_members - n_unnamed_members + 1 );
443
441
if (members == NULL ) {
444
442
PyErr_NoMemory ();
@@ -463,8 +461,6 @@ initialize_members(PyStructSequence_Desc *desc,
463
461
}
464
462
members [k ].name = NULL ;
465
463
466
- * pn_members = n_members ;
467
- * pn_unnamed_members = n_unnamed_members ;
468
464
return members ;
469
465
}
470
466
@@ -510,39 +506,58 @@ _PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type,
510
506
PyStructSequence_Desc * desc ,
511
507
unsigned long tp_flags )
512
508
{
513
- if (type -> tp_flags & Py_TPFLAGS_READY ) {
514
- if (_PyStaticType_InitBuiltin (type ) < 0 ) {
515
- goto failed_init_builtin ;
509
+ Py_ssize_t n_unnamed_members ;
510
+ Py_ssize_t n_members = count_members (desc , & n_unnamed_members );
511
+ PyMemberDef * members = NULL ;
512
+
513
+ int initialized = 1 ;
514
+ if ((type -> tp_flags & Py_TPFLAGS_READY ) == 0 ) {
515
+ assert (type -> tp_name == NULL );
516
+ assert (type -> tp_members == NULL );
517
+ assert (type -> tp_base == NULL );
518
+
519
+ members = initialize_members (desc , n_members , n_unnamed_members );
520
+ if (members == NULL ) {
521
+ goto error ;
516
522
}
517
- return 0 ;
518
- }
523
+ initialize_static_fields (type , desc , members , tp_flags );
519
524
520
- PyMemberDef * members ;
521
- Py_ssize_t n_members , n_unnamed_members ;
522
-
523
- members = initialize_members (desc , & n_members , & n_unnamed_members );
524
- if (members == NULL ) {
525
- return -1 ;
525
+ _Py_SetImmortal (type );
526
+ initialized = 0 ;
527
+ }
528
+ #ifndef NDEBUG
529
+ else {
530
+ // Ensure that the type was initialized.
531
+ assert (type -> tp_name != NULL );
532
+ assert (type -> tp_members != NULL );
533
+ assert (type -> tp_base == & PyTuple_Type );
534
+ assert ((type -> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN ));
535
+ assert (_Py_IsImmortal (type ));
526
536
}
527
- initialize_static_fields ( type , desc , members , tp_flags );
537
+ #endif
528
538
529
- Py_INCREF (type ); // XXX It should be immortal.
530
539
if (_PyStaticType_InitBuiltin (type ) < 0 ) {
531
- PyMem_Free (members );
532
- goto failed_init_builtin ;
540
+ PyErr_Format (PyExc_RuntimeError ,
541
+ "Can't initialize builtin type %s" ,
542
+ desc -> name );
543
+ goto error ;
544
+ }
545
+ // This should be dropped if tp_dict is made per-interpreter.
546
+ if (initialized ) {
547
+ return 0 ;
533
548
}
534
549
535
550
if (initialize_structseq_dict (
536
551
desc , type -> tp_dict , n_members , n_unnamed_members ) < 0 ) {
537
- PyMem_Free (members );
538
- return -1 ;
552
+ goto error ;
539
553
}
554
+
540
555
return 0 ;
541
556
542
- failed_init_builtin :
543
- PyErr_Format ( PyExc_RuntimeError ,
544
- "Can't initialize builtin type %s" ,
545
- desc -> name );
557
+ error :
558
+ if ( members != NULL ) {
559
+ PyMem_Free ( members );
560
+ }
546
561
return -1 ;
547
562
}
548
563
@@ -566,7 +581,8 @@ PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc)
566
581
return -1 ;
567
582
}
568
583
569
- members = initialize_members (desc , & n_members , & n_unnamed_members );
584
+ n_members = count_members (desc , & n_unnamed_members );
585
+ members = initialize_members (desc , n_members , n_unnamed_members );
570
586
if (members == NULL ) {
571
587
return -1 ;
572
588
}
@@ -585,35 +601,32 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
585
601
}
586
602
587
603
604
+ /* This is exposed in the internal API, not the public API.
605
+ It is only called on builtin static types, which are all
606
+ initialized via _PyStructSequence_InitBuiltinWithFlags(). */
607
+
588
608
void
589
- _PyStructSequence_FiniType (PyTypeObject * type )
609
+ _PyStructSequence_FiniBuiltin (PyTypeObject * type )
590
610
{
591
611
// Ensure that the type is initialized
592
612
assert (type -> tp_name != NULL );
593
613
assert (type -> tp_base == & PyTuple_Type );
614
+ assert ((type -> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN ));
615
+ assert (_Py_IsImmortal (type ));
594
616
595
617
// Cannot delete a type if it still has subclasses
596
618
if (_PyType_HasSubclasses (type )) {
619
+ // XXX Shouldn't this be an error?
597
620
return ;
598
621
}
599
622
600
- // Undo PyStructSequence_NewType()
601
- type -> tp_name = NULL ;
602
- PyMem_Free (type -> tp_members );
603
-
604
623
_PyStaticType_Dealloc (type );
605
- assert (Py_REFCNT (type ) == 1 );
606
- // Undo Py_INCREF(type) of _PyStructSequence_InitType().
607
- // Don't use Py_DECREF(): static type must not be deallocated
608
- Py_SET_REFCNT (type , 0 );
609
- #ifdef Py_REF_DEBUG
610
- _Py_DecRefTotal (_PyInterpreterState_GET ());
611
- #endif
612
624
613
- // Make sure that _PyStructSequence_InitType() will initialize
614
- // the type again
615
- assert (Py_REFCNT (type ) == 0 );
616
- assert (type -> tp_name == NULL );
625
+ // Undo _PyStructSequence_InitBuiltinWithFlags().
626
+ type -> tp_name = NULL ;
627
+ PyMem_Free (type -> tp_members );
628
+ type -> tp_members = NULL ;
629
+ type -> tp_base = NULL ;
617
630
}
618
631
619
632
@@ -627,7 +640,8 @@ _PyStructSequence_NewType(PyStructSequence_Desc *desc, unsigned long tp_flags)
627
640
Py_ssize_t n_members , n_unnamed_members ;
628
641
629
642
/* Initialize MemberDefs */
630
- members = initialize_members (desc , & n_members , & n_unnamed_members );
643
+ n_members = count_members (desc , & n_unnamed_members );
644
+ members = initialize_members (desc , n_members , n_unnamed_members );
631
645
if (members == NULL ) {
632
646
return NULL ;
633
647
}
0 commit comments