summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorPablo Galindo <Pablogsal@gmail.com>2021-04-14 23:03:43 (GMT)
committerGitHub <noreply@github.com>2021-04-14 23:03:43 (GMT)
commit3fc65b97d09fd29272fdf60d2e567bfb070da824 (patch)
tree08600f42b2c24c49cc092e3dd19f67660c17fb2e /Python
parent5cb601f956886b32641f818b5da347cc86a43db2 (diff)
downloadcpython-3fc65b97d09fd29272fdf60d2e567bfb070da824.zip
cpython-3fc65b97d09fd29272fdf60d2e567bfb070da824.tar.gz
cpython-3fc65b97d09fd29272fdf60d2e567bfb070da824.tar.bz2
bpo-38530: Optimize the calculation of string sizes when offering suggestions (GH-25412)
Diffstat (limited to 'Python')
-rw-r--r--Python/suggestions.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/Python/suggestions.c b/Python/suggestions.c
index bdc8e2f..258e3f1 100644
--- a/Python/suggestions.c
+++ b/Python/suggestions.c
@@ -9,10 +9,8 @@
/* Calculate the Levenshtein distance between string1 and string2 */
static size_t
-levenshtein_distance(const char *a, const char *b) {
-
- const size_t a_size = strlen(a);
- const size_t b_size = strlen(b);
+levenshtein_distance(const char *a, size_t a_size,
+ const char *b, size_t b_size) {
if (a_size > MAX_STRING_SIZE || b_size > MAX_STRING_SIZE) {
return 0;
@@ -87,17 +85,20 @@ calculate_suggestions(PyObject *dir,
Py_ssize_t suggestion_distance = PyUnicode_GetLength(name);
PyObject *suggestion = NULL;
- const char *name_str = PyUnicode_AsUTF8(name);
+ Py_ssize_t name_size;
+ const char *name_str = PyUnicode_AsUTF8AndSize(name, &name_size);
if (name_str == NULL) {
return NULL;
}
for (int i = 0; i < dir_size; ++i) {
PyObject *item = PyList_GET_ITEM(dir, i);
- const char *item_str = PyUnicode_AsUTF8(item);
+ Py_ssize_t item_size;
+ const char *item_str = PyUnicode_AsUTF8AndSize(item, &item_size);
if (item_str == NULL) {
return NULL;
}
- Py_ssize_t current_distance = levenshtein_distance(name_str, item_str);
+ Py_ssize_t current_distance = levenshtein_distance(
+ name_str, name_size, item_str, item_size);
if (current_distance == 0 || current_distance > MAX_DISTANCE) {
continue;
}
@@ -138,7 +139,8 @@ static PyObject *
offer_suggestions_for_name_error(PyNameErrorObject *exc) {
PyObject *name = exc->name; // borrowed reference
PyTracebackObject *traceback = (PyTracebackObject *) exc->traceback; // borrowed reference
- // Abort if we don't have an attribute name or we have an invalid one
+ // Abort if we don't have a variable name or we have an invalid one
+ // or if we don't have a traceback to work with
if (name == NULL || traceback == NULL || !PyUnicode_CheckExact(name)) {
return NULL;
}