mirror of
https://github.com/python/cpython.git
synced 2025-07-23 19:25:40 +00:00
bpo-36763: Implement PyWideStringList_Insert() of PEP 587 (GH-15423)
(cherry picked from commit 3842f2997f
)
Co-authored-by: Victor Stinner <vstinner@redhat.com>
This commit is contained in:
parent
fe64ba611b
commit
a6427cb2a2
5 changed files with 51 additions and 13 deletions
|
@ -72,8 +72,12 @@ PyWideStringList
|
||||||
|
|
||||||
.. c:function:: PyStatus PyWideStringList_Insert(PyWideStringList *list, Py_ssize_t index, const wchar_t *item)
|
.. c:function:: PyStatus PyWideStringList_Insert(PyWideStringList *list, Py_ssize_t index, const wchar_t *item)
|
||||||
|
|
||||||
Insert *item* into *list* at *index*. If *index* is greater than *list*
|
Insert *item* into *list* at *index*.
|
||||||
length, just append *item* to *list*.
|
|
||||||
|
If *index* is greater than or equal to *list* length, append *item* to
|
||||||
|
*list*.
|
||||||
|
|
||||||
|
*index* must be greater than or equal to 0.
|
||||||
|
|
||||||
Python must be preinitialized to call this function.
|
Python must be preinitialized to call this function.
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,9 @@ typedef struct {
|
||||||
|
|
||||||
PyAPI_FUNC(PyStatus) PyWideStringList_Append(PyWideStringList *list,
|
PyAPI_FUNC(PyStatus) PyWideStringList_Append(PyWideStringList *list,
|
||||||
const wchar_t *item);
|
const wchar_t *item);
|
||||||
|
PyAPI_FUNC(PyStatus) PyWideStringList_Insert(PyWideStringList *list,
|
||||||
|
Py_ssize_t index,
|
||||||
|
const wchar_t *item);
|
||||||
|
|
||||||
|
|
||||||
/* --- PyPreConfig ----------------------------------------------- */
|
/* --- PyPreConfig ----------------------------------------------- */
|
||||||
|
|
|
@ -500,7 +500,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
self.fail(f"fail to decode stdout: {stdout!r}")
|
self.fail(f"fail to decode stdout: {stdout!r}")
|
||||||
|
|
||||||
def get_expected_config(self, expected_preconfig, expected, env, api,
|
def get_expected_config(self, expected_preconfig, expected, env, api,
|
||||||
add_path=None):
|
modify_path_cb=None):
|
||||||
cls = self.__class__
|
cls = self.__class__
|
||||||
if cls.EXPECTED_CONFIG is None:
|
if cls.EXPECTED_CONFIG is None:
|
||||||
cls.EXPECTED_CONFIG = self._get_expected_config(env)
|
cls.EXPECTED_CONFIG = self._get_expected_config(env)
|
||||||
|
@ -556,8 +556,9 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
prepend_path = expected['pythonpath_env']
|
prepend_path = expected['pythonpath_env']
|
||||||
if prepend_path is not None:
|
if prepend_path is not None:
|
||||||
expected['module_search_paths'] = [prepend_path, *expected['module_search_paths']]
|
expected['module_search_paths'] = [prepend_path, *expected['module_search_paths']]
|
||||||
if add_path is not None:
|
if modify_path_cb is not None:
|
||||||
expected['module_search_paths'] = [*expected['module_search_paths'], add_path]
|
expected['module_search_paths'] = expected['module_search_paths'].copy()
|
||||||
|
modify_path_cb(expected['module_search_paths'])
|
||||||
|
|
||||||
for key in self.COPY_PRE_CONFIG:
|
for key in self.COPY_PRE_CONFIG:
|
||||||
if key not in expected_preconfig:
|
if key not in expected_preconfig:
|
||||||
|
@ -602,7 +603,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
self.assertEqual(configs['global_config'], expected)
|
self.assertEqual(configs['global_config'], expected)
|
||||||
|
|
||||||
def check_all_configs(self, testname, expected_config=None,
|
def check_all_configs(self, testname, expected_config=None,
|
||||||
expected_preconfig=None, add_path=None, stderr=None,
|
expected_preconfig=None, modify_path_cb=None, stderr=None,
|
||||||
*, api):
|
*, api):
|
||||||
env = remove_python_envvars()
|
env = remove_python_envvars()
|
||||||
|
|
||||||
|
@ -628,7 +629,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
|
|
||||||
self.get_expected_config(expected_preconfig,
|
self.get_expected_config(expected_preconfig,
|
||||||
expected_config, env,
|
expected_config, env,
|
||||||
api, add_path)
|
api, modify_path_cb)
|
||||||
|
|
||||||
out, err = self.run_embedded_interpreter(testname, env=env)
|
out, err = self.run_embedded_interpreter(testname, env=env)
|
||||||
if stderr is None and not expected_config['verbose']:
|
if stderr is None and not expected_config['verbose']:
|
||||||
|
@ -893,9 +894,12 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
'program_name': './init_read_set',
|
'program_name': './init_read_set',
|
||||||
'executable': 'my_executable',
|
'executable': 'my_executable',
|
||||||
}
|
}
|
||||||
|
def modify_path(path):
|
||||||
|
path.insert(1, "test_path_insert1")
|
||||||
|
path.append("test_path_append")
|
||||||
self.check_all_configs("test_init_read_set", config,
|
self.check_all_configs("test_init_read_set", config,
|
||||||
api=API_PYTHON,
|
api=API_PYTHON,
|
||||||
add_path="init_read_set_path")
|
modify_path_cb=modify_path)
|
||||||
|
|
||||||
def test_init_run_main(self):
|
def test_init_run_main(self):
|
||||||
code = ('import _testinternalcapi, json; '
|
code = ('import _testinternalcapi, json; '
|
||||||
|
|
|
@ -1350,8 +1350,14 @@ static int test_init_read_set(void)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = PyWideStringList_Insert(&config.module_search_paths,
|
||||||
|
1, L"test_path_insert1");
|
||||||
|
if (PyStatus_Exception(status)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
status = PyWideStringList_Append(&config.module_search_paths,
|
status = PyWideStringList_Append(&config.module_search_paths,
|
||||||
L"init_read_set_path");
|
L"test_path_append");
|
||||||
if (PyStatus_Exception(status)) {
|
if (PyStatus_Exception(status)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,32 +297,53 @@ _PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
|
||||||
|
|
||||||
|
|
||||||
PyStatus
|
PyStatus
|
||||||
PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
|
PyWideStringList_Insert(PyWideStringList *list,
|
||||||
|
Py_ssize_t index, const wchar_t *item)
|
||||||
{
|
{
|
||||||
if (list->length == PY_SSIZE_T_MAX) {
|
Py_ssize_t len = list->length;
|
||||||
|
if (len == PY_SSIZE_T_MAX) {
|
||||||
/* length+1 would overflow */
|
/* length+1 would overflow */
|
||||||
return _PyStatus_NO_MEMORY();
|
return _PyStatus_NO_MEMORY();
|
||||||
}
|
}
|
||||||
|
if (index < 0) {
|
||||||
|
return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0");
|
||||||
|
}
|
||||||
|
if (index > len) {
|
||||||
|
index = len;
|
||||||
|
}
|
||||||
|
|
||||||
wchar_t *item2 = _PyMem_RawWcsdup(item);
|
wchar_t *item2 = _PyMem_RawWcsdup(item);
|
||||||
if (item2 == NULL) {
|
if (item2 == NULL) {
|
||||||
return _PyStatus_NO_MEMORY();
|
return _PyStatus_NO_MEMORY();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size = (list->length + 1) * sizeof(list->items[0]);
|
size_t size = (len + 1) * sizeof(list->items[0]);
|
||||||
wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
|
wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
|
||||||
if (items2 == NULL) {
|
if (items2 == NULL) {
|
||||||
PyMem_RawFree(item2);
|
PyMem_RawFree(item2);
|
||||||
return _PyStatus_NO_MEMORY();
|
return _PyStatus_NO_MEMORY();
|
||||||
}
|
}
|
||||||
|
|
||||||
items2[list->length] = item2;
|
if (index < len) {
|
||||||
|
memmove(&items2[index + 1],
|
||||||
|
&items2[index],
|
||||||
|
(len - index) * sizeof(items2[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
items2[index] = item2;
|
||||||
list->items = items2;
|
list->items = items2;
|
||||||
list->length++;
|
list->length++;
|
||||||
return _PyStatus_OK();
|
return _PyStatus_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PyStatus
|
||||||
|
PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
|
||||||
|
{
|
||||||
|
return PyWideStringList_Insert(list, list->length, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PyStatus
|
PyStatus
|
||||||
_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
|
_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue