gh-116738: Make _suggestions module thread-safe (gh-140321)

This commit is contained in:
Alper
2025-10-21 17:14:48 -07:00
committed by GitHub
parent 29b38b7aae
commit b3a38438d8
4 changed files with 33 additions and 3 deletions

View File

@@ -0,0 +1,24 @@
import unittest
from test.support import import_helper, threading_helper
from test.support.threading_helper import run_concurrently
suggestions = import_helper.import_module("_suggestions")
NTHREADS = 10
@threading_helper.requires_working_threading()
class SuggestionsTests(unittest.TestCase):
def test_generate_suggestions(self):
candidates = [str(i) for i in range(100)]
def worker():
_ = suggestions._generate_suggestions(candidates, "42")
candidates.clear()
run_concurrently(worker_func=worker, nthreads=NTHREADS)
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,2 @@
Make _suggestions module thread-safe on the :term:`free threaded <free
threading>` build.

View File

@@ -8,6 +8,7 @@ module _suggestions
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e58d81fafad5637b]*/
/*[clinic input]
@critical_section candidates
_suggestions._generate_suggestions
candidates: object
item: unicode
@@ -18,7 +19,7 @@ Returns the candidate in candidates that's closest to item
static PyObject *
_suggestions__generate_suggestions_impl(PyObject *module,
PyObject *candidates, PyObject *item)
/*[clinic end generated code: output=79be7b653ae5e7ca input=ba2a8dddc654e33a]*/
/*[clinic end generated code: output=79be7b653ae5e7ca input=92861a6c9bd8f667]*/
{
// Check if dir is a list
if (!PyList_CheckExact(candidates)) {
@@ -29,7 +30,7 @@ _suggestions__generate_suggestions_impl(PyObject *module,
// Check if all elements in the list are Unicode
Py_ssize_t size = PyList_Size(candidates);
for (Py_ssize_t i = 0; i < size; ++i) {
PyObject *elem = PyList_GetItem(candidates, i);
PyObject *elem = PyList_GET_ITEM(candidates, i);
if (!PyUnicode_Check(elem)) {
PyErr_SetString(PyExc_TypeError, "all elements in 'candidates' must be strings");
return NULL;

View File

@@ -2,6 +2,7 @@
preserve
[clinic start generated code]*/
#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION()
#include "pycore_modsupport.h" // _PyArg_CheckPositional()
PyDoc_STRVAR(_suggestions__generate_suggestions__doc__,
@@ -33,9 +34,11 @@ _suggestions__generate_suggestions(PyObject *module, PyObject *const *args, Py_s
goto exit;
}
item = args[1];
Py_BEGIN_CRITICAL_SECTION(candidates);
return_value = _suggestions__generate_suggestions_impl(module, candidates, item);
Py_END_CRITICAL_SECTION();
exit:
return return_value;
}
/*[clinic end generated code: output=1d8e963cdae30b13 input=a9049054013a1b77]*/
/*[clinic end generated code: output=1690dd15a464d19c input=a9049054013a1b77]*/