Skip to content

Commit 77a1f6a

Browse files
committed
Fix check_freezable only checking object types
1 parent fe61776 commit 77a1f6a

2 files changed

Lines changed: 19 additions & 7 deletions

File tree

Objects/typeobject.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12763,6 +12763,7 @@ _PyType_HasExtensionSlots(PyTypeObject *tp)
1276312763
PySequenceMethods *base_sq = base->tp_as_sequence;
1276412764
EXT_TEST(sq, length);
1276512765
EXT_TEST(sq, concat);
12766+
EXT_TEST(sq, repeat);
1276612767
EXT_TEST(sq, item);
1276712768
EXT_TEST(sq, ass_item);
1276812769
EXT_TEST(sq, contains);

Python/immutability.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -369,10 +369,10 @@ is_freezable_builtin(PyTypeObject *type)
369369
}
370370

371371
static int
372-
is_explicitly_freezable(struct _Py_immutability_state *state, PyObject *obj)
372+
is_explicitly_freezable(struct _Py_immutability_state *state, PyTypeObject *obj)
373373
{
374374
int result = 0;
375-
PyObject *ref = type_weakref(state, (PyObject *)obj->ob_type);
375+
PyObject *ref = type_weakref(state, (PyObject *)obj);
376376
if(ref == NULL){
377377
return -1;
378378
}
@@ -413,19 +413,28 @@ static FreezableCheck check_freezable(struct _Py_immutability_state *state, PyOb
413413
return INVALID_NOT_FREEZABLE;
414414
}
415415

416-
if(is_freezable_builtin(obj->ob_type)){
416+
// The following checks only apply to type objects. At this point
417+
// we know that all objects reachable by `obj` can be frozen,
418+
// including the type. Unfreezeable types will therefore block `obj`
419+
// from being frozen before this point.
420+
if (!Py_IS_TYPE(obj, &PyType_Type)) {
421+
return VALID_IMPLICIT;
422+
}
423+
424+
PyTypeObject* ty = (PyTypeObject*) obj;
425+
if(is_freezable_builtin(ty)){
417426
return VALID_BUILTIN;
418427
}
419428

420-
result = is_explicitly_freezable(state, obj);
429+
result = is_explicitly_freezable(state, ty);
421430
if(result == -1){
422431
return ERROR;
423432
}
424433
else if(result == 1){
425434
return VALID_EXPLICIT;
426435
}
427436

428-
if(_PyType_HasExtensionSlots(obj->ob_type)){
437+
if(_PyType_HasExtensionSlots(ty)){
429438
return INVALID_C_EXTENSIONS;
430439
}
431440

@@ -519,9 +528,11 @@ int _PyImmutability_Freeze(PyObject* obj)
519528
goto error;
520529

521530
case INVALID_C_EXTENSIONS:
531+
assert(Py_IS_TYPE(obj, &PyType_Type));
532+
PyTypeObject* ty = (PyTypeObject*) item;
522533
PyObject* error_msg = PyUnicode_FromFormat(
523-
"Cannot freeze instance of type %s due to custom functionality implemented in C",
524-
(item->ob_type->tp_name));
534+
"Cannot freeze type %s due to custom functionality implemented in C",
535+
(ty->tp_name));
525536
PyErr_SetObject(PyExc_TypeError, error_msg);
526537
goto error;
527538

0 commit comments

Comments
 (0)