@@ -369,10 +369,11 @@ is_freezable_builtin(PyTypeObject *type)
369369}
370370
371371static 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