From 1cf149a5275fe2564c868b119850dea124579310 Mon Sep 17 00:00:00 2001 From: Cody Maloney Date: Wed, 10 Jun 2026 02:13:46 -0700 Subject: [PATCH] [3.15] gh-143008: Fix race re-initializing TextIOWrapper (#151203) __init__() changes multiple variables and may be called more than once from multiple threads. (cherry picked from commit 0318867acf72e3acf78f480db73a69982573263a) --- .../Library/2026-06-04-18-22-56.gh-issue-143008.z5tw-J.rst | 1 + Modules/_io/clinic/textio.c.h | 4 +++- Modules/_io/textio.c | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-06-04-18-22-56.gh-issue-143008.z5tw-J.rst diff --git a/Misc/NEWS.d/next/Library/2026-06-04-18-22-56.gh-issue-143008.z5tw-J.rst b/Misc/NEWS.d/next/Library/2026-06-04-18-22-56.gh-issue-143008.z5tw-J.rst new file mode 100644 index 000000000000000..e99bc39c45f9b8f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-06-04-18-22-56.gh-issue-143008.z5tw-J.rst @@ -0,0 +1 @@ +Fix race conditions when re-initializing a :class:`io.TextIOWrapper` object. diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h index de9216a9e05fe14..f35538ee75fa48a 100644 --- a/Modules/_io/clinic/textio.c.h +++ b/Modules/_io/clinic/textio.c.h @@ -624,7 +624,9 @@ _io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) goto exit; } skip_optional_pos: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io_TextIOWrapper___init___impl((textio *)self, buffer, encoding, errors, newline, line_buffering, write_through); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1284,4 +1286,4 @@ _io_TextIOWrapper__CHUNK_SIZE_set(textio *self, PyObject *value, void *Py_UNUSED return return_value; } -/*[clinic end generated code: output=3ac677af6649862d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2d73d5adb0ce09a8 input=a9049054013a1b77]*/ diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index ef3b3e98b725f83..d093514aa66c6ad 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -1049,6 +1049,7 @@ io_check_errors(PyObject *errors) /*[clinic input] +@critical_section _io.TextIOWrapper.__init__ buffer: object encoding: str(accept={str, NoneType}) = None @@ -1092,7 +1093,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, const char *encoding, PyObject *errors, const char *newline, int line_buffering, int write_through) -/*[clinic end generated code: output=72267c0c01032ed2 input=e6cfaaaf6059d4f5]*/ +/*[clinic end generated code: output=72267c0c01032ed2 input=0f077220214c40a4]*/ { PyObject *raw, *codec_info = NULL; PyObject *res;