summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorGregory P. Smith <greg@krypto.org>2022-10-03 20:55:45 (GMT)
committerGitHub <noreply@github.com>2022-10-03 20:55:45 (GMT)
commitb0f89cb4311b696f875e58f14258ce315be09bce (patch)
treec387a1482f5b7c1a12061cf0f755835cf95a6a71 /Lib
parentcfbc7dd91059cb663c7fe13c661665943495ed7f (diff)
downloadcpython-b0f89cb4311b696f875e58f14258ce315be09bce.zip
cpython-b0f89cb4311b696f875e58f14258ce315be09bce.tar.gz
cpython-b0f89cb4311b696f875e58f14258ce315be09bce.tar.bz2
gh-96512: Move int_max_str_digits setting to PyConfig (#96944)
It had to live as a global outside of PyConfig for stable ABI reasons in the pre-3.12 backports. This removes the `_Py_global_config_int_max_str_digits` and gets rid of the equivalent field in the internal `struct _is PyInterpreterState` as code can just use the existing nested config struct within that. Adds tests to verify unique settings and configs in subinterpreters.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_capi.py33
-rw-r--r--Lib/test/test_cmd_line.py3
-rw-r--r--Lib/test/test_embed.py4
-rw-r--r--Lib/test/test_int.py20
4 files changed, 59 insertions, 1 deletions
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index 94f0809..2c6fe34 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -999,6 +999,39 @@ class SubinterpreterTest(unittest.TestCase):
self.assertEqual(ret, 0)
self.assertEqual(pickle.load(f), {'a': '123x', 'b': '123'})
+ def test_py_config_isoloated_per_interpreter(self):
+ # A config change in one interpreter must not leak to out to others.
+ #
+ # This test could verify ANY config value, it just happens to have been
+ # written around the time of int_max_str_digits. Refactoring is okay.
+ code = """if 1:
+ import sys, _testinternalcapi
+
+ # Any config value would do, this happens to be the one being
+ # double checked at the time this test was written.
+ config = _testinternalcapi.get_config()
+ config['int_max_str_digits'] = 55555
+ _testinternalcapi.set_config(config)
+ sub_value = _testinternalcapi.get_config()['int_max_str_digits']
+ assert sub_value == 55555, sub_value
+ """
+ before_config = _testinternalcapi.get_config()
+ assert before_config['int_max_str_digits'] != 55555
+ self.assertEqual(support.run_in_subinterp(code), 0,
+ 'subinterp code failure, check stderr.')
+ after_config = _testinternalcapi.get_config()
+ self.assertIsNot(
+ before_config, after_config,
+ "Expected get_config() to return a new dict on each call")
+ self.assertEqual(before_config, after_config,
+ "CAUTION: Tests executed after this may be "
+ "running under an altered config.")
+ # try:...finally: calling set_config(before_config) not done
+ # as that results in sys.argv, sys.path, and sys.warnoptions
+ # "being modified by test_capi" per test.regrtest. So if this
+ # test fails, assume that the environment in this process may
+ # be altered and suspect.
+
def test_mutate_exception(self):
"""
Exceptions saved in global module state get shared between
diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
index 3de8c3d..9429800 100644
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -882,7 +882,8 @@ class CmdLineTest(unittest.TestCase):
return tuple(int(i) for i in out.split())
res = assert_python_ok('-c', code)
- self.assertEqual(res2int(res), (-1, sys.get_int_max_str_digits()))
+ current_max = sys.get_int_max_str_digits()
+ self.assertEqual(res2int(res), (current_max, current_max))
res = assert_python_ok('-X', 'int_max_str_digits=0', '-c', code)
self.assertEqual(res2int(res), (0, 0))
res = assert_python_ok('-X', 'int_max_str_digits=4000', '-c', code)
diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py
index 6b5d485..c5aeb94 100644
--- a/Lib/test/test_embed.py
+++ b/Lib/test/test_embed.py
@@ -434,6 +434,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
'install_signal_handlers': 1,
'use_hash_seed': 0,
'hash_seed': 0,
+ 'int_max_str_digits': sys.int_info.default_max_str_digits,
'faulthandler': 0,
'tracemalloc': 0,
'perf_profiling': 0,
@@ -876,6 +877,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
'platlibdir': 'my_platlibdir',
'module_search_paths': self.IGNORE_CONFIG,
'safe_path': 1,
+ 'int_max_str_digits': 31337,
'check_hash_pycs_mode': 'always',
'pathconfig_warnings': 0,
@@ -912,6 +914,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
'platlibdir': 'env_platlibdir',
'module_search_paths': self.IGNORE_CONFIG,
'safe_path': 1,
+ 'int_max_str_digits': 4567,
}
self.check_all_configs("test_init_compat_env", config, preconfig,
api=API_COMPAT)
@@ -944,6 +947,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
'platlibdir': 'env_platlibdir',
'module_search_paths': self.IGNORE_CONFIG,
'safe_path': 1,
+ 'int_max_str_digits': 4567,
}
self.check_all_configs("test_init_python_env", config, preconfig,
api=API_PYTHON)
diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py
index c972b8a..625c388 100644
--- a/Lib/test/test_int.py
+++ b/Lib/test/test_int.py
@@ -770,6 +770,26 @@ class IntStrDigitLimitsTests(unittest.TestCase):
with self.subTest(base=base):
self._other_base_helper(base)
+ def test_int_max_str_digits_is_per_interpreter(self):
+ # Changing the limit in one interpreter does not change others.
+ code = """if 1:
+ # Subinterpreters maintain and enforce their own limit
+ import sys
+ sys.set_int_max_str_digits(2323)
+ try:
+ int('3'*3333)
+ except ValueError:
+ pass
+ else:
+ raise AssertionError('Expected a int max str digits ValueError.')
+ """
+ with support.adjust_int_max_str_digits(4000):
+ before_value = sys.get_int_max_str_digits()
+ self.assertEqual(support.run_in_subinterp(code), 0,
+ 'subinterp code failure, check stderr.')
+ after_value = sys.get_int_max_str_digits()
+ self.assertEqual(before_value, after_value)
+
class IntSubclassStrDigitLimitsTests(IntStrDigitLimitsTests):
int_class = IntSubclass