@@ -536,9 +536,29 @@ PyFunction_SetClosure(PyObject *op, PyObject *closure)
536536 return 0 ;
537537}
538538
539+ static void
540+ func_set_annotations_and_annotate (PyFunctionObject * op , PyObject * annotations ,
541+ PyObject * annotate )
542+ {
543+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (op );
544+ // Care is needed, finalizers can run when references are dropped. Store
545+ // both new values before dropping references to the old.
546+ PyObject * old_annotations = op -> func_annotations ;
547+ PyObject * old_annotate = op -> func_annotate ;
548+ FT_ATOMIC_STORE_PTR_RELEASE (op -> func_annotations , annotations );
549+ FT_ATOMIC_STORE_PTR_RELEASE (op -> func_annotate , annotate );
550+ if (old_annotations != NULL && !_Py_IsImmortal (old_annotations )) {
551+ _PyObject_XDecRefDelayed (old_annotations );
552+ }
553+ if (old_annotate != NULL && !_Py_IsImmortal (old_annotate )) {
554+ _PyObject_XDecRefDelayed (old_annotate );
555+ }
556+ }
557+
539558static PyObject *
540559func_get_annotation_dict (PyFunctionObject * op )
541560{
561+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (op );
542562 if (op -> func_annotations == NULL ) {
543563 if (op -> func_annotate == NULL || !PyCallable_Check (op -> func_annotate )) {
544564 Py_RETURN_NONE ;
@@ -555,7 +575,7 @@ func_get_annotation_dict(PyFunctionObject *op)
555575 Py_DECREF (ann_dict );
556576 return NULL ;
557577 }
558- Py_XSETREF ( op -> func_annotations , ann_dict );
578+ _PyObject_XSetRefDelayed ( & op -> func_annotations , ann_dict );
559579 return ann_dict ;
560580 }
561581 if (PyTuple_CheckExact (op -> func_annotations )) {
@@ -577,7 +597,7 @@ func_get_annotation_dict(PyFunctionObject *op)
577597 return NULL ;
578598 }
579599 }
580- Py_SETREF ( op -> func_annotations , ann_dict );
600+ _PyObject_XSetRefDelayed ( & op -> func_annotations , ann_dict );
581601 }
582602 assert (PyDict_Check (op -> func_annotations ));
583603 return op -> func_annotations ;
@@ -590,7 +610,11 @@ PyFunction_GetAnnotations(PyObject *op)
590610 PyErr_BadInternalCall ();
591611 return NULL ;
592612 }
593- return func_get_annotation_dict ((PyFunctionObject * )op );
613+ PyObject * d ;
614+ Py_BEGIN_CRITICAL_SECTION (op );
615+ d = func_get_annotation_dict ((PyFunctionObject * )op );
616+ Py_END_CRITICAL_SECTION ();
617+ return d ;
594618}
595619
596620int
@@ -612,8 +636,7 @@ PyFunction_SetAnnotations(PyObject *op, PyObject *annotations)
612636 }
613637 PyFunctionObject * func = (PyFunctionObject * )op ;
614638 Py_BEGIN_CRITICAL_SECTION (func );
615- Py_XSETREF (func -> func_annotations , annotations );
616- Py_CLEAR (func -> func_annotate );
639+ func_set_annotations_and_annotate (func , annotations , NULL );
617640 Py_END_CRITICAL_SECTION ();
618641 return 0 ;
619642}
@@ -920,12 +943,11 @@ function___annotate___set_impl(PyFunctionObject *self, PyObject *value)
920943/*[clinic end generated code: output=05b7dfc07ada66cd input=eb6225e358d97448]*/
921944{
922945 if (Py_IsNone (value )) {
923- Py_XSETREF ( self -> func_annotate , Py_NewRef (value ));
946+ _PyObject_XSetRefDelayed ( & self -> func_annotate , Py_NewRef (value ));
924947 return 0 ;
925948 }
926949 else if (PyCallable_Check (value )) {
927- Py_XSETREF (self -> func_annotate , Py_NewRef (value ));
928- Py_CLEAR (self -> func_annotations );
950+ func_set_annotations_and_annotate (self , NULL , Py_NewRef (value ));
929951 return 0 ;
930952 }
931953 else {
@@ -950,9 +972,10 @@ function___annotations___get_impl(PyFunctionObject *self)
950972 PyObject * d = NULL ;
951973 if (self -> func_annotations == NULL &&
952974 (self -> func_annotate == NULL || !PyCallable_Check (self -> func_annotate ))) {
953- self -> func_annotations = PyDict_New ();
954- if (self -> func_annotations == NULL )
975+ PyObject * ann_dict = PyDict_New ();
976+ if (ann_dict == NULL )
955977 return NULL ;
978+ FT_ATOMIC_STORE_PTR_RELEASE (self -> func_annotations , ann_dict );
956979 }
957980 d = func_get_annotation_dict (self );
958981 return Py_XNewRef (d );
@@ -979,8 +1002,7 @@ function___annotations___set_impl(PyFunctionObject *self, PyObject *value)
9791002 "__annotations__ must be set to a dict object" );
9801003 return -1 ;
9811004 }
982- Py_XSETREF (self -> func_annotations , Py_XNewRef (value ));
983- Py_CLEAR (self -> func_annotate );
1005+ func_set_annotations_and_annotate (self , Py_XNewRef (value ), NULL );
9841006 return 0 ;
9851007}
9861008
0 commit comments