Coverage Report

Created: 2025-07-11 06:59

/src/Python-3.8.3/Python/_warnings.c
Line
Count
Source (jump to first uncovered line)
1
#include "Python.h"
2
#include "pycore_pystate.h"
3
#include "frameobject.h"
4
#include "clinic/_warnings.c.h"
5
6
0
#define MODULE_NAME "_warnings"
7
8
PyDoc_STRVAR(warnings__doc__,
9
MODULE_NAME " provides basic warning filtering support.\n"
10
"It is a helper module to speed up interpreter start-up.");
11
12
_Py_IDENTIFIER(stderr);
13
#ifndef Py_DEBUG
14
_Py_IDENTIFIER(default);
15
_Py_IDENTIFIER(ignore);
16
#endif
17
18
19
/*************************************************************************/
20
21
typedef struct _warnings_runtime_state WarningsState;
22
23
/* Forward declaration of the _warnings module definition. */
24
static struct PyModuleDef warningsmodule;
25
26
/* Given a module object, get its per-module state. */
27
static WarningsState *
28
_Warnings_GetState()
29
28
{
30
28
    PyThreadState *tstate = PyThreadState_GET();
31
28
    if (tstate == NULL) {
32
0
        PyErr_SetString(PyExc_RuntimeError,
33
0
                        "_Warnings_GetState: could not identify current interpreter");
34
0
        return NULL;
35
0
    }
36
28
    return &tstate->interp->warnings;
37
28
}
38
39
/* Clear the given warnings module state. */
40
static void
41
_Warnings_ClearState(WarningsState *st)
42
0
{
43
0
    Py_CLEAR(st->filters);
44
0
    Py_CLEAR(st->once_registry);
45
0
    Py_CLEAR(st->default_action);
46
0
}
47
48
#ifndef Py_DEBUG
49
static PyObject *
50
create_filter(PyObject *category, _Py_Identifier *id, const char *modname)
51
70
{
52
70
    PyObject *modname_obj = NULL;
53
70
    PyObject *action_str = _PyUnicode_FromId(id);
54
70
    if (action_str == NULL) {
55
0
        return NULL;
56
0
    }
57
58
    /* Default to "no module name" for initial filter set */
59
70
    if (modname != NULL) {
60
14
        modname_obj = PyUnicode_InternFromString(modname);
61
14
        if (modname_obj == NULL) {
62
0
            return NULL;
63
0
        }
64
56
    } else {
65
56
        modname_obj = Py_None;
66
56
    }
67
68
    /* This assumes the line number is zero for now. */
69
70
    return PyTuple_Pack(5, action_str, Py_None,
70
70
                        category, modname_obj, _PyLong_Zero);
71
70
}
72
#endif
73
74
static PyObject *
75
init_filters(void)
76
14
{
77
#ifdef Py_DEBUG
78
    /* Py_DEBUG builds show all warnings by default */
79
    return PyList_New(0);
80
#else
81
    /* Other builds ignore a number of warning categories by default */
82
14
    PyObject *filters = PyList_New(5);
83
14
    if (filters == NULL) {
84
0
        return NULL;
85
0
    }
86
87
14
    size_t pos = 0;  /* Post-incremented in each use. */
88
14
    PyList_SET_ITEM(filters, pos++,
89
14
                    create_filter(PyExc_DeprecationWarning, &PyId_default, "__main__"));
90
14
    PyList_SET_ITEM(filters, pos++,
91
14
                    create_filter(PyExc_DeprecationWarning, &PyId_ignore, NULL));
92
14
    PyList_SET_ITEM(filters, pos++,
93
14
                    create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore, NULL));
94
14
    PyList_SET_ITEM(filters, pos++,
95
14
                    create_filter(PyExc_ImportWarning, &PyId_ignore, NULL));
96
14
    PyList_SET_ITEM(filters, pos++,
97
14
                    create_filter(PyExc_ResourceWarning, &PyId_ignore, NULL));
98
99
84
    for (size_t x = 0; x < pos; x++) {
100
70
        if (PyList_GET_ITEM(filters, x) == NULL) {
101
0
            Py_DECREF(filters);
102
0
            return NULL;
103
0
        }
104
70
    }
105
14
    return filters;
106
14
#endif
107
14
}
108
109
/* Initialize the given warnings module state. */
110
static int
111
_Warnings_InitState(WarningsState *st)
112
28
{
113
28
    if (st->filters == NULL) {
114
14
        st->filters = init_filters();
115
14
        if (st->filters == NULL) {
116
0
            goto error;
117
0
        }
118
14
    }
119
120
28
    if (st->once_registry == NULL) {
121
14
        st->once_registry = PyDict_New();
122
14
        if (st->once_registry == NULL) {
123
0
            goto error;
124
0
        }
125
14
    }
126
127
28
    if (st->default_action == NULL) {
128
14
        st->default_action = PyUnicode_FromString("default");
129
14
        if (st->default_action == NULL) {
130
0
            goto error;
131
0
        }
132
14
    }
133
134
28
    st->filters_version = 0;
135
136
28
    return 0;
137
138
0
error:
139
0
    _Warnings_ClearState(st);
140
0
    return -1;
141
28
}
142
143
144
/*************************************************************************/
145
146
static int
147
check_matched(PyObject *obj, PyObject *arg)
148
0
{
149
0
    PyObject *result;
150
0
    _Py_IDENTIFIER(match);
151
0
    int rc;
152
153
    /* A 'None' filter always matches */
154
0
    if (obj == Py_None)
155
0
        return 1;
156
157
    /* An internal plain text default filter must match exactly */
158
0
    if (PyUnicode_CheckExact(obj)) {
159
0
        int cmp_result = PyUnicode_Compare(obj, arg);
160
0
        if (cmp_result == -1 && PyErr_Occurred()) {
161
0
            return -1;
162
0
        }
163
0
        return !cmp_result;
164
0
    }
165
166
    /* Otherwise assume a regex filter and call its match() method */
167
0
    result = _PyObject_CallMethodIdObjArgs(obj, &PyId_match, arg, NULL);
168
0
    if (result == NULL)
169
0
        return -1;
170
171
0
    rc = PyObject_IsTrue(result);
172
0
    Py_DECREF(result);
173
0
    return rc;
174
0
}
175
176
/*
177
   Returns a new reference.
178
   A NULL return value can mean false or an error.
179
*/
180
static PyObject *
181
get_warnings_attr(_Py_Identifier *attr_id, int try_import)
182
0
{
183
0
    PyObject *warnings_str;
184
0
    PyObject *warnings_module, *obj;
185
0
    _Py_IDENTIFIER(warnings);
186
187
0
    warnings_str = _PyUnicode_FromId(&PyId_warnings);
188
0
    if (warnings_str == NULL) {
189
0
        return NULL;
190
0
    }
191
192
    /* don't try to import after the start of the Python finallization */
193
0
    if (try_import && !_Py_IsFinalizing()) {
194
0
        warnings_module = PyImport_Import(warnings_str);
195
0
        if (warnings_module == NULL) {
196
            /* Fallback to the C implementation if we cannot get
197
               the Python implementation */
198
0
            if (PyErr_ExceptionMatches(PyExc_ImportError)) {
199
0
                PyErr_Clear();
200
0
            }
201
0
            return NULL;
202
0
        }
203
0
    }
204
0
    else {
205
        /* if we're so late into Python finalization that the module dict is
206
           gone, then we can't even use PyImport_GetModule without triggering
207
           an interpreter abort.
208
        */
209
0
        if (!_PyInterpreterState_GET_UNSAFE()->modules) {
210
0
            return NULL;
211
0
        }
212
0
        warnings_module = PyImport_GetModule(warnings_str);
213
0
        if (warnings_module == NULL)
214
0
            return NULL;
215
0
    }
216
217
0
    (void)_PyObject_LookupAttrId(warnings_module, attr_id, &obj);
218
0
    Py_DECREF(warnings_module);
219
0
    return obj;
220
0
}
221
222
223
static PyObject *
224
get_once_registry(WarningsState *st)
225
0
{
226
0
    PyObject *registry;
227
0
    _Py_IDENTIFIER(onceregistry);
228
229
0
    registry = get_warnings_attr(&PyId_onceregistry, 0);
230
0
    if (registry == NULL) {
231
0
        if (PyErr_Occurred())
232
0
            return NULL;
233
0
        assert(st->once_registry);
234
0
        return st->once_registry;
235
0
    }
236
0
    if (!PyDict_Check(registry)) {
237
0
        PyErr_Format(PyExc_TypeError,
238
0
                     MODULE_NAME ".onceregistry must be a dict, "
239
0
                     "not '%.200s'",
240
0
                     Py_TYPE(registry)->tp_name);
241
0
        Py_DECREF(registry);
242
0
        return NULL;
243
0
    }
244
0
    Py_SETREF(st->once_registry, registry);
245
0
    return registry;
246
0
}
247
248
249
static PyObject *
250
get_default_action(WarningsState *st)
251
0
{
252
0
    PyObject *default_action;
253
0
    _Py_IDENTIFIER(defaultaction);
254
255
0
    default_action = get_warnings_attr(&PyId_defaultaction, 0);
256
0
    if (default_action == NULL) {
257
0
        if (PyErr_Occurred()) {
258
0
            return NULL;
259
0
        }
260
0
        assert(st->default_action);
261
0
        return st->default_action;
262
0
    }
263
0
    if (!PyUnicode_Check(default_action)) {
264
0
        PyErr_Format(PyExc_TypeError,
265
0
                     MODULE_NAME ".defaultaction must be a string, "
266
0
                     "not '%.200s'",
267
0
                     Py_TYPE(default_action)->tp_name);
268
0
        Py_DECREF(default_action);
269
0
        return NULL;
270
0
    }
271
0
    Py_SETREF(st->default_action, default_action);
272
0
    return default_action;
273
0
}
274
275
276
/* The item is a new reference. */
277
static PyObject*
278
get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
279
           PyObject *module, PyObject **item)
280
0
{
281
0
    PyObject *action;
282
0
    Py_ssize_t i;
283
0
    PyObject *warnings_filters;
284
0
    _Py_IDENTIFIER(filters);
285
0
    WarningsState *st = _Warnings_GetState();
286
0
    if (st == NULL) {
287
0
        return NULL;
288
0
    }
289
290
0
    warnings_filters = get_warnings_attr(&PyId_filters, 0);
291
0
    if (warnings_filters == NULL) {
292
0
        if (PyErr_Occurred())
293
0
            return NULL;
294
0
    }
295
0
    else {
296
0
        Py_SETREF(st->filters, warnings_filters);
297
0
    }
298
299
0
    PyObject *filters = st->filters;
300
0
    if (filters == NULL || !PyList_Check(filters)) {
301
0
        PyErr_SetString(PyExc_ValueError,
302
0
                        MODULE_NAME ".filters must be a list");
303
0
        return NULL;
304
0
    }
305
306
    /* WarningsState.filters could change while we are iterating over it. */
307
0
    for (i = 0; i < PyList_GET_SIZE(filters); i++) {
308
0
        PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
309
0
        Py_ssize_t ln;
310
0
        int is_subclass, good_msg, good_mod;
311
312
0
        tmp_item = PyList_GET_ITEM(filters, i);
313
0
        if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
314
0
            PyErr_Format(PyExc_ValueError,
315
0
                         MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
316
0
            return NULL;
317
0
        }
318
319
        /* Python code: action, msg, cat, mod, ln = item */
320
0
        Py_INCREF(tmp_item);
321
0
        action = PyTuple_GET_ITEM(tmp_item, 0);
322
0
        msg = PyTuple_GET_ITEM(tmp_item, 1);
323
0
        cat = PyTuple_GET_ITEM(tmp_item, 2);
324
0
        mod = PyTuple_GET_ITEM(tmp_item, 3);
325
0
        ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
326
327
0
        if (!PyUnicode_Check(action)) {
328
0
            PyErr_Format(PyExc_TypeError,
329
0
                         "action must be a string, not '%.200s'",
330
0
                         Py_TYPE(action)->tp_name);
331
0
            Py_DECREF(tmp_item);
332
0
            return NULL;
333
0
        }
334
335
0
        good_msg = check_matched(msg, text);
336
0
        if (good_msg == -1) {
337
0
            Py_DECREF(tmp_item);
338
0
            return NULL;
339
0
        }
340
341
0
        good_mod = check_matched(mod, module);
342
0
        if (good_mod == -1) {
343
0
            Py_DECREF(tmp_item);
344
0
            return NULL;
345
0
        }
346
347
0
        is_subclass = PyObject_IsSubclass(category, cat);
348
0
        if (is_subclass == -1) {
349
0
            Py_DECREF(tmp_item);
350
0
            return NULL;
351
0
        }
352
353
0
        ln = PyLong_AsSsize_t(ln_obj);
354
0
        if (ln == -1 && PyErr_Occurred()) {
355
0
            Py_DECREF(tmp_item);
356
0
            return NULL;
357
0
        }
358
359
0
        if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
360
0
            *item = tmp_item;
361
0
            return action;
362
0
        }
363
364
0
        Py_DECREF(tmp_item);
365
0
    }
366
367
0
    action = get_default_action(st);
368
0
    if (action != NULL) {
369
0
        Py_INCREF(Py_None);
370
0
        *item = Py_None;
371
0
        return action;
372
0
    }
373
374
0
    return NULL;
375
0
}
376
377
378
static int
379
already_warned(PyObject *registry, PyObject *key, int should_set)
380
0
{
381
0
    PyObject *version_obj, *already_warned;
382
0
    _Py_IDENTIFIER(version);
383
384
0
    if (key == NULL)
385
0
        return -1;
386
387
0
    WarningsState *st = _Warnings_GetState();
388
0
    if (st == NULL) {
389
0
        return -1;
390
0
    }
391
0
    version_obj = _PyDict_GetItemIdWithError(registry, &PyId_version);
392
0
    if (version_obj == NULL
393
0
        || !PyLong_CheckExact(version_obj)
394
0
        || PyLong_AsLong(version_obj) != st->filters_version)
395
0
    {
396
0
        if (PyErr_Occurred()) {
397
0
            return -1;
398
0
        }
399
0
        PyDict_Clear(registry);
400
0
        version_obj = PyLong_FromLong(st->filters_version);
401
0
        if (version_obj == NULL)
402
0
            return -1;
403
0
        if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
404
0
            Py_DECREF(version_obj);
405
0
            return -1;
406
0
        }
407
0
        Py_DECREF(version_obj);
408
0
    }
409
0
    else {
410
0
        already_warned = PyDict_GetItemWithError(registry, key);
411
0
        if (already_warned != NULL) {
412
0
            int rc = PyObject_IsTrue(already_warned);
413
0
            if (rc != 0)
414
0
                return rc;
415
0
        }
416
0
        else if (PyErr_Occurred()) {
417
0
            return -1;
418
0
        }
419
0
    }
420
421
    /* This warning wasn't found in the registry, set it. */
422
0
    if (should_set)
423
0
        return PyDict_SetItem(registry, key, Py_True);
424
0
    return 0;
425
0
}
426
427
/* New reference. */
428
static PyObject *
429
normalize_module(PyObject *filename)
430
0
{
431
0
    PyObject *module;
432
0
    int kind;
433
0
    void *data;
434
0
    Py_ssize_t len;
435
436
0
    len = PyUnicode_GetLength(filename);
437
0
    if (len < 0)
438
0
        return NULL;
439
440
0
    if (len == 0)
441
0
        return PyUnicode_FromString("<unknown>");
442
443
0
    kind = PyUnicode_KIND(filename);
444
0
    data = PyUnicode_DATA(filename);
445
446
    /* if filename.endswith(".py"): */
447
0
    if (len >= 3 &&
448
0
        PyUnicode_READ(kind, data, len-3) == '.' &&
449
0
        PyUnicode_READ(kind, data, len-2) == 'p' &&
450
0
        PyUnicode_READ(kind, data, len-1) == 'y')
451
0
    {
452
0
        module = PyUnicode_Substring(filename, 0, len-3);
453
0
    }
454
0
    else {
455
0
        module = filename;
456
0
        Py_INCREF(module);
457
0
    }
458
0
    return module;
459
0
}
460
461
static int
462
update_registry(PyObject *registry, PyObject *text, PyObject *category,
463
                int add_zero)
464
0
{
465
0
    PyObject *altkey;
466
0
    int rc;
467
468
0
    if (add_zero)
469
0
        altkey = PyTuple_Pack(3, text, category, _PyLong_Zero);
470
0
    else
471
0
        altkey = PyTuple_Pack(2, text, category);
472
473
0
    rc = already_warned(registry, altkey, 1);
474
0
    Py_XDECREF(altkey);
475
0
    return rc;
476
0
}
477
478
static void
479
show_warning(PyObject *filename, int lineno, PyObject *text,
480
             PyObject *category, PyObject *sourceline)
481
0
{
482
0
    PyObject *f_stderr;
483
0
    PyObject *name;
484
0
    char lineno_str[128];
485
0
    _Py_IDENTIFIER(__name__);
486
487
0
    PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
488
489
0
    name = _PyObject_GetAttrId(category, &PyId___name__);
490
0
    if (name == NULL)  /* XXX Can an object lack a '__name__' attribute? */
491
0
        goto error;
492
493
0
    f_stderr = _PySys_GetObjectId(&PyId_stderr);
494
0
    if (f_stderr == NULL) {
495
0
        fprintf(stderr, "lost sys.stderr\n");
496
0
        goto error;
497
0
    }
498
499
    /* Print "filename:lineno: category: text\n" */
500
0
    if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
501
0
        goto error;
502
0
    if (PyFile_WriteString(lineno_str, f_stderr) < 0)
503
0
        goto error;
504
0
    if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
505
0
        goto error;
506
0
    if (PyFile_WriteString(": ", f_stderr) < 0)
507
0
        goto error;
508
0
    if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
509
0
        goto error;
510
0
    if (PyFile_WriteString("\n", f_stderr) < 0)
511
0
        goto error;
512
0
    Py_CLEAR(name);
513
514
    /* Print "  source_line\n" */
515
0
    if (sourceline) {
516
0
        int kind;
517
0
        void *data;
518
0
        Py_ssize_t i, len;
519
0
        Py_UCS4 ch;
520
0
        PyObject *truncated;
521
522
0
        if (PyUnicode_READY(sourceline) < 1)
523
0
            goto error;
524
525
0
        kind = PyUnicode_KIND(sourceline);
526
0
        data = PyUnicode_DATA(sourceline);
527
0
        len = PyUnicode_GET_LENGTH(sourceline);
528
0
        for (i=0; i<len; i++) {
529
0
            ch = PyUnicode_READ(kind, data, i);
530
0
            if (ch != ' ' && ch != '\t' && ch != '\014')
531
0
                break;
532
0
        }
533
534
0
        truncated = PyUnicode_Substring(sourceline, i, len);
535
0
        if (truncated == NULL)
536
0
            goto error;
537
538
0
        PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
539
0
        Py_DECREF(truncated);
540
0
        PyFile_WriteString("\n", f_stderr);
541
0
    }
542
0
    else {
543
0
        _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
544
0
    }
545
546
0
error:
547
0
    Py_XDECREF(name);
548
0
    PyErr_Clear();
549
0
}
550
551
static int
552
call_show_warning(PyObject *category, PyObject *text, PyObject *message,
553
                  PyObject *filename, int lineno, PyObject *lineno_obj,
554
                  PyObject *sourceline, PyObject *source)
555
0
{
556
0
    PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
557
0
    _Py_IDENTIFIER(_showwarnmsg);
558
0
    _Py_IDENTIFIER(WarningMessage);
559
560
    /* If the source parameter is set, try to get the Python implementation.
561
       The Python implementation is able to log the traceback where the source
562
       was allocated, whereas the C implementation doesn't. */
563
0
    show_fn = get_warnings_attr(&PyId__showwarnmsg, source != NULL);
564
0
    if (show_fn == NULL) {
565
0
        if (PyErr_Occurred())
566
0
            return -1;
567
0
        show_warning(filename, lineno, text, category, sourceline);
568
0
        return 0;
569
0
    }
570
571
0
    if (!PyCallable_Check(show_fn)) {
572
0
        PyErr_SetString(PyExc_TypeError,
573
0
                "warnings._showwarnmsg() must be set to a callable");
574
0
        goto error;
575
0
    }
576
577
0
    warnmsg_cls = get_warnings_attr(&PyId_WarningMessage, 0);
578
0
    if (warnmsg_cls == NULL) {
579
0
        if (!PyErr_Occurred()) {
580
0
            PyErr_SetString(PyExc_RuntimeError,
581
0
                    "unable to get warnings.WarningMessage");
582
0
        }
583
0
        goto error;
584
0
    }
585
586
0
    msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
587
0
            filename, lineno_obj, Py_None, Py_None, source,
588
0
            NULL);
589
0
    Py_DECREF(warnmsg_cls);
590
0
    if (msg == NULL)
591
0
        goto error;
592
593
0
    res = PyObject_CallFunctionObjArgs(show_fn, msg, NULL);
594
0
    Py_DECREF(show_fn);
595
0
    Py_DECREF(msg);
596
597
0
    if (res == NULL)
598
0
        return -1;
599
600
0
    Py_DECREF(res);
601
0
    return 0;
602
603
0
error:
604
0
    Py_XDECREF(show_fn);
605
0
    return -1;
606
0
}
607
608
static PyObject *
609
warn_explicit(PyObject *category, PyObject *message,
610
              PyObject *filename, int lineno,
611
              PyObject *module, PyObject *registry, PyObject *sourceline,
612
              PyObject *source)
613
0
{
614
0
    PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
615
0
    PyObject *item = NULL;
616
0
    PyObject *action;
617
0
    int rc;
618
619
    /* module can be None if a warning is emitted late during Python shutdown.
620
       In this case, the Python warnings module was probably unloaded, filters
621
       are no more available to choose as action. It is safer to ignore the
622
       warning and do nothing. */
623
0
    if (module == Py_None)
624
0
        Py_RETURN_NONE;
625
626
0
    if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
627
0
        PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
628
0
        return NULL;
629
0
    }
630
631
    /* Normalize module. */
632
0
    if (module == NULL) {
633
0
        module = normalize_module(filename);
634
0
        if (module == NULL)
635
0
            return NULL;
636
0
    }
637
0
    else
638
0
        Py_INCREF(module);
639
640
    /* Normalize message. */
641
0
    Py_INCREF(message);  /* DECREF'ed in cleanup. */
642
0
    rc = PyObject_IsInstance(message, PyExc_Warning);
643
0
    if (rc == -1) {
644
0
        goto cleanup;
645
0
    }
646
0
    if (rc == 1) {
647
0
        text = PyObject_Str(message);
648
0
        if (text == NULL)
649
0
            goto cleanup;
650
0
        category = (PyObject*)message->ob_type;
651
0
    }
652
0
    else {
653
0
        text = message;
654
0
        message = PyObject_CallFunctionObjArgs(category, message, NULL);
655
0
        if (message == NULL)
656
0
            goto cleanup;
657
0
    }
658
659
0
    lineno_obj = PyLong_FromLong(lineno);
660
0
    if (lineno_obj == NULL)
661
0
        goto cleanup;
662
663
0
    if (source == Py_None) {
664
0
        source = NULL;
665
0
    }
666
667
    /* Create key. */
668
0
    key = PyTuple_Pack(3, text, category, lineno_obj);
669
0
    if (key == NULL)
670
0
        goto cleanup;
671
672
0
    if ((registry != NULL) && (registry != Py_None)) {
673
0
        rc = already_warned(registry, key, 0);
674
0
        if (rc == -1)
675
0
            goto cleanup;
676
0
        else if (rc == 1)
677
0
            goto return_none;
678
        /* Else this warning hasn't been generated before. */
679
0
    }
680
681
0
    action = get_filter(category, text, lineno, module, &item);
682
0
    if (action == NULL)
683
0
        goto cleanup;
684
685
0
    if (_PyUnicode_EqualToASCIIString(action, "error")) {
686
0
        PyErr_SetObject(category, message);
687
0
        goto cleanup;
688
0
    }
689
690
0
    if (_PyUnicode_EqualToASCIIString(action, "ignore")) {
691
0
        goto return_none;
692
0
    }
693
694
    /* Store in the registry that we've been here, *except* when the action
695
       is "always". */
696
0
    rc = 0;
697
0
    if (!_PyUnicode_EqualToASCIIString(action, "always")) {
698
0
        if (registry != NULL && registry != Py_None &&
699
0
            PyDict_SetItem(registry, key, Py_True) < 0)
700
0
        {
701
0
            goto cleanup;
702
0
        }
703
704
0
        if (_PyUnicode_EqualToASCIIString(action, "once")) {
705
0
            if (registry == NULL || registry == Py_None) {
706
0
                WarningsState *st = _Warnings_GetState();
707
0
                if (st == NULL) {
708
0
                    goto cleanup;
709
0
                }
710
0
                registry = get_once_registry(st);
711
0
                if (registry == NULL)
712
0
                    goto cleanup;
713
0
            }
714
            /* WarningsState.once_registry[(text, category)] = 1 */
715
0
            rc = update_registry(registry, text, category, 0);
716
0
        }
717
0
        else if (_PyUnicode_EqualToASCIIString(action, "module")) {
718
            /* registry[(text, category, 0)] = 1 */
719
0
            if (registry != NULL && registry != Py_None)
720
0
                rc = update_registry(registry, text, category, 0);
721
0
        }
722
0
        else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
723
0
            PyErr_Format(PyExc_RuntimeError,
724
0
                        "Unrecognized action (%R) in warnings.filters:\n %R",
725
0
                        action, item);
726
0
            goto cleanup;
727
0
        }
728
0
    }
729
730
0
    if (rc == 1)  /* Already warned for this module. */
731
0
        goto return_none;
732
0
    if (rc == 0) {
733
0
        if (call_show_warning(category, text, message, filename, lineno,
734
0
                              lineno_obj, sourceline, source) < 0)
735
0
            goto cleanup;
736
0
    }
737
0
    else /* if (rc == -1) */
738
0
        goto cleanup;
739
740
0
 return_none:
741
0
    result = Py_None;
742
0
    Py_INCREF(result);
743
744
0
 cleanup:
745
0
    Py_XDECREF(item);
746
0
    Py_XDECREF(key);
747
0
    Py_XDECREF(text);
748
0
    Py_XDECREF(lineno_obj);
749
0
    Py_DECREF(module);
750
0
    Py_XDECREF(message);
751
0
    return result;  /* Py_None or NULL. */
752
0
}
753
754
static int
755
is_internal_frame(PyFrameObject *frame)
756
0
{
757
0
    static PyObject *importlib_string = NULL;
758
0
    static PyObject *bootstrap_string = NULL;
759
0
    PyObject *filename;
760
0
    int contains;
761
762
0
    if (importlib_string == NULL) {
763
0
        importlib_string = PyUnicode_FromString("importlib");
764
0
        if (importlib_string == NULL) {
765
0
            return 0;
766
0
        }
767
768
0
        bootstrap_string = PyUnicode_FromString("_bootstrap");
769
0
        if (bootstrap_string == NULL) {
770
0
            Py_DECREF(importlib_string);
771
0
            return 0;
772
0
        }
773
0
        Py_INCREF(importlib_string);
774
0
        Py_INCREF(bootstrap_string);
775
0
    }
776
777
0
    if (frame == NULL || frame->f_code == NULL ||
778
0
            frame->f_code->co_filename == NULL) {
779
0
        return 0;
780
0
    }
781
0
    filename = frame->f_code->co_filename;
782
0
    if (!PyUnicode_Check(filename)) {
783
0
        return 0;
784
0
    }
785
0
    contains = PyUnicode_Contains(filename, importlib_string);
786
0
    if (contains < 0) {
787
0
        return 0;
788
0
    }
789
0
    else if (contains > 0) {
790
0
        contains = PyUnicode_Contains(filename, bootstrap_string);
791
0
        if (contains < 0) {
792
0
            return 0;
793
0
        }
794
0
        else if (contains > 0) {
795
0
            return 1;
796
0
        }
797
0
    }
798
799
0
    return 0;
800
0
}
801
802
static PyFrameObject *
803
next_external_frame(PyFrameObject *frame)
804
0
{
805
0
    do {
806
0
        frame = frame->f_back;
807
0
    } while (frame != NULL && is_internal_frame(frame));
808
809
0
    return frame;
810
0
}
811
812
/* filename, module, and registry are new refs, globals is borrowed */
813
/* Returns 0 on error (no new refs), 1 on success */
814
static int
815
setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
816
              PyObject **module, PyObject **registry)
817
0
{
818
0
    _Py_IDENTIFIER(__warningregistry__);
819
0
    _Py_IDENTIFIER(__name__);
820
0
    PyObject *globals;
821
822
    /* Setup globals, filename and lineno. */
823
0
    PyFrameObject *f = _PyThreadState_GET()->frame;
824
    // Stack level comparisons to Python code is off by one as there is no
825
    // warnings-related stack level to avoid.
826
0
    if (stack_level <= 0 || is_internal_frame(f)) {
827
0
        while (--stack_level > 0 && f != NULL) {
828
0
            f = f->f_back;
829
0
        }
830
0
    }
831
0
    else {
832
0
        while (--stack_level > 0 && f != NULL) {
833
0
            f = next_external_frame(f);
834
0
        }
835
0
    }
836
837
0
    if (f == NULL) {
838
0
        globals = _PyInterpreterState_GET_UNSAFE()->sysdict;
839
0
        *filename = PyUnicode_FromString("sys");
840
0
        *lineno = 1;
841
0
    }
842
0
    else {
843
0
        globals = f->f_globals;
844
0
        *filename = f->f_code->co_filename;
845
0
        Py_INCREF(*filename);
846
0
        *lineno = PyFrame_GetLineNumber(f);
847
0
    }
848
849
0
    *module = NULL;
850
851
    /* Setup registry. */
852
0
    assert(globals != NULL);
853
0
    assert(PyDict_Check(globals));
854
0
    *registry = _PyDict_GetItemIdWithError(globals, &PyId___warningregistry__);
855
0
    if (*registry == NULL) {
856
0
        int rc;
857
858
0
        if (PyErr_Occurred()) {
859
0
            goto handle_error;
860
0
        }
861
0
        *registry = PyDict_New();
862
0
        if (*registry == NULL)
863
0
            goto handle_error;
864
865
0
         rc = _PyDict_SetItemId(globals, &PyId___warningregistry__, *registry);
866
0
         if (rc < 0)
867
0
            goto handle_error;
868
0
    }
869
0
    else
870
0
        Py_INCREF(*registry);
871
872
    /* Setup module. */
873
0
    *module = _PyDict_GetItemIdWithError(globals, &PyId___name__);
874
0
    if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) {
875
0
        Py_INCREF(*module);
876
0
    }
877
0
    else if (PyErr_Occurred()) {
878
0
        goto handle_error;
879
0
    }
880
0
    else {
881
0
        *module = PyUnicode_FromString("<string>");
882
0
        if (*module == NULL)
883
0
            goto handle_error;
884
0
    }
885
886
0
    return 1;
887
888
0
 handle_error:
889
0
    Py_XDECREF(*registry);
890
0
    Py_XDECREF(*module);
891
0
    Py_DECREF(*filename);
892
0
    return 0;
893
0
}
894
895
static PyObject *
896
get_category(PyObject *message, PyObject *category)
897
0
{
898
0
    int rc;
899
900
    /* Get category. */
901
0
    rc = PyObject_IsInstance(message, PyExc_Warning);
902
0
    if (rc == -1)
903
0
        return NULL;
904
905
0
    if (rc == 1)
906
0
        category = (PyObject*)message->ob_type;
907
0
    else if (category == NULL || category == Py_None)
908
0
        category = PyExc_UserWarning;
909
910
    /* Validate category. */
911
0
    rc = PyObject_IsSubclass(category, PyExc_Warning);
912
    /* category is not a subclass of PyExc_Warning or
913
       PyObject_IsSubclass raised an error */
914
0
    if (rc == -1 || rc == 0) {
915
0
        PyErr_Format(PyExc_TypeError,
916
0
                     "category must be a Warning subclass, not '%s'",
917
0
                     Py_TYPE(category)->tp_name);
918
0
        return NULL;
919
0
    }
920
921
0
    return category;
922
0
}
923
924
static PyObject *
925
do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
926
        PyObject *source)
927
0
{
928
0
    PyObject *filename, *module, *registry, *res;
929
0
    int lineno;
930
931
0
    if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
932
0
        return NULL;
933
934
0
    res = warn_explicit(category, message, filename, lineno, module, registry,
935
0
                        NULL, source);
936
0
    Py_DECREF(filename);
937
0
    Py_DECREF(registry);
938
0
    Py_DECREF(module);
939
0
    return res;
940
0
}
941
942
/*[clinic input]
943
warn as warnings_warn
944
945
    message: object
946
    category: object = None
947
    stacklevel: Py_ssize_t = 1
948
    source: object = None
949
950
Issue a warning, or maybe ignore it or raise an exception.
951
[clinic start generated code]*/
952
953
static PyObject *
954
warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
955
                   Py_ssize_t stacklevel, PyObject *source)
956
/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
957
0
{
958
0
    category = get_category(message, category);
959
0
    if (category == NULL)
960
0
        return NULL;
961
0
    return do_warn(message, category, stacklevel, source);
962
0
}
963
964
static PyObject *
965
get_source_line(PyObject *module_globals, int lineno)
966
0
{
967
0
    _Py_IDENTIFIER(get_source);
968
0
    _Py_IDENTIFIER(__loader__);
969
0
    _Py_IDENTIFIER(__name__);
970
0
    PyObject *loader;
971
0
    PyObject *module_name;
972
0
    PyObject *get_source;
973
0
    PyObject *source;
974
0
    PyObject *source_list;
975
0
    PyObject *source_line;
976
977
    /* Check/get the requisite pieces needed for the loader. */
978
0
    loader = _PyDict_GetItemIdWithError(module_globals, &PyId___loader__);
979
0
    if (loader == NULL) {
980
0
        return NULL;
981
0
    }
982
0
    Py_INCREF(loader);
983
0
    module_name = _PyDict_GetItemIdWithError(module_globals, &PyId___name__);
984
0
    if (!module_name) {
985
0
        Py_DECREF(loader);
986
0
        return NULL;
987
0
    }
988
0
    Py_INCREF(module_name);
989
990
    /* Make sure the loader implements the optional get_source() method. */
991
0
    (void)_PyObject_LookupAttrId(loader, &PyId_get_source, &get_source);
992
0
    Py_DECREF(loader);
993
0
    if (!get_source) {
994
0
        Py_DECREF(module_name);
995
0
        return NULL;
996
0
    }
997
    /* Call get_source() to get the source code. */
998
0
    source = PyObject_CallFunctionObjArgs(get_source, module_name, NULL);
999
0
    Py_DECREF(get_source);
1000
0
    Py_DECREF(module_name);
1001
0
    if (!source) {
1002
0
        return NULL;
1003
0
    }
1004
0
    if (source == Py_None) {
1005
0
        Py_DECREF(source);
1006
0
        return NULL;
1007
0
    }
1008
1009
    /* Split the source into lines. */
1010
0
    source_list = PyUnicode_Splitlines(source, 0);
1011
0
    Py_DECREF(source);
1012
0
    if (!source_list) {
1013
0
        return NULL;
1014
0
    }
1015
1016
    /* Get the source line. */
1017
0
    source_line = PyList_GetItem(source_list, lineno-1);
1018
0
    Py_XINCREF(source_line);
1019
0
    Py_DECREF(source_list);
1020
0
    return source_line;
1021
0
}
1022
1023
static PyObject *
1024
warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
1025
0
{
1026
0
    static char *kwd_list[] = {"message", "category", "filename", "lineno",
1027
0
                                "module", "registry", "module_globals",
1028
0
                                "source", 0};
1029
0
    PyObject *message;
1030
0
    PyObject *category;
1031
0
    PyObject *filename;
1032
0
    int lineno;
1033
0
    PyObject *module = NULL;
1034
0
    PyObject *registry = NULL;
1035
0
    PyObject *module_globals = NULL;
1036
0
    PyObject *sourceobj = NULL;
1037
0
    PyObject *source_line = NULL;
1038
0
    PyObject *returned;
1039
1040
0
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
1041
0
                kwd_list, &message, &category, &filename, &lineno, &module,
1042
0
                &registry, &module_globals, &sourceobj))
1043
0
        return NULL;
1044
1045
0
    if (module_globals && module_globals != Py_None) {
1046
0
        if (!PyDict_Check(module_globals)) {
1047
0
            PyErr_Format(PyExc_TypeError,
1048
0
                         "module_globals must be a dict, not '%.200s'",
1049
0
                         Py_TYPE(module_globals)->tp_name);
1050
0
            return NULL;
1051
0
        }
1052
1053
0
        source_line = get_source_line(module_globals, lineno);
1054
0
        if (source_line == NULL && PyErr_Occurred()) {
1055
0
            return NULL;
1056
0
        }
1057
0
    }
1058
0
    returned = warn_explicit(category, message, filename, lineno, module,
1059
0
                             registry, source_line, sourceobj);
1060
0
    Py_XDECREF(source_line);
1061
0
    return returned;
1062
0
}
1063
1064
static PyObject *
1065
warnings_filters_mutated(PyObject *self, PyObject *args)
1066
0
{
1067
0
    WarningsState *st = _Warnings_GetState();
1068
0
    if (st == NULL) {
1069
0
        return NULL;
1070
0
    }
1071
0
    st->filters_version++;
1072
0
    Py_RETURN_NONE;
1073
0
}
1074
1075
1076
/* Function to issue a warning message; may raise an exception. */
1077
1078
static int
1079
warn_unicode(PyObject *category, PyObject *message,
1080
             Py_ssize_t stack_level, PyObject *source)
1081
0
{
1082
0
    PyObject *res;
1083
1084
0
    if (category == NULL)
1085
0
        category = PyExc_RuntimeWarning;
1086
1087
0
    res = do_warn(message, category, stack_level, source);
1088
0
    if (res == NULL)
1089
0
        return -1;
1090
0
    Py_DECREF(res);
1091
1092
0
    return 0;
1093
0
}
1094
1095
static int
1096
_PyErr_WarnFormatV(PyObject *source,
1097
                   PyObject *category, Py_ssize_t stack_level,
1098
                   const char *format, va_list vargs)
1099
0
{
1100
0
    PyObject *message;
1101
0
    int res;
1102
1103
0
    message = PyUnicode_FromFormatV(format, vargs);
1104
0
    if (message == NULL)
1105
0
        return -1;
1106
1107
0
    res = warn_unicode(category, message, stack_level, source);
1108
0
    Py_DECREF(message);
1109
0
    return res;
1110
0
}
1111
1112
int
1113
PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
1114
                 const char *format, ...)
1115
0
{
1116
0
    int res;
1117
0
    va_list vargs;
1118
1119
0
#ifdef HAVE_STDARG_PROTOTYPES
1120
0
    va_start(vargs, format);
1121
#else
1122
    va_start(vargs);
1123
#endif
1124
0
    res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
1125
0
    va_end(vargs);
1126
0
    return res;
1127
0
}
1128
1129
int
1130
PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
1131
                      const char *format, ...)
1132
0
{
1133
0
    int res;
1134
0
    va_list vargs;
1135
1136
0
#ifdef HAVE_STDARG_PROTOTYPES
1137
0
    va_start(vargs, format);
1138
#else
1139
    va_start(vargs);
1140
#endif
1141
0
    res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
1142
0
                             stack_level, format, vargs);
1143
0
    va_end(vargs);
1144
0
    return res;
1145
0
}
1146
1147
1148
int
1149
PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
1150
0
{
1151
0
    int ret;
1152
0
    PyObject *message = PyUnicode_FromString(text);
1153
0
    if (message == NULL)
1154
0
        return -1;
1155
0
    ret = warn_unicode(category, message, stack_level, NULL);
1156
0
    Py_DECREF(message);
1157
0
    return ret;
1158
0
}
1159
1160
/* PyErr_Warn is only for backwards compatibility and will be removed.
1161
   Use PyErr_WarnEx instead. */
1162
1163
#undef PyErr_Warn
1164
1165
int
1166
PyErr_Warn(PyObject *category, const char *text)
1167
0
{
1168
0
    return PyErr_WarnEx(category, text, 1);
1169
0
}
1170
1171
/* Warning with explicit origin */
1172
int
1173
PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1174
                         PyObject *filename, int lineno,
1175
                         PyObject *module, PyObject *registry)
1176
0
{
1177
0
    PyObject *res;
1178
0
    if (category == NULL)
1179
0
        category = PyExc_RuntimeWarning;
1180
0
    res = warn_explicit(category, message, filename, lineno,
1181
0
                        module, registry, NULL, NULL);
1182
0
    if (res == NULL)
1183
0
        return -1;
1184
0
    Py_DECREF(res);
1185
0
    return 0;
1186
0
}
1187
1188
int
1189
PyErr_WarnExplicit(PyObject *category, const char *text,
1190
                   const char *filename_str, int lineno,
1191
                   const char *module_str, PyObject *registry)
1192
0
{
1193
0
    PyObject *message = PyUnicode_FromString(text);
1194
0
    PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1195
0
    PyObject *module = NULL;
1196
0
    int ret = -1;
1197
1198
0
    if (message == NULL || filename == NULL)
1199
0
        goto exit;
1200
0
    if (module_str != NULL) {
1201
0
        module = PyUnicode_FromString(module_str);
1202
0
        if (module == NULL)
1203
0
            goto exit;
1204
0
    }
1205
1206
0
    ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1207
0
                                   module, registry);
1208
1209
0
 exit:
1210
0
    Py_XDECREF(message);
1211
0
    Py_XDECREF(module);
1212
0
    Py_XDECREF(filename);
1213
0
    return ret;
1214
0
}
1215
1216
int
1217
PyErr_WarnExplicitFormat(PyObject *category,
1218
                         const char *filename_str, int lineno,
1219
                         const char *module_str, PyObject *registry,
1220
                         const char *format, ...)
1221
0
{
1222
0
    PyObject *message;
1223
0
    PyObject *module = NULL;
1224
0
    PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1225
0
    int ret = -1;
1226
0
    va_list vargs;
1227
1228
0
    if (filename == NULL)
1229
0
        goto exit;
1230
0
    if (module_str != NULL) {
1231
0
        module = PyUnicode_FromString(module_str);
1232
0
        if (module == NULL)
1233
0
            goto exit;
1234
0
    }
1235
1236
0
#ifdef HAVE_STDARG_PROTOTYPES
1237
0
    va_start(vargs, format);
1238
#else
1239
    va_start(vargs);
1240
#endif
1241
0
    message = PyUnicode_FromFormatV(format, vargs);
1242
0
    if (message != NULL) {
1243
0
        PyObject *res;
1244
0
        res = warn_explicit(category, message, filename, lineno,
1245
0
                            module, registry, NULL, NULL);
1246
0
        Py_DECREF(message);
1247
0
        if (res != NULL) {
1248
0
            Py_DECREF(res);
1249
0
            ret = 0;
1250
0
        }
1251
0
    }
1252
0
    va_end(vargs);
1253
0
exit:
1254
0
    Py_XDECREF(module);
1255
0
    Py_XDECREF(filename);
1256
0
    return ret;
1257
0
}
1258
1259
void
1260
_PyErr_WarnUnawaitedCoroutine(PyObject *coro)
1261
0
{
1262
    /* First, we attempt to funnel the warning through
1263
       warnings._warn_unawaited_coroutine.
1264
1265
       This could raise an exception, due to:
1266
       - a bug
1267
       - some kind of shutdown-related brokenness
1268
       - succeeding, but with an "error" warning filter installed, so the
1269
         warning is converted into a RuntimeWarning exception
1270
1271
       In the first two cases, we want to print the error (so we know what it
1272
       is!), and then print a warning directly as a fallback. In the last
1273
       case, we want to print the error (since it's the warning!), but *not*
1274
       do a fallback. And after we print the error we can't check for what
1275
       type of error it was (because PyErr_WriteUnraisable clears it), so we
1276
       need a flag to keep track.
1277
1278
       Since this is called from __del__ context, it's careful to never raise
1279
       an exception.
1280
    */
1281
0
    _Py_IDENTIFIER(_warn_unawaited_coroutine);
1282
0
    int warned = 0;
1283
0
    PyObject *fn = get_warnings_attr(&PyId__warn_unawaited_coroutine, 1);
1284
0
    if (fn) {
1285
0
        PyObject *res = PyObject_CallFunctionObjArgs(fn, coro, NULL);
1286
0
        Py_DECREF(fn);
1287
0
        if (res || PyErr_ExceptionMatches(PyExc_RuntimeWarning)) {
1288
0
            warned = 1;
1289
0
        }
1290
0
        Py_XDECREF(res);
1291
0
    }
1292
1293
0
    if (PyErr_Occurred()) {
1294
0
        PyErr_WriteUnraisable(coro);
1295
0
    }
1296
0
    if (!warned) {
1297
0
        if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
1298
0
                             "coroutine '%.50S' was never awaited",
1299
0
                             ((PyCoroObject *)coro)->cr_qualname) < 0)
1300
0
        {
1301
0
            PyErr_WriteUnraisable(coro);
1302
0
        }
1303
0
    }
1304
0
}
1305
1306
PyDoc_STRVAR(warn_explicit_doc,
1307
"Low-level interface to warnings functionality.");
1308
1309
static PyMethodDef warnings_functions[] = {
1310
    WARNINGS_WARN_METHODDEF
1311
    {"warn_explicit", (PyCFunction)(void(*)(void))warnings_warn_explicit,
1312
        METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
1313
    {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
1314
        NULL},
1315
    /* XXX(brett.cannon): add showwarning? */
1316
    /* XXX(brett.cannon): Reasonable to add formatwarning? */
1317
    {NULL, NULL}                /* sentinel */
1318
};
1319
1320
1321
static struct PyModuleDef warningsmodule = {
1322
        PyModuleDef_HEAD_INIT,
1323
        MODULE_NAME,            /* m_name */
1324
        warnings__doc__,        /* m_doc */
1325
        0,                      /* m_size */
1326
        warnings_functions,     /* m_methods */
1327
        NULL,                   /* m_reload */
1328
        NULL,                   /* m_traverse */
1329
        NULL,                   /* m_clear */
1330
        NULL                    /* m_free */
1331
};
1332
1333
1334
PyMODINIT_FUNC
1335
_PyWarnings_Init(void)
1336
28
{
1337
28
    PyObject *m;
1338
1339
28
    m = PyModule_Create(&warningsmodule);
1340
28
    if (m == NULL) {
1341
0
        return NULL;
1342
0
    }
1343
1344
28
    WarningsState *st = _Warnings_GetState();
1345
28
    if (st == NULL) {
1346
0
        goto error;
1347
0
    }
1348
28
    if (_Warnings_InitState(st) < 0) {
1349
0
        goto error;
1350
0
    }
1351
1352
28
    Py_INCREF(st->filters);
1353
28
    if (PyModule_AddObject(m, "filters", st->filters) < 0) {
1354
0
        goto error;
1355
0
    }
1356
1357
28
    Py_INCREF(st->once_registry);
1358
28
    if (PyModule_AddObject(m, "_onceregistry", st->once_registry) < 0) {
1359
0
        goto error;
1360
0
    }
1361
1362
28
    Py_INCREF(st->default_action);
1363
28
    if (PyModule_AddObject(m, "_defaultaction", st->default_action) < 0) {
1364
0
        goto error;
1365
0
    }
1366
1367
28
    return m;
1368
1369
0
error:
1370
0
    if (st != NULL) {
1371
0
        _Warnings_ClearState(st);
1372
0
    }
1373
0
    Py_DECREF(m);
1374
0
    return NULL;
1375
28
}
1376
1377
// We need this to ensure that warnings still work until late in finalization.
1378
void
1379
_PyWarnings_Fini(PyInterpreterState *interp)
1380
0
{
1381
0
    _Warnings_ClearState(&interp->warnings);
1382
0
}