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(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__": | ||||
|     unittest.main() | ||||
|  |  | |||
|  | @ -0,0 +1 @@ | |||
| Py_Main() can again be called after Py_Initialize(), as in Python 3.6. | ||||
|  | @ -2696,10 +2696,14 @@ pymain_main(_PyMain *pymain) | |||
| 
 | ||||
|     pymain_init_stdio(pymain); | ||||
| 
 | ||||
|     /* bpo-34008: For backward compatibility reasons, calling Py_Main() after
 | ||||
|        Py_Initialize() ignores the new configuration. */ | ||||
|     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) { | ||||
|         _Py_FatalInitError(pymain->err); | ||||
|  |  | |||
|  | @ -276,6 +276,21 @@ static int test_initialize_twice(void) | |||
|     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. | ||||
|  | @ -302,6 +317,7 @@ static struct TestCase TestCases[] = { | |||
|     { "pre_initialization_sys_options", test_pre_initialization_sys_options }, | ||||
|     { "bpo20891", test_bpo20891 }, | ||||
|     { "initialize_twice", test_initialize_twice }, | ||||
|     { "initialize_pymain", test_initialize_pymain }, | ||||
|     { NULL, NULL } | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -772,6 +772,22 @@ _Py_InitializeCore(const _PyCoreConfig *core_config) | |||
|     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
 | ||||
|  * | ||||
|  * After calling this function, most of the restrictions on the interpreter | ||||
|  | @ -793,9 +809,6 @@ _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config) | |||
|     if (!_PyRuntime.core_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 */ | ||||
|     tstate = PyThreadState_GET(); | ||||
|  | @ -810,6 +823,10 @@ _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *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) { | ||||
|         /* 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