mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	bpo-34008: Allow to call Py_Main() after Py_Initialize() (GH-8043)
Py_Main() can again be called after Py_Initialize(), as in Python 3.6. The new configuration is ignored, except of _PyMainInterpreterConfig.argv which is used to update sys.argv.
This commit is contained in:
		
							parent
							
								
									2c5c0a367c
								
							
						
					
					
						commit
						fb47bca9ee
					
				
					 5 changed files with 52 additions and 6 deletions
				
			
		|  | @ -238,6 +238,14 @@ def test_initialize_twice(self): | ||||||
|         self.assertEqual(out, '') |         self.assertEqual(out, '') | ||||||
|         self.assertEqual(err, '') |         self.assertEqual(err, '') | ||||||
| 
 | 
 | ||||||
|  |     def test_initialize_pymain(self): | ||||||
|  |         """ | ||||||
|  |         bpo-34008: Calling Py_Main() after Py_Initialize() must not fail. | ||||||
|  |         """ | ||||||
|  |         out, err = self.run_embedded_interpreter("initialize_pymain") | ||||||
|  |         self.assertEqual(out.rstrip(), "Py_Main() after Py_Initialize: sys.argv=['-c', 'arg2']") | ||||||
|  |         self.assertEqual(err, '') | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||||
|     unittest.main() |     unittest.main() | ||||||
|  |  | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | Py_Main() can again be called after Py_Initialize(), as in Python 3.6. | ||||||
|  | @ -2696,9 +2696,13 @@ pymain_main(_PyMain *pymain) | ||||||
| 
 | 
 | ||||||
|     pymain_init_stdio(pymain); |     pymain_init_stdio(pymain); | ||||||
| 
 | 
 | ||||||
|     pymain->err = _Py_InitializeCore(&pymain->config); |     /* bpo-34008: For backward compatibility reasons, calling Py_Main() after
 | ||||||
|     if (_Py_INIT_FAILED(pymain->err)) { |        Py_Initialize() ignores the new configuration. */ | ||||||
|         _Py_FatalInitError(pymain->err); |     if (!_PyRuntime.initialized) { | ||||||
|  |         pymain->err = _Py_InitializeCore(&pymain->config); | ||||||
|  |         if (_Py_INIT_FAILED(pymain->err)) { | ||||||
|  |             _Py_FatalInitError(pymain->err); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (pymain_init_python_main(pymain) < 0) { |     if (pymain_init_python_main(pymain) < 0) { | ||||||
|  |  | ||||||
|  | @ -276,6 +276,21 @@ static int test_initialize_twice(void) | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static int test_initialize_pymain(void) | ||||||
|  | { | ||||||
|  |     wchar_t *argv[] = {L"PYTHON", L"-c", | ||||||
|  |                        L"import sys; print(f'Py_Main() after Py_Initialize: sys.argv={sys.argv}')", | ||||||
|  |                        L"arg2"}; | ||||||
|  |     _testembed_Py_Initialize(); | ||||||
|  | 
 | ||||||
|  |     /* bpo-34008: Calling Py_Main() after Py_Initialize() must not crash */ | ||||||
|  |     Py_Main(Py_ARRAY_LENGTH(argv), argv); | ||||||
|  | 
 | ||||||
|  |     Py_Finalize(); | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| /* *********************************************************
 | /* *********************************************************
 | ||||||
|  * List of test cases and the function that implements it. |  * List of test cases and the function that implements it. | ||||||
|  | @ -302,6 +317,7 @@ static struct TestCase TestCases[] = { | ||||||
|     { "pre_initialization_sys_options", test_pre_initialization_sys_options }, |     { "pre_initialization_sys_options", test_pre_initialization_sys_options }, | ||||||
|     { "bpo20891", test_bpo20891 }, |     { "bpo20891", test_bpo20891 }, | ||||||
|     { "initialize_twice", test_initialize_twice }, |     { "initialize_twice", test_initialize_twice }, | ||||||
|  |     { "initialize_pymain", test_initialize_pymain }, | ||||||
|     { NULL, NULL } |     { NULL, NULL } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -772,6 +772,22 @@ _Py_InitializeCore(const _PyCoreConfig *core_config) | ||||||
|     return _Py_INIT_OK(); |     return _Py_INIT_OK(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* Py_Initialize() has already been called: update the main interpreter
 | ||||||
|  |    configuration. Example of bpo-34008: Py_Main() called after | ||||||
|  |    Py_Initialize(). */ | ||||||
|  | static _PyInitError | ||||||
|  | _Py_ReconfigureMainInterpreter(PyInterpreterState *interp, | ||||||
|  |                                const _PyMainInterpreterConfig *config) | ||||||
|  | { | ||||||
|  |     if (config->argv != NULL) { | ||||||
|  |         int res = PyDict_SetItemString(interp->sysdict, "argv", config->argv); | ||||||
|  |         if (res < 0) { | ||||||
|  |             return _Py_INIT_ERR("fail to set sys.argv"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return _Py_INIT_OK(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* Update interpreter state based on supplied configuration settings
 | /* Update interpreter state based on supplied configuration settings
 | ||||||
|  * |  * | ||||||
|  * After calling this function, most of the restrictions on the interpreter |  * After calling this function, most of the restrictions on the interpreter | ||||||
|  | @ -793,9 +809,6 @@ _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config) | ||||||
|     if (!_PyRuntime.core_initialized) { |     if (!_PyRuntime.core_initialized) { | ||||||
|         return _Py_INIT_ERR("runtime core not initialized"); |         return _Py_INIT_ERR("runtime core not initialized"); | ||||||
|     } |     } | ||||||
|     if (_PyRuntime.initialized) { |  | ||||||
|         return _Py_INIT_ERR("main interpreter already initialized"); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     /* Get current thread state and interpreter pointer */ |     /* Get current thread state and interpreter pointer */ | ||||||
|     tstate = PyThreadState_GET(); |     tstate = PyThreadState_GET(); | ||||||
|  | @ -810,6 +823,10 @@ _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config) | ||||||
|         return _Py_INIT_ERR("failed to copy main interpreter config"); |         return _Py_INIT_ERR("failed to copy main interpreter config"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (_PyRuntime.initialized) { | ||||||
|  |         return _Py_ReconfigureMainInterpreter(interp, config); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (interp->core_config._disable_importlib) { |     if (interp->core_config._disable_importlib) { | ||||||
|         /* Special mode for freeze_importlib: run with no import system
 |         /* Special mode for freeze_importlib: run with no import system
 | ||||||
|          * |          * | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner