@@ -3621,7 +3621,7 @@ static void object_dealloc(PyObject *);
3621
3621
static PyObject * object_new (PyTypeObject * ,PyObject * ,PyObject * );
3622
3622
static int object_init (PyObject * ,PyObject * ,PyObject * );
3623
3623
static int update_slot (PyTypeObject * ,PyObject * );
3624
- static void fixup_slot_dispatchers (PyTypeObject * );
3624
+ static int fixup_slot_dispatchers (PyTypeObject * );
3625
3625
static int type_new_set_names (PyTypeObject * );
3626
3626
static int type_new_init_subclass (PyTypeObject * ,PyObject * );
3627
3627
@@ -4577,7 +4577,9 @@ type_new_impl(type_new_ctx *ctx)
4577
4577
}
4578
4578
4579
4579
// Put the proper slots in place
4580
- fixup_slot_dispatchers (type );
4580
+ if (fixup_slot_dispatchers (type )< 0 ) {
4581
+ gotoerror ;
4582
+ }
4581
4583
4582
4584
if (!_PyDict_HasOnlyStringKeys (type -> tp_dict )) {
4583
4585
if (PyErr_WarnFormat (
@@ -11329,10 +11331,12 @@ update_slot(PyTypeObject *type, PyObject *name)
11329
11331
11330
11332
/* Store the proper functions in the slot dispatches at class (type)
11331
11333
definition time, based upon which operations the class overrides in its
11332
- dict. */
11333
- static void
11334
+ dict.Returns -1 and exception set on error or 0 otherwise. */
11335
+ static int
11334
11336
fixup_slot_dispatchers (PyTypeObject * type )
11335
11337
{
11338
+ int res = 0 ;
11339
+
11336
11340
// This lock isn't strictly necessary because the type has not been
11337
11341
// exposed to anyone else yet, but update_ont_slot calls find_name_in_mro
11338
11342
// where we'd like to assert that the type is locked.
@@ -11341,10 +11345,11 @@ fixup_slot_dispatchers(PyTypeObject *type)
11341
11345
PyObject * mro = lookup_tp_mro (type );
11342
11346
assert (mro );
11343
11347
11344
- // Try to prebuild MRO dict. If we fails then clear mro_dict and
11345
- // reset error flag because we don't expect any exceptions. If
11346
- // fails to prebuild MRO dict then update_on_slot will use
11347
- // previous version of find_name_in_mro.
11348
+ // Try to prebuild MRO dict. We build it in bottom-top manner,
11349
+ // from bottom base to the top one, because the bottommost base
11350
+ // has more items then other and copying it is preferable than
11351
+ // merging.
11352
+ // If we fails, then stop init type.
11348
11353
PyObject * mro_dict = NULL ;
11349
11354
Py_ssize_t n = PyTuple_GET_SIZE (mro );
11350
11355
for (Py_ssize_t i = 0 ;i < n ;i ++ ) {
@@ -11355,26 +11360,31 @@ fixup_slot_dispatchers(PyTypeObject *type)
11355
11360
if (i == 0 ) {
11356
11361
mro_dict = PyDict_Copy (dict );
11357
11362
if (!mro_dict ) {
11358
- PyErr_Clear () ;
11359
- break ;
11363
+ res = -1 ;
11364
+ goto finish ;
11360
11365
}
11361
11366
}else {
11362
11367
if (PyDict_Merge (mro_dict ,dict ,1 )< 0 ) {
11363
- Py_CLEAR (mro_dict );
11364
- PyErr_Clear ();
11365
- break ;
11368
+ res = -1 ;
11369
+ gotofinish ;
11366
11370
}
11367
11371
}
11368
11372
}
11369
11373
11374
+ assert (!res );
11375
+ assert (mro_dict );
11370
11376
assert (!PyErr_Occurred ());
11371
11377
for (pytype_slotdef * p = slotdefs ;p -> name ; ) {
11372
11378
p = update_one_slot (type ,p ,mro_dict );
11373
11379
}
11374
11380
11381
+ assert (!PyErr_Occurred ());
11382
+
11383
+ finish :
11375
11384
Py_XDECREF (mro_dict );
11376
11385
11377
11386
END_TYPE_LOCK ();
11387
+ return res ;
11378
11388
}
11379
11389
11380
11390
static void