From d8212c20c16ce7288beb86729913470cd6d727f1 Mon Sep 17 00:00:00 2001 From: Bhuvansh Kataria Date: Wed, 5 Aug 2026 19:09:31 +0000 Subject: [PATCH] gh-154930: Use atomic loads in UnicodeDecodeError.__str__ --- .../2026-08-05-19-08-47.gh-issue-154930.-OifdL.rst | 3 +++ Objects/exceptions.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-08-05-19-08-47.gh-issue-154930.-OifdL.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-08-05-19-08-47.gh-issue-154930.-OifdL.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-08-05-19-08-47.gh-issue-154930.-OifdL.rst new file mode 100644 index 000000000000000..7ba02bf4db95dfc --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-08-05-19-08-47.gh-issue-154930.-OifdL.rst @@ -0,0 +1,3 @@ +Use atomic loads for ``UnicodeDecodeError.start`` and +``UnicodeDecodeError.end`` in ``UnicodeDecodeError.__str__()`` to avoid a +data race in free-threaded builds. diff --git a/Objects/exceptions.c b/Objects/exceptions.c index fb546ad2673576d..48cb031139057d4 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -3945,7 +3945,8 @@ UnicodeDecodeError_str(PyObject *self) goto done; } Py_ssize_t len = PyBytes_GET_SIZE(exc->object); - Py_ssize_t start = exc->start, end = exc->end; + Py_ssize_t start = FT_ATOMIC_LOAD_SSIZE_RELAXED(exc->start); + Py_ssize_t end = FT_ATOMIC_LOAD_SSIZE_RELAXED(exc->end); if ((start >= 0 && start < len) && (end >= 0 && end <= len) && end == start + 1) { int badbyte = (int)(PyBytes_AS_STRING(exc->object)[start] & 0xff);