diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py index fa675f626cbe10..5d5ef44ae16300 100644 --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -732,6 +732,24 @@ def test_int_max_str_digits_is_per_interpreter(self): after_value = sys.get_int_max_str_digits() self.assertEqual(before_value, after_value) + def test_int_max_str_digits_not_inherited_by_subinterpreter(self): + # gh-98417: sys.set_int_max_str_digits() changes runtime state + # only; it must not be written back into the interpreter's + # initialization config. Interpreters created afterwards start + # from the initial config, not the current runtime value. + sentinel = 99_999 + if sys.get_int_max_str_digits() == sentinel: + sentinel = 88_888 + code = f"""if 1: + import sys + if sys.get_int_max_str_digits() == {sentinel}: + raise AssertionError( + 'subinterpreter inherited a runtime limit change') + """ + with support.adjust_int_max_str_digits(sentinel): + self.assertEqual(support.run_in_subinterp(code), 0, + 'subinterp code failure, check stderr.') + class IntSubclassStrDigitLimitsTests(IntStrDigitLimitsTests): int_class = IntSubclass diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-02-06-15-00.gh-issue-98417.Qk3vXm.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-02-06-15-00.gh-issue-98417.Qk3vXm.rst new file mode 100644 index 00000000000000..29ea4fd046d344 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-02-06-15-00.gh-issue-98417.Qk3vXm.rst @@ -0,0 +1,5 @@ +:func:`sys.set_int_max_str_digits` no longer writes the new limit back into +the interpreter's initialization configuration (:c:type:`PyConfig`). As a +consequence, interpreters created after changing the limit at runtime now +start with the initial configured limit rather than inheriting the runtime +value. diff --git a/Python/sysmodule.c b/Python/sysmodule.c index d9f7b9c449cfb9..f6d142290f954d 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -4701,10 +4701,7 @@ _PySys_SetIntMaxStrDigits(int maxdigits) return -1; } - // Set PyInterpreterState.long_state.max_str_digits - // and PyInterpreterState.config.int_max_str_digits. PyInterpreterState *interp = _PyInterpreterState_GET(); _Py_atomic_store_int(&interp->long_state.max_str_digits, maxdigits); - _Py_atomic_store_int(&interp->config.int_max_str_digits, maxdigits); return 0; }