summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2020-06-30 06:03:15 (GMT)
committerGitHub <noreply@github.com>2020-06-30 06:03:15 (GMT)
commit349f76c6aace5a4a2b57f6b442a532faf0027d6b (patch)
treec9d8fe1e3062e51e65cd7b2a763822908cb7a1cb
parentb3332660adb02babb7e66e45310c66dc9a9a94da (diff)
downloadcpython-349f76c6aace5a4a2b57f6b442a532faf0027d6b.zip
cpython-349f76c6aace5a4a2b57f6b442a532faf0027d6b.tar.gz
cpython-349f76c6aace5a4a2b57f6b442a532faf0027d6b.tar.bz2
bpo-36346: Prepare for removing the legacy Unicode C API (AC only). (GH-21223)
-rw-r--r--Include/cpython/unicodeobject.h5
-rw-r--r--Lib/test/clinic.test19
-rw-r--r--Modules/clinic/_winapi.c.h15
-rw-r--r--Modules/clinic/posixmodule.c.h63
-rw-r--r--Objects/unicodeobject.c74
-rw-r--r--PC/clinic/winreg.c.h327
-rwxr-xr-xTools/clinic/clinic.py65
7 files changed, 523 insertions, 45 deletions
diff --git a/Include/cpython/unicodeobject.h b/Include/cpython/unicodeobject.h
index 88a97a4..0f19b2a 100644
--- a/Include/cpython/unicodeobject.h
+++ b/Include/cpython/unicodeobject.h
@@ -11,6 +11,8 @@
/* --- Internal Unicode Operations ---------------------------------------- */
+#define USE_UNICODE_WCHAR_CACHE 1
+
/* Since splitting on whitespace is an important use case, and
whitespace in most situations is solely ASCII whitespace, we
optimize for the common case by using a quick look-up table
@@ -1169,4 +1171,7 @@ PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*);
and where the hash values are equal (i.e. a very probable match) */
PyAPI_FUNC(int) _PyUnicode_EQ(PyObject *, PyObject *);
+PyAPI_FUNC(int) _PyUnicode_WideCharString_Converter(PyObject *, void *);
+PyAPI_FUNC(int) _PyUnicode_WideCharString_Opt_Converter(PyObject *, void *);
+
PyAPI_FUNC(Py_ssize_t) _PyUnicode_ScanIdentifier(PyObject *);
diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test
index f2be613..07e1382 100644
--- a/Lib/test/clinic.test
+++ b/Lib/test/clinic.test
@@ -1813,13 +1813,26 @@ test_Py_UNICODE_converter(PyObject *module, PyObject *const *args, Py_ssize_t na
const Py_UNICODE *e;
Py_ssize_clean_t e_length;
- if (!_PyArg_ParseStack(args, nargs, "uuZu#Z#:test_Py_UNICODE_converter",
- &a, &b, &c, &d, &d_length, &e, &e_length)) {
+ if (!_PyArg_ParseStack(args, nargs, "O&O&O&u#Z#:test_Py_UNICODE_converter",
+ _PyUnicode_WideCharString_Converter, &a, _PyUnicode_WideCharString_Converter, &b, _PyUnicode_WideCharString_Opt_Converter, &c, &d, &d_length, &e, &e_length)) {
goto exit;
}
return_value = test_Py_UNICODE_converter_impl(module, a, b, c, d, d_length, e, e_length);
exit:
+ /* Cleanup for a */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)a);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ /* Cleanup for b */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)b);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ /* Cleanup for c */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)c);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -1830,7 +1843,7 @@ test_Py_UNICODE_converter_impl(PyObject *module, const Py_UNICODE *a,
Py_ssize_clean_t d_length,
const Py_UNICODE *e,
Py_ssize_clean_t e_length)
-/*[clinic end generated code: output=dd0a09a1b772e57b input=064a3b68ad7f04b0]*/
+/*[clinic end generated code: output=ef45e982fedf0b3d input=064a3b68ad7f04b0]*/
/*[clinic input]
diff --git a/Modules/clinic/_winapi.c.h b/Modules/clinic/_winapi.c.h
index e21f2bc..6022dfe 100644
--- a/Modules/clinic/_winapi.c.h
+++ b/Modules/clinic/_winapi.c.h
@@ -367,13 +367,22 @@ _winapi_CreateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
const Py_UNICODE *current_directory;
PyObject *startup_info;
- if (!_PyArg_ParseStack(args, nargs, "ZOOOikOZO:CreateProcess",
- &application_name, &command_line, &proc_attrs, &thread_attrs, &inherit_handles, &creation_flags, &env_mapping, &current_directory, &startup_info)) {
+ if (!_PyArg_ParseStack(args, nargs, "O&OOOikOO&O:CreateProcess",
+ _PyUnicode_WideCharString_Opt_Converter, &application_name, &command_line, &proc_attrs, &thread_attrs, &inherit_handles, &creation_flags, &env_mapping, _PyUnicode_WideCharString_Opt_Converter, &current_directory, &startup_info)) {
goto exit;
}
return_value = _winapi_CreateProcess_impl(module, application_name, command_line, proc_attrs, thread_attrs, inherit_handles, creation_flags, env_mapping, current_directory, startup_info);
exit:
+ /* Cleanup for application_name */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)application_name);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ /* Cleanup for current_directory */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)current_directory);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -1097,4 +1106,4 @@ _winapi_GetFileType(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P
exit:
return return_value;
}
-/*[clinic end generated code: output=f3897898ea1da99d input=a9049054013a1b77]*/
+/*[clinic end generated code: output=db87076a32fa7abe input=a9049054013a1b77]*/
diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h
index b691cfb..6533edf 100644
--- a/Modules/clinic/posixmodule.c.h
+++ b/Modules/clinic/posixmodule.c.h
@@ -1674,12 +1674,28 @@ os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"command", NULL};
- static _PyArg_Parser _parser = {"u:system", _keywords, 0};
+ static _PyArg_Parser _parser = {NULL, _keywords, "system", 0};
+ PyObject *argsbuf[1];
const Py_UNICODE *command;
long _return_value;
- if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
- &command)) {
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!PyUnicode_Check(args[0])) {
+ _PyArg_BadArgument("system", "argument 'command'", "str", args[0]);
+ goto exit;
+ }
+ #if USE_UNICODE_WCHAR_CACHE
+ _Py_COMP_DIAG_PUSH
+ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ command = _PyUnicode_AsUnicode(args[0]);
+ _Py_COMP_DIAG_POP
+ #else /* USE_UNICODE_WCHAR_CACHE */
+ command = PyUnicode_AsWideCharString(args[0], NULL);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ if (command == NULL) {
goto exit;
}
_return_value = os_system_impl(module, command);
@@ -1689,6 +1705,11 @@ os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k
return_value = PyLong_FromLong(_return_value);
exit:
+ /* Cleanup for command */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)command);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -6998,19 +7019,47 @@ os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"filepath", "operation", NULL};
- static _PyArg_Parser _parser = {"O&|u:startfile", _keywords, 0};
+ static _PyArg_Parser _parser = {NULL, _keywords, "startfile", 0};
+ PyObject *argsbuf[2];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
path_t filepath = PATH_T_INITIALIZE("startfile", "filepath", 0, 0);
const Py_UNICODE *operation = NULL;
- if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
- path_converter, &filepath, &operation)) {
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!path_converter(args[0], &filepath)) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ if (!PyUnicode_Check(args[1])) {
+ _PyArg_BadArgument("startfile", "argument 'operation'", "str", args[1]);
goto exit;
}
+ #if USE_UNICODE_WCHAR_CACHE
+ _Py_COMP_DIAG_PUSH
+ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ operation = _PyUnicode_AsUnicode(args[1]);
+ _Py_COMP_DIAG_POP
+ #else /* USE_UNICODE_WCHAR_CACHE */
+ operation = PyUnicode_AsWideCharString(args[1], NULL);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ if (operation == NULL) {
+ goto exit;
+ }
+skip_optional_pos:
return_value = os_startfile_impl(module, &filepath, operation);
exit:
/* Cleanup for filepath */
path_cleanup(&filepath);
+ /* Cleanup for operation */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)operation);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
return return_value;
}
@@ -8876,4 +8925,4 @@ exit:
#ifndef OS_WAITSTATUS_TO_EXITCODE_METHODDEF
#define OS_WAITSTATUS_TO_EXITCODE_METHODDEF
#endif /* !defined(OS_WAITSTATUS_TO_EXITCODE_METHODDEF) */
-/*[clinic end generated code: output=d7c1212a94613496 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=ba3d4b35fda2c208 input=a9049054013a1b77]*/
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 8eafdacf..db3f55e 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -3273,6 +3273,80 @@ PyUnicode_AsWideCharString(PyObject *unicode,
#endif /* HAVE_WCHAR_H */
+int
+_PyUnicode_WideCharString_Converter(PyObject *obj, void *ptr)
+{
+ wchar_t **p = (wchar_t **)ptr;
+ if (obj == NULL) {
+#if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free(*p);
+#endif /* USE_UNICODE_WCHAR_CACHE */
+ *p = NULL;
+ return 1;
+ }
+ if (PyUnicode_Check(obj)) {
+#if USE_UNICODE_WCHAR_CACHE
+_Py_COMP_DIAG_PUSH
+_Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ *p = (wchar_t *)_PyUnicode_AsUnicode(obj);
+ if (*p == NULL) {
+ return 0;
+ }
+ return 1;
+_Py_COMP_DIAG_POP
+#else /* USE_UNICODE_WCHAR_CACHE */
+ *p = PyUnicode_AsWideCharString(obj, NULL);
+ if (*p == NULL) {
+ return 0;
+ }
+ return Py_CLEANUP_SUPPORTED;
+#endif /* USE_UNICODE_WCHAR_CACHE */
+ }
+ PyErr_Format(PyExc_TypeError,
+ "argument must be str, not %.50s",
+ obj->ob_type->tp_name);
+ return 0;
+}
+
+int
+_PyUnicode_WideCharString_Opt_Converter(PyObject *obj, void *ptr)
+{
+ wchar_t **p = (wchar_t **)ptr;
+ if (obj == NULL) {
+#if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free(*p);
+#endif /* USE_UNICODE_WCHAR_CACHE */
+ *p = NULL;
+ return 1;
+ }
+ if (obj == Py_None) {
+ *p = NULL;
+ return 1;
+ }
+ if (PyUnicode_Check(obj)) {
+#if USE_UNICODE_WCHAR_CACHE
+_Py_COMP_DIAG_PUSH
+_Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ *p = (wchar_t *)_PyUnicode_AsUnicode(obj);
+ if (*p == NULL) {
+ return 0;
+ }
+ return 1;
+_Py_COMP_DIAG_POP
+#else /* USE_UNICODE_WCHAR_CACHE */
+ *p = PyUnicode_AsWideCharString(obj, NULL);
+ if (*p == NULL) {
+ return 0;
+ }
+ return Py_CLEANUP_SUPPORTED;
+#endif /* USE_UNICODE_WCHAR_CACHE */
+ }
+ PyErr_Format(PyExc_TypeError,
+ "argument must be str or None, not %.50s",
+ obj->ob_type->tp_name);
+ return 0;
+}
+
PyObject *
PyUnicode_FromOrdinal(int ordinal)
{
diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h
index 5f37fcd..5c97eae 100644
--- a/PC/clinic/winreg.c.h
+++ b/PC/clinic/winreg.c.h
@@ -152,8 +152,30 @@ winreg_ConnectRegistry(PyObject *module, PyObject *const *args, Py_ssize_t nargs
HKEY key;
HKEY _return_value;
- if (!_PyArg_ParseStack(args, nargs, "ZO&:ConnectRegistry",
- &computer_name, clinic_HKEY_converter, &key)) {
+ if (!_PyArg_CheckPositional("ConnectRegistry", nargs, 2, 2)) {
+ goto exit;
+ }
+ if (args[0] == Py_None) {
+ computer_name = NULL;
+ }
+ else if (PyUnicode_Check(args[0])) {
+ #if USE_UNICODE_WCHAR_CACHE
+ _Py_COMP_DIAG_PUSH
+ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ computer_name = _PyUnicode_AsUnicode(args[0]);
+ _Py_COMP_DIAG_POP
+ #else /* USE_UNICODE_WCHAR_CACHE */
+ computer_name = PyUnicode_AsWideCharString(args[0], NULL);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ if (computer_name == NULL) {
+ goto exit;
+ }
+ }
+ else {
+ _PyArg_BadArgument("ConnectRegistry", "argument 1", "str or None", args[0]);
+ goto exit;
+ }
+ if (!clinic_HKEY_converter(args[1], &key)) {
goto exit;
}
_return_value = winreg_ConnectRegistry_impl(module, computer_name, key);
@@ -163,6 +185,11 @@ winreg_ConnectRegistry(PyObject *module, PyObject *const *args, Py_ssize_t nargs
return_value = PyHKEY_FromHKEY(_return_value);
exit:
+ /* Cleanup for computer_name */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)computer_name);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -199,8 +226,30 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
const Py_UNICODE *sub_key;
HKEY _return_value;
- if (!_PyArg_ParseStack(args, nargs, "O&Z:CreateKey",
- clinic_HKEY_converter, &key, &sub_key)) {
+ if (!_PyArg_CheckPositional("CreateKey", nargs, 2, 2)) {
+ goto exit;
+ }
+ if (!clinic_HKEY_converter(args[0], &key)) {
+ goto exit;
+ }
+ if (args[1] == Py_None) {
+ sub_key = NULL;
+ }
+ else if (PyUnicode_Check(args[1])) {
+ #if USE_UNICODE_WCHAR_CACHE
+ _Py_COMP_DIAG_PUSH
+ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ sub_key = _PyUnicode_AsUnicode(args[1]);
+ _Py_COMP_DIAG_POP
+ #else /* USE_UNICODE_WCHAR_CACHE */
+ sub_key = PyUnicode_AsWideCharString(args[1], NULL);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ if (sub_key == NULL) {
+ goto exit;
+ }
+ }
+ else {
+ _PyArg_BadArgument("CreateKey", "argument 2", "str or None", args[1]);
goto exit;
}
_return_value = winreg_CreateKey_impl(module, key, sub_key);
@@ -210,6 +259,11 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
return_value = PyHKEY_FromHKEY(_return_value);
exit:
+ /* Cleanup for sub_key */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)sub_key);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -251,7 +305,7 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL};
- static _PyArg_Parser _parser = {"O&Z|ii:CreateKeyEx", _keywords, 0};
+ static _PyArg_Parser _parser = {"O&O&|ii:CreateKeyEx", _keywords, 0};
HKEY key;
const Py_UNICODE *sub_key;
int reserved = 0;
@@ -259,7 +313,7 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py
HKEY _return_value;
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
- clinic_HKEY_converter, &key, &sub_key, &reserved, &access)) {
+ clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &reserved, &access)) {
goto exit;
}
_return_value = winreg_CreateKeyEx_impl(module, key, sub_key, reserved, access);
@@ -269,6 +323,11 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py
return_value = PyHKEY_FromHKEY(_return_value);
exit:
+ /* Cleanup for sub_key */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)sub_key);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -303,13 +362,35 @@ winreg_DeleteKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
HKEY key;
const Py_UNICODE *sub_key;
- if (!_PyArg_ParseStack(args, nargs, "O&u:DeleteKey",
- clinic_HKEY_converter, &key, &sub_key)) {
+ if (!_PyArg_CheckPositional("DeleteKey", nargs, 2, 2)) {
+ goto exit;
+ }
+ if (!clinic_HKEY_converter(args[0], &key)) {
+ goto exit;
+ }
+ if (!PyUnicode_Check(args[1])) {
+ _PyArg_BadArgument("DeleteKey", "argument 2", "str", args[1]);
+ goto exit;
+ }
+ #if USE_UNICODE_WCHAR_CACHE
+ _Py_COMP_DIAG_PUSH
+ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ sub_key = _PyUnicode_AsUnicode(args[1]);
+ _Py_COMP_DIAG_POP
+ #else /* USE_UNICODE_WCHAR_CACHE */
+ sub_key = PyUnicode_AsWideCharString(args[1], NULL);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ if (sub_key == NULL) {
goto exit;
}
return_value = winreg_DeleteKey_impl(module, key, sub_key);
exit:
+ /* Cleanup for sub_key */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)sub_key);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -351,19 +432,24 @@ winreg_DeleteKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"key", "sub_key", "access", "reserved", NULL};
- static _PyArg_Parser _parser = {"O&u|ii:DeleteKeyEx", _keywords, 0};
+ static _PyArg_Parser _parser = {"O&O&|ii:DeleteKeyEx", _keywords, 0};
HKEY key;
const Py_UNICODE *sub_key;
REGSAM access = KEY_WOW64_64KEY;
int reserved = 0;
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
- clinic_HKEY_converter, &key, &sub_key, &access, &reserved)) {
+ clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Converter, &sub_key, &access, &reserved)) {
goto exit;
}
return_value = winreg_DeleteKeyEx_impl(module, key, sub_key, access, reserved);
exit:
+ /* Cleanup for sub_key */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)sub_key);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -391,13 +477,40 @@ winreg_DeleteValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
HKEY key;
const Py_UNICODE *value;
- if (!_PyArg_ParseStack(args, nargs, "O&Z:DeleteValue",
- clinic_HKEY_converter, &key, &value)) {
+ if (!_PyArg_CheckPositional("DeleteValue", nargs, 2, 2)) {
+ goto exit;
+ }
+ if (!clinic_HKEY_converter(args[0], &key)) {
+ goto exit;
+ }
+ if (args[1] == Py_None) {
+ value = NULL;
+ }
+ else if (PyUnicode_Check(args[1])) {
+ #if USE_UNICODE_WCHAR_CACHE
+ _Py_COMP_DIAG_PUSH
+ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ value = _PyUnicode_AsUnicode(args[1]);
+ _Py_COMP_DIAG_POP
+ #else /* USE_UNICODE_WCHAR_CACHE */
+ value = PyUnicode_AsWideCharString(args[1], NULL);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ if (value == NULL) {
+ goto exit;
+ }
+ }
+ else {
+ _PyArg_BadArgument("DeleteValue", "argument 2", "str or None", args[1]);
goto exit;
}
return_value = winreg_DeleteValue_impl(module, key, value);
exit:
+ /* Cleanup for value */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)value);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -517,12 +630,29 @@ winreg_ExpandEnvironmentStrings(PyObject *module, PyObject *arg)
PyObject *return_value = NULL;
const Py_UNICODE *string;
- if (!PyArg_Parse(arg, "u:ExpandEnvironmentStrings", &string)) {
+ if (!PyUnicode_Check(arg)) {
+ _PyArg_BadArgument("ExpandEnvironmentStrings", "argument", "str", arg);
+ goto exit;
+ }
+ #if USE_UNICODE_WCHAR_CACHE
+ _Py_COMP_DIAG_PUSH
+ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ string = _PyUnicode_AsUnicode(arg);
+ _Py_COMP_DIAG_POP
+ #else /* USE_UNICODE_WCHAR_CACHE */
+ string = PyUnicode_AsWideCharString(arg, NULL);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ if (string == NULL) {
goto exit;
}
return_value = winreg_ExpandEnvironmentStrings_impl(module, string);
exit:
+ /* Cleanup for string */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)string);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -609,13 +739,54 @@ winreg_LoadKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
const Py_UNICODE *sub_key;
const Py_UNICODE *file_name;
- if (!_PyArg_ParseStack(args, nargs, "O&uu:LoadKey",
- clinic_HKEY_converter, &key, &sub_key, &file_name)) {
+ if (!_PyArg_CheckPositional("LoadKey", nargs, 3, 3)) {
+ goto exit;
+ }
+ if (!clinic_HKEY_converter(args[0], &key)) {
+ goto exit;
+ }
+ if (!PyUnicode_Check(args[1])) {
+ _PyArg_BadArgument("LoadKey", "argument 2", "str", args[1]);
+ goto exit;
+ }
+ #if USE_UNICODE_WCHAR_CACHE
+ _Py_COMP_DIAG_PUSH
+ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ sub_key = _PyUnicode_AsUnicode(args[1]);
+ _Py_COMP_DIAG_POP
+ #else /* USE_UNICODE_WCHAR_CACHE */
+ sub_key = PyUnicode_AsWideCharString(args[1], NULL);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ if (sub_key == NULL) {
+ goto exit;
+ }
+ if (!PyUnicode_Check(args[2])) {
+ _PyArg_BadArgument("LoadKey", "argument 3", "str", args[2]);
+ goto exit;
+ }
+ #if USE_UNICODE_WCHAR_CACHE
+ _Py_COMP_DIAG_PUSH
+ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ file_name = _PyUnicode_AsUnicode(args[2]);
+ _Py_COMP_DIAG_POP
+ #else /* USE_UNICODE_WCHAR_CACHE */
+ file_name = PyUnicode_AsWideCharString(args[2], NULL);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ if (file_name == NULL) {
goto exit;
}
return_value = winreg_LoadKey_impl(module, key, sub_key, file_name);
exit:
+ /* Cleanup for sub_key */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)sub_key);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ /* Cleanup for file_name */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)file_name);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -650,7 +821,7 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL};
- static _PyArg_Parser _parser = {"O&Z|ii:OpenKey", _keywords, 0};
+ static _PyArg_Parser _parser = {"O&O&|ii:OpenKey", _keywords, 0};
HKEY key;
const Py_UNICODE *sub_key;
int reserved = 0;
@@ -658,7 +829,7 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje
HKEY _return_value;
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
- clinic_HKEY_converter, &key, &sub_key, &reserved, &access)) {
+ clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &reserved, &access)) {
goto exit;
}
_return_value = winreg_OpenKey_impl(module, key, sub_key, reserved, access);
@@ -668,6 +839,11 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje
return_value = PyHKEY_FromHKEY(_return_value);
exit:
+ /* Cleanup for sub_key */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)sub_key);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -702,7 +878,7 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL};
- static _PyArg_Parser _parser = {"O&Z|ii:OpenKeyEx", _keywords, 0};
+ static _PyArg_Parser _parser = {"O&O&|ii:OpenKeyEx", _keywords, 0};
HKEY key;
const Py_UNICODE *sub_key;
int reserved = 0;
@@ -710,7 +886,7 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb
HKEY _return_value;
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
- clinic_HKEY_converter, &key, &sub_key, &reserved, &access)) {
+ clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &reserved, &access)) {
goto exit;
}
_return_value = winreg_OpenKeyEx_impl(module, key, sub_key, reserved, access);
@@ -720,6 +896,11 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb
return_value = PyHKEY_FromHKEY(_return_value);
exit:
+ /* Cleanup for sub_key */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)sub_key);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -792,13 +973,40 @@ winreg_QueryValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
HKEY key;
const Py_UNICODE *sub_key;
- if (!_PyArg_ParseStack(args, nargs, "O&Z:QueryValue",
- clinic_HKEY_converter, &key, &sub_key)) {
+ if (!_PyArg_CheckPositional("QueryValue", nargs, 2, 2)) {
+ goto exit;
+ }
+ if (!clinic_HKEY_converter(args[0], &key)) {
+ goto exit;
+ }
+ if (args[1] == Py_None) {
+ sub_key = NULL;
+ }
+ else if (PyUnicode_Check(args[1])) {
+ #if USE_UNICODE_WCHAR_CACHE
+ _Py_COMP_DIAG_PUSH
+ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ sub_key = _PyUnicode_AsUnicode(args[1]);
+ _Py_COMP_DIAG_POP
+ #else /* USE_UNICODE_WCHAR_CACHE */
+ sub_key = PyUnicode_AsWideCharString(args[1], NULL);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ if (sub_key == NULL) {
+ goto exit;
+ }
+ }
+ else {
+ _PyArg_BadArgument("QueryValue", "argument 2", "str or None", args[1]);
goto exit;
}
return_value = winreg_QueryValue_impl(module, key, sub_key);
exit:
+ /* Cleanup for sub_key */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)sub_key);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -831,13 +1039,40 @@ winreg_QueryValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
HKEY key;
const Py_UNICODE *name;
- if (!_PyArg_ParseStack(args, nargs, "O&Z:QueryValueEx",
- clinic_HKEY_converter, &key, &name)) {
+ if (!_PyArg_CheckPositional("QueryValueEx", nargs, 2, 2)) {
+ goto exit;
+ }
+ if (!clinic_HKEY_converter(args[0], &key)) {
+ goto exit;
+ }
+ if (args[1] == Py_None) {
+ name = NULL;
+ }
+ else if (PyUnicode_Check(args[1])) {
+ #if USE_UNICODE_WCHAR_CACHE
+ _Py_COMP_DIAG_PUSH
+ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ name = _PyUnicode_AsUnicode(args[1]);
+ _Py_COMP_DIAG_POP
+ #else /* USE_UNICODE_WCHAR_CACHE */
+ name = PyUnicode_AsWideCharString(args[1], NULL);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ if (name == NULL) {
+ goto exit;
+ }
+ }
+ else {
+ _PyArg_BadArgument("QueryValueEx", "argument 2", "str or None", args[1]);
goto exit;
}
return_value = winreg_QueryValueEx_impl(module, key, name);
exit:
+ /* Cleanup for name */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)name);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -875,13 +1110,35 @@ winreg_SaveKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
HKEY key;
const Py_UNICODE *file_name;
- if (!_PyArg_ParseStack(args, nargs, "O&u:SaveKey",
- clinic_HKEY_converter, &key, &file_name)) {
+ if (!_PyArg_CheckPositional("SaveKey", nargs, 2, 2)) {
+ goto exit;
+ }
+ if (!clinic_HKEY_converter(args[0], &key)) {
+ goto exit;
+ }
+ if (!PyUnicode_Check(args[1])) {
+ _PyArg_BadArgument("SaveKey", "argument 2", "str", args[1]);
+ goto exit;
+ }
+ #if USE_UNICODE_WCHAR_CACHE
+ _Py_COMP_DIAG_PUSH
+ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ file_name = _PyUnicode_AsUnicode(args[1]);
+ _Py_COMP_DIAG_POP
+ #else /* USE_UNICODE_WCHAR_CACHE */
+ file_name = PyUnicode_AsWideCharString(args[1], NULL);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ if (file_name == NULL) {
goto exit;
}
return_value = winreg_SaveKey_impl(module, key, file_name);
exit:
+ /* Cleanup for file_name */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)file_name);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -929,13 +1186,18 @@ winreg_SetValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
const Py_UNICODE *value;
Py_ssize_clean_t value_length;
- if (!_PyArg_ParseStack(args, nargs, "O&Zku#:SetValue",
- clinic_HKEY_converter, &key, &sub_key, &type, &value, &value_length)) {
+ if (!_PyArg_ParseStack(args, nargs, "O&O&ku#:SetValue",
+ clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &type, &value, &value_length)) {
goto exit;
}
return_value = winreg_SetValue_impl(module, key, sub_key, type, value, value_length);
exit:
+ /* Cleanup for sub_key */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)sub_key);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -1000,13 +1262,18 @@ winreg_SetValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
DWORD type;
PyObject *value;
- if (!_PyArg_ParseStack(args, nargs, "O&ZOkO:SetValueEx",
- clinic_HKEY_converter, &key, &value_name, &reserved, &type, &value)) {
+ if (!_PyArg_ParseStack(args, nargs, "O&O&OkO:SetValueEx",
+ clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &value_name, &reserved, &type, &value)) {
goto exit;
}
return_value = winreg_SetValueEx_impl(module, key, value_name, reserved, type, value);
exit:
+ /* Cleanup for value_name */
+ #if !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free((void *)value_name);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+
return return_value;
}
@@ -1111,4 +1378,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg)
exit:
return return_value;
}
-/*[clinic end generated code: output=f4f996d40d06f14c input=a9049054013a1b77]*/
+/*[clinic end generated code: output=fa5f21ea6a75d0e9 input=a9049054013a1b77]*/
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py
index b1bf782..3a9f4c2 100755
--- a/Tools/clinic/clinic.py
+++ b/Tools/clinic/clinic.py
@@ -3374,20 +3374,81 @@ class unicode_converter(CConverter):
displayname=displayname)
return super().parse_arg(argname, displayname)
+@add_legacy_c_converter('u')
@add_legacy_c_converter('u#', zeroes=True)
@add_legacy_c_converter('Z', accept={str, NoneType})
@add_legacy_c_converter('Z#', accept={str, NoneType}, zeroes=True)
class Py_UNICODE_converter(CConverter):
type = 'const Py_UNICODE *'
default_type = (str, Null, NoneType)
- format_unit = 'u'
def converter_init(self, *, accept={str}, zeroes=False):
format_unit = 'Z' if accept=={str, NoneType} else 'u'
if zeroes:
format_unit += '#'
self.length = True
- self.format_unit = format_unit
+ self.format_unit = format_unit
+ else:
+ self.accept = accept
+ if accept == {str}:
+ self.converter = '_PyUnicode_WideCharString_Converter'
+ elif accept == {str, NoneType}:
+ self.converter = '_PyUnicode_WideCharString_Opt_Converter'
+ else:
+ fail("Py_UNICODE_converter: illegal 'accept' argument " + repr(accept))
+
+ def cleanup(self):
+ if not self.length:
+ return """\
+#if !USE_UNICODE_WCHAR_CACHE
+PyMem_Free((void *){name});
+#endif /* USE_UNICODE_WCHAR_CACHE */
+""".format(name=self.name)
+
+ def parse_arg(self, argname, argnum):
+ if not self.length:
+ if self.accept == {str}:
+ return """
+ if (!PyUnicode_Check({argname})) {{{{
+ _PyArg_BadArgument("{{name}}", {argnum}, "str", {argname});
+ goto exit;
+ }}}}
+ #if USE_UNICODE_WCHAR_CACHE
+ _Py_COMP_DIAG_PUSH
+ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ {paramname} = _PyUnicode_AsUnicode({argname});
+ _Py_COMP_DIAG_POP
+ #else /* USE_UNICODE_WCHAR_CACHE */
+ {paramname} = PyUnicode_AsWideCharString({argname}, NULL);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ if ({paramname} == NULL) {{{{
+ goto exit;
+ }}}}
+ """.format(argname=argname, paramname=self.name, argnum=argnum)
+ elif self.accept == {str, NoneType}:
+ return """
+ if ({argname} == Py_None) {{{{
+ {paramname} = NULL;
+ }}}}
+ else if (PyUnicode_Check({argname})) {{{{
+ #if USE_UNICODE_WCHAR_CACHE
+ _Py_COMP_DIAG_PUSH
+ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ {paramname} = _PyUnicode_AsUnicode({argname});
+ _Py_COMP_DIAG_POP
+ #else /* USE_UNICODE_WCHAR_CACHE */
+ {paramname} = PyUnicode_AsWideCharString({argname}, NULL);
+ #endif /* USE_UNICODE_WCHAR_CACHE */
+ if ({paramname} == NULL) {{{{
+ goto exit;
+ }}}}
+ }}}}
+ else {{{{
+ _PyArg_BadArgument("{{name}}", {argnum}, "str or None", {argname});
+ goto exit;
+ }}}}
+ """.format(argname=argname, paramname=self.name, argnum=argnum)
+ return super().parse_arg(argname, argnum)
@add_legacy_c_converter('s*', accept={str, buffer})
@add_legacy_c_converter('z*', accept={str, buffer, NoneType})