@@ -178,225 +178,6 @@ _Py_CalculateSuggestions(PyObject *dir,
178
178
return Py_XNewRef (suggestion );
179
179
}
180
180
181
- static PyObject *
182
- get_suggestions_for_attribute_error (PyAttributeErrorObject * exc )
183
- {
184
- PyObject * name = exc -> name ; // borrowed reference
185
- PyObject * obj = exc -> obj ; // borrowed reference
186
-
187
- // Abort if we don't have an attribute name or we have an invalid one
188
- if (name == NULL || obj == NULL || !PyUnicode_CheckExact (name )) {
189
- return NULL ;
190
- }
191
-
192
- PyObject * dir = PyObject_Dir (obj );
193
- if (dir == NULL ) {
194
- return NULL ;
195
- }
196
-
197
- PyObject * suggestions = _Py_CalculateSuggestions (dir , name );
198
- Py_DECREF (dir );
199
- return suggestions ;
200
- }
201
-
202
- static PyObject *
203
- offer_suggestions_for_attribute_error (PyAttributeErrorObject * exc )
204
- {
205
- PyObject * suggestion = get_suggestions_for_attribute_error (exc );
206
- if (suggestion == NULL ) {
207
- return NULL ;
208
- }
209
- // Add a trailer ". Did you mean: (...)?"
210
- PyObject * result = PyUnicode_FromFormat (". Did you mean: %R?" , suggestion );
211
- Py_DECREF (suggestion );
212
- return result ;
213
- }
214
-
215
- static PyObject *
216
- get_suggestions_for_name_error (PyObject * name , PyFrameObject * frame )
217
- {
218
- PyCodeObject * code = PyFrame_GetCode (frame );
219
- assert (code != NULL && code -> co_localsplusnames != NULL );
220
-
221
- PyObject * varnames = _PyCode_GetVarnames (code );
222
- Py_DECREF (code );
223
- if (varnames == NULL ) {
224
- return NULL ;
225
- }
226
- PyObject * dir = PySequence_List (varnames );
227
- Py_DECREF (varnames );
228
- if (dir == NULL ) {
229
- return NULL ;
230
- }
231
-
232
- // Are we inside a method and the instance has an attribute called 'name'?
233
- int res = PySequence_Contains (dir , & _Py_ID (self ));
234
- if (res < 0 ) {
235
- goto error ;
236
- }
237
- if (res > 0 ) {
238
- PyObject * locals = PyFrame_GetLocals (frame );
239
- if (!locals ) {
240
- goto error ;
241
- }
242
- PyObject * self = PyDict_GetItemWithError (locals , & _Py_ID (self )); /* borrowed */
243
- if (!self ) {
244
- Py_DECREF (locals );
245
- goto error ;
246
- }
247
-
248
- res = PyObject_HasAttrWithError (self , name );
249
- Py_DECREF (locals );
250
- if (res < 0 ) {
251
- goto error ;
252
- }
253
- if (res ) {
254
- Py_DECREF (dir );
255
- return PyUnicode_FromFormat ("self.%U" , name );
256
- }
257
- }
258
-
259
- PyObject * suggestions = _Py_CalculateSuggestions (dir , name );
260
- Py_DECREF (dir );
261
- if (suggestions != NULL || PyErr_Occurred ()) {
262
- return suggestions ;
263
- }
264
-
265
- dir = PySequence_List (frame -> f_frame -> f_globals );
266
- if (dir == NULL ) {
267
- return NULL ;
268
- }
269
- suggestions = _Py_CalculateSuggestions (dir , name );
270
- Py_DECREF (dir );
271
- if (suggestions != NULL || PyErr_Occurred ()) {
272
- return suggestions ;
273
- }
274
-
275
- dir = PySequence_List (frame -> f_frame -> f_builtins );
276
- if (dir == NULL ) {
277
- return NULL ;
278
- }
279
- suggestions = _Py_CalculateSuggestions (dir , name );
280
- Py_DECREF (dir );
281
-
282
- return suggestions ;
283
-
284
- error :
285
- Py_DECREF (dir );
286
- return NULL ;
287
- }
288
-
289
- static bool
290
- is_name_stdlib_module (PyObject * name )
291
- {
292
- const char * the_name = PyUnicode_AsUTF8 (name );
293
- Py_ssize_t len = Py_ARRAY_LENGTH (_Py_stdlib_module_names );
294
- for (Py_ssize_t i = 0 ; i < len ; i ++ ) {
295
- if (strcmp (the_name , _Py_stdlib_module_names [i ]) == 0 ) {
296
- return 1 ;
297
- }
298
- }
299
- return 0 ;
300
- }
301
-
302
- static PyObject *
303
- offer_suggestions_for_name_error (PyNameErrorObject * exc )
304
- {
305
- PyObject * name = exc -> name ; // borrowed reference
306
- PyTracebackObject * traceback = (PyTracebackObject * ) exc -> traceback ; // borrowed reference
307
- // Abort if we don't have a variable name or we have an invalid one
308
- // or if we don't have a traceback to work with
309
- if (name == NULL || !PyUnicode_CheckExact (name ) ||
310
- traceback == NULL || !Py_IS_TYPE (traceback , & PyTraceBack_Type )
311
- ) {
312
- return NULL ;
313
- }
314
-
315
- // Move to the traceback of the exception
316
- while (1 ) {
317
- PyTracebackObject * next = traceback -> tb_next ;
318
- if (next == NULL || !Py_IS_TYPE (next , & PyTraceBack_Type )) {
319
- break ;
320
- }
321
- else {
322
- traceback = next ;
323
- }
324
- }
325
-
326
- PyFrameObject * frame = traceback -> tb_frame ;
327
- assert (frame != NULL );
328
-
329
- PyObject * suggestion = get_suggestions_for_name_error (name , frame );
330
- if (suggestion == NULL && PyErr_Occurred ()) {
331
- return NULL ;
332
- }
333
-
334
- // Add a trailer ". Did you mean: (...)?"
335
- PyObject * result = NULL ;
336
- if (!is_name_stdlib_module (name )) {
337
- if (suggestion == NULL ) {
338
- return NULL ;
339
- }
340
- result = PyUnicode_FromFormat (". Did you mean: %R?" , suggestion );
341
- } else if (suggestion == NULL ) {
342
- result = PyUnicode_FromFormat (". Did you forget to import %R?" , name );
343
- } else {
344
- result = PyUnicode_FromFormat (". Did you mean: %R? Or did you forget to import %R?" , suggestion , name );
345
- }
346
- Py_XDECREF (suggestion );
347
- return result ;
348
- }
349
-
350
- static PyObject *
351
- offer_suggestions_for_import_error (PyImportErrorObject * exc )
352
- {
353
- PyObject * mod_name = exc -> name ; // borrowed reference
354
- PyObject * name = exc -> name_from ; // borrowed reference
355
- if (name == NULL || mod_name == NULL || name == Py_None ||
356
- !PyUnicode_CheckExact (name ) || !PyUnicode_CheckExact (mod_name )) {
357
- return NULL ;
358
- }
359
-
360
- PyObject * mod = PyImport_GetModule (mod_name );
361
- if (mod == NULL ) {
362
- return NULL ;
363
- }
364
-
365
- PyObject * dir = PyObject_Dir (mod );
366
- Py_DECREF (mod );
367
- if (dir == NULL ) {
368
- return NULL ;
369
- }
370
-
371
- PyObject * suggestion = _Py_CalculateSuggestions (dir , name );
372
- Py_DECREF (dir );
373
- if (!suggestion ) {
374
- return NULL ;
375
- }
376
-
377
- PyObject * result = PyUnicode_FromFormat (". Did you mean: %R?" , suggestion );
378
- Py_DECREF (suggestion );
379
- return result ;
380
- }
381
-
382
- // Offer suggestions for a given exception. Returns a python string object containing the
383
- // suggestions. This function returns NULL if no suggestion was found or if an exception happened,
384
- // users must call PyErr_Occurred() to disambiguate.
385
- PyObject *
386
- _Py_Offer_Suggestions (PyObject * exception )
387
- {
388
- PyObject * result = NULL ;
389
- assert (!PyErr_Occurred ());
390
- if (Py_IS_TYPE (exception , (PyTypeObject * )PyExc_AttributeError )) {
391
- result = offer_suggestions_for_attribute_error ((PyAttributeErrorObject * ) exception );
392
- } else if (Py_IS_TYPE (exception , (PyTypeObject * )PyExc_NameError )) {
393
- result = offer_suggestions_for_name_error ((PyNameErrorObject * ) exception );
394
- } else if (Py_IS_TYPE (exception , (PyTypeObject * )PyExc_ImportError )) {
395
- result = offer_suggestions_for_import_error ((PyImportErrorObject * ) exception );
396
- }
397
- return result ;
398
- }
399
-
400
181
Py_ssize_t
401
182
_Py_UTF8_Edit_Cost (PyObject * a , PyObject * b , Py_ssize_t max_cost )
402
183
{
0 commit comments