bpo-39796: Fix _warnings module initialization (GH-18739)
* Add _PyWarnings_InitState() which only initializes the _warnings module state (tstate->interp->warnings) without creating a module object * Py_InitializeFromConfig() now calls _PyWarnings_InitState() instead of _PyWarnings_Init() * Rename also private functions of _warnings.c to avoid confusion between the public C API and the private C API.
This commit is contained in:
parent
4482337dec
commit
66b7973c1b
|
@ -17,6 +17,8 @@ struct _warnings_runtime_state {
|
|||
long filters_version;
|
||||
};
|
||||
|
||||
extern PyStatus _PyWarnings_InitState(PyThreadState *tstate);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "Python.h"
|
||||
#include "pycore_initconfig.h"
|
||||
#include "pycore_pyerrors.h"
|
||||
#include "pycore_pystate.h"
|
||||
#include "frameobject.h"
|
||||
|
@ -28,12 +29,12 @@ _Py_IDENTIFIER(__name__);
|
|||
|
||||
/* Given a module object, get its per-module state. */
|
||||
static WarningsState *
|
||||
_Warnings_GetState()
|
||||
warnings_get_state(void)
|
||||
{
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
if (tstate == NULL) {
|
||||
_PyErr_SetString(tstate, PyExc_RuntimeError,
|
||||
"_Warnings_GetState: could not identify "
|
||||
"warnings_get_state: could not identify "
|
||||
"current interpreter");
|
||||
return NULL;
|
||||
}
|
||||
|
@ -42,7 +43,7 @@ _Warnings_GetState()
|
|||
|
||||
/* Clear the given warnings module state. */
|
||||
static void
|
||||
_Warnings_ClearState(WarningsState *st)
|
||||
warnings_clear_state(WarningsState *st)
|
||||
{
|
||||
Py_CLEAR(st->filters);
|
||||
Py_CLEAR(st->once_registry);
|
||||
|
@ -112,7 +113,7 @@ init_filters(void)
|
|||
|
||||
/* Initialize the given warnings module state. */
|
||||
static int
|
||||
_Warnings_InitState(WarningsState *st)
|
||||
warnings_init_state(WarningsState *st)
|
||||
{
|
||||
if (st->filters == NULL) {
|
||||
st->filters = init_filters();
|
||||
|
@ -140,7 +141,7 @@ _Warnings_InitState(WarningsState *st)
|
|||
return 0;
|
||||
|
||||
error:
|
||||
_Warnings_ClearState(st);
|
||||
warnings_clear_state(st);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -286,7 +287,7 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
|
|||
Py_ssize_t i;
|
||||
PyObject *warnings_filters;
|
||||
_Py_IDENTIFIER(filters);
|
||||
WarningsState *st = _Warnings_GetState();
|
||||
WarningsState *st = warnings_get_state();
|
||||
if (st == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -388,7 +389,7 @@ already_warned(PyObject *registry, PyObject *key, int should_set)
|
|||
if (key == NULL)
|
||||
return -1;
|
||||
|
||||
WarningsState *st = _Warnings_GetState();
|
||||
WarningsState *st = warnings_get_state();
|
||||
if (st == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -706,7 +707,7 @@ warn_explicit(PyObject *category, PyObject *message,
|
|||
|
||||
if (_PyUnicode_EqualToASCIIString(action, "once")) {
|
||||
if (registry == NULL || registry == Py_None) {
|
||||
WarningsState *st = _Warnings_GetState();
|
||||
WarningsState *st = warnings_get_state();
|
||||
if (st == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -1066,7 +1067,7 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
static PyObject *
|
||||
warnings_filters_mutated(PyObject *self, PyObject *args)
|
||||
{
|
||||
WarningsState *st = _Warnings_GetState();
|
||||
WarningsState *st = warnings_get_state();
|
||||
if (st == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1333,6 +1334,16 @@ static struct PyModuleDef warningsmodule = {
|
|||
};
|
||||
|
||||
|
||||
PyStatus
|
||||
_PyWarnings_InitState(PyThreadState *tstate)
|
||||
{
|
||||
if (warnings_init_state(&tstate->interp->warnings) < 0) {
|
||||
return _PyStatus_ERR("can't initialize warnings");
|
||||
}
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
|
||||
PyMODINIT_FUNC
|
||||
_PyWarnings_Init(void)
|
||||
{
|
||||
|
@ -1343,11 +1354,11 @@ _PyWarnings_Init(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
WarningsState *st = _Warnings_GetState();
|
||||
WarningsState *st = warnings_get_state();
|
||||
if (st == NULL) {
|
||||
goto error;
|
||||
}
|
||||
if (_Warnings_InitState(st) < 0) {
|
||||
if (warnings_init_state(st) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -1370,7 +1381,7 @@ _PyWarnings_Init(void)
|
|||
|
||||
error:
|
||||
if (st != NULL) {
|
||||
_Warnings_ClearState(st);
|
||||
warnings_clear_state(st);
|
||||
}
|
||||
Py_DECREF(m);
|
||||
return NULL;
|
||||
|
@ -1380,5 +1391,5 @@ error:
|
|||
void
|
||||
_PyWarnings_Fini(PyInterpreterState *interp)
|
||||
{
|
||||
_Warnings_ClearState(&interp->warnings);
|
||||
warnings_clear_state(&interp->warnings);
|
||||
}
|
||||
|
|
|
@ -677,8 +677,9 @@ pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod)
|
|||
const PyConfig *config = &tstate->interp->config;
|
||||
if (_Py_IsMainInterpreter(tstate)) {
|
||||
/* Initialize _warnings. */
|
||||
if (_PyWarnings_Init() == NULL) {
|
||||
return _PyStatus_ERR("can't initialize warnings");
|
||||
status = _PyWarnings_InitState(tstate);
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (config->_install_importlib) {
|
||||
|
|
Loading…
Reference in New Issue