@@ -369,10 +369,10 @@ 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{
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