@@ -112,7 +112,8 @@ converting the dict to the combined table.
112112
113113#include "Python.h"
114114#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
115- #include "pycore_object.h"
115+ #include "pycore_object.h" // _PyObject_GC_TRACK()
116+ #include "pycore_pyerrors.h" // _PyErr_Fetch()
116117#include "pycore_pystate.h" // _PyThreadState_GET()
117118#include "dict-common.h"
118119#include "stringlib/eq.h" // unicode_eq()
@@ -1387,14 +1388,12 @@ _PyDict_NewPresized(Py_ssize_t minused)
13871388PyObject *
13881389PyDict_GetItem (PyObject * op , PyObject * key )
13891390{
1390- Py_hash_t hash ;
1391- Py_ssize_t ix ;
1391+ if (!PyDict_Check (op )) {
1392+ return NULL ;
1393+ }
13921394 PyDictObject * mp = (PyDictObject * )op ;
1393- PyThreadState * tstate ;
1394- PyObject * value ;
13951395
1396- if (!PyDict_Check (op ))
1397- return NULL ;
1396+ Py_hash_t hash ;
13981397 if (!PyUnicode_CheckExact (key ) ||
13991398 (hash = ((PyASCIIObject * ) key )-> hash ) == -1 )
14001399 {
@@ -1405,28 +1404,26 @@ PyDict_GetItem(PyObject *op, PyObject *key)
14051404 }
14061405 }
14071406
1408- /* We can arrive here with a NULL tstate during initialization: try
1409- running "python -Wi" for an example related to string interning.
1410- Let's just hope that no exception occurs then... This must be
1411- _PyThreadState_GET() and not PyThreadState_Get() because the latter
1412- abort Python if tstate is NULL. */
1413- tstate = _PyThreadState_GET ();
1414- if (tstate != NULL && tstate -> curexc_type != NULL ) {
1415- /* preserve the existing exception */
1416- PyObject * err_type , * err_value , * err_tb ;
1417- PyErr_Fetch (& err_type , & err_value , & err_tb );
1418- ix = (mp -> ma_keys -> dk_lookup )(mp , key , hash , & value );
1419- /* ignore errors */
1420- PyErr_Restore (err_type , err_value , err_tb );
1421- if (ix < 0 )
1422- return NULL ;
1423- }
1424- else {
1425- ix = (mp -> ma_keys -> dk_lookup )(mp , key , hash , & value );
1426- if (ix < 0 ) {
1427- PyErr_Clear ();
1428- return NULL ;
1429- }
1407+ PyThreadState * tstate = _PyThreadState_GET ();
1408+ #ifdef Py_DEBUG
1409+ // bpo-40839: Before Python 3.10, it was possible to call PyDict_GetItem()
1410+ // with the GIL released.
1411+ _Py_EnsureTstateNotNULL (tstate );
1412+ #endif
1413+
1414+ /* Preserve the existing exception */
1415+ PyObject * exc_type , * exc_value , * exc_tb ;
1416+ PyObject * value ;
1417+ Py_ssize_t ix ;
1418+
1419+ _PyErr_Fetch (tstate , & exc_type , & exc_value , & exc_tb );
1420+ ix = (mp -> ma_keys -> dk_lookup )(mp , key , hash , & value );
1421+
1422+ /* Ignore any exception raised by the lookup */
1423+ _PyErr_Restore (tstate , exc_type , exc_value , exc_tb );
1424+
1425+ if (ix < 0 ) {
1426+ return NULL ;
14301427 }
14311428 return value ;
14321429}
0 commit comments