Skip to content

Commit

Permalink
bpo-36346: Prepare for removing the legacy Unicode C API (AC only). (p…
Browse files Browse the repository at this point in the history
  • Loading branch information
serhiy-storchaka authored Jun 30, 2020
1 parent b333266 commit 349f76c
Show file tree
Hide file tree
Showing 7 changed files with 523 additions and 45 deletions.
5 changes: 5 additions & 0 deletions Include/cpython/unicodeobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 *);
19 changes: 16 additions & 3 deletions Lib/test/clinic.test
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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]
Expand Down
15 changes: 12 additions & 3 deletions Modules/clinic/_winapi.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 56 additions & 7 deletions Modules/clinic/posixmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

74 changes: 74 additions & 0 deletions Objects/unicodeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
Loading

0 comments on commit 349f76c

Please sign in to comment.