Skip to content

Commit 3fc65b9

Browse files
authored
bpo-38530: Optimize the calculation of string sizes when offering suggestions (GH-25412)
1 parent 5cb601f commit 3fc65b9

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

Python/suggestions.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,8 @@
99

1010
/* Calculate the Levenshtein distance between string1 and string2 */
1111
static size_t
12-
levenshtein_distance(const char *a, const char *b) {
13-
14-
const size_t a_size = strlen(a);
15-
const size_t b_size = strlen(b);
12+
levenshtein_distance(const char *a, size_t a_size,
13+
const char *b, size_t b_size) {
1614

1715
if (a_size > MAX_STRING_SIZE || b_size > MAX_STRING_SIZE) {
1816
return 0;
@@ -87,17 +85,20 @@ calculate_suggestions(PyObject *dir,
8785

8886
Py_ssize_t suggestion_distance = PyUnicode_GetLength(name);
8987
PyObject *suggestion = NULL;
90-
const char *name_str = PyUnicode_AsUTF8(name);
88+
Py_ssize_t name_size;
89+
const char *name_str = PyUnicode_AsUTF8AndSize(name, &name_size);
9190
if (name_str == NULL) {
9291
return NULL;
9392
}
9493
for (int i = 0; i < dir_size; ++i) {
9594
PyObject *item = PyList_GET_ITEM(dir, i);
96-
const char *item_str = PyUnicode_AsUTF8(item);
95+
Py_ssize_t item_size;
96+
const char *item_str = PyUnicode_AsUTF8AndSize(item, &item_size);
9797
if (item_str == NULL) {
9898
return NULL;
9999
}
100-
Py_ssize_t current_distance = levenshtein_distance(name_str, item_str);
100+
Py_ssize_t current_distance = levenshtein_distance(
101+
name_str, name_size, item_str, item_size);
101102
if (current_distance == 0 || current_distance > MAX_DISTANCE) {
102103
continue;
103104
}
@@ -138,7 +139,8 @@ static PyObject *
138139
offer_suggestions_for_name_error(PyNameErrorObject *exc) {
139140
PyObject *name = exc->name; // borrowed reference
140141
PyTracebackObject *traceback = (PyTracebackObject *) exc->traceback; // borrowed reference
141-
// Abort if we don't have an attribute name or we have an invalid one
142+
// Abort if we don't have a variable name or we have an invalid one
143+
// or if we don't have a traceback to work with
142144
if (name == NULL || traceback == NULL || !PyUnicode_CheckExact(name)) {
143145
return NULL;
144146
}

0 commit comments

Comments
 (0)