Coverage Report

Created: 2026-10-31 06:21

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