Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit99e2e60

Browse files
authored
gh-99139: Improve NameError error suggestion for instances (#99140)
1 parenta0bc75e commit99e2e60

File tree

7 files changed

+92
-0
lines changed

7 files changed

+92
-0
lines changed

‎Doc/whatsnew/3.12.rst‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,27 @@ Important deprecations, removals or restrictions:
7575
Improved Error Messages
7676
=======================
7777

78+
* Improve the error suggestion for:exc:`NameError` exceptions for instances.
79+
Now if a:exc:`NameError` is raised in a method and the instance has an
80+
attribute that's exactly equal to the name in the exception, the suggestion
81+
will include ``self.<NAME>`` instead of the closest match in the method
82+
scope. Contributed by Pablo Galindo in:gh:`99139`.
83+
84+
>>>classA:
85+
...def__init__(self):
86+
...self.blech=1
87+
...
88+
...deffoo(self):
89+
...somethin= blech
90+
91+
>>>A().foo()
92+
Traceback (most recent call last):
93+
File "<stdin>", line 1
94+
somethin = blech
95+
^^^^^
96+
NameError: name 'blech' is not defined. Did you mean: 'self.blech'?
97+
98+
7899
* Improve the:exc:`SyntaxError` error message when the user types ``import x
79100
from y`` instead of ``from y import x``. Contributed by Pablo Galindo in:gh:`98931`.
80101

‎Include/internal/pycore_global_strings.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,7 @@ struct _Py_global_strings {
600600
STRUCT_FOR_ID(seek)
601601
STRUCT_FOR_ID(seekable)
602602
STRUCT_FOR_ID(selectors)
603+
STRUCT_FOR_ID(self)
603604
STRUCT_FOR_ID(send)
604605
STRUCT_FOR_ID(sep)
605606
STRUCT_FOR_ID(sequence)

‎Include/internal/pycore_runtime_init_generated.h‎

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎Lib/test/test_traceback.py‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3356,6 +3356,31 @@ def func():
33563356

33573357
actual=self.get_suggestion(func)
33583358
self.assertNotIn("blech",actual)
3359+
3360+
deftest_name_error_with_instance(self):
3361+
classA:
3362+
def__init__(self):
3363+
self.blech=None
3364+
deffoo(self):
3365+
blich=1
3366+
x=blech
3367+
3368+
instance=A()
3369+
actual=self.get_suggestion(instance.foo)
3370+
self.assertIn("self.blech",actual)
3371+
3372+
deftest_unbound_local_error_with_instance(self):
3373+
classA:
3374+
def__init__(self):
3375+
self.blech=None
3376+
deffoo(self):
3377+
blich=1
3378+
x=blech
3379+
blech=1
3380+
3381+
instance=A()
3382+
actual=self.get_suggestion(instance.foo)
3383+
self.assertNotIn("self.blech",actual)
33593384

33603385
deftest_unbound_local_error_does_not_match(self):
33613386
deffunc():

‎Lib/traceback.py‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,16 @@ def _compute_suggestion_error(exc_value, tb, wrong_name):
10371037
+list(frame.f_globals)
10381038
+list(frame.f_builtins)
10391039
)
1040+
1041+
# Check first if we are in a method and the instance
1042+
# has the wrong name as attribute
1043+
if'self'inframe.f_locals:
1044+
self=frame.f_locals['self']
1045+
ifhasattr(self,wrong_name):
1046+
returnf"self.{wrong_name}"
1047+
1048+
# Compute closest match
1049+
10401050
iflen(d)>_MAX_CANDIDATE_ITEMS:
10411051
returnNone
10421052
wrong_name_len=len(wrong_name)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Improve the error suggestion for:exc:`NameError` exceptions for instances.
2+
Now if a:exc:`NameError` is raised in a method and the instance has an
3+
attribute that's exactly equal to the name in the exception, the suggestion
4+
will include ``self.<NAME>`` instead of the closest match in the method
5+
scope. Patch by Pablo Galindo

‎Python/suggestions.c‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include"Python.h"
22
#include"pycore_frame.h"
3+
#include"pycore_runtime_init.h"// _Py_ID()
34

45
#include"pycore_pyerrors.h"
56
#include"pycore_code.h"// _PyCode_GetVarnames()
@@ -226,6 +227,24 @@ get_suggestions_for_name_error(PyObject* name, PyFrameObject* frame)
226227
returnNULL;
227228
}
228229

230+
// Are we inside a method and the instance has an attribute called 'name'?
231+
if (PySequence_Contains(dir,&_Py_ID(self))>0) {
232+
PyObject*locals=PyFrame_GetLocals(frame);
233+
if (!locals) {
234+
gotoerror;
235+
}
236+
PyObject*self=PyDict_GetItem(locals,&_Py_ID(self));/* borrowed */
237+
Py_DECREF(locals);
238+
if (!self) {
239+
gotoerror;
240+
}
241+
242+
if (PyObject_HasAttr(self,name)) {
243+
Py_DECREF(dir);
244+
returnPyUnicode_FromFormat("self.%S",name);
245+
}
246+
}
247+
229248
PyObject*suggestions=calculate_suggestions(dir,name);
230249
Py_DECREF(dir);
231250
if (suggestions!=NULL) {
@@ -250,6 +269,10 @@ get_suggestions_for_name_error(PyObject* name, PyFrameObject* frame)
250269
Py_DECREF(dir);
251270

252271
returnsuggestions;
272+
273+
error:
274+
Py_DECREF(dir);
275+
returnNULL;
253276
}
254277

255278
staticbool

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp