diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index a7d912178a2..6833b2540d6 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -1472,5 +1472,11 @@ def test_audit_run_stdin(self): timeout=support.SHORT_TIMEOUT, returncode=1) +class MiscTests(EmbeddingTestsMixin, unittest.TestCase): + def test_unicode_id_init(self): + # bpo-42882: Test that _PyUnicode_FromId() works + # when Python is initialized multiples times. + self.run_embedded_interpreter("test_unicode_id_init") + if __name__ == "__main__": unittest.main() diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 748ea8a8f33..52c56746813 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -1686,6 +1686,42 @@ static int test_get_argc_argv(void) } +static int test_unicode_id_init(void) +{ + // bpo-42882: Test that _PyUnicode_FromId() works + // when Python is initialized multiples times. + _Py_IDENTIFIER(test_unicode_id_init); + + // Initialize Python once without using the identifier + _testembed_Py_Initialize(); + Py_Finalize(); + + // Now initialize Python multiple times and use the identifier. + // The first _PyUnicode_FromId() call initializes the identifier index. + for (int i=0; i<3; i++) { + _testembed_Py_Initialize(); + + PyObject *str1, *str2; + + str1 = _PyUnicode_FromId(&PyId_test_unicode_id_init); + assert(str1 != NULL); + assert(Py_REFCNT(str1) == 1); + + str2 = PyUnicode_FromString("test_unicode_id_init"); + assert(str2 != NULL); + + assert(PyUnicode_Compare(str1, str2) == 0); + + // str1 is a borrowed reference + Py_DECREF(str2); + + Py_Finalize(); + } + return 0; +} + + + /* ********************************************************* * List of test cases and the function that implements it. * @@ -1754,6 +1790,8 @@ static struct TestCase TestCases[] = { {"test_audit_run_interactivehook", test_audit_run_interactivehook}, {"test_audit_run_startup", test_audit_run_startup}, {"test_audit_run_stdin", test_audit_run_stdin}, + + {"test_unicode_id_init", test_unicode_id_init}, {NULL, NULL} };