Skip to content

Commit 66b7973

Browse files
authored
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.
1 parent 4482337 commit 66b7973

File tree

3 files changed

+29
-15
lines changed

3 files changed

+29
-15
lines changed

Include/internal/pycore_warnings.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ struct _warnings_runtime_state {
1717
long filters_version;
1818
};
1919

20+
extern PyStatus _PyWarnings_InitState(PyThreadState *tstate);
21+
2022
#ifdef __cplusplus
2123
}
2224
#endif

Python/_warnings.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "Python.h"
2+
#include "pycore_initconfig.h"
23
#include "pycore_pyerrors.h"
34
#include "pycore_pystate.h"
45
#include "frameobject.h"
@@ -28,12 +29,12 @@ _Py_IDENTIFIER(__name__);
2829

2930
/* Given a module object, get its per-module state. */
3031
static WarningsState *
31-
_Warnings_GetState()
32+
warnings_get_state(void)
3233
{
3334
PyThreadState *tstate = _PyThreadState_GET();
3435
if (tstate == NULL) {
3536
_PyErr_SetString(tstate, PyExc_RuntimeError,
36-
"_Warnings_GetState: could not identify "
37+
"warnings_get_state: could not identify "
3738
"current interpreter");
3839
return NULL;
3940
}
@@ -42,7 +43,7 @@ _Warnings_GetState()
4243

4344
/* Clear the given warnings module state. */
4445
static void
45-
_Warnings_ClearState(WarningsState *st)
46+
warnings_clear_state(WarningsState *st)
4647
{
4748
Py_CLEAR(st->filters);
4849
Py_CLEAR(st->once_registry);
@@ -112,7 +113,7 @@ init_filters(void)
112113

113114
/* Initialize the given warnings module state. */
114115
static int
115-
_Warnings_InitState(WarningsState *st)
116+
warnings_init_state(WarningsState *st)
116117
{
117118
if (st->filters == NULL) {
118119
st->filters = init_filters();
@@ -140,7 +141,7 @@ _Warnings_InitState(WarningsState *st)
140141
return 0;
141142

142143
error:
143-
_Warnings_ClearState(st);
144+
warnings_clear_state(st);
144145
return -1;
145146
}
146147

@@ -286,7 +287,7 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
286287
Py_ssize_t i;
287288
PyObject *warnings_filters;
288289
_Py_IDENTIFIER(filters);
289-
WarningsState *st = _Warnings_GetState();
290+
WarningsState *st = warnings_get_state();
290291
if (st == NULL) {
291292
return NULL;
292293
}
@@ -388,7 +389,7 @@ already_warned(PyObject *registry, PyObject *key, int should_set)
388389
if (key == NULL)
389390
return -1;
390391

391-
WarningsState *st = _Warnings_GetState();
392+
WarningsState *st = warnings_get_state();
392393
if (st == NULL) {
393394
return -1;
394395
}
@@ -706,7 +707,7 @@ warn_explicit(PyObject *category, PyObject *message,
706707

707708
if (_PyUnicode_EqualToASCIIString(action, "once")) {
708709
if (registry == NULL || registry == Py_None) {
709-
WarningsState *st = _Warnings_GetState();
710+
WarningsState *st = warnings_get_state();
710711
if (st == NULL) {
711712
goto cleanup;
712713
}
@@ -1066,7 +1067,7 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
10661067
static PyObject *
10671068
warnings_filters_mutated(PyObject *self, PyObject *args)
10681069
{
1069-
WarningsState *st = _Warnings_GetState();
1070+
WarningsState *st = warnings_get_state();
10701071
if (st == NULL) {
10711072
return NULL;
10721073
}
@@ -1333,6 +1334,16 @@ static struct PyModuleDef warningsmodule = {
13331334
};
13341335

13351336

1337+
PyStatus
1338+
_PyWarnings_InitState(PyThreadState *tstate)
1339+
{
1340+
if (warnings_init_state(&tstate->interp->warnings) < 0) {
1341+
return _PyStatus_ERR("can't initialize warnings");
1342+
}
1343+
return _PyStatus_OK();
1344+
}
1345+
1346+
13361347
PyMODINIT_FUNC
13371348
_PyWarnings_Init(void)
13381349
{
@@ -1343,11 +1354,11 @@ _PyWarnings_Init(void)
13431354
return NULL;
13441355
}
13451356

1346-
WarningsState *st = _Warnings_GetState();
1357+
WarningsState *st = warnings_get_state();
13471358
if (st == NULL) {
13481359
goto error;
13491360
}
1350-
if (_Warnings_InitState(st) < 0) {
1361+
if (warnings_init_state(st) < 0) {
13511362
goto error;
13521363
}
13531364

@@ -1370,7 +1381,7 @@ _PyWarnings_Init(void)
13701381

13711382
error:
13721383
if (st != NULL) {
1373-
_Warnings_ClearState(st);
1384+
warnings_clear_state(st);
13741385
}
13751386
Py_DECREF(m);
13761387
return NULL;
@@ -1380,5 +1391,5 @@ _PyWarnings_Init(void)
13801391
void
13811392
_PyWarnings_Fini(PyInterpreterState *interp)
13821393
{
1383-
_Warnings_ClearState(&interp->warnings);
1394+
warnings_clear_state(&interp->warnings);
13841395
}

Python/pylifecycle.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -677,8 +677,9 @@ pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod)
677677
const PyConfig *config = &tstate->interp->config;
678678
if (_Py_IsMainInterpreter(tstate)) {
679679
/* Initialize _warnings. */
680-
if (_PyWarnings_Init() == NULL) {
681-
return _PyStatus_ERR("can't initialize warnings");
680+
status = _PyWarnings_InitState(tstate);
681+
if (_PyStatus_EXCEPTION(status)) {
682+
return status;
682683
}
683684

684685
if (config->_install_importlib) {

0 commit comments

Comments
 (0)