Skip to content

Commit dbd88f0

Browse files
committed
More
1 parent 61d510b commit dbd88f0

File tree

4 files changed

+46
-41
lines changed

4 files changed

+46
-41
lines changed

Include/internal/pycore_suggestions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
# error "this header requires Py_BUILD_CORE define"
88
#endif
99

10-
int _Py_offer_suggestions(PyObject* exception, PyObject* value);
10+
int _Py_Offer_Suggestions(PyObject* exception, PyObject* value);
1111

1212
#endif /* !Py_INTERNAL_SUGGESTIONS_H */

Objects/object.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -889,15 +889,17 @@ static inline int
889889
set_attribute_error_context(PyObject* v, PyObject* name)
890890
{
891891
assert(PyErr_Occurred());
892+
_Py_IDENTIFIER(name);
893+
_Py_IDENTIFIER(obj);
892894
// Intercept AttributeError exceptions and augment them to offer
893895
// suggestions later.
894896
if (PyErr_ExceptionMatches(PyExc_AttributeError)){
895897
PyObject *type, *value, *traceback;
896898
PyErr_Fetch(&type, &value, &traceback);
897899
PyErr_NormalizeException(&type, &value, &traceback);
898900
if (PyErr_GivenExceptionMatches(value, PyExc_AttributeError) &&
899-
(PyObject_SetAttrString(value, "name", name) ||
900-
PyObject_SetAttrString(value, "obj", v))) {
901+
(_PyObject_SetAttrId(value, &PyId_name, name) ||
902+
_PyObject_SetAttrId(value, &PyId_obj, v))) {
901903
return 1;
902904
}
903905
PyErr_Restore(type, value, traceback);
@@ -922,19 +924,20 @@ PyObject_GetAttr(PyObject *v, PyObject *name)
922924
}
923925
else if (tp->tp_getattr != NULL) {
924926
const char *name_str = PyUnicode_AsUTF8(name);
925-
if (name_str == NULL)
927+
if (name_str == NULL) {
926928
return NULL;
929+
}
927930
result = (*tp->tp_getattr)(v, (char *)name_str);
928-
} else {
931+
}
932+
else {
929933
PyErr_Format(PyExc_AttributeError,
930934
"'%.50s' object has no attribute '%U'",
931935
tp->tp_name, name);
932936
}
933937

934-
if (!result && set_attribute_error_context(v, name)) {
935-
return NULL;
938+
if (result == NULL) {
939+
set_attribute_error_context(v, name);
936940
}
937-
938941
return result;
939942
}
940943

@@ -1195,10 +1198,7 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method)
11951198
"'%.50s' object has no attribute '%U'",
11961199
tp->tp_name, name);
11971200

1198-
if (set_attribute_error_context(obj, name)) {
1199-
return 0;
1200-
}
1201-
1201+
set_attribute_error_context(obj, name);
12021202
return 0;
12031203
}
12041204

Python/pythonrun.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include "errcode.h" // E_EOF
2525
#include "code.h" // PyCodeObject
2626
#include "marshal.h" // PyMarshal_ReadLongFromFile()
27-
#include "pycore_suggestions.h" // _Py_offer_suggestions
27+
#include "pycore_suggestions.h" // _Py_Offer_Suggestions
2828

2929
#ifdef MS_WINDOWS
3030
# include "malloc.h" // alloca()
@@ -1082,7 +1082,7 @@ PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
10821082
return;
10831083
}
10841084

1085-
if (_Py_offer_suggestions(exception, value) != 0) {
1085+
if (_Py_Offer_Suggestions(exception, value) != 0) {
10861086
return;
10871087
}
10881088

Python/suggestions.c

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ distance(const char *string1, const char *string2)
5959
/* initalize first row */
6060
row = (size_t*)PyMem_Malloc(len2*sizeof(size_t));
6161
if (!row) {
62-
return (size_t)(-1);
62+
return (Py_ssize_t)(-1);
6363
}
6464
end = row + len2 - 1;
6565
for (i = 0; i < len2 - half; i++) {
@@ -72,7 +72,7 @@ distance(const char *string1, const char *string2)
7272
* necessary */
7373
row[0] = len1 - half - 1;
7474
for (i = 1; i < len1; i++) {
75-
size_t *p;
75+
size_t *scan_ptr;
7676
const char char1 = string1[i - 1];
7777
const char *char2p;
7878
size_t D, x;
@@ -82,17 +82,18 @@ distance(const char *string1, const char *string2)
8282
size_t c3;
8383

8484
char2p = string2 + offset;
85-
p = row + offset;
86-
c3 = *(p++) + (char1 != *(char2p++));
87-
x = *p;
85+
scan_ptr = row + offset;
86+
c3 = *(scan_ptr++) + (char1 != *(char2p++));
87+
x = *scan_ptr;
8888
x++;
8989
D = x;
90-
if (x > c3)
90+
if (x > c3) {
9191
x = c3;
92-
*(p++) = x;
92+
}
93+
*(scan_ptr++) = x;
9394
}
9495
else {
95-
p = row + 1;
96+
scan_ptr = row + 1;
9697
char2p = string2;
9798
D = x = i;
9899
}
@@ -101,24 +102,26 @@ distance(const char *string1, const char *string2)
101102
end = row + len2 + i - half - 2;
102103
}
103104
/* main */
104-
while (p <= end) {
105+
while (scan_ptr <= end) {
105106
size_t c3 = --D + (char1 != *(char2p++));
106107
x++;
107-
if (x > c3)
108+
if (x > c3) {
108109
x = c3;
109-
D = *p;
110+
}
111+
D = *scan_ptr;
110112
D++;
111113
if (x > D)
112114
x = D;
113-
*(p++) = x;
115+
*(scan_ptr++) = x;
114116
}
115117
/* lower triangle sentinel */
116118
if (i <= half) {
117119
size_t c3 = --D + (char1 != *char2p);
118120
x++;
119-
if (x > c3)
121+
if (x > c3) {
120122
x = c3;
121-
*p = x;
123+
}
124+
*scan_ptr = x;
122125
}
123126
}
124127
i = *end;
@@ -131,6 +134,7 @@ calculate_suggestions(PyObject* dir,
131134
PyObject* name,
132135
PyObject* oldexceptionvalue)
133136
{
137+
assert(!PyErr_Occurred());
134138
assert(PyList_CheckExact(dir));
135139

136140
Py_ssize_t dir_size = PyList_GET_SIZE(dir);
@@ -166,13 +170,13 @@ calculate_suggestions(PyObject* dir,
166170

167171
static int
168172
offer_suggestions_for_attribute_error(PyAttributeErrorObject* exc) {
169-
int return_val = 0;
173+
int return_val = -1;
170174

171-
PyObject* name = exc->name;
172-
PyObject* v = exc->obj;
175+
PyObject* name = exc->name; // borrowed reference
176+
PyObject* obj = exc->obj; // borrowed reference
173177

174-
// Aboirt if we don't have an attribute name or we have an invalid one
175-
if ((name == NULL) || (v == NULL) || !PyUnicode_CheckExact(name)) {
178+
// Abort if we don't have an attribute name or we have an invalid one
179+
if (name == NULL || obj == NULL || !PyUnicode_CheckExact(name)) {
176180
return -1;
177181
}
178182

@@ -181,13 +185,15 @@ offer_suggestions_for_attribute_error(PyAttributeErrorObject* exc) {
181185
switch (nargs) {
182186
case 0:
183187
oldexceptionvalue = PyUnicode_New(0, 0);
188+
if (oldexceptionvalue == NULL) {
189+
return -1;
190+
}
184191
break;
185192
case 1:
186193
oldexceptionvalue = PyTuple_GET_ITEM(exc->args, 0);
187194
Py_INCREF(oldexceptionvalue);
188-
// Check that the the message is an uncode objects that we can use.
195+
// Check that the the message is an unicode objects that we can use.
189196
if (!PyUnicode_CheckExact(oldexceptionvalue)) {
190-
return_val = -1;
191197
goto exit;
192198
}
193199
break;
@@ -197,8 +203,8 @@ offer_suggestions_for_attribute_error(PyAttributeErrorObject* exc) {
197203
return 0;
198204
}
199205

200-
PyObject* dir = PyObject_Dir(v);
201-
if (!dir) {
206+
PyObject* dir = PyObject_Dir(obj);
207+
if (dir == NULL) {
202208
goto exit;
203209
}
204210

@@ -210,15 +216,14 @@ offer_suggestions_for_attribute_error(PyAttributeErrorObject* exc) {
210216
goto exit;
211217
}
212218

213-
PyObject* old_args = exc->args;
214219
PyObject* new_args = PyTuple_Pack(1, newexceptionvalue);
215220
Py_DECREF(newexceptionvalue);
216221
if (new_args == NULL) {
217-
return_val = -1;
218222
goto exit;
219223
}
224+
Py_SETREF(exc->args, new_args);
220225
exc->args = new_args;
221-
Py_DECREF(old_args);
226+
return_val = 0;
222227

223228
exit:
224229
Py_DECREF(oldexceptionvalue);
@@ -229,7 +234,7 @@ offer_suggestions_for_attribute_error(PyAttributeErrorObject* exc) {
229234
}
230235

231236

232-
int _Py_offer_suggestions(PyObject* exception, PyObject* value) {
237+
int _Py_Offer_Suggestions(PyObject* exception, PyObject* value) {
233238
if (PyErr_GivenExceptionMatches(exception, PyExc_AttributeError) &&
234239
offer_suggestions_for_attribute_error((PyAttributeErrorObject*) value) != 0) {
235240
PyErr_Clear();

0 commit comments

Comments
 (0)