bpo-1635741: Port _locale extension module to multiphase initialization (PEP 489) (GH-18358)
Co-authored-by: Petr Viktorin <pviktori@redhat.com>
This commit is contained in:
parent
704e2065f8
commit
a158168a78
|
@ -0,0 +1 @@
|
||||||
|
Port _locale extension module to multiphase initialization (:pep:`489`).
|
|
@ -41,7 +41,17 @@ This software comes with no warranty. Use at your own risk.
|
||||||
|
|
||||||
PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
|
PyDoc_STRVAR(locale__doc__, "Support for POSIX locales.");
|
||||||
|
|
||||||
static PyObject *Error;
|
typedef struct _locale_state {
|
||||||
|
PyObject *Error;
|
||||||
|
} _locale_state;
|
||||||
|
|
||||||
|
static inline _locale_state*
|
||||||
|
get_locale_state(PyObject *m)
|
||||||
|
{
|
||||||
|
void *state = PyModule_GetState(m);
|
||||||
|
assert(state != NULL);
|
||||||
|
return (_locale_state *)state;
|
||||||
|
}
|
||||||
|
|
||||||
/* support functions for formatting floating point numbers */
|
/* support functions for formatting floating point numbers */
|
||||||
|
|
||||||
|
@ -94,7 +104,8 @@ PyLocale_setlocale(PyObject* self, PyObject* args)
|
||||||
#if defined(MS_WINDOWS)
|
#if defined(MS_WINDOWS)
|
||||||
if (category < LC_MIN || category > LC_MAX)
|
if (category < LC_MIN || category > LC_MAX)
|
||||||
{
|
{
|
||||||
PyErr_SetString(Error, "invalid locale category");
|
PyErr_SetString(get_locale_state(self)->Error,
|
||||||
|
"invalid locale category");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -104,7 +115,8 @@ PyLocale_setlocale(PyObject* self, PyObject* args)
|
||||||
result = setlocale(category, locale);
|
result = setlocale(category, locale);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
/* operation failed, no setting was changed */
|
/* operation failed, no setting was changed */
|
||||||
PyErr_SetString(Error, "unsupported locale setting");
|
PyErr_SetString(get_locale_state(self)->Error,
|
||||||
|
"unsupported locale setting");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
result_object = PyUnicode_DecodeLocale(result, NULL);
|
result_object = PyUnicode_DecodeLocale(result, NULL);
|
||||||
|
@ -114,7 +126,8 @@ PyLocale_setlocale(PyObject* self, PyObject* args)
|
||||||
/* get locale */
|
/* get locale */
|
||||||
result = setlocale(category, NULL);
|
result = setlocale(category, NULL);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
PyErr_SetString(Error, "locale query failed");
|
PyErr_SetString(get_locale_state(self)->Error,
|
||||||
|
"locale query failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
result_object = PyUnicode_DecodeLocale(result, NULL);
|
result_object = PyUnicode_DecodeLocale(result, NULL);
|
||||||
|
@ -622,14 +635,16 @@ PyDoc_STRVAR(bindtextdomain__doc__,
|
||||||
"Bind the C library's domain to dir.");
|
"Bind the C library's domain to dir.");
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
PyIntl_bindtextdomain(PyObject* self,PyObject*args)
|
PyIntl_bindtextdomain(PyObject* self, PyObject*args)
|
||||||
{
|
{
|
||||||
char *domain, *dirname, *current_dirname;
|
char *domain, *dirname, *current_dirname;
|
||||||
PyObject *dirname_obj, *dirname_bytes = NULL, *result;
|
PyObject *dirname_obj, *dirname_bytes = NULL, *result;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj))
|
if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj))
|
||||||
return 0;
|
return 0;
|
||||||
if (!strlen(domain)) {
|
if (!strlen(domain)) {
|
||||||
PyErr_SetString(Error, "domain must be a non-empty string");
|
PyErr_SetString(get_locale_state(self)->Error,
|
||||||
|
"domain must be a non-empty string");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (dirname_obj != Py_None) {
|
if (dirname_obj != Py_None) {
|
||||||
|
@ -710,31 +725,13 @@ static struct PyMethodDef PyLocale_Methods[] = {
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
static struct PyModuleDef _localemodule = {
|
_locale_exec(PyObject *m)
|
||||||
PyModuleDef_HEAD_INIT,
|
|
||||||
"_locale",
|
|
||||||
locale__doc__,
|
|
||||||
-1,
|
|
||||||
PyLocale_Methods,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
PyMODINIT_FUNC
|
|
||||||
PyInit__locale(void)
|
|
||||||
{
|
{
|
||||||
PyObject *m;
|
|
||||||
#ifdef HAVE_LANGINFO_H
|
#ifdef HAVE_LANGINFO_H
|
||||||
int i;
|
int i;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m = PyModule_Create(&_localemodule);
|
|
||||||
if (m == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
PyModule_AddIntMacro(m, LC_CTYPE);
|
PyModule_AddIntMacro(m, LC_CTYPE);
|
||||||
PyModule_AddIntMacro(m, LC_TIME);
|
PyModule_AddIntMacro(m, LC_TIME);
|
||||||
PyModule_AddIntMacro(m, LC_COLLATE);
|
PyModule_AddIntMacro(m, LC_COLLATE);
|
||||||
|
@ -748,12 +745,16 @@ PyInit__locale(void)
|
||||||
PyModule_AddIntMacro(m, LC_ALL);
|
PyModule_AddIntMacro(m, LC_ALL);
|
||||||
PyModule_AddIntMacro(m, CHAR_MAX);
|
PyModule_AddIntMacro(m, CHAR_MAX);
|
||||||
|
|
||||||
Error = PyErr_NewException("locale.Error", NULL, NULL);
|
_locale_state *state = get_locale_state(m);
|
||||||
if (Error == NULL) {
|
state->Error = PyErr_NewException("locale.Error", NULL, NULL);
|
||||||
Py_DECREF(m);
|
if (state->Error == NULL) {
|
||||||
return NULL;
|
return -1;
|
||||||
|
}
|
||||||
|
Py_INCREF(get_locale_state(m)->Error);
|
||||||
|
if (PyModule_AddObject(m, "Error", get_locale_state(m)->Error) < 0) {
|
||||||
|
Py_DECREF(get_locale_state(m)->Error);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
PyModule_AddObject(m, "Error", Error);
|
|
||||||
|
|
||||||
#ifdef HAVE_LANGINFO_H
|
#ifdef HAVE_LANGINFO_H
|
||||||
for (i = 0; langinfo_constants[i].name; i++) {
|
for (i = 0; langinfo_constants[i].name; i++) {
|
||||||
|
@ -763,10 +764,58 @@ PyInit__locale(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
Py_DECREF(m);
|
return -1;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
return m;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct PyModuleDef_Slot _locale_slots[] = {
|
||||||
|
{Py_mod_exec, _locale_exec},
|
||||||
|
{0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
locale_traverse(PyObject *m, visitproc visit, void *arg)
|
||||||
|
{
|
||||||
|
_locale_state *state = (_locale_state*)PyModule_GetState(m);
|
||||||
|
if (state) {
|
||||||
|
Py_VISIT(state->Error);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
locale_clear(PyObject *m)
|
||||||
|
{
|
||||||
|
_locale_state *state = (_locale_state*)PyModule_GetState(m);
|
||||||
|
if (state) {
|
||||||
|
Py_CLEAR(state->Error);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
locale_free(PyObject *m)
|
||||||
|
{
|
||||||
|
locale_clear(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct PyModuleDef _localemodule = {
|
||||||
|
PyModuleDef_HEAD_INIT,
|
||||||
|
"_locale",
|
||||||
|
locale__doc__,
|
||||||
|
sizeof(_locale_state),
|
||||||
|
PyLocale_Methods,
|
||||||
|
_locale_slots,
|
||||||
|
locale_traverse,
|
||||||
|
locale_clear,
|
||||||
|
(freefunc)locale_free,
|
||||||
|
};
|
||||||
|
|
||||||
|
PyMODINIT_FUNC
|
||||||
|
PyInit__locale(void)
|
||||||
|
{
|
||||||
|
return PyModuleDef_Init(&_localemodule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue