blob: e9c8fed198ebfe4f5d76f0b94f50c9960e57855b [file]
#include "pyconfig.h" // Py_GIL_DISABLED
#ifdef Py_GIL_DISABLED
# define Py_TARGET_ABI3T 0x030f0000
#else
// Need limited C API version 3.13 for PyMem_RawFree()
# define Py_LIMITED_API 0x030d0000
#endif
#include "parts.h"
static PyObject *
codec_namereplace_errors(PyObject *Py_UNUSED(module), PyObject *exc)
{
assert(exc != NULL);
return PyCodec_NameReplaceErrors(exc);
}
// Test Py_DecodeLocale()
static PyObject *
decode_locale(PyObject *Py_UNUSED(module), PyObject *arg)
{
const char *str;
Py_ssize_t unused_len;
// Accept embedded null bytes
if (PyArg_Parse(arg, "y#", &str, &unused_len) < 0) {
return NULL;
}
const size_t size_canary = (size_t)-123;
size_t size = size_canary;
wchar_t *wstr = Py_DecodeLocale(str, &size);
if (wstr == NULL) {
if (size == (size_t)-1) {
PyErr_NoMemory();
}
else if (size == (size_t)-2) {
PyErr_SetString(PyExc_RuntimeError, "decode error");
}
else {
PyErr_Format(PyExc_SystemError,
"unknown Py_DecodeLocale() return value: %zd",
(Py_ssize_t)size);
}
return NULL;
}
assert(wstr != NULL);
assert(size != size_canary);
PyObject *result = PyUnicode_FromWideChar(wstr, size);
PyMem_RawFree(wstr);
return result;
}
// Test Py_EncodeLocale()
static PyObject *
encode_locale(PyObject *Py_UNUSED(module), PyObject *arg)
{
PyObject *unicode;
if (PyArg_Parse(arg, "U", &unicode) < 0) {
return NULL;
}
// Accept embedded null characters
Py_ssize_t unused_wlen;
wchar_t *wstr = PyUnicode_AsWideCharString(unicode, &unused_wlen);
if (wstr == NULL) {
return NULL;
}
const size_t error_pos_canary = (size_t)-123;
size_t error_pos = error_pos_canary;
char *str = Py_EncodeLocale(wstr, &error_pos);
PyMem_Free(wstr);
if (str == NULL) {
if (error_pos == (size_t)-1) {
return PyErr_NoMemory();
}
else {
assert(error_pos != error_pos_canary);
return PyErr_Format(PyExc_RuntimeError,
"encode error: pos=%zd", error_pos);
}
}
assert(error_pos == error_pos_canary);
PyObject *result = PyBytes_FromString(str);
PyMem_Free(str);
return result;
}
static PyMethodDef test_methods[] = {
{"codec_namereplace_errors", codec_namereplace_errors, METH_O},
{"decode_locale", decode_locale, METH_O},
{"encode_locale", encode_locale, METH_O},
{NULL},
};
int
_PyTestLimitedCAPI_Init_Codec(PyObject *module)
{
return PyModule_AddFunctions(module, test_methods);
}