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