@@ -1741,6 +1741,16 @@ static int initconfig_getint(PyInitConfig *config, const char *name)
17411741 return (int )value ;
17421742}
17431743
1744+ static void initconfig_error (PyInitConfig * config )
1745+ {
1746+ const char * err_msg ;
1747+ int res = PyInitConfig_GetError (config , & err_msg );
1748+ assert (res == 1 );
1749+
1750+ printf ("Python init failed: %s\n" , err_msg );
1751+ PyInitConfig_Free (config );
1752+ }
1753+
17441754
17451755static int test_initconfig_api (void )
17461756{
@@ -1795,12 +1805,8 @@ static int test_initconfig_api(void)
17951805 return 0 ;
17961806
17971807error :
1798- {
1799- const char * err_msg ;
1800- (void )PyInitConfig_GetError (config , & err_msg );
1801- printf ("Python init failed: %s\n" , err_msg );
1802- exit (1 );
1803- }
1808+ initconfig_error (config );
1809+ return 1 ;
18041810}
18051811
18061812
@@ -1953,12 +1959,8 @@ static int test_initconfig_module(void)
19531959 return 0 ;
19541960
19551961error :
1956- {
1957- const char * err_msg ;
1958- (void )PyInitConfig_GetError (config , & err_msg );
1959- printf ("Python init failed: %s\n" , err_msg );
1960- exit (1 );
1961- }
1962+ initconfig_error (config );
1963+ return 1 ;
19621964}
19631965
19641966
@@ -2170,6 +2172,77 @@ static int test_init_in_background_thread(void)
21702172}
21712173
21722174
2175+ static PyStatus init_callback (void * arg )
2176+ {
2177+ const char * msg = (const char * )arg ;
2178+ printf ("%s\n" , msg );
2179+
2180+ PyObject * modules = PySys_GetAttrString ("modules" );
2181+ if (modules == NULL ) {
2182+ return PyStatus_Error ("failed to get sys.modules" );
2183+ }
2184+
2185+ PyObject * builtins = PyEval_GetBuiltins (); // borrowed ref
2186+ if (builtins == NULL ) {
2187+ Py_DECREF (modules );
2188+ return PyStatus_Error ("failed to get builtins" );
2189+ }
2190+
2191+ PyObject * sorted ;
2192+ if (PyDict_GetItemStringRef (builtins , "sorted" , & sorted ) <= 0 ) {
2193+ Py_DECREF (modules );
2194+ return PyStatus_Error ("failed to get sorted" );
2195+ }
2196+
2197+ PyObject * names = PyObject_CallOneArg (sorted , modules );
2198+ Py_DECREF (modules );
2199+ if (names == NULL ) {
2200+ return PyStatus_Error ("sorted failed" );
2201+ }
2202+
2203+ PySys_FormatStdout ("sys.modules: %R\n" , names );
2204+ Py_DECREF (names );
2205+
2206+ return PyStatus_Ok ();
2207+ }
2208+
2209+
2210+ static int test_init_callback (void )
2211+ {
2212+ PyInitConfig * config = PyInitConfig_Create ();
2213+ if (config == NULL ) {
2214+ printf ("Init allocation error\n" );
2215+ return 1 ;
2216+ }
2217+
2218+ if (PyInitConfig_SetStr (config , "program_name" , PROGRAM_NAME_UTF8 ) < 0 ) {
2219+ goto error ;
2220+ }
2221+
2222+ const char * ignored_msg = "ignored_msg" ;
2223+ if (PyInitConfig_SetInitCallback (config , init_callback , (void * )ignored_msg ) < 0 ) {
2224+ goto error ;
2225+ }
2226+
2227+ // PyInitConfig_SetInitCallback() can be called more than once, but the
2228+ // previous callback and callback argument are overridden.
2229+ const char * msg = "Hello Callback!" ;
2230+ if (PyInitConfig_SetInitCallback (config , init_callback , (void * )msg ) < 0 ) {
2231+ goto error ;
2232+ }
2233+
2234+ if (Py_InitializeFromInitConfig (config ) < 0 ) {
2235+ goto error ;
2236+ }
2237+ PyInitConfig_Free (config );
2238+ return 0 ;
2239+
2240+ error :
2241+ initconfig_error (config );
2242+ return 1 ;
2243+ }
2244+
2245+
21732246#ifndef MS_WINDOWS
21742247#include "test_frozenmain.h" // M_test_frozenmain
21752248
@@ -2658,6 +2731,7 @@ static struct TestCase TestCases[] = {
26582731 {"test_init_use_frozen_modules" , test_init_use_frozen_modules },
26592732 {"test_init_main_interpreter_settings" , test_init_main_interpreter_settings },
26602733 {"test_init_in_background_thread" , test_init_in_background_thread },
2734+ {"test_init_callback" , test_init_callback },
26612735
26622736 // Audit
26632737 {"test_open_code_hook" , test_open_code_hook },
0 commit comments