GH-81057: remove static state from suggestions.c (#99411)

This commit is contained in:
Kumar Aditya 2022-11-30 16:55:16 +05:30 committed by GitHub
parent 59665d0280
commit fe17d35313
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -41,10 +41,8 @@ substitution_cost(char a, char b)
static Py_ssize_t static Py_ssize_t
levenshtein_distance(const char *a, size_t a_size, levenshtein_distance(const char *a, size_t a_size,
const char *b, size_t b_size, const char *b, size_t b_size,
size_t max_cost) size_t max_cost, size_t *buffer)
{ {
static size_t buffer[MAX_STRING_SIZE];
// Both strings are the same (by identity) // Both strings are the same (by identity)
if (a == b) { if (a == b) {
return 0; return 0;
@ -147,12 +145,16 @@ calculate_suggestions(PyObject *dir,
if (name_str == NULL) { if (name_str == NULL) {
return NULL; return NULL;
} }
size_t *buffer = PyMem_New(size_t, MAX_STRING_SIZE);
if (buffer == NULL) {
return PyErr_NoMemory();
}
for (int i = 0; i < dir_size; ++i) { for (int i = 0; i < dir_size; ++i) {
PyObject *item = PyList_GET_ITEM(dir, i); PyObject *item = PyList_GET_ITEM(dir, i);
Py_ssize_t item_size; Py_ssize_t item_size;
const char *item_str = PyUnicode_AsUTF8AndSize(item, &item_size); const char *item_str = PyUnicode_AsUTF8AndSize(item, &item_size);
if (item_str == NULL) { if (item_str == NULL) {
PyMem_Free(buffer);
return NULL; return NULL;
} }
if (PyUnicode_CompareWithASCIIString(name, item_str) == 0) { if (PyUnicode_CompareWithASCIIString(name, item_str) == 0) {
@ -163,8 +165,8 @@ calculate_suggestions(PyObject *dir,
// Don't take matches we've already beaten. // Don't take matches we've already beaten.
max_distance = Py_MIN(max_distance, suggestion_distance - 1); max_distance = Py_MIN(max_distance, suggestion_distance - 1);
Py_ssize_t current_distance = Py_ssize_t current_distance =
levenshtein_distance(name_str, name_size, levenshtein_distance(name_str, name_size, item_str,
item_str, item_size, max_distance); item_size, max_distance, buffer);
if (current_distance > max_distance) { if (current_distance > max_distance) {
continue; continue;
} }
@ -173,6 +175,7 @@ calculate_suggestions(PyObject *dir,
suggestion_distance = current_distance; suggestion_distance = current_distance;
} }
} }
PyMem_Free(buffer);
return Py_XNewRef(suggestion); return Py_XNewRef(suggestion);
} }
@ -238,7 +241,7 @@ get_suggestions_for_name_error(PyObject* name, PyFrameObject* frame)
if (!self) { if (!self) {
goto error; goto error;
} }
if (PyObject_HasAttr(self, name)) { if (PyObject_HasAttr(self, name)) {
Py_DECREF(dir); Py_DECREF(dir);
return PyUnicode_FromFormat("self.%S", name); return PyUnicode_FromFormat("self.%S", name);
@ -401,6 +404,14 @@ _Py_UTF8_Edit_Cost(PyObject *a, PyObject *b, Py_ssize_t max_cost)
if (max_cost == -1) { if (max_cost == -1) {
max_cost = MOVE_COST * Py_MAX(size_a, size_b); max_cost = MOVE_COST * Py_MAX(size_a, size_b);
} }
return levenshtein_distance(utf8_a, size_a, utf8_b, size_b, max_cost); size_t *buffer = PyMem_New(size_t, MAX_STRING_SIZE);
if (buffer == NULL) {
PyErr_NoMemory();
return -1;
}
Py_ssize_t res = levenshtein_distance(utf8_a, size_a,
utf8_b, size_b, max_cost, buffer);
PyMem_Free(buffer);
return res;
} }