cpython/Lib/test/test_free_threading/test_os.py
Victor Stinner c774d1526f
[3.15] gh-158893: Make os.strerror() thread-safe (#159120)
* gh-157695: Parse also _Py_HAVE_xxx variables in sysconfig (#158926)

Add parse_config_h() tests to test_sysconfig.

(cherry picked from commit 978a8befa5)

* gh-158893: Make os.strerror() thread-safe (#158927)

Make os.strerror() thread-safe: use the reentrant strerror_r()
function if available.

* The configure script now checks if strerror_r() is supported.
* Add a stress test to test_free_threading.test_os (new module).
* Add a comment on decode_current_locale() assertion which fails if
  the input string is mutated.
* Add an assertion to _Py_DecodeLocale() to detect if the input
  string was mutated during the function call.

* gh-158893: Add internal _Py_strerror() function (#158982)

Add a new internal _Py_strerror() function to Python/fileutils.c. It
uses strerror_r() if available, or use strerror() otherwise.

Replace all strerror(code) calls with _Py_strerror(code).

(cherry picked from commit 15dd7356f3)
2026-10-10 22:08:49 +02:00

36 lines
1,019 B
Python

import errno
import os
import sysconfig
import unittest
from test.support import threading_helper
from test.support.threading_helper import run_concurrently
NTHREADS = 10
@threading_helper.requires_working_threading()
class TestOs(unittest.TestCase):
@unittest.skipUnless(sysconfig.get_config_var('_Py_HAVE_STRERROR_R'),
'need _Py_HAVE_STRERROR_R macro')
def test_strerror(self):
# gh-158893: os.strerror() is implemented with strerror_r() which is
# thread safe. Well, check if it's actually the case.
last_error = max([getattr(errno, name) for name in dir(errno)
if name.startswith('E')])
test_errors = tuple(range(1, last_error + 1))
loops = 20
def worker():
for _ in range(loops):
for i in test_errors:
os.strerror(i)
run_concurrently(
worker_func=worker, nthreads=NTHREADS
)
if __name__ == "__main__":
unittest.main()