Coverage Report

Created: 2026-03-23 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Python/_warnings.c
Line
Count
Source
1
#include "Python.h"
2
#include "pycore_frame.h"         // PyFrameObject
3
#include "pycore_genobject.h"     // PyAsyncGenObject
4
#include "pycore_import.h"        // _PyImport_GetModules()
5
#include "pycore_interpframe.h"   // _PyFrame_GetCode()
6
#include "pycore_long.h"          // _PyLong_GetZero()
7
#include "pycore_pylifecycle.h"   // _Py_IsInterpreterFinalizing()
8
#include "pycore_pystate.h"       // _PyThreadState_GET()
9
#include "pycore_traceback.h"     // _Py_DisplaySourceLine()
10
#include "pycore_tuple.h"         // _PyTuple_FromPair
11
#include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString()
12
13
#include <stdbool.h>
14
#include "clinic/_warnings.c.h"
15
16
17
0
#define MODULE_NAME "_warnings"
18
19
PyDoc_STRVAR(warnings__doc__,
20
MODULE_NAME " provides basic warning filtering support.\n"
21
"It is a helper module to speed up interpreter start-up.");
22
23
24
/*************************************************************************/
25
26
typedef struct _warnings_runtime_state WarningsState;
27
28
static inline int
29
check_interp(PyInterpreterState *interp)
30
1.48M
{
31
1.48M
    if (interp == NULL) {
32
0
        PyErr_SetString(PyExc_RuntimeError,
33
0
                        "warnings_get_state: could not identify "
34
0
                        "current interpreter");
35
0
        return 0;
36
0
    }
37
1.48M
    return 1;
38
1.48M
}
39
40
static inline PyInterpreterState *
41
get_current_interp(void)
42
69.9k
{
43
69.9k
    PyInterpreterState *interp = _PyInterpreterState_GET();
44
69.9k
    return check_interp(interp) ? interp : NULL;
45
69.9k
}
46
47
static inline PyThreadState *
48
get_current_tstate(void)
49
1.41M
{
50
1.41M
    PyThreadState *tstate = _PyThreadState_GET();
51
1.41M
    if (tstate == NULL) {
52
0
        (void)check_interp(NULL);
53
0
        return NULL;
54
0
    }
55
1.41M
    return check_interp(tstate->interp) ? tstate : NULL;
56
1.41M
}
57
58
/* Given a module object, get its per-module state. */
59
static WarningsState *
60
warnings_get_state(PyInterpreterState *interp)
61
2.86M
{
62
2.86M
    return &interp->warnings;
63
2.86M
}
64
65
/* Clear the given warnings module state. */
66
static void
67
warnings_clear_state(WarningsState *st)
68
0
{
69
0
    Py_CLEAR(st->filters);
70
0
    Py_CLEAR(st->once_registry);
71
0
    Py_CLEAR(st->default_action);
72
0
    Py_CLEAR(st->context);
73
0
}
74
75
#ifndef Py_DEBUG
76
static PyObject *
77
create_filter(PyObject *category, PyObject *action_str, const char *modname)
78
180
{
79
180
    PyObject *modname_obj = NULL;
80
81
    /* Default to "no module name" for initial filter set */
82
180
    if (modname != NULL) {
83
36
        modname_obj = PyUnicode_InternFromString(modname);
84
36
        if (modname_obj == NULL) {
85
0
            return NULL;
86
0
        }
87
144
    } else {
88
144
        modname_obj = Py_NewRef(Py_None);
89
144
    }
90
91
    /* This assumes the line number is zero for now. */
92
180
    PyObject *filter = PyTuple_Pack(5, action_str, Py_None,
93
180
                                    category, modname_obj, _PyLong_GetZero());
94
180
    Py_DECREF(modname_obj);
95
180
    return filter;
96
180
}
97
#endif
98
99
static PyObject *
100
init_filters(PyInterpreterState *interp)
101
36
{
102
#ifdef Py_DEBUG
103
    /* Py_DEBUG builds show all warnings by default */
104
    return PyList_New(0);
105
#else
106
    /* Other builds ignore a number of warning categories by default */
107
36
    PyObject *filters = PyList_New(5);
108
36
    if (filters == NULL) {
109
0
        return NULL;
110
0
    }
111
112
36
    size_t pos = 0;  /* Post-incremented in each use. */
113
36
#define ADD(TYPE, ACTION, MODNAME) \
114
180
    PyList_SET_ITEM(filters, pos++, \
115
180
                    create_filter(TYPE, &_Py_ID(ACTION), MODNAME));
116
36
    ADD(PyExc_DeprecationWarning, default, "__main__");
117
36
    ADD(PyExc_DeprecationWarning, ignore, NULL);
118
36
    ADD(PyExc_PendingDeprecationWarning, ignore, NULL);
119
36
    ADD(PyExc_ImportWarning, ignore, NULL);
120
36
    ADD(PyExc_ResourceWarning, ignore, NULL);
121
36
#undef ADD
122
123
216
    for (size_t x = 0; x < pos; x++) {
124
180
        if (PyList_GET_ITEM(filters, x) == NULL) {
125
0
            Py_DECREF(filters);
126
0
            return NULL;
127
0
        }
128
180
    }
129
36
    return filters;
130
36
#endif
131
36
}
132
133
/* Initialize the given warnings module state. */
134
int
135
_PyWarnings_InitState(PyInterpreterState *interp)
136
36
{
137
36
    WarningsState *st = &interp->warnings;
138
139
36
    if (st->filters == NULL) {
140
36
        st->filters = init_filters(interp);
141
36
        if (st->filters == NULL) {
142
0
            return -1;
143
0
        }
144
36
    }
145
146
36
    if (st->once_registry == NULL) {
147
36
        st->once_registry = PyDict_New();
148
36
        if (st->once_registry == NULL) {
149
0
            return -1;
150
0
        }
151
36
    }
152
153
36
    if (st->default_action == NULL) {
154
36
        st->default_action = PyUnicode_FromString("default");
155
36
        if (st->default_action == NULL) {
156
0
            return -1;
157
0
        }
158
36
    }
159
160
36
    if (st->context == NULL) {
161
36
        st->context = PyContextVar_New("_warnings_context", NULL);
162
36
        if (st->context == NULL) {
163
0
            return -1;
164
0
        }
165
36
    }
166
167
36
    st->filters_version = 0;
168
36
    return 0;
169
36
}
170
171
172
/*************************************************************************/
173
174
static int
175
check_matched(PyInterpreterState *interp, PyObject *obj, PyObject *arg, PyObject *arg2)
176
2.14M
{
177
2.14M
    PyObject *result;
178
2.14M
    int rc;
179
180
    /* A 'None' filter always matches */
181
2.14M
    if (obj == Py_None)
182
1.92M
        return 1;
183
184
    /* An internal plain text default filter must match exactly */
185
216k
    if (PyUnicode_CheckExact(obj)) {
186
216k
        if (arg == NULL) {
187
0
            return 0;
188
0
        }
189
216k
        int cmp_result = PyUnicode_Compare(obj, arg);
190
216k
        if (cmp_result == -1 && PyErr_Occurred()) {
191
0
            return -1;
192
0
        }
193
216k
        return !cmp_result;
194
216k
    }
195
196
    /* Otherwise assume a regex filter and call its match() method */
197
0
    if (arg != NULL) {
198
0
        result = PyObject_CallMethodOneArg(obj, &_Py_ID(match), arg);
199
0
    }
200
0
    else {
201
0
        PyObject *match = PyImport_ImportModuleAttrString("_py_warnings", "_match_filename");
202
0
        if (match == NULL) {
203
0
            return -1;
204
0
        }
205
0
        result = PyObject_CallFunctionObjArgs(match, obj, arg2, NULL);
206
0
        Py_DECREF(match);
207
0
    }
208
0
    if (result == NULL)
209
0
        return -1;
210
0
    rc = PyObject_IsTrue(result);
211
0
    Py_DECREF(result);
212
0
    return rc;
213
0
}
214
215
#define GET_WARNINGS_ATTR(interp, ATTR, try_import) \
216
856k
    get_warnings_attr(interp, &_Py_ID(ATTR), try_import)
217
218
/*
219
   Returns a new reference.
220
   A NULL return value can mean false or an error.
221
*/
222
static PyObject *
223
get_warnings_attr(PyInterpreterState *interp, PyObject *attr, int try_import)
224
856k
{
225
856k
    PyObject *warnings_module, *obj;
226
227
    /* don't try to import after the start of the Python finallization */
228
856k
    if (try_import && !_Py_IsInterpreterFinalizing(interp)) {
229
209k
        warnings_module = PyImport_Import(&_Py_ID(warnings));
230
209k
        if (warnings_module == NULL) {
231
            /* Fallback to the C implementation if we cannot get
232
               the Python implementation */
233
0
            if (PyErr_ExceptionMatches(PyExc_ImportError)) {
234
0
                PyErr_Clear();
235
0
            }
236
0
            return NULL;
237
0
        }
238
209k
    }
239
647k
    else {
240
        /* if we're so late into Python finalization that the module dict is
241
           gone, then we can't even use PyImport_GetModule without triggering
242
           an interpreter abort.
243
        */
244
647k
        if (!_PyImport_GetModules(interp)) {
245
0
            return NULL;
246
0
        }
247
647k
        warnings_module = PyImport_GetModule(&_Py_ID(warnings));
248
647k
        if (warnings_module == NULL)
249
0
            return NULL;
250
647k
    }
251
252
856k
    (void)PyObject_GetOptionalAttr(warnings_module, attr, &obj);
253
856k
    Py_DECREF(warnings_module);
254
856k
    return obj;
255
856k
}
256
257
static inline void
258
warnings_lock(PyInterpreterState *interp)
259
736k
{
260
736k
    WarningsState *st = warnings_get_state(interp);
261
736k
    assert(st != NULL);
262
736k
    _PyRecursiveMutex_Lock(&st->lock);
263
736k
}
264
265
static inline int
266
warnings_unlock(PyInterpreterState *interp)
267
736k
{
268
736k
    WarningsState *st = warnings_get_state(interp);
269
736k
    assert(st != NULL);
270
736k
    return _PyRecursiveMutex_TryUnlock(&st->lock);
271
736k
}
272
273
static inline bool
274
warnings_lock_held(WarningsState *st)
275
23.2k
{
276
23.2k
    return PyMutex_IsLocked(&st->lock.mutex);
277
23.2k
}
278
279
static PyObject *
280
get_warnings_context(PyInterpreterState *interp)
281
227k
{
282
227k
    WarningsState *st = warnings_get_state(interp);
283
227k
    assert(PyContextVar_CheckExact(st->context));
284
227k
    PyObject *ctx;
285
227k
    if (PyContextVar_Get(st->context, NULL, &ctx) < 0) {
286
0
        return NULL;
287
0
    }
288
227k
    if (ctx == NULL) {
289
227k
        Py_RETURN_NONE;
290
227k
    }
291
0
    return ctx;
292
227k
}
293
294
static PyObject *
295
get_warnings_context_filters(PyInterpreterState *interp)
296
227k
{
297
227k
    PyObject *ctx = get_warnings_context(interp);
298
227k
    if (ctx == NULL) {
299
0
        return NULL;
300
0
    }
301
227k
    if (ctx == Py_None) {
302
227k
        Py_RETURN_NONE;
303
227k
    }
304
0
    PyObject *context_filters = PyObject_GetAttr(ctx, &_Py_ID(_filters));
305
0
    Py_DECREF(ctx);
306
0
    if (context_filters == NULL) {
307
0
        return NULL;
308
0
    }
309
0
    if (!PyList_Check(context_filters)) {
310
0
        PyErr_SetString(PyExc_ValueError,
311
0
                        "_filters of warnings._warnings_context must be a list");
312
0
        Py_DECREF(context_filters);
313
0
        return NULL;
314
0
    }
315
0
    return context_filters;
316
0
}
317
318
// Returns a borrowed reference to the list.
319
static PyObject *
320
get_warnings_filters(PyInterpreterState *interp)
321
227k
{
322
227k
    WarningsState *st = warnings_get_state(interp);
323
227k
    PyObject *warnings_filters = GET_WARNINGS_ATTR(interp, filters, 0);
324
227k
    if (warnings_filters == NULL) {
325
0
        if (PyErr_Occurred())
326
0
            return NULL;
327
0
    }
328
227k
    else {
329
227k
        Py_SETREF(st->filters, warnings_filters);
330
227k
    }
331
332
227k
    PyObject *filters = st->filters;
333
227k
    if (filters == NULL || !PyList_Check(filters)) {
334
0
        PyErr_SetString(PyExc_ValueError,
335
0
                        MODULE_NAME ".filters must be a list");
336
0
        return NULL;
337
0
    }
338
227k
    return filters;
339
227k
}
340
341
/*[clinic input]
342
_acquire_lock as warnings_acquire_lock
343
344
[clinic start generated code]*/
345
346
static PyObject *
347
warnings_acquire_lock_impl(PyObject *module)
348
/*[clinic end generated code: output=594313457d1bf8e1 input=46ec20e55acca52f]*/
349
23.2k
{
350
23.2k
    PyInterpreterState *interp = get_current_interp();
351
23.2k
    if (interp == NULL) {
352
0
        return NULL;
353
0
    }
354
23.2k
    warnings_lock(interp);
355
23.2k
    Py_RETURN_NONE;
356
23.2k
}
357
358
/*[clinic input]
359
_release_lock as warnings_release_lock
360
361
[clinic start generated code]*/
362
363
static PyObject *
364
warnings_release_lock_impl(PyObject *module)
365
/*[clinic end generated code: output=d73d5a8789396750 input=ea01bb77870c5693]*/
366
23.2k
{
367
23.2k
    PyInterpreterState *interp = get_current_interp();
368
23.2k
    if (interp == NULL) {
369
0
        return NULL;
370
0
    }
371
23.2k
    if (warnings_unlock(interp) < 0) {
372
0
        PyErr_SetString(PyExc_RuntimeError, "cannot release un-acquired lock");
373
0
        return NULL;
374
0
    }
375
23.2k
    Py_RETURN_NONE;
376
23.2k
}
377
378
static PyObject *
379
get_once_registry(PyInterpreterState *interp)
380
0
{
381
0
    WarningsState *st = warnings_get_state(interp);
382
0
    assert(st != NULL);
383
384
0
    assert(warnings_lock_held(st));
385
386
0
    PyObject *registry = GET_WARNINGS_ATTR(interp, onceregistry, 0);
387
0
    if (registry == NULL) {
388
0
        if (PyErr_Occurred())
389
0
            return NULL;
390
0
        assert(st->once_registry);
391
0
        return st->once_registry;
392
0
    }
393
0
    if (!PyDict_Check(registry)) {
394
0
        PyErr_Format(PyExc_TypeError,
395
0
                     MODULE_NAME ".onceregistry must be a dict, "
396
0
                     "not '%.200s'",
397
0
                     Py_TYPE(registry)->tp_name);
398
0
        Py_DECREF(registry);
399
0
        return NULL;
400
0
    }
401
0
    Py_SETREF(st->once_registry, registry);
402
0
    return registry;
403
0
}
404
405
406
static PyObject *
407
get_default_action(PyInterpreterState *interp)
408
209k
{
409
209k
    WarningsState *st = warnings_get_state(interp);
410
209k
    assert(st != NULL);
411
412
209k
    assert(warnings_lock_held(st));
413
414
209k
    PyObject *default_action = GET_WARNINGS_ATTR(interp, defaultaction, 0);
415
209k
    if (default_action == NULL) {
416
0
        if (PyErr_Occurred()) {
417
0
            return NULL;
418
0
        }
419
0
        assert(st->default_action);
420
0
        return st->default_action;
421
0
    }
422
209k
    if (!PyUnicode_Check(default_action)) {
423
0
        PyErr_Format(PyExc_TypeError,
424
0
                     MODULE_NAME ".defaultaction must be a string, "
425
0
                     "not '%.200s'",
426
0
                     Py_TYPE(default_action)->tp_name);
427
0
        Py_DECREF(default_action);
428
0
        return NULL;
429
0
    }
430
209k
    Py_SETREF(st->default_action, default_action);
431
209k
    return default_action;
432
209k
}
433
434
/* Search filters list of match, returns false on error.  If no match
435
 * then 'matched_action' is NULL.  */
436
static bool
437
filter_search(PyInterpreterState *interp, PyObject *category,
438
              PyObject *text, Py_ssize_t lineno,
439
              PyObject *module, PyObject *filename, char *list_name, PyObject *filters,
440
227k
              PyObject **item, PyObject **matched_action) {
441
227k
    bool result = true;
442
227k
    *matched_action = NULL;
443
    /* Avoid the filters list changing while we iterate over it. */
444
227k
    Py_BEGIN_CRITICAL_SECTION(filters);
445
1.28M
    for (Py_ssize_t i = 0; i < PyList_GET_SIZE(filters); i++) {
446
1.07M
        PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
447
1.07M
        Py_ssize_t ln;
448
1.07M
        int is_subclass, good_msg, good_mod;
449
450
1.07M
        tmp_item = PyList_GET_ITEM(filters, i);
451
1.07M
        if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
452
0
            PyErr_Format(PyExc_ValueError,
453
0
                         "warnings.%s item %zd isn't a 5-tuple", list_name, i);
454
0
            result = false;
455
0
            break;
456
0
        }
457
458
        /* Python code: action, msg, cat, mod, ln = item */
459
1.07M
        Py_INCREF(tmp_item);
460
1.07M
        action = PyTuple_GET_ITEM(tmp_item, 0);
461
1.07M
        msg = PyTuple_GET_ITEM(tmp_item, 1);
462
1.07M
        cat = PyTuple_GET_ITEM(tmp_item, 2);
463
1.07M
        mod = PyTuple_GET_ITEM(tmp_item, 3);
464
1.07M
        ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
465
466
1.07M
        if (!PyUnicode_Check(action)) {
467
0
            PyErr_Format(PyExc_TypeError,
468
0
                         "action must be a string, not '%.200s'",
469
0
                         Py_TYPE(action)->tp_name);
470
0
            Py_DECREF(tmp_item);
471
0
            result = false;
472
0
            break;
473
0
        }
474
475
1.07M
        good_msg = check_matched(interp, msg, text, NULL);
476
1.07M
        if (good_msg == -1) {
477
0
            Py_DECREF(tmp_item);
478
0
            result = false;
479
0
            break;
480
0
        }
481
482
1.07M
        good_mod = check_matched(interp, mod, module, filename);
483
1.07M
        if (good_mod == -1) {
484
0
            Py_DECREF(tmp_item);
485
0
            result = false;
486
0
            break;
487
0
        }
488
489
1.07M
        is_subclass = PyObject_IsSubclass(category, cat);
490
1.07M
        if (is_subclass == -1) {
491
0
            Py_DECREF(tmp_item);
492
0
            result = false;
493
0
            break;
494
0
        }
495
496
1.07M
        ln = PyLong_AsSsize_t(ln_obj);
497
1.07M
        if (ln == -1 && PyErr_Occurred()) {
498
0
            Py_DECREF(tmp_item);
499
0
            result = false;
500
0
            break;
501
0
        }
502
503
1.07M
        if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
504
17.3k
            *item = tmp_item;
505
17.3k
            *matched_action = action;
506
17.3k
            result = true;
507
17.3k
            break;
508
17.3k
        }
509
510
1.05M
        Py_DECREF(tmp_item);
511
1.05M
    }
512
227k
    Py_END_CRITICAL_SECTION();
513
227k
    return result;
514
227k
}
515
516
/* The item is a new reference. */
517
static PyObject*
518
get_filter(PyInterpreterState *interp, PyObject *category,
519
           PyObject *text, Py_ssize_t lineno,
520
           PyObject *module, PyObject *filename, PyObject **item)
521
227k
{
522
#ifdef Py_DEBUG
523
    WarningsState *st = warnings_get_state(interp);
524
    assert(st != NULL);
525
    assert(warnings_lock_held(st));
526
#endif
527
528
    /* check _warning_context _filters list */
529
227k
    PyObject *context_filters = get_warnings_context_filters(interp);
530
227k
    if (context_filters == NULL) {
531
0
        return NULL;
532
0
    }
533
227k
    bool use_global_filters = false;
534
227k
    if (context_filters == Py_None) {
535
227k
        use_global_filters = true;
536
227k
    } else {
537
0
        PyObject *context_action = NULL;
538
0
        if (!filter_search(interp, category, text, lineno, module, filename, "_warnings_context _filters",
539
0
                           context_filters, item, &context_action)) {
540
0
            Py_DECREF(context_filters);
541
0
            return NULL;
542
0
        }
543
0
        Py_DECREF(context_filters);
544
0
        if (context_action != NULL) {
545
0
            return context_action;
546
0
        }
547
0
    }
548
549
227k
    PyObject *action;
550
551
227k
    if (use_global_filters) {
552
        /* check warnings.filters list */
553
227k
        PyObject *filters = get_warnings_filters(interp);
554
227k
        if (filters == NULL) {
555
0
            return NULL;
556
0
        }
557
227k
        if (!filter_search(interp, category, text, lineno, module, filename, "filters",
558
227k
                           filters, item, &action)) {
559
0
            return NULL;
560
0
        }
561
227k
        if (action != NULL) {
562
17.3k
            return action;
563
17.3k
        }
564
227k
    }
565
566
209k
    action = get_default_action(interp);
567
209k
    if (action != NULL) {
568
209k
        *item = Py_NewRef(Py_None);
569
209k
        return action;
570
209k
    }
571
572
0
    return NULL;
573
209k
}
574
575
576
static int
577
already_warned(PyInterpreterState *interp, PyObject *registry, PyObject *key,
578
               int should_set)
579
701k
{
580
701k
    PyObject *already_warned;
581
582
701k
    if (key == NULL)
583
0
        return -1;
584
585
701k
    WarningsState *st = warnings_get_state(interp);
586
701k
    assert(st != NULL);
587
701k
    assert(warnings_lock_held(st));
588
589
701k
    PyObject *version_obj;
590
701k
    if (PyDict_GetItemRef(registry, &_Py_ID(version), &version_obj) < 0) {
591
0
        return -1;
592
0
    }
593
701k
    bool should_update_version = (
594
701k
        version_obj == NULL
595
701k
        || !PyLong_CheckExact(version_obj)
596
701k
        || PyLong_AsLong(version_obj) != st->filters_version
597
701k
    );
598
701k
    Py_XDECREF(version_obj);
599
701k
    if (should_update_version) {
600
3.69k
        PyDict_Clear(registry);
601
3.69k
        version_obj = PyLong_FromLong(st->filters_version);
602
3.69k
        if (version_obj == NULL)
603
0
            return -1;
604
3.69k
        if (PyDict_SetItem(registry, &_Py_ID(version), version_obj) < 0) {
605
0
            Py_DECREF(version_obj);
606
0
            return -1;
607
0
        }
608
3.69k
        Py_DECREF(version_obj);
609
3.69k
    }
610
698k
    else {
611
698k
        if (PyDict_GetItemRef(registry, key, &already_warned) < 0) {
612
0
            return -1;
613
0
        }
614
698k
        if (already_warned != NULL) {
615
485k
            int rc = PyObject_IsTrue(already_warned);
616
485k
            Py_DECREF(already_warned);
617
485k
            if (rc != 0)
618
485k
                return rc;
619
485k
        }
620
698k
    }
621
622
    /* This warning wasn't found in the registry, set it. */
623
216k
    if (should_set)
624
0
        return PyDict_SetItem(registry, key, Py_True);
625
216k
    return 0;
626
216k
}
627
628
static int
629
update_registry(PyInterpreterState *interp, PyObject *registry, PyObject *text,
630
                PyObject *category, int add_zero)
631
0
{
632
0
    PyObject *altkey;
633
0
    int rc;
634
635
0
    if (add_zero)
636
0
        altkey = PyTuple_Pack(3, text, category, _PyLong_GetZero());
637
0
    else
638
0
        altkey = _PyTuple_FromPair(text, category);
639
640
0
    rc = already_warned(interp, registry, altkey, 1);
641
0
    Py_XDECREF(altkey);
642
0
    return rc;
643
0
}
644
645
static void
646
show_warning(PyThreadState *tstate, PyObject *filename, int lineno,
647
             PyObject *text, PyObject *category, PyObject *sourceline)
648
0
{
649
0
    PyObject *f_stderr = NULL;
650
0
    PyObject *name;
651
0
    char lineno_str[128];
652
653
0
    PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
654
655
0
    name = PyObject_GetAttr(category, &_Py_ID(__name__));
656
0
    if (name == NULL) {
657
0
        goto error;
658
0
    }
659
660
0
    if (PySys_GetOptionalAttr(&_Py_ID(stderr), &f_stderr) <= 0) {
661
0
        fprintf(stderr, "lost sys.stderr\n");
662
0
        goto error;
663
0
    }
664
665
    /* Print "filename:lineno: category: text\n" */
666
0
    if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
667
0
        goto error;
668
0
    if (PyFile_WriteString(lineno_str, f_stderr) < 0)
669
0
        goto error;
670
0
    if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
671
0
        goto error;
672
0
    if (PyFile_WriteString(": ", f_stderr) < 0)
673
0
        goto error;
674
0
    if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
675
0
        goto error;
676
0
    if (PyFile_WriteString("\n", f_stderr) < 0)
677
0
        goto error;
678
0
    Py_CLEAR(name);
679
680
    /* Print "  source_line\n" */
681
0
    if (sourceline) {
682
0
        int kind;
683
0
        const void *data;
684
0
        Py_ssize_t i, len;
685
0
        Py_UCS4 ch;
686
0
        PyObject *truncated;
687
688
0
        kind = PyUnicode_KIND(sourceline);
689
0
        data = PyUnicode_DATA(sourceline);
690
0
        len = PyUnicode_GET_LENGTH(sourceline);
691
0
        for (i=0; i<len; i++) {
692
0
            ch = PyUnicode_READ(kind, data, i);
693
0
            if (ch != ' ' && ch != '\t' && ch != '\014')
694
0
                break;
695
0
        }
696
697
0
        truncated = PyUnicode_Substring(sourceline, i, len);
698
0
        if (truncated == NULL)
699
0
            goto error;
700
701
0
        PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
702
0
        Py_DECREF(truncated);
703
0
        PyFile_WriteString("\n", f_stderr);
704
0
    }
705
0
    else {
706
0
        _Py_DisplaySourceLine(f_stderr, filename, lineno, 2, NULL, NULL);
707
0
    }
708
709
0
error:
710
0
    Py_XDECREF(f_stderr);
711
0
    Py_XDECREF(name);
712
0
    PyErr_Clear();
713
0
}
714
715
static int
716
call_show_warning(PyThreadState *tstate, PyObject *category,
717
                  PyObject *text, PyObject *message,
718
                  PyObject *filename, int lineno, PyObject *lineno_obj,
719
                  PyObject *sourceline, PyObject *source)
720
209k
{
721
209k
    PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
722
209k
    PyInterpreterState *interp = tstate->interp;
723
724
    /* The Python implementation is able to log the traceback where the source
725
       was allocated, whereas the C implementation doesn't. */
726
209k
    show_fn = GET_WARNINGS_ATTR(interp, _showwarnmsg, 1);
727
209k
    if (show_fn == NULL) {
728
0
        if (PyErr_Occurred())
729
0
            return -1;
730
0
        show_warning(tstate, filename, lineno, text, category, sourceline);
731
0
        return 0;
732
0
    }
733
734
209k
    if (!PyCallable_Check(show_fn)) {
735
0
        PyErr_SetString(PyExc_TypeError,
736
0
                "warnings._showwarnmsg() must be set to a callable");
737
0
        goto error;
738
0
    }
739
740
209k
    warnmsg_cls = GET_WARNINGS_ATTR(interp, WarningMessage, 0);
741
209k
    if (warnmsg_cls == NULL) {
742
0
        if (!PyErr_Occurred()) {
743
0
            PyErr_SetString(PyExc_RuntimeError,
744
0
                    "unable to get warnings.WarningMessage");
745
0
        }
746
0
        goto error;
747
0
    }
748
749
209k
    msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
750
209k
            filename, lineno_obj, Py_None, Py_None, source,
751
209k
            NULL);
752
209k
    Py_DECREF(warnmsg_cls);
753
209k
    if (msg == NULL)
754
0
        goto error;
755
756
209k
    res = PyObject_CallOneArg(show_fn, msg);
757
209k
    Py_DECREF(show_fn);
758
209k
    Py_DECREF(msg);
759
760
209k
    if (res == NULL)
761
0
        return -1;
762
763
209k
    Py_DECREF(res);
764
209k
    return 0;
765
766
0
error:
767
0
    Py_XDECREF(show_fn);
768
0
    return -1;
769
209k
}
770
771
static PyObject *
772
warn_explicit(PyThreadState *tstate, PyObject *category, PyObject *message,
773
              PyObject *filename, int lineno,
774
              PyObject *module, PyObject *registry, PyObject *sourceline,
775
              PyObject *source)
776
712k
{
777
712k
    PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
778
712k
    PyObject *item = NULL;
779
712k
    PyObject *action;
780
712k
    int rc;
781
712k
    PyInterpreterState *interp = tstate->interp;
782
783
    /* module can be None if a warning is emitted late during Python shutdown.
784
       In this case, the Python warnings module was probably unloaded, filters
785
       are no more available to choose as action. It is safer to ignore the
786
       warning and do nothing. */
787
712k
    if (module == Py_None)
788
0
        Py_RETURN_NONE;
789
790
712k
    if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
791
0
        PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
792
0
        return NULL;
793
0
    }
794
795
    /* Normalize message. */
796
712k
    Py_INCREF(message);  /* DECREF'ed in cleanup. */
797
712k
    if (PyObject_TypeCheck(message, (PyTypeObject *)PyExc_Warning)) {
798
0
        text = PyObject_Str(message);
799
0
        if (text == NULL)
800
0
            goto cleanup;
801
0
        category = (PyObject*)Py_TYPE(message);
802
0
    }
803
712k
    else {
804
712k
        text = message;
805
712k
        message = PyObject_CallOneArg(category, message);
806
712k
        if (message == NULL)
807
0
            goto cleanup;
808
712k
    }
809
810
712k
    lineno_obj = PyLong_FromLong(lineno);
811
712k
    if (lineno_obj == NULL)
812
0
        goto cleanup;
813
814
712k
    if (source == Py_None) {
815
701k
        source = NULL;
816
701k
    }
817
818
    /* Create key. */
819
712k
    key = PyTuple_Pack(3, text, category, lineno_obj);
820
712k
    if (key == NULL)
821
0
        goto cleanup;
822
823
712k
    if ((registry != NULL) && (registry != Py_None)) {
824
701k
        rc = already_warned(interp, registry, key, 0);
825
701k
        if (rc == -1)
826
0
            goto cleanup;
827
701k
        else if (rc == 1)
828
485k
            goto return_none;
829
        /* Else this warning hasn't been generated before. */
830
701k
    }
831
832
227k
    action = get_filter(interp, category, text, lineno, module, filename, &item);
833
227k
    if (action == NULL)
834
0
        goto cleanup;
835
836
227k
    if (_PyUnicode_EqualToASCIIString(action, "error")) {
837
0
        PyErr_SetObject(category, message);
838
0
        goto cleanup;
839
0
    }
840
841
227k
    if (_PyUnicode_EqualToASCIIString(action, "ignore")) {
842
17.3k
        goto return_none;
843
17.3k
    }
844
845
    /* Store in the registry that we've been here, *except* when the action
846
       is "always" or "all". */
847
209k
    rc = 0;
848
209k
    if (!_PyUnicode_EqualToASCIIString(action, "always") && !_PyUnicode_EqualToASCIIString(action, "all")) {
849
209k
        if (registry != NULL && registry != Py_None &&
850
209k
            PyDict_SetItem(registry, key, Py_True) < 0)
851
0
        {
852
0
            goto cleanup;
853
0
        }
854
855
209k
        if (_PyUnicode_EqualToASCIIString(action, "once")) {
856
0
            if (registry == NULL || registry == Py_None) {
857
0
                registry = get_once_registry(interp);
858
0
                if (registry == NULL)
859
0
                    goto cleanup;
860
0
            }
861
            /* WarningsState.once_registry[(text, category)] = 1 */
862
0
            rc = update_registry(interp, registry, text, category, 0);
863
0
        }
864
209k
        else if (_PyUnicode_EqualToASCIIString(action, "module")) {
865
            /* registry[(text, category, 0)] = 1 */
866
0
            if (registry != NULL && registry != Py_None)
867
0
                rc = update_registry(interp, registry, text, category, 0);
868
0
        }
869
209k
        else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
870
0
            PyErr_Format(PyExc_RuntimeError,
871
0
                        "Unrecognized action (%R) in warnings.filters:\n %R",
872
0
                        action, item);
873
0
            goto cleanup;
874
0
        }
875
209k
    }
876
877
209k
    if (rc == 1)  /* Already warned for this module. */
878
0
        goto return_none;
879
209k
    if (rc == 0) {
880
209k
        if (call_show_warning(tstate, category, text, message, filename,
881
209k
                              lineno, lineno_obj, sourceline, source) < 0)
882
0
            goto cleanup;
883
209k
    }
884
0
    else /* if (rc == -1) */
885
0
        goto cleanup;
886
887
712k
 return_none:
888
712k
    result = Py_NewRef(Py_None);
889
890
712k
 cleanup:
891
712k
    Py_XDECREF(item);
892
712k
    Py_XDECREF(key);
893
712k
    Py_XDECREF(text);
894
712k
    Py_XDECREF(lineno_obj);
895
712k
    Py_XDECREF(message);
896
712k
    return result;  /* Py_None or NULL. */
897
712k
}
898
899
static PyObject *
900
get_frame_filename(PyFrameObject *frame)
901
15.2M
{
902
15.2M
    PyCodeObject *code = PyFrame_GetCode(frame);
903
15.2M
    PyObject *filename = code->co_filename;
904
15.2M
    Py_DECREF(code);
905
15.2M
    return filename;
906
15.2M
}
907
908
static bool
909
is_internal_filename(PyObject *filename)
910
15.2M
{
911
15.2M
    if (!PyUnicode_Check(filename)) {
912
0
        return false;
913
0
    }
914
915
15.2M
    int contains = PyUnicode_Contains(filename, &_Py_ID(importlib));
916
15.2M
    if (contains < 0) {
917
0
        return false;
918
0
    }
919
15.2M
    else if (contains > 0) {
920
0
        contains = PyUnicode_Contains(filename, &_Py_ID(_bootstrap));
921
0
        if (contains < 0) {
922
0
            return false;
923
0
        }
924
0
        else if (contains > 0) {
925
0
            return true;
926
0
        }
927
0
    }
928
929
15.2M
    return false;
930
15.2M
}
931
932
static bool
933
is_filename_to_skip(PyObject *filename, PyTupleObject *skip_file_prefixes)
934
14.5M
{
935
14.5M
    if (skip_file_prefixes) {
936
126
        if (!PyUnicode_Check(filename)) {
937
0
            return false;
938
0
        }
939
940
126
        Py_ssize_t prefixes = PyTuple_GET_SIZE(skip_file_prefixes);
941
168
        for (Py_ssize_t idx = 0; idx < prefixes; ++idx)
942
126
        {
943
126
            PyObject *prefix = PyTuple_GET_ITEM(skip_file_prefixes, idx);
944
126
            Py_ssize_t found = PyUnicode_Tailmatch(filename, prefix,
945
126
                                                   0, PY_SSIZE_T_MAX, -1);
946
126
            if (found == 1) {
947
84
                return true;
948
84
            }
949
42
            if (found < 0) {
950
0
                return false;
951
0
            }
952
42
        }
953
126
    }
954
14.5M
    return false;
955
14.5M
}
956
957
static bool
958
is_internal_frame(PyFrameObject *frame)
959
701k
{
960
701k
    if (frame == NULL) {
961
0
        return false;
962
0
    }
963
964
701k
    PyObject *filename = get_frame_filename(frame);
965
701k
    if (filename == NULL) {
966
0
        return false;
967
0
    }
968
969
701k
    return is_internal_filename(filename);
970
701k
}
971
972
static PyFrameObject *
973
next_external_frame(PyFrameObject *frame, PyTupleObject *skip_file_prefixes)
974
14.5M
{
975
14.5M
    PyObject *frame_filename;
976
14.5M
    do {
977
14.5M
        PyFrameObject *back = PyFrame_GetBack(frame);
978
14.5M
        Py_SETREF(frame, back);
979
14.5M
    } while (frame != NULL && (frame_filename = get_frame_filename(frame)) &&
980
14.5M
             (is_internal_filename(frame_filename) ||
981
14.5M
              is_filename_to_skip(frame_filename, skip_file_prefixes)));
982
983
14.5M
    return frame;
984
14.5M
}
985
986
/* filename, module, and registry are new refs, globals is borrowed */
987
/* skip_file_prefixes is either NULL or a tuple of strs. */
988
/* Returns 0 on error (no new refs), 1 on success */
989
static int
990
setup_context(Py_ssize_t stack_level,
991
              PyTupleObject *skip_file_prefixes,
992
              PyObject **filename, int *lineno,
993
              PyObject **module, PyObject **registry)
994
701k
{
995
701k
    PyObject *globals;
996
997
    /* Setup globals, filename and lineno. */
998
701k
    PyThreadState *tstate = get_current_tstate();
999
701k
    if (tstate == NULL) {
1000
0
        return 0;
1001
0
    }
1002
701k
    if (skip_file_prefixes) {
1003
        /* Type check our data structure up front. Later code that uses it
1004
         * isn't structured to report errors. */
1005
42
        Py_ssize_t prefixes = PyTuple_GET_SIZE(skip_file_prefixes);
1006
84
        for (Py_ssize_t idx = 0; idx < prefixes; ++idx)
1007
42
        {
1008
42
            PyObject *prefix = PyTuple_GET_ITEM(skip_file_prefixes, idx);
1009
42
            if (!PyUnicode_Check(prefix)) {
1010
0
                PyErr_Format(PyExc_TypeError,
1011
0
                             "Found non-str '%s' in skip_file_prefixes.",
1012
0
                             Py_TYPE(prefix)->tp_name);
1013
0
                return 0;
1014
0
            }
1015
42
        }
1016
42
    }
1017
701k
    PyInterpreterState *interp = tstate->interp;
1018
701k
    PyFrameObject *f = PyThreadState_GetFrame(tstate);
1019
    // Stack level comparisons to Python code is off by one as there is no
1020
    // warnings-related stack level to avoid.
1021
701k
    if (stack_level <= 0 || is_internal_frame(f)) {
1022
0
        while (--stack_level > 0 && f != NULL) {
1023
0
            PyFrameObject *back = PyFrame_GetBack(f);
1024
0
            Py_SETREF(f, back);
1025
0
        }
1026
0
    }
1027
701k
    else {
1028
15.2M
        while (--stack_level > 0 && f != NULL) {
1029
14.5M
            f = next_external_frame(f, skip_file_prefixes);
1030
14.5M
        }
1031
701k
    }
1032
1033
701k
    if (f == NULL) {
1034
0
        globals = interp->sysdict;
1035
0
        *filename = PyUnicode_FromString("<sys>");
1036
0
        *lineno = 0;
1037
0
    }
1038
701k
    else {
1039
701k
        globals = f->f_frame->f_globals;
1040
701k
        *filename = Py_NewRef(_PyFrame_GetCode(f->f_frame)->co_filename);
1041
701k
        *lineno = PyFrame_GetLineNumber(f);
1042
701k
        Py_DECREF(f);
1043
701k
    }
1044
1045
701k
    *module = NULL;
1046
1047
    /* Setup registry. */
1048
701k
    assert(globals != NULL);
1049
701k
    assert(PyAnyDict_Check(globals));
1050
701k
    int rc = PyDict_GetItemRef(globals, &_Py_ID(__warningregistry__),
1051
701k
                               registry);
1052
701k
    if (rc < 0) {
1053
0
        goto handle_error;
1054
0
    }
1055
701k
    if (*registry == NULL) {
1056
7
        *registry = PyDict_New();
1057
7
        if (*registry == NULL)
1058
0
            goto handle_error;
1059
1060
7
         rc = PyDict_SetItem(globals, &_Py_ID(__warningregistry__), *registry);
1061
7
         if (rc < 0)
1062
0
            goto handle_error;
1063
7
    }
1064
1065
    /* Setup module. */
1066
701k
    rc = PyDict_GetItemRef(globals, &_Py_ID(__name__), module);
1067
701k
    if (rc < 0) {
1068
0
        goto handle_error;
1069
0
    }
1070
701k
    if (rc > 0) {
1071
701k
        if (Py_IsNone(*module) || PyUnicode_Check(*module)) {
1072
701k
            return 1;
1073
701k
        }
1074
0
        Py_DECREF(*module);
1075
0
    }
1076
0
    *module = PyUnicode_FromString("<string>");
1077
0
    if (*module == NULL) {
1078
0
        goto handle_error;
1079
0
    }
1080
1081
0
    return 1;
1082
1083
0
 handle_error:
1084
0
    Py_XDECREF(*registry);
1085
0
    Py_XDECREF(*module);
1086
0
    Py_DECREF(*filename);
1087
0
    return 0;
1088
0
}
1089
1090
static PyObject *
1091
get_category(PyObject *message, PyObject *category)
1092
701k
{
1093
701k
    if (PyObject_TypeCheck(message, (PyTypeObject *)PyExc_Warning)) {
1094
        /* Ignore the category argument. */
1095
0
        return (PyObject*)Py_TYPE(message);
1096
0
    }
1097
701k
    if (category == NULL || category == Py_None) {
1098
3.73k
        return PyExc_UserWarning;
1099
3.73k
    }
1100
1101
    /* Validate category. */
1102
698k
    if (!PyType_Check(category)) {
1103
0
        PyErr_Format(PyExc_TypeError,
1104
0
                     "category must be a Warning subclass, not '%T'",
1105
0
                     category);
1106
0
        return NULL;
1107
0
    }
1108
698k
    if (!PyType_IsSubtype((PyTypeObject *)category, (PyTypeObject *)PyExc_Warning)) {
1109
0
        PyErr_Format(PyExc_TypeError,
1110
0
                     "category must be a Warning subclass, not class '%N'",
1111
0
                     (PyTypeObject *)category);
1112
0
        return NULL;
1113
0
    }
1114
1115
698k
    return category;
1116
698k
}
1117
1118
static PyObject *
1119
do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
1120
        PyObject *source, PyTupleObject *skip_file_prefixes)
1121
701k
{
1122
701k
    PyObject *filename, *module, *registry, *res;
1123
701k
    int lineno;
1124
1125
701k
    PyThreadState *tstate = get_current_tstate();
1126
701k
    if (tstate == NULL) {
1127
0
        return NULL;
1128
0
    }
1129
1130
701k
    if (!setup_context(stack_level, skip_file_prefixes,
1131
701k
                       &filename, &lineno, &module, &registry))
1132
0
        return NULL;
1133
1134
701k
    warnings_lock(tstate->interp);
1135
701k
    res = warn_explicit(tstate, category, message, filename, lineno, module, registry,
1136
701k
                        NULL, source);
1137
701k
    warnings_unlock(tstate->interp);
1138
701k
    Py_DECREF(filename);
1139
701k
    Py_DECREF(registry);
1140
701k
    Py_DECREF(module);
1141
701k
    return res;
1142
701k
}
1143
1144
/*[clinic input]
1145
warn as warnings_warn
1146
1147
    message: object
1148
      Text of the warning message.
1149
    category: object = None
1150
      The Warning category subclass. Defaults to UserWarning.
1151
    stacklevel: Py_ssize_t = 1
1152
      How far up the call stack to make this warning appear. A value of 2 for
1153
      example attributes the warning to the caller of the code calling warn().
1154
    source: object = None
1155
      If supplied, the destroyed object which emitted a ResourceWarning
1156
    *
1157
    skip_file_prefixes: object(type='PyTupleObject *', subclass_of='&PyTuple_Type') = NULL
1158
      An optional tuple of module filename prefixes indicating frames to skip
1159
      during stacklevel computations for stack frame attribution.
1160
1161
Issue a warning, or maybe ignore it or raise an exception.
1162
[clinic start generated code]*/
1163
1164
static PyObject *
1165
warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
1166
                   Py_ssize_t stacklevel, PyObject *source,
1167
                   PyTupleObject *skip_file_prefixes)
1168
/*[clinic end generated code: output=a68e0f6906c65f80 input=eb37c6a18bec4ea1]*/
1169
701k
{
1170
701k
    category = get_category(message, category);
1171
701k
    if (category == NULL)
1172
0
        return NULL;
1173
701k
    if (skip_file_prefixes) {
1174
42
        if (PyTuple_GET_SIZE(skip_file_prefixes) > 0) {
1175
42
            if (stacklevel < 2) {
1176
42
                stacklevel = 2;
1177
42
            }
1178
42
        } else {
1179
0
            Py_DECREF((PyObject *)skip_file_prefixes);
1180
0
            skip_file_prefixes = NULL;
1181
0
        }
1182
42
    }
1183
701k
    return do_warn(message, category, stacklevel, source, skip_file_prefixes);
1184
701k
}
1185
1186
static PyObject *
1187
get_source_line(PyInterpreterState *interp, PyObject *module_globals, int lineno)
1188
0
{
1189
0
    PyObject *loader;
1190
0
    PyObject *module_name;
1191
0
    PyObject *get_source;
1192
0
    PyObject *source;
1193
0
    PyObject *source_list;
1194
0
    PyObject *source_line;
1195
1196
    /* stolen from import.c */
1197
0
    loader = _PyImport_BlessMyLoader(interp, module_globals);
1198
0
    if (loader == NULL) {
1199
0
        return NULL;
1200
0
    }
1201
1202
0
    int rc = PyDict_GetItemRef(module_globals, &_Py_ID(__name__),
1203
0
                               &module_name);
1204
0
    if (rc < 0 || rc == 0) {
1205
0
        Py_DECREF(loader);
1206
0
        return NULL;
1207
0
    }
1208
1209
    /* Make sure the loader implements the optional get_source() method. */
1210
0
    (void)PyObject_GetOptionalAttr(loader, &_Py_ID(get_source), &get_source);
1211
0
    Py_DECREF(loader);
1212
0
    if (!get_source) {
1213
0
        Py_DECREF(module_name);
1214
0
        return NULL;
1215
0
    }
1216
    /* Call get_source() to get the source code. */
1217
0
    source = PyObject_CallOneArg(get_source, module_name);
1218
0
    Py_DECREF(get_source);
1219
0
    Py_DECREF(module_name);
1220
0
    if (!source) {
1221
0
        return NULL;
1222
0
    }
1223
0
    if (source == Py_None) {
1224
0
        Py_DECREF(source);
1225
0
        return NULL;
1226
0
    }
1227
1228
    /* Split the source into lines. */
1229
0
    source_list = PyUnicode_Splitlines(source, 0);
1230
0
    Py_DECREF(source);
1231
0
    if (!source_list) {
1232
0
        return NULL;
1233
0
    }
1234
1235
    /* Get the source line. */
1236
0
    source_line = PyList_GetItem(source_list, lineno-1);
1237
0
    Py_XINCREF(source_line);
1238
0
    Py_DECREF(source_list);
1239
0
    return source_line;
1240
0
}
1241
1242
/*[clinic input]
1243
warn_explicit as warnings_warn_explicit
1244
1245
    message: object
1246
    category: object
1247
    filename: unicode
1248
    lineno: int
1249
    module as mod: object = NULL
1250
    registry: object = None
1251
    module_globals: object = None
1252
    source as sourceobj: object = None
1253
1254
Issue a warning, or maybe ignore it or raise an exception.
1255
[clinic start generated code]*/
1256
1257
static PyObject *
1258
warnings_warn_explicit_impl(PyObject *module, PyObject *message,
1259
                            PyObject *category, PyObject *filename,
1260
                            int lineno, PyObject *mod, PyObject *registry,
1261
                            PyObject *module_globals, PyObject *sourceobj)
1262
/*[clinic end generated code: output=c49c62b15a49a186 input=df6eeb8b45e712f1]*/
1263
0
{
1264
0
    PyObject *source_line = NULL;
1265
0
    PyObject *returned;
1266
1267
0
    PyThreadState *tstate = get_current_tstate();
1268
0
    if (tstate == NULL) {
1269
0
        return NULL;
1270
0
    }
1271
1272
0
    if (module_globals && module_globals != Py_None) {
1273
0
        if (!PyAnyDict_Check(module_globals)) {
1274
0
            PyErr_Format(PyExc_TypeError,
1275
0
                         "module_globals must be a dict or a frozendict, "
1276
0
                         "not %T",
1277
0
                         module_globals);
1278
0
            return NULL;
1279
0
        }
1280
1281
0
        source_line = get_source_line(tstate->interp, module_globals, lineno);
1282
0
        if (source_line == NULL && PyErr_Occurred()) {
1283
0
            return NULL;
1284
0
        }
1285
0
    }
1286
1287
0
    warnings_lock(tstate->interp);
1288
0
    returned = warn_explicit(tstate, category, message, filename, lineno,
1289
0
                             mod, registry, source_line, sourceobj);
1290
0
    warnings_unlock(tstate->interp);
1291
0
    Py_XDECREF(source_line);
1292
0
    return returned;
1293
0
}
1294
1295
/*[clinic input]
1296
_filters_mutated_lock_held as warnings_filters_mutated_lock_held
1297
1298
[clinic start generated code]*/
1299
1300
static PyObject *
1301
warnings_filters_mutated_lock_held_impl(PyObject *module)
1302
/*[clinic end generated code: output=df5c84f044e856ec input=34208bf03d70e432]*/
1303
23.2k
{
1304
23.2k
    PyInterpreterState *interp = get_current_interp();
1305
23.2k
    if (interp == NULL) {
1306
0
        return NULL;
1307
0
    }
1308
1309
23.2k
    WarningsState *st = warnings_get_state(interp);
1310
23.2k
    assert(st != NULL);
1311
1312
    // Note that the lock must be held by the caller.
1313
23.2k
    if (!warnings_lock_held(st)) {
1314
0
        PyErr_SetString(PyExc_RuntimeError, "warnings lock is not held");
1315
0
        return NULL;
1316
0
    }
1317
1318
23.2k
    st->filters_version++;
1319
1320
23.2k
    Py_RETURN_NONE;
1321
23.2k
}
1322
1323
/* Function to issue a warning message; may raise an exception. */
1324
1325
static int
1326
warn_unicode(PyObject *category, PyObject *message,
1327
             Py_ssize_t stack_level, PyObject *source)
1328
0
{
1329
0
    PyObject *res;
1330
1331
0
    if (category == NULL)
1332
0
        category = PyExc_RuntimeWarning;
1333
1334
0
    res = do_warn(message, category, stack_level, source, NULL);
1335
0
    if (res == NULL)
1336
0
        return -1;
1337
0
    Py_DECREF(res);
1338
1339
0
    return 0;
1340
0
}
1341
1342
static int
1343
_PyErr_WarnFormatV(PyObject *source,
1344
                   PyObject *category, Py_ssize_t stack_level,
1345
                   const char *format, va_list vargs)
1346
0
{
1347
0
    PyObject *message;
1348
0
    int res;
1349
1350
0
    message = PyUnicode_FromFormatV(format, vargs);
1351
0
    if (message == NULL)
1352
0
        return -1;
1353
1354
0
    res = warn_unicode(category, message, stack_level, source);
1355
0
    Py_DECREF(message);
1356
0
    return res;
1357
0
}
1358
1359
int
1360
PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
1361
                 const char *format, ...)
1362
0
{
1363
0
    int res;
1364
0
    va_list vargs;
1365
1366
0
    va_start(vargs, format);
1367
0
    res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
1368
0
    va_end(vargs);
1369
0
    return res;
1370
0
}
1371
1372
static int
1373
_PyErr_WarnFormat(PyObject *source, PyObject *category, Py_ssize_t stack_level,
1374
                  const char *format, ...)
1375
0
{
1376
0
    int res;
1377
0
    va_list vargs;
1378
1379
0
    va_start(vargs, format);
1380
0
    res = _PyErr_WarnFormatV(source, category, stack_level, format, vargs);
1381
0
    va_end(vargs);
1382
0
    return res;
1383
0
}
1384
1385
int
1386
PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
1387
                      const char *format, ...)
1388
0
{
1389
0
    int res;
1390
0
    va_list vargs;
1391
1392
0
    va_start(vargs, format);
1393
0
    res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
1394
0
                             stack_level, format, vargs);
1395
0
    va_end(vargs);
1396
0
    return res;
1397
0
}
1398
1399
1400
int
1401
PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
1402
0
{
1403
0
    int ret;
1404
0
    PyObject *message = PyUnicode_FromString(text);
1405
0
    if (message == NULL)
1406
0
        return -1;
1407
0
    ret = warn_unicode(category, message, stack_level, NULL);
1408
0
    Py_DECREF(message);
1409
0
    return ret;
1410
0
}
1411
1412
/* PyErr_Warn is only for backwards compatibility and will be removed.
1413
   Use PyErr_WarnEx instead. */
1414
1415
#undef PyErr_Warn
1416
1417
int
1418
PyErr_Warn(PyObject *category, const char *text)
1419
0
{
1420
0
    return PyErr_WarnEx(category, text, 1);
1421
0
}
1422
1423
/* Warning with explicit origin */
1424
int
1425
PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1426
                         PyObject *filename, int lineno,
1427
                         PyObject *module, PyObject *registry)
1428
11.1k
{
1429
11.1k
    PyObject *res;
1430
11.1k
    if (category == NULL)
1431
0
        category = PyExc_RuntimeWarning;
1432
11.1k
    PyThreadState *tstate = get_current_tstate();
1433
11.1k
    if (tstate == NULL) {
1434
0
        return -1;
1435
0
    }
1436
1437
11.1k
    warnings_lock(tstate->interp);
1438
11.1k
    res = warn_explicit(tstate, category, message, filename, lineno,
1439
11.1k
                        module, registry, NULL, NULL);
1440
11.1k
    warnings_unlock(tstate->interp);
1441
11.1k
    if (res == NULL)
1442
0
        return -1;
1443
11.1k
    Py_DECREF(res);
1444
11.1k
    return 0;
1445
11.1k
}
1446
1447
int
1448
PyErr_WarnExplicit(PyObject *category, const char *text,
1449
                   const char *filename_str, int lineno,
1450
                   const char *module_str, PyObject *registry)
1451
0
{
1452
0
    PyObject *message = PyUnicode_FromString(text);
1453
0
    if (message == NULL) {
1454
0
        return -1;
1455
0
    }
1456
0
    PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1457
0
    if (filename == NULL) {
1458
0
        Py_DECREF(message);
1459
0
        return -1;
1460
0
    }
1461
0
    PyObject *module = NULL;
1462
0
    if (module_str != NULL) {
1463
0
        module = PyUnicode_FromString(module_str);
1464
0
        if (module == NULL) {
1465
0
            Py_DECREF(filename);
1466
0
            Py_DECREF(message);
1467
0
            return -1;
1468
0
        }
1469
0
    }
1470
1471
0
    int ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1472
0
                                       module, registry);
1473
0
    Py_XDECREF(module);
1474
0
    Py_DECREF(filename);
1475
0
    Py_DECREF(message);
1476
0
    return ret;
1477
0
}
1478
1479
int
1480
PyErr_WarnExplicitFormat(PyObject *category,
1481
                         const char *filename_str, int lineno,
1482
                         const char *module_str, PyObject *registry,
1483
                         const char *format, ...)
1484
0
{
1485
0
    PyObject *message;
1486
0
    PyObject *module = NULL;
1487
0
    PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1488
0
    int ret = -1;
1489
0
    va_list vargs;
1490
1491
0
    if (filename == NULL)
1492
0
        goto exit;
1493
0
    if (module_str != NULL) {
1494
0
        module = PyUnicode_FromString(module_str);
1495
0
        if (module == NULL)
1496
0
            goto exit;
1497
0
    }
1498
1499
0
    va_start(vargs, format);
1500
0
    message = PyUnicode_FromFormatV(format, vargs);
1501
0
    if (message != NULL) {
1502
0
        PyObject *res;
1503
0
        PyThreadState *tstate = get_current_tstate();
1504
0
        if (tstate != NULL) {
1505
0
            warnings_lock(tstate->interp);
1506
0
            res = warn_explicit(tstate, category, message, filename, lineno,
1507
0
                                module, registry, NULL, NULL);
1508
0
            warnings_unlock(tstate->interp);
1509
0
            Py_DECREF(message);
1510
0
            if (res != NULL) {
1511
0
                Py_DECREF(res);
1512
0
                ret = 0;
1513
0
            }
1514
0
        }
1515
0
    }
1516
0
    va_end(vargs);
1517
0
exit:
1518
0
    Py_XDECREF(module);
1519
0
    Py_XDECREF(filename);
1520
0
    return ret;
1521
0
}
1522
1523
void
1524
_PyErr_WarnUnawaitedAgenMethod(PyAsyncGenObject *agen, PyObject *method)
1525
0
{
1526
0
    PyObject *exc = PyErr_GetRaisedException();
1527
0
    if (_PyErr_WarnFormat((PyObject *)agen, PyExc_RuntimeWarning, 1,
1528
0
                          "coroutine method %R of %R was never awaited",
1529
0
                          method, agen->ag_qualname) < 0)
1530
0
    {
1531
0
        PyErr_FormatUnraisable("Exception ignored while "
1532
0
                               "finalizing async generator %R", agen);
1533
0
    }
1534
0
    PyErr_SetRaisedException(exc);
1535
0
}
1536
1537
1538
void
1539
_PyErr_WarnUnawaitedCoroutine(PyObject *coro)
1540
0
{
1541
    /* First, we attempt to funnel the warning through
1542
       warnings._warn_unawaited_coroutine.
1543
1544
       This could raise an exception, due to:
1545
       - a bug
1546
       - some kind of shutdown-related brokenness
1547
       - succeeding, but with an "error" warning filter installed, so the
1548
         warning is converted into a RuntimeWarning exception
1549
1550
       In the first two cases, we want to print the error (so we know what it
1551
       is!), and then print a warning directly as a fallback. In the last
1552
       case, we want to print the error (since it's the warning!), but *not*
1553
       do a fallback. And after we print the error we can't check for what
1554
       type of error it was (because PyErr_WriteUnraisable clears it), so we
1555
       need a flag to keep track.
1556
1557
       Since this is called from __del__ context, it's careful to never raise
1558
       an exception.
1559
    */
1560
0
    int warned = 0;
1561
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
1562
0
    assert(interp != NULL);
1563
0
    PyObject *fn = GET_WARNINGS_ATTR(interp, _warn_unawaited_coroutine, 1);
1564
0
    if (fn) {
1565
0
        PyObject *res = PyObject_CallOneArg(fn, coro);
1566
0
        Py_DECREF(fn);
1567
0
        if (res || PyErr_ExceptionMatches(PyExc_RuntimeWarning)) {
1568
0
            warned = 1;
1569
0
        }
1570
0
        Py_XDECREF(res);
1571
0
    }
1572
1573
0
    if (PyErr_Occurred()) {
1574
0
        PyErr_FormatUnraisable("Exception ignored while "
1575
0
                               "finalizing coroutine %R", coro);
1576
0
    }
1577
1578
0
    if (!warned) {
1579
0
        if (_PyErr_WarnFormat(coro, PyExc_RuntimeWarning, 1,
1580
0
                              "coroutine '%S' was never awaited",
1581
0
                              ((PyCoroObject *)coro)->cr_qualname) < 0)
1582
0
        {
1583
0
            PyErr_FormatUnraisable("Exception ignored while "
1584
0
                                   "finalizing coroutine %R", coro);
1585
0
        }
1586
0
    }
1587
0
}
1588
1589
static PyMethodDef warnings_functions[] = {
1590
    WARNINGS_WARN_METHODDEF
1591
    WARNINGS_WARN_EXPLICIT_METHODDEF
1592
    WARNINGS_FILTERS_MUTATED_LOCK_HELD_METHODDEF
1593
    WARNINGS_ACQUIRE_LOCK_METHODDEF
1594
    WARNINGS_RELEASE_LOCK_METHODDEF
1595
    /* XXX(brett.cannon): add showwarning? */
1596
    /* XXX(brett.cannon): Reasonable to add formatwarning? */
1597
    {NULL, NULL}                /* sentinel */
1598
};
1599
1600
1601
static int
1602
warnings_module_exec(PyObject *module)
1603
36
{
1604
36
    PyInterpreterState *interp = get_current_interp();
1605
36
    if (interp == NULL) {
1606
0
        return -1;
1607
0
    }
1608
36
    WarningsState *st = warnings_get_state(interp);
1609
36
    if (st == NULL) {
1610
0
        return -1;
1611
0
    }
1612
36
    if (PyModule_AddObjectRef(module, "filters", st->filters) < 0) {
1613
0
        return -1;
1614
0
    }
1615
36
    if (PyModule_AddObjectRef(module, "_onceregistry", st->once_registry) < 0) {
1616
0
        return -1;
1617
0
    }
1618
36
    if (PyModule_AddObjectRef(module, "_defaultaction", st->default_action) < 0) {
1619
0
        return -1;
1620
0
    }
1621
36
    if (PyModule_AddObjectRef(module, "_warnings_context", st->context) < 0) {
1622
0
        return -1;
1623
0
    }
1624
36
    return 0;
1625
36
}
1626
1627
1628
static PyModuleDef_Slot warnings_slots[] = {
1629
    {Py_mod_exec, warnings_module_exec},
1630
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
1631
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
1632
    {0, NULL}
1633
};
1634
1635
static struct PyModuleDef warnings_module = {
1636
    PyModuleDef_HEAD_INIT,
1637
    .m_name = MODULE_NAME,
1638
    .m_doc = warnings__doc__,
1639
    .m_size = 0,
1640
    .m_methods = warnings_functions,
1641
    .m_slots = warnings_slots,
1642
};
1643
1644
1645
PyMODINIT_FUNC
1646
_PyWarnings_Init(void)
1647
36
{
1648
36
    return PyModuleDef_Init(&warnings_module);
1649
36
}
1650
1651
// We need this to ensure that warnings still work until late in finalization.
1652
void
1653
_PyWarnings_Fini(PyInterpreterState *interp)
1654
0
{
1655
0
    warnings_clear_state(&interp->warnings);
1656
0
}