Skip to content

Commit 6d3fa7b

Browse files
committed
Fix check_freezable only checking object types
1 parent fe61776 commit 6d3fa7b

1 file changed

Lines changed: 19 additions & 7 deletions

File tree

Python/immutability.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -369,10 +369,11 @@ 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
{
374+
374375
int result = 0;
375-
PyObject *ref = type_weakref(state, (PyObject *)obj->ob_type);
376+
PyObject *ref = type_weakref(state, (PyObject *)obj);
376377
if(ref == NULL){
377378
return -1;
378379
}
@@ -413,19 +414,28 @@ static FreezableCheck check_freezable(struct _Py_immutability_state *state, PyOb
413414
return INVALID_NOT_FREEZABLE;
414415
}
415416

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

420-
result = is_explicitly_freezable(state, obj);
430+
result = is_explicitly_freezable(state, ty);
421431
if(result == -1){
422432
return ERROR;
423433
}
424434
else if(result == 1){
425435
return VALID_EXPLICIT;
426436
}
427437

428-
if(_PyType_HasExtensionSlots(obj->ob_type)){
438+
if(_PyType_HasExtensionSlots(ty)){
429439
return INVALID_C_EXTENSIONS;
430440
}
431441

@@ -519,9 +529,11 @@ int _PyImmutability_Freeze(PyObject* obj)
519529
goto error;
520530

521531
case INVALID_C_EXTENSIONS:
532+
assert(Py_IS_TYPE(obj, &PyType_Type));
533+
PyTypeObject* ty = (PyTypeObject*) item;
522534
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));
535+
"Cannot freeze type %s due to custom functionality implemented in C",
536+
(ty->tp_name));
525537
PyErr_SetObject(PyExc_TypeError, error_msg);
526538
goto error;
527539

0 commit comments

Comments
 (0)