Skip to content

Commit 9d1f704

Browse files
committed
gh-159672: Simplify keyword trial ownership
1 parent 2497054 commit 9d1f704

1 file changed

Lines changed: 11 additions & 14 deletions

File tree

‎Parser/pegen.c‎

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,9 +1112,6 @@ add_keyword_typo(KeywordTypo *candidates, int *count, int mark,
11121112
if (word == NULL) {
11131113
return -1;
11141114
}
1115-
if (PyUnicode_GET_LENGTH(name) <= 2) {
1116-
max_cost = Py_MIN(max_cost, 2);
1117-
}
11181115
Py_ssize_t cost = _Py_UTF8_Edit_Cost(name, word, max_cost);
11191116
// Adjacent transpositions are one spelling error. The shared Levenshtein
11201117
// distance counts them as two substitutions.
@@ -1185,17 +1182,20 @@ keyword_trial_accepts(Parser *p, const KeywordTypo *candidate)
11851182
static int
11861183
try_keyword_typo(Parser *p, const KeywordTypo *candidate, KeywordTrial *state)
11871184
{
1185+
PyArena *arena = _PyArena_New();
1186+
if (arena == NULL) {
1187+
return -1;
1188+
}
11881189
// Token text belongs to the original arena. Token headers and memo entries
11891190
// must be private: even a failed trial can memoize nodes containing its edit.
1190-
Token *tokens = PyMem_Malloc(p->fill * sizeof(*tokens));
1191-
Token **index = PyMem_Malloc(p->fill * sizeof(*index));
1191+
Token *tokens = _PyArena_Malloc(arena, p->fill * sizeof(*tokens));
1192+
Token **index = _PyArena_Malloc(arena, p->fill * sizeof(*index));
11921193
Parser trial = *p;
11931194
trial.identifier_cache = p->identifier_cache == NULL ? NULL :
11941195
PyMem_Malloc(IDENTIFIER_CACHE_SIZE * sizeof(*trial.identifier_cache));
1195-
PyArena *arena = _PyArena_New();
11961196
PyObject *replacement = PyBytes_FromString(candidate->keyword);
11971197
int accepted = -1;
1198-
if (tokens == NULL || index == NULL || arena == NULL || replacement == NULL ||
1198+
if (tokens == NULL || index == NULL || replacement == NULL ||
11991199
(p->identifier_cache != NULL && trial.identifier_cache == NULL))
12001200
{
12011201
goto done;
@@ -1239,14 +1239,10 @@ try_keyword_typo(Parser *p, const KeywordTypo *candidate, KeywordTrial *state)
12391239
accepted = keyword_trial_accepts(&trial, candidate);
12401240
done:
12411241
// No Parser_Free: the trial borrows the tokenizer and type-ignore comments,
1242-
// and its token headers are a single allocation.
1242+
// and its token arrays belong to the arena.
12431243
PyMem_Free(trial.identifier_cache);
1244-
if (arena != NULL) {
1245-
_PyArena_Free(arena);
1246-
}
1244+
_PyArena_Free(arena);
12471245
Py_XDECREF(replacement);
1248-
PyMem_Free(index);
1249-
PyMem_Free(tokens);
12501246
return PyErr_Occurred() ? -1 : accepted;
12511247
}
12521248

@@ -1357,7 +1353,8 @@ collect_keyword_typos(Parser *p, PySyntaxErrorObject *error, KeywordTypo *candid
13571353
// Preserve missing-comma diagnostics and correctly spelled keywords
13581354
// unless one edit repairs the input. For keywords, only substitute a
13591355
// character: deleting one from "for" must not suggest "or".
1360-
Py_ssize_t max_cost = p->missing_comma || is_keyword ? 2 : 4;
1356+
Py_ssize_t max_cost =
1357+
p->missing_comma || is_keyword || PyUnicode_GET_LENGTH(name) <= 2 ? 2 : 4;
13611358
int result = 0;
13621359
for (int length = 0; length < p->n_keyword_lists && result == 0; length++) {
13631360
if (is_keyword && length != text_length) {

0 commit comments

Comments
 (0)