@@ -151,15 +151,15 @@ calculate_suggestions(PyObject *dir,
151151 }
152152 for (int i = 0 ; i < dir_size ; ++ i ) {
153153 PyObject * item = PyList_GET_ITEM (dir , i );
154+ if (_PyUnicode_Equal (name , item )) {
155+ continue ;
156+ }
154157 Py_ssize_t item_size ;
155158 const char * item_str = PyUnicode_AsUTF8AndSize (item , & item_size );
156159 if (item_str == NULL ) {
157160 PyMem_Free (buffer );
158161 return NULL ;
159162 }
160- if (PyUnicode_CompareWithASCIIString (name , item_str ) == 0 ) {
161- continue ;
162- }
163163 // No more than 1/3 of the involved characters should need changed.
164164 Py_ssize_t max_distance = (name_size + item_size + 3 ) * MOVE_COST / 6 ;
165165 // Don't take matches we've already beaten.
@@ -220,37 +220,48 @@ get_suggestions_for_name_error(PyObject* name, PyFrameObject* frame)
220220 assert (code != NULL && code -> co_localsplusnames != NULL );
221221
222222 PyObject * varnames = _PyCode_GetVarnames (code );
223+ Py_DECREF (code );
223224 if (varnames == NULL ) {
224225 return NULL ;
225226 }
226227 PyObject * dir = PySequence_List (varnames );
227228 Py_DECREF (varnames );
228- Py_DECREF (code );
229229 if (dir == NULL ) {
230230 return NULL ;
231231 }
232232
233233 // Are we inside a method and the instance has an attribute called 'name'?
234- if (PySequence_Contains (dir , & _Py_ID (self )) > 0 ) {
234+ int res = PySequence_Contains (dir , & _Py_ID (self ));
235+ if (res < 0 ) {
236+ goto error ;
237+ }
238+ if (res > 0 ) {
235239 PyObject * locals = PyFrame_GetLocals (frame );
236240 if (!locals ) {
237241 goto error ;
238242 }
239- PyObject * self = PyDict_GetItem (locals , & _Py_ID (self )); /* borrowed */
240- Py_DECREF (locals );
243+ PyObject * self = PyDict_GetItemWithError (locals , & _Py_ID (self )); /* borrowed */
241244 if (!self ) {
245+ Py_DECREF (locals );
242246 goto error ;
243247 }
244248
245- if (PyObject_HasAttr (self , name )) {
249+ PyObject * value ;
250+ res = _PyObject_LookupAttr (self , name , & value );
251+ Py_DECREF (locals );
252+ if (res < 0 ) {
253+ goto error ;
254+ }
255+ if (value ) {
256+ Py_DECREF (value );
246257 Py_DECREF (dir );
247- return PyUnicode_FromFormat ("self.%S " , name );
258+ return PyUnicode_FromFormat ("self.%U " , name );
248259 }
249260 }
250261
251262 PyObject * suggestions = calculate_suggestions (dir , name );
252263 Py_DECREF (dir );
253- if (suggestions != NULL ) {
264+ if (suggestions != NULL || PyErr_Occurred () ) {
254265 return suggestions ;
255266 }
256267
@@ -260,7 +271,7 @@ get_suggestions_for_name_error(PyObject* name, PyFrameObject* frame)
260271 }
261272 suggestions = calculate_suggestions (dir , name );
262273 Py_DECREF (dir );
263- if (suggestions != NULL ) {
274+ if (suggestions != NULL || PyErr_Occurred () ) {
264275 return suggestions ;
265276 }
266277
@@ -319,15 +330,16 @@ offer_suggestions_for_name_error(PyNameErrorObject *exc)
319330 assert (frame != NULL );
320331
321332 PyObject * suggestion = get_suggestions_for_name_error (name , frame );
322- bool is_stdlib_module = is_name_stdlib_module (name );
323-
324- if (suggestion == NULL && !is_stdlib_module ) {
333+ if (suggestion == NULL && PyErr_Occurred ()) {
325334 return NULL ;
326335 }
327336
328337 // Add a trailer ". Did you mean: (...)?"
329338 PyObject * result = NULL ;
330- if (!is_stdlib_module ) {
339+ if (!is_name_stdlib_module (name )) {
340+ if (suggestion == NULL ) {
341+ return NULL ;
342+ }
331343 result = PyUnicode_FromFormat (". Did you mean: %R?" , suggestion );
332344 } else if (suggestion == NULL ) {
333345 result = PyUnicode_FromFormat (". Did you forget to import %R?" , name );
0 commit comments