@@ -21,7 +21,8 @@ static PyMemberDef frame_memberlist[] = {
2121static PyObject *
2222frame_getlocals (PyFrameObject * f , void * closure )
2323{
24- PyFrame_FastToLocals (f );
24+ if (PyFrame_FastToLocalsWithError (f ) < 0 )
25+ return NULL ;
2526 Py_INCREF (f -> f_locals );
2627 return f -> f_locals ;
2728}
@@ -772,12 +773,9 @@ PyFrame_BlockPop(PyFrameObject *f)
772773 If deref is true, then the values being copied are cell variables
773774 and the value is extracted from the cell variable before being put
774775 in dict.
775-
776- Exceptions raised while modifying the dict are silently ignored,
777- because there is no good way to report them.
778776 */
779777
780- static void
778+ static int
781779map_to_dict (PyObject * map , Py_ssize_t nmap , PyObject * dict , PyObject * * values ,
782780 int deref )
783781{
@@ -794,14 +792,19 @@ map_to_dict(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values,
794792 value = PyCell_GET (value );
795793 }
796794 if (value == NULL ) {
797- if (PyObject_DelItem (dict , key ) != 0 )
798- PyErr_Clear ();
795+ if (PyObject_DelItem (dict , key ) != 0 ) {
796+ if (PyErr_ExceptionMatches (PyExc_KeyError ))
797+ PyErr_Clear ();
798+ else
799+ return -1 ;
800+ }
799801 }
800802 else {
801803 if (PyObject_SetItem (dict , key , value ) != 0 )
802- PyErr_Clear () ;
804+ return -1 ;
803805 }
804806 }
807+ return 0 ;
805808}
806809
807810/* Copy values from the "locals" dict into the fast locals.
@@ -858,42 +861,49 @@ dict_to_map(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values,
858861 }
859862}
860863
861- void
862- PyFrame_FastToLocals (PyFrameObject * f )
864+ int
865+ PyFrame_FastToLocalsWithError (PyFrameObject * f )
863866{
864867 /* Merge fast locals into f->f_locals */
865868 PyObject * locals , * map ;
866869 PyObject * * fast ;
867- PyObject * error_type , * error_value , * error_traceback ;
868870 PyCodeObject * co ;
869871 Py_ssize_t j ;
870872 Py_ssize_t ncells , nfreevars ;
871- if (f == NULL )
872- return ;
873+
874+ if (f == NULL ) {
875+ PyErr_BadInternalCall ();
876+ return -1 ;
877+ }
873878 locals = f -> f_locals ;
874879 if (locals == NULL ) {
875880 locals = f -> f_locals = PyDict_New ();
876- if (locals == NULL ) {
877- PyErr_Clear (); /* Can't report it :-( */
878- return ;
879- }
881+ if (locals == NULL )
882+ return -1 ;
880883 }
881884 co = f -> f_code ;
882885 map = co -> co_varnames ;
883- if (!PyTuple_Check (map ))
884- return ;
885- PyErr_Fetch (& error_type , & error_value , & error_traceback );
886+ if (!PyTuple_Check (map )) {
887+ PyErr_Format (PyExc_SystemError ,
888+ "co_varnames must be a tuple, not %s" ,
889+ Py_TYPE (map )-> tp_name );
890+ return -1 ;
891+ }
886892 fast = f -> f_localsplus ;
887893 j = PyTuple_GET_SIZE (map );
888894 if (j > co -> co_nlocals )
889895 j = co -> co_nlocals ;
890- if (co -> co_nlocals )
891- map_to_dict (map , j , locals , fast , 0 );
896+ if (co -> co_nlocals ) {
897+ if (map_to_dict (map , j , locals , fast , 0 ) < 0 )
898+ return -1 ;
899+ }
892900 ncells = PyTuple_GET_SIZE (co -> co_cellvars );
893901 nfreevars = PyTuple_GET_SIZE (co -> co_freevars );
894902 if (ncells || nfreevars ) {
895- map_to_dict (co -> co_cellvars , ncells ,
896- locals , fast + co -> co_nlocals , 1 );
903+ if (map_to_dict (co -> co_cellvars , ncells ,
904+ locals , fast + co -> co_nlocals , 1 ))
905+ return -1 ;
906+
897907 /* If the namespace is unoptimized, then one of the
898908 following cases applies:
899909 1. It does not contain free variables, because it
@@ -903,11 +913,24 @@ PyFrame_FastToLocals(PyFrameObject *f)
903913 into the locals dict used by the class.
904914 */
905915 if (co -> co_flags & CO_OPTIMIZED ) {
906- map_to_dict (co -> co_freevars , nfreevars ,
907- locals , fast + co -> co_nlocals + ncells , 1 );
916+ if (map_to_dict (co -> co_freevars , nfreevars ,
917+ locals , fast + co -> co_nlocals + ncells , 1 ) < 0 )
918+ return -1 ;
908919 }
909920 }
910- PyErr_Restore (error_type , error_value , error_traceback );
921+ return 0 ;
922+ }
923+
924+ void
925+ PyFrame_FastToLocals (PyFrameObject * f )
926+ {
927+ int res ;
928+
929+ assert (!PyErr_Occurred ());
930+
931+ res = PyFrame_FastToLocalsWithError (f );
932+ if (res < 0 )
933+ PyErr_Clear ();
911934}
912935
913936void
0 commit comments