From c2728bff7a0793ee4c9957f23cd581098b469142 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 21 Jun 2018 15:28:26 +0200 Subject: [PATCH 1/2] bpo-33932: Calling Py_Initialize() twice does nothing Calling Py_Initialize() twice does nothing, instead of failing with a fatal error: restore the Python 3.6 behaviour. --- Lib/test/test_embed.py | 9 +++++++++ .../C API/2018-06-21-15-29-59.bpo-33932.VSlXyS.rst | 2 ++ Programs/_testembed.c | 14 ++++++++++++++ Python/pylifecycle.c | 3 ++- 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/C API/2018-06-21-15-29-59.bpo-33932.VSlXyS.rst diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index c52cb9948782df..f3b60433ccc131 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -229,6 +229,15 @@ def test_bpo20891(self): self.assertEqual(out, '') self.assertEqual(err, '') + def test_initialize_twice(self): + """ + bpo-33932: Calling Py_Initialize() twice should do nothing (and not + crash!). + """ + out, err = self.run_embedded_interpreter("initialize_twice") + self.assertEqual(out, '') + self.assertEqual(err, '') + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/C API/2018-06-21-15-29-59.bpo-33932.VSlXyS.rst b/Misc/NEWS.d/next/C API/2018-06-21-15-29-59.bpo-33932.VSlXyS.rst new file mode 100644 index 00000000000000..90ca3ece091987 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2018-06-21-15-29-59.bpo-33932.VSlXyS.rst @@ -0,0 +1,2 @@ +Calling Py_Initialize() twice does nothing, instead of failing with a fatal +error: restore the Python 3.6 behaviour. diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 7406470ae65c58..b8827f074b9cce 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -263,6 +263,19 @@ static int test_bpo20891(void) return 0; } +static int test_initialize_twice(void) +{ + _testembed_Py_Initialize(); + + /* bpo-33932: Calling Py_Initialize() twice should do nothing + * (and not crash!). */ + Py_Initialize(); + + Py_Finalize(); + + return 0; +} + /* ********************************************************* * List of test cases and the function that implements it. @@ -288,6 +301,7 @@ static struct TestCase TestCases[] = { { "pre_initialization_api", test_pre_initialization_api }, { "pre_initialization_sys_options", test_pre_initialization_sys_options }, { "bpo20891", test_bpo20891 }, + { "initialize_twice", test_initialize_twice }, { NULL, NULL } }; diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 958219b744580d..8d57bda8914112 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -616,7 +616,8 @@ _Py_InitializeCore(const _PyCoreConfig *core_config) } if (_PyRuntime.initialized) { - return _Py_INIT_ERR("main interpreter already initialized"); + /* bpo-33932: Calling Py_Initialize() twice does nothing. */ + return _Py_INIT_OK(); } if (_PyRuntime.core_initialized) { return _Py_INIT_ERR("runtime core already initialized"); From 66e0a374aa608789b6a8021f2859449a1b8cca2b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 21 Jun 2018 17:31:05 +0200 Subject: [PATCH 2/2] Fix _Py_InitializeEx_Private() Exit early if Python is already initialized. Revert my previous change in _Py_InitializeCore(). --- Python/pylifecycle.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 8d57bda8914112..9bf0ebd35d0dc1 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -616,8 +616,7 @@ _Py_InitializeCore(const _PyCoreConfig *core_config) } if (_PyRuntime.initialized) { - /* bpo-33932: Calling Py_Initialize() twice does nothing. */ - return _Py_INIT_OK(); + return _Py_INIT_ERR("main interpreter already initialized"); } if (_PyRuntime.core_initialized) { return _Py_INIT_ERR("runtime core already initialized"); @@ -893,6 +892,11 @@ _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config) _PyInitError _Py_InitializeEx_Private(int install_sigs, int install_importlib) { + if (_PyRuntime.initialized) { + /* bpo-33932: Calling Py_Initialize() twice does nothing. */ + return _Py_INIT_OK(); + } + _PyCoreConfig config = _PyCoreConfig_INIT; _PyInitError err;