diff options
author | Gregory P. Smith <greg@krypto.org> | 2022-10-03 20:55:45 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-03 20:55:45 (GMT) |
commit | b0f89cb4311b696f875e58f14258ce315be09bce (patch) | |
tree | c387a1482f5b7c1a12061cf0f755835cf95a6a71 /Lib | |
parent | cfbc7dd91059cb663c7fe13c661665943495ed7f (diff) | |
download | cpython-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.py | 33 | ||||
-rw-r--r-- | Lib/test/test_cmd_line.py | 3 | ||||
-rw-r--r-- | Lib/test/test_embed.py | 4 | ||||
-rw-r--r-- | Lib/test/test_int.py | 20 |
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 |