@@ -1772,6 +1772,99 @@ static int test_initconfig_api(void)
17721772}
17731773
17741774
1775+ static void
1776+ check_initconfig_error (PyInitConfig * config , const char * expected )
1777+ {
1778+ const char * err_msg ;
1779+ assert (PyInitConfig_GetError (config , & err_msg ) == 1 );
1780+ assert (strcmp (err_msg , expected ) == 0 );
1781+ }
1782+
1783+
1784+ // Test errors of PyInitConfig_Set*() functions
1785+ static int test_initconfig_set_errors (void )
1786+ {
1787+ char * strlist [] = {"value" };
1788+
1789+ PyInitConfig * config = PyInitConfig_Create ();
1790+ if (config == NULL ) {
1791+ printf ("Init allocation error\n" );
1792+ return 1 ;
1793+ }
1794+
1795+ // Unknown option
1796+ assert (PyInitConfig_SetInt (config , "non-existent" , 123 ) < 0 );
1797+ check_initconfig_error (config , "unknown config option name" );
1798+ assert (PyInitConfig_SetStr (config , "non-existent" , "abc" ) < 0 );
1799+ check_initconfig_error (config , "unknown config option name" );
1800+ assert (PyInitConfig_SetStrList (config , "non-existent" ,
1801+ Py_ARRAY_LENGTH (strlist ), strlist ) < 0 );
1802+ check_initconfig_error (config , "unknown config option name" );
1803+
1804+
1805+ // Wrong type
1806+ assert (PyInitConfig_SetInt (config , "platlibdir" , 123 ) == -1 );
1807+ check_initconfig_error (config , "config option type is not int" );
1808+
1809+ assert (PyInitConfig_SetStr (config , "cpu_count" , "abc" ) == -1 );
1810+ check_initconfig_error (config , "config option type is not string" );
1811+
1812+ assert (PyInitConfig_SetStrList (config , "cpu_count" ,
1813+ Py_ARRAY_LENGTH (strlist ), strlist ) < 0 );
1814+ check_initconfig_error (config , "config option type is not strings list" );
1815+
1816+
1817+ // Test SetInt() range: cpu_count option type is PyConfig_MEMBER_INT
1818+ assert (PyInitConfig_SetInt (config , "cpu_count" , INT_MIN ) == 0 );
1819+ assert (PyInitConfig_SetInt (config , "cpu_count" , INT_MAX ) == 0 );
1820+
1821+ assert (PyInitConfig_SetInt (config , "cpu_count" , INT64_MIN ) == -1 );
1822+ check_initconfig_error (config , "config option value is out of int range" );
1823+ assert (PyInitConfig_SetInt (config , "cpu_count" , INT64_MAX ) == -1 );
1824+ check_initconfig_error (config , "config option value is out of int range" );
1825+
1826+
1827+ // Test SetInt() range: verbose option type is PyConfig_MEMBER_UINT
1828+ assert (PyInitConfig_SetInt (config , "verbose" , 0 ) == 0 );
1829+ assert (PyInitConfig_SetInt (config , "verbose" , UINT_MAX ) == 0 );
1830+
1831+ assert (PyInitConfig_SetInt (config , "verbose" , -1 ) == -1 );
1832+ check_initconfig_error (config , "config option value is out of unsigned int range" );
1833+ assert (PyInitConfig_SetInt (config , "verbose" , INT64_MAX ) == -1 );
1834+ check_initconfig_error (config , "config option value is out of unsigned int range" );
1835+
1836+
1837+ // SetStr() decode error
1838+ assert (PyInitConfig_SetStr (config , "platlibdir" , "\xff" ) == -1 );
1839+ check_initconfig_error (config , "decoding error" );
1840+
1841+
1842+ // Setting a non-optional string to NULL fails with an error,
1843+ // but leaves the optional unchanged.
1844+ if (PyInitConfig_SetStr (config , "program_name" , PROGRAM_NAME_UTF8 ) < 0 ) {
1845+ goto error ;
1846+ }
1847+ assert (PyInitConfig_SetStr (config , "program_name" , NULL ) < 0 );
1848+ check_initconfig_error (config , "config option string cannot be NULL" );
1849+ char * str ;
1850+ assert (PyInitConfig_GetStr (config , "program_name" , & str ) == 0 );
1851+ assert (strcmp (str , PROGRAM_NAME_UTF8 ) == 0 );
1852+ free (str );
1853+
1854+
1855+ PyInitConfig_Free (config );
1856+ return 0 ;
1857+
1858+ error :
1859+ {
1860+ const char * err_msg ;
1861+ (void )PyInitConfig_GetError (config , & err_msg );
1862+ printf ("Python init failed: %s\n" , err_msg );
1863+ exit (1 );
1864+ }
1865+ }
1866+
1867+
17751868static int test_initconfig_get_api (void )
17761869{
17771870 PyInitConfig * config = PyInitConfig_Create ();
@@ -1796,7 +1889,7 @@ static int test_initconfig_get_api(void)
17961889 assert (PyInitConfig_SetInt (config , "utf8_mode" , 0 ) == 0 );
17971890 assert (initconfig_getint (config , "utf8_mode" ) == 0 );
17981891
1799- // test PyInitConfig_GetStr() on an optional string (can be NULL )
1892+ // test PyInitConfig_GetStr() on an unset string (NULL by default )
18001893 char * str ;
18011894 assert (PyInitConfig_GetStr (config , "program_name" , & str ) == 0 );
18021895 assert (str == NULL );
@@ -3199,6 +3292,7 @@ static struct TestCase TestCases[] = {
31993292 {"test_init_is_python_build" , test_init_is_python_build },
32003293 {"test_init_warnoptions" , test_init_warnoptions },
32013294 {"test_initconfig_api" , test_initconfig_api },
3295+ {"test_initconfig_set_errors" , test_initconfig_set_errors },
32023296 {"test_initconfig_get_api" , test_initconfig_get_api },
32033297 {"test_initconfig_exit" , test_initconfig_exit },
32043298 {"test_initconfig_module" , test_initconfig_module },
0 commit comments