Skip to content

Commit b680011

Browse files
committed
Fix GetStr() doc; add tests on set errors
1 parent b75a5f4 commit b680011

3 files changed

Lines changed: 100 additions & 3 deletions

File tree

‎Doc/c-api/init_config.rst‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@ UTF-8 encoded string. See :ref:`Configuration Options <pyinitconfig-opts>`.
155155
* Set *\*value*, and return ``0`` on success.
156156
* Set an error in *config* and return ``-1`` on error.
157157
158-
*\*value* can be set to ``NULL`` if the option is an optional string and the
159-
option is unset.
158+
*\*value* can be set to ``NULL`` if the option is unset or if the option is
159+
an optional string.
160160
Optional strings are documented with the type ``str | None`` in the
161161
:ref:`Configuration Options <pyinitconfig-opts>` table.
162162

‎Lib/test/test_embed.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1977,6 +1977,9 @@ def test_initconfig_api(self):
19771977
self.check_all_configs("test_initconfig_api", config, preconfig,
19781978
api=API_ISOLATED, ignore_stderr=True)
19791979

1980+
def test_initconfig_set_errors(self):
1981+
self.run_embedded_interpreter("test_initconfig_set_errors")
1982+
19801983
def test_initconfig_get_api(self):
19811984
self.run_embedded_interpreter("test_initconfig_get_api")
19821985

‎Programs/_testembed.c‎

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
17751868
static 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

Comments
 (0)