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
check_interp(PyInterpreterState * interp)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 *
get_current_interp(void)34 get_current_interp(void)
35 {
36 PyInterpreterState *interp = _PyInterpreterState_GET();
37 return check_interp(interp) ? interp : NULL;
38 }
39
40 static inline PyThreadState *
get_current_tstate(void)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 *
warnings_get_state(PyInterpreterState * interp)53 warnings_get_state(PyInterpreterState *interp)
54 {
55 return &interp->warnings;
56 }
57
58 /* Clear the given warnings module state. */
59 static void
warnings_clear_state(WarningsState * st)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 *
create_filter(PyObject * category,PyObject * action_str,const char * modname)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 *
init_filters(PyInterpreterState * interp)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
_PyWarnings_InitState(PyInterpreterState * interp)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
check_matched(PyInterpreterState * interp,PyObject * obj,PyObject * arg)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 *
get_warnings_attr(PyInterpreterState * interp,PyObject * attr,int try_import)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_IsFinalizing()) {
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 (!interp->modules) {
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 *
get_once_registry(PyInterpreterState * interp)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 *
get_default_action(PyInterpreterState * interp)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*
get_filter(PyInterpreterState * interp,PyObject * category,PyObject * text,Py_ssize_t lineno,PyObject * module,PyObject ** item)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 Py_INCREF(Py_None);
386 *item = Py_None;
387 return action;
388 }
389
390 return NULL;
391 }
392
393
394 static int
already_warned(PyInterpreterState * interp,PyObject * registry,PyObject * key,int should_set)395 already_warned(PyInterpreterState *interp, PyObject *registry, PyObject *key,
396 int should_set)
397 {
398 PyObject *version_obj, *already_warned;
399
400 if (key == NULL)
401 return -1;
402
403 WarningsState *st = warnings_get_state(interp);
404 if (st == NULL) {
405 return -1;
406 }
407 version_obj = _PyDict_GetItemWithError(registry, &_Py_ID(version));
408 if (version_obj == NULL
409 || !PyLong_CheckExact(version_obj)
410 || PyLong_AsLong(version_obj) != st->filters_version)
411 {
412 if (PyErr_Occurred()) {
413 return -1;
414 }
415 PyDict_Clear(registry);
416 version_obj = PyLong_FromLong(st->filters_version);
417 if (version_obj == NULL)
418 return -1;
419 if (PyDict_SetItem(registry, &_Py_ID(version), version_obj) < 0) {
420 Py_DECREF(version_obj);
421 return -1;
422 }
423 Py_DECREF(version_obj);
424 }
425 else {
426 already_warned = PyDict_GetItemWithError(registry, key);
427 if (already_warned != NULL) {
428 int rc = PyObject_IsTrue(already_warned);
429 if (rc != 0)
430 return rc;
431 }
432 else if (PyErr_Occurred()) {
433 return -1;
434 }
435 }
436
437 /* This warning wasn't found in the registry, set it. */
438 if (should_set)
439 return PyDict_SetItem(registry, key, Py_True);
440 return 0;
441 }
442
443 /* New reference. */
444 static PyObject *
normalize_module(PyObject * filename)445 normalize_module(PyObject *filename)
446 {
447 PyObject *module;
448 int kind;
449 const void *data;
450 Py_ssize_t len;
451
452 len = PyUnicode_GetLength(filename);
453 if (len < 0)
454 return NULL;
455
456 if (len == 0)
457 return PyUnicode_FromString("<unknown>");
458
459 kind = PyUnicode_KIND(filename);
460 data = PyUnicode_DATA(filename);
461
462 /* if filename.endswith(".py"): */
463 if (len >= 3 &&
464 PyUnicode_READ(kind, data, len-3) == '.' &&
465 PyUnicode_READ(kind, data, len-2) == 'p' &&
466 PyUnicode_READ(kind, data, len-1) == 'y')
467 {
468 module = PyUnicode_Substring(filename, 0, len-3);
469 }
470 else {
471 module = filename;
472 Py_INCREF(module);
473 }
474 return module;
475 }
476
477 static int
update_registry(PyInterpreterState * interp,PyObject * registry,PyObject * text,PyObject * category,int add_zero)478 update_registry(PyInterpreterState *interp, PyObject *registry, PyObject *text,
479 PyObject *category, int add_zero)
480 {
481 PyObject *altkey;
482 int rc;
483
484 if (add_zero)
485 altkey = PyTuple_Pack(3, text, category, _PyLong_GetZero());
486 else
487 altkey = PyTuple_Pack(2, text, category);
488
489 rc = already_warned(interp, registry, altkey, 1);
490 Py_XDECREF(altkey);
491 return rc;
492 }
493
494 static void
show_warning(PyThreadState * tstate,PyObject * filename,int lineno,PyObject * text,PyObject * category,PyObject * sourceline)495 show_warning(PyThreadState *tstate, PyObject *filename, int lineno,
496 PyObject *text, PyObject *category, PyObject *sourceline)
497 {
498 PyObject *f_stderr;
499 PyObject *name;
500 char lineno_str[128];
501
502 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
503
504 name = PyObject_GetAttr(category, &_Py_ID(__name__));
505 if (name == NULL) {
506 goto error;
507 }
508
509 f_stderr = _PySys_GetAttr(tstate, &_Py_ID(stderr));
510 if (f_stderr == NULL) {
511 fprintf(stderr, "lost sys.stderr\n");
512 goto error;
513 }
514
515 /* Print "filename:lineno: category: text\n" */
516 if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
517 goto error;
518 if (PyFile_WriteString(lineno_str, f_stderr) < 0)
519 goto error;
520 if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
521 goto error;
522 if (PyFile_WriteString(": ", f_stderr) < 0)
523 goto error;
524 if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
525 goto error;
526 if (PyFile_WriteString("\n", f_stderr) < 0)
527 goto error;
528 Py_CLEAR(name);
529
530 /* Print " source_line\n" */
531 if (sourceline) {
532 int kind;
533 const void *data;
534 Py_ssize_t i, len;
535 Py_UCS4 ch;
536 PyObject *truncated;
537
538 if (PyUnicode_READY(sourceline) < 1)
539 goto error;
540
541 kind = PyUnicode_KIND(sourceline);
542 data = PyUnicode_DATA(sourceline);
543 len = PyUnicode_GET_LENGTH(sourceline);
544 for (i=0; i<len; i++) {
545 ch = PyUnicode_READ(kind, data, i);
546 if (ch != ' ' && ch != '\t' && ch != '\014')
547 break;
548 }
549
550 truncated = PyUnicode_Substring(sourceline, i, len);
551 if (truncated == NULL)
552 goto error;
553
554 PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
555 Py_DECREF(truncated);
556 PyFile_WriteString("\n", f_stderr);
557 }
558 else {
559 _Py_DisplaySourceLine(f_stderr, filename, lineno, 2, NULL, NULL);
560 }
561
562 error:
563 Py_XDECREF(name);
564 PyErr_Clear();
565 }
566
567 static int
call_show_warning(PyThreadState * tstate,PyObject * category,PyObject * text,PyObject * message,PyObject * filename,int lineno,PyObject * lineno_obj,PyObject * sourceline,PyObject * source)568 call_show_warning(PyThreadState *tstate, PyObject *category,
569 PyObject *text, PyObject *message,
570 PyObject *filename, int lineno, PyObject *lineno_obj,
571 PyObject *sourceline, PyObject *source)
572 {
573 PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
574 PyInterpreterState *interp = tstate->interp;
575
576 /* If the source parameter is set, try to get the Python implementation.
577 The Python implementation is able to log the traceback where the source
578 was allocated, whereas the C implementation doesn't. */
579 show_fn = GET_WARNINGS_ATTR(interp, _showwarnmsg, source != NULL);
580 if (show_fn == NULL) {
581 if (PyErr_Occurred())
582 return -1;
583 show_warning(tstate, filename, lineno, text, category, sourceline);
584 return 0;
585 }
586
587 if (!PyCallable_Check(show_fn)) {
588 PyErr_SetString(PyExc_TypeError,
589 "warnings._showwarnmsg() must be set to a callable");
590 goto error;
591 }
592
593 warnmsg_cls = GET_WARNINGS_ATTR(interp, WarningMessage, 0);
594 if (warnmsg_cls == NULL) {
595 if (!PyErr_Occurred()) {
596 PyErr_SetString(PyExc_RuntimeError,
597 "unable to get warnings.WarningMessage");
598 }
599 goto error;
600 }
601
602 msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
603 filename, lineno_obj, Py_None, Py_None, source,
604 NULL);
605 Py_DECREF(warnmsg_cls);
606 if (msg == NULL)
607 goto error;
608
609 res = PyObject_CallOneArg(show_fn, msg);
610 Py_DECREF(show_fn);
611 Py_DECREF(msg);
612
613 if (res == NULL)
614 return -1;
615
616 Py_DECREF(res);
617 return 0;
618
619 error:
620 Py_XDECREF(show_fn);
621 return -1;
622 }
623
624 static PyObject *
warn_explicit(PyThreadState * tstate,PyObject * category,PyObject * message,PyObject * filename,int lineno,PyObject * module,PyObject * registry,PyObject * sourceline,PyObject * source)625 warn_explicit(PyThreadState *tstate, PyObject *category, PyObject *message,
626 PyObject *filename, int lineno,
627 PyObject *module, PyObject *registry, PyObject *sourceline,
628 PyObject *source)
629 {
630 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
631 PyObject *item = NULL;
632 PyObject *action;
633 int rc;
634 PyInterpreterState *interp = tstate->interp;
635
636 /* module can be None if a warning is emitted late during Python shutdown.
637 In this case, the Python warnings module was probably unloaded, filters
638 are no more available to choose as action. It is safer to ignore the
639 warning and do nothing. */
640 if (module == Py_None)
641 Py_RETURN_NONE;
642
643 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
644 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
645 return NULL;
646 }
647
648 /* Normalize module. */
649 if (module == NULL) {
650 module = normalize_module(filename);
651 if (module == NULL)
652 return NULL;
653 }
654 else
655 Py_INCREF(module);
656
657 /* Normalize message. */
658 Py_INCREF(message); /* DECREF'ed in cleanup. */
659 rc = PyObject_IsInstance(message, PyExc_Warning);
660 if (rc == -1) {
661 goto cleanup;
662 }
663 if (rc == 1) {
664 text = PyObject_Str(message);
665 if (text == NULL)
666 goto cleanup;
667 category = (PyObject*)Py_TYPE(message);
668 }
669 else {
670 text = message;
671 message = PyObject_CallOneArg(category, message);
672 if (message == NULL)
673 goto cleanup;
674 }
675
676 lineno_obj = PyLong_FromLong(lineno);
677 if (lineno_obj == NULL)
678 goto cleanup;
679
680 if (source == Py_None) {
681 source = NULL;
682 }
683
684 /* Create key. */
685 key = PyTuple_Pack(3, text, category, lineno_obj);
686 if (key == NULL)
687 goto cleanup;
688
689 if ((registry != NULL) && (registry != Py_None)) {
690 rc = already_warned(interp, registry, key, 0);
691 if (rc == -1)
692 goto cleanup;
693 else if (rc == 1)
694 goto return_none;
695 /* Else this warning hasn't been generated before. */
696 }
697
698 action = get_filter(interp, category, text, lineno, module, &item);
699 if (action == NULL)
700 goto cleanup;
701
702 if (_PyUnicode_EqualToASCIIString(action, "error")) {
703 PyErr_SetObject(category, message);
704 goto cleanup;
705 }
706
707 if (_PyUnicode_EqualToASCIIString(action, "ignore")) {
708 goto return_none;
709 }
710
711 /* Store in the registry that we've been here, *except* when the action
712 is "always". */
713 rc = 0;
714 if (!_PyUnicode_EqualToASCIIString(action, "always")) {
715 if (registry != NULL && registry != Py_None &&
716 PyDict_SetItem(registry, key, Py_True) < 0)
717 {
718 goto cleanup;
719 }
720
721 if (_PyUnicode_EqualToASCIIString(action, "once")) {
722 if (registry == NULL || registry == Py_None) {
723 registry = get_once_registry(interp);
724 if (registry == NULL)
725 goto cleanup;
726 }
727 /* WarningsState.once_registry[(text, category)] = 1 */
728 rc = update_registry(interp, registry, text, category, 0);
729 }
730 else if (_PyUnicode_EqualToASCIIString(action, "module")) {
731 /* registry[(text, category, 0)] = 1 */
732 if (registry != NULL && registry != Py_None)
733 rc = update_registry(interp, registry, text, category, 0);
734 }
735 else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
736 PyErr_Format(PyExc_RuntimeError,
737 "Unrecognized action (%R) in warnings.filters:\n %R",
738 action, item);
739 goto cleanup;
740 }
741 }
742
743 if (rc == 1) /* Already warned for this module. */
744 goto return_none;
745 if (rc == 0) {
746 if (call_show_warning(tstate, category, text, message, filename,
747 lineno, lineno_obj, sourceline, source) < 0)
748 goto cleanup;
749 }
750 else /* if (rc == -1) */
751 goto cleanup;
752
753 return_none:
754 result = Py_None;
755 Py_INCREF(result);
756
757 cleanup:
758 Py_XDECREF(item);
759 Py_XDECREF(key);
760 Py_XDECREF(text);
761 Py_XDECREF(lineno_obj);
762 Py_DECREF(module);
763 Py_XDECREF(message);
764 return result; /* Py_None or NULL. */
765 }
766
767 static int
is_internal_frame(PyFrameObject * frame)768 is_internal_frame(PyFrameObject *frame)
769 {
770 if (frame == NULL) {
771 return 0;
772 }
773
774 PyCodeObject *code = PyFrame_GetCode(frame);
775 PyObject *filename = code->co_filename;
776 Py_DECREF(code);
777
778 if (filename == NULL) {
779 return 0;
780 }
781 if (!PyUnicode_Check(filename)) {
782 return 0;
783 }
784
785 int contains = PyUnicode_Contains(filename, &_Py_ID(importlib));
786 if (contains < 0) {
787 return 0;
788 }
789 else if (contains > 0) {
790 contains = PyUnicode_Contains(filename, &_Py_ID(_bootstrap));
791 if (contains < 0) {
792 return 0;
793 }
794 else if (contains > 0) {
795 return 1;
796 }
797 }
798
799 return 0;
800 }
801
802 static PyFrameObject *
next_external_frame(PyFrameObject * frame)803 next_external_frame(PyFrameObject *frame)
804 {
805 do {
806 PyFrameObject *back = PyFrame_GetBack(frame);
807 Py_DECREF(frame);
808 frame = back;
809 } while (frame != NULL && is_internal_frame(frame));
810
811 return frame;
812 }
813
814 /* filename, module, and registry are new refs, globals is borrowed */
815 /* Returns 0 on error (no new refs), 1 on success */
816 static int
setup_context(Py_ssize_t stack_level,PyObject ** filename,int * lineno,PyObject ** module,PyObject ** registry)817 setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
818 PyObject **module, PyObject **registry)
819 {
820 PyObject *globals;
821
822 /* Setup globals, filename and lineno. */
823 PyThreadState *tstate = get_current_tstate();
824 if (tstate == NULL) {
825 return 0;
826 }
827 PyInterpreterState *interp = tstate->interp;
828 PyFrameObject *f = PyThreadState_GetFrame(tstate);
829 // Stack level comparisons to Python code is off by one as there is no
830 // warnings-related stack level to avoid.
831 if (stack_level <= 0 || is_internal_frame(f)) {
832 while (--stack_level > 0 && f != NULL) {
833 PyFrameObject *back = PyFrame_GetBack(f);
834 Py_DECREF(f);
835 f = back;
836 }
837 }
838 else {
839 while (--stack_level > 0 && f != NULL) {
840 f = next_external_frame(f);
841 }
842 }
843
844 if (f == NULL) {
845 globals = interp->sysdict;
846 *filename = PyUnicode_FromString("sys");
847 *lineno = 1;
848 }
849 else {
850 globals = f->f_frame->f_globals;
851 *filename = f->f_frame->f_code->co_filename;
852 Py_INCREF(*filename);
853 *lineno = PyFrame_GetLineNumber(f);
854 Py_DECREF(f);
855 }
856
857 *module = NULL;
858
859 /* Setup registry. */
860 assert(globals != NULL);
861 assert(PyDict_Check(globals));
862 *registry = _PyDict_GetItemWithError(globals, &_Py_ID(__warningregistry__));
863 if (*registry == NULL) {
864 int rc;
865
866 if (_PyErr_Occurred(tstate)) {
867 goto handle_error;
868 }
869 *registry = PyDict_New();
870 if (*registry == NULL)
871 goto handle_error;
872
873 rc = PyDict_SetItem(globals, &_Py_ID(__warningregistry__), *registry);
874 if (rc < 0)
875 goto handle_error;
876 }
877 else
878 Py_INCREF(*registry);
879
880 /* Setup module. */
881 *module = _PyDict_GetItemWithError(globals, &_Py_ID(__name__));
882 if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) {
883 Py_INCREF(*module);
884 }
885 else if (_PyErr_Occurred(tstate)) {
886 goto handle_error;
887 }
888 else {
889 *module = PyUnicode_FromString("<string>");
890 if (*module == NULL)
891 goto handle_error;
892 }
893
894 return 1;
895
896 handle_error:
897 Py_XDECREF(*registry);
898 Py_XDECREF(*module);
899 Py_DECREF(*filename);
900 return 0;
901 }
902
903 static PyObject *
get_category(PyObject * message,PyObject * category)904 get_category(PyObject *message, PyObject *category)
905 {
906 int rc;
907
908 /* Get category. */
909 rc = PyObject_IsInstance(message, PyExc_Warning);
910 if (rc == -1)
911 return NULL;
912
913 if (rc == 1)
914 category = (PyObject*)Py_TYPE(message);
915 else if (category == NULL || category == Py_None)
916 category = PyExc_UserWarning;
917
918 /* Validate category. */
919 rc = PyObject_IsSubclass(category, PyExc_Warning);
920 /* category is not a subclass of PyExc_Warning or
921 PyObject_IsSubclass raised an error */
922 if (rc == -1 || rc == 0) {
923 PyErr_Format(PyExc_TypeError,
924 "category must be a Warning subclass, not '%s'",
925 Py_TYPE(category)->tp_name);
926 return NULL;
927 }
928
929 return category;
930 }
931
932 static PyObject *
do_warn(PyObject * message,PyObject * category,Py_ssize_t stack_level,PyObject * source)933 do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
934 PyObject *source)
935 {
936 PyObject *filename, *module, *registry, *res;
937 int lineno;
938
939 PyThreadState *tstate = get_current_tstate();
940 if (tstate == NULL) {
941 return NULL;
942 }
943
944 if (!setup_context(stack_level, &filename, &lineno, &module, ®istry))
945 return NULL;
946
947 res = warn_explicit(tstate, category, message, filename, lineno, module, registry,
948 NULL, source);
949 Py_DECREF(filename);
950 Py_DECREF(registry);
951 Py_DECREF(module);
952 return res;
953 }
954
955 /*[clinic input]
956 warn as warnings_warn
957
958 message: object
959 category: object = None
960 stacklevel: Py_ssize_t = 1
961 source: object = None
962
963 Issue a warning, or maybe ignore it or raise an exception.
964 [clinic start generated code]*/
965
966 static PyObject *
warnings_warn_impl(PyObject * module,PyObject * message,PyObject * category,Py_ssize_t stacklevel,PyObject * source)967 warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
968 Py_ssize_t stacklevel, PyObject *source)
969 /*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
970 {
971 category = get_category(message, category);
972 if (category == NULL)
973 return NULL;
974 return do_warn(message, category, stacklevel, source);
975 }
976
977 static PyObject *
get_source_line(PyInterpreterState * interp,PyObject * module_globals,int lineno)978 get_source_line(PyInterpreterState *interp, PyObject *module_globals, int lineno)
979 {
980 PyObject *loader;
981 PyObject *module_name;
982 PyObject *get_source;
983 PyObject *source;
984 PyObject *source_list;
985 PyObject *source_line;
986
987 /* Check/get the requisite pieces needed for the loader. */
988 loader = _PyDict_GetItemWithError(module_globals, &_Py_ID(__loader__));
989 if (loader == NULL) {
990 return NULL;
991 }
992 Py_INCREF(loader);
993 module_name = _PyDict_GetItemWithError(module_globals, &_Py_ID(__name__));
994 if (!module_name) {
995 Py_DECREF(loader);
996 return NULL;
997 }
998 Py_INCREF(module_name);
999
1000 /* Make sure the loader implements the optional get_source() method. */
1001 (void)_PyObject_LookupAttr(loader, &_Py_ID(get_source), &get_source);
1002 Py_DECREF(loader);
1003 if (!get_source) {
1004 Py_DECREF(module_name);
1005 return NULL;
1006 }
1007 /* Call get_source() to get the source code. */
1008 source = PyObject_CallOneArg(get_source, module_name);
1009 Py_DECREF(get_source);
1010 Py_DECREF(module_name);
1011 if (!source) {
1012 return NULL;
1013 }
1014 if (source == Py_None) {
1015 Py_DECREF(source);
1016 return NULL;
1017 }
1018
1019 /* Split the source into lines. */
1020 source_list = PyUnicode_Splitlines(source, 0);
1021 Py_DECREF(source);
1022 if (!source_list) {
1023 return NULL;
1024 }
1025
1026 /* Get the source line. */
1027 source_line = PyList_GetItem(source_list, lineno-1);
1028 Py_XINCREF(source_line);
1029 Py_DECREF(source_list);
1030 return source_line;
1031 }
1032
1033 static PyObject *
warnings_warn_explicit(PyObject * self,PyObject * args,PyObject * kwds)1034 warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
1035 {
1036 static char *kwd_list[] = {"message", "category", "filename", "lineno",
1037 "module", "registry", "module_globals",
1038 "source", 0};
1039 PyObject *message;
1040 PyObject *category;
1041 PyObject *filename;
1042 int lineno;
1043 PyObject *module = NULL;
1044 PyObject *registry = NULL;
1045 PyObject *module_globals = NULL;
1046 PyObject *sourceobj = NULL;
1047 PyObject *source_line = NULL;
1048 PyObject *returned;
1049
1050 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
1051 kwd_list, &message, &category, &filename, &lineno, &module,
1052 ®istry, &module_globals, &sourceobj))
1053 return NULL;
1054
1055 PyThreadState *tstate = get_current_tstate();
1056 if (tstate == NULL) {
1057 return NULL;
1058 }
1059
1060 if (module_globals && module_globals != Py_None) {
1061 if (!PyDict_Check(module_globals)) {
1062 PyErr_Format(PyExc_TypeError,
1063 "module_globals must be a dict, not '%.200s'",
1064 Py_TYPE(module_globals)->tp_name);
1065 return NULL;
1066 }
1067
1068 source_line = get_source_line(tstate->interp, module_globals, lineno);
1069 if (source_line == NULL && PyErr_Occurred()) {
1070 return NULL;
1071 }
1072 }
1073 returned = warn_explicit(tstate, category, message, filename, lineno, module,
1074 registry, source_line, sourceobj);
1075 Py_XDECREF(source_line);
1076 return returned;
1077 }
1078
1079 static PyObject *
warnings_filters_mutated(PyObject * self,PyObject * Py_UNUSED (args))1080 warnings_filters_mutated(PyObject *self, PyObject *Py_UNUSED(args))
1081 {
1082 PyInterpreterState *interp = get_current_interp();
1083 if (interp == NULL) {
1084 return NULL;
1085 }
1086 WarningsState *st = warnings_get_state(interp);
1087 if (st == NULL) {
1088 return NULL;
1089 }
1090 st->filters_version++;
1091 Py_RETURN_NONE;
1092 }
1093
1094
1095 /* Function to issue a warning message; may raise an exception. */
1096
1097 static int
warn_unicode(PyObject * category,PyObject * message,Py_ssize_t stack_level,PyObject * source)1098 warn_unicode(PyObject *category, PyObject *message,
1099 Py_ssize_t stack_level, PyObject *source)
1100 {
1101 PyObject *res;
1102
1103 if (category == NULL)
1104 category = PyExc_RuntimeWarning;
1105
1106 res = do_warn(message, category, stack_level, source);
1107 if (res == NULL)
1108 return -1;
1109 Py_DECREF(res);
1110
1111 return 0;
1112 }
1113
1114 static int
_PyErr_WarnFormatV(PyObject * source,PyObject * category,Py_ssize_t stack_level,const char * format,va_list vargs)1115 _PyErr_WarnFormatV(PyObject *source,
1116 PyObject *category, Py_ssize_t stack_level,
1117 const char *format, va_list vargs)
1118 {
1119 PyObject *message;
1120 int res;
1121
1122 message = PyUnicode_FromFormatV(format, vargs);
1123 if (message == NULL)
1124 return -1;
1125
1126 res = warn_unicode(category, message, stack_level, source);
1127 Py_DECREF(message);
1128 return res;
1129 }
1130
1131 int
PyErr_WarnFormat(PyObject * category,Py_ssize_t stack_level,const char * format,...)1132 PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
1133 const char *format, ...)
1134 {
1135 int res;
1136 va_list vargs;
1137
1138 #ifdef HAVE_STDARG_PROTOTYPES
1139 va_start(vargs, format);
1140 #else
1141 va_start(vargs);
1142 #endif
1143 res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
1144 va_end(vargs);
1145 return res;
1146 }
1147
1148 static int
_PyErr_WarnFormat(PyObject * source,PyObject * category,Py_ssize_t stack_level,const char * format,...)1149 _PyErr_WarnFormat(PyObject *source, PyObject *category, Py_ssize_t stack_level,
1150 const char *format, ...)
1151 {
1152 int res;
1153 va_list vargs;
1154
1155 #ifdef HAVE_STDARG_PROTOTYPES
1156 va_start(vargs, format);
1157 #else
1158 va_start(vargs);
1159 #endif
1160 res = _PyErr_WarnFormatV(source, category, stack_level, format, vargs);
1161 va_end(vargs);
1162 return res;
1163 }
1164
1165 int
PyErr_ResourceWarning(PyObject * source,Py_ssize_t stack_level,const char * format,...)1166 PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
1167 const char *format, ...)
1168 {
1169 int res;
1170 va_list vargs;
1171
1172 #ifdef HAVE_STDARG_PROTOTYPES
1173 va_start(vargs, format);
1174 #else
1175 va_start(vargs);
1176 #endif
1177 res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
1178 stack_level, format, vargs);
1179 va_end(vargs);
1180 return res;
1181 }
1182
1183
1184 int
PyErr_WarnEx(PyObject * category,const char * text,Py_ssize_t stack_level)1185 PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
1186 {
1187 int ret;
1188 PyObject *message = PyUnicode_FromString(text);
1189 if (message == NULL)
1190 return -1;
1191 ret = warn_unicode(category, message, stack_level, NULL);
1192 Py_DECREF(message);
1193 return ret;
1194 }
1195
1196 /* PyErr_Warn is only for backwards compatibility and will be removed.
1197 Use PyErr_WarnEx instead. */
1198
1199 #undef PyErr_Warn
1200
1201 int
PyErr_Warn(PyObject * category,const char * text)1202 PyErr_Warn(PyObject *category, const char *text)
1203 {
1204 return PyErr_WarnEx(category, text, 1);
1205 }
1206
1207 /* Warning with explicit origin */
1208 int
PyErr_WarnExplicitObject(PyObject * category,PyObject * message,PyObject * filename,int lineno,PyObject * module,PyObject * registry)1209 PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1210 PyObject *filename, int lineno,
1211 PyObject *module, PyObject *registry)
1212 {
1213 PyObject *res;
1214 if (category == NULL)
1215 category = PyExc_RuntimeWarning;
1216 PyThreadState *tstate = get_current_tstate();
1217 if (tstate == NULL) {
1218 return -1;
1219 }
1220 res = warn_explicit(tstate, category, message, filename, lineno,
1221 module, registry, NULL, NULL);
1222 if (res == NULL)
1223 return -1;
1224 Py_DECREF(res);
1225 return 0;
1226 }
1227
1228 int
PyErr_WarnExplicit(PyObject * category,const char * text,const char * filename_str,int lineno,const char * module_str,PyObject * registry)1229 PyErr_WarnExplicit(PyObject *category, const char *text,
1230 const char *filename_str, int lineno,
1231 const char *module_str, PyObject *registry)
1232 {
1233 PyObject *message = PyUnicode_FromString(text);
1234 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1235 PyObject *module = NULL;
1236 int ret = -1;
1237
1238 if (message == NULL || filename == NULL)
1239 goto exit;
1240 if (module_str != NULL) {
1241 module = PyUnicode_FromString(module_str);
1242 if (module == NULL)
1243 goto exit;
1244 }
1245
1246 ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1247 module, registry);
1248
1249 exit:
1250 Py_XDECREF(message);
1251 Py_XDECREF(module);
1252 Py_XDECREF(filename);
1253 return ret;
1254 }
1255
1256 int
PyErr_WarnExplicitFormat(PyObject * category,const char * filename_str,int lineno,const char * module_str,PyObject * registry,const char * format,...)1257 PyErr_WarnExplicitFormat(PyObject *category,
1258 const char *filename_str, int lineno,
1259 const char *module_str, PyObject *registry,
1260 const char *format, ...)
1261 {
1262 PyObject *message;
1263 PyObject *module = NULL;
1264 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1265 int ret = -1;
1266 va_list vargs;
1267
1268 if (filename == NULL)
1269 goto exit;
1270 if (module_str != NULL) {
1271 module = PyUnicode_FromString(module_str);
1272 if (module == NULL)
1273 goto exit;
1274 }
1275
1276 #ifdef HAVE_STDARG_PROTOTYPES
1277 va_start(vargs, format);
1278 #else
1279 va_start(vargs);
1280 #endif
1281 message = PyUnicode_FromFormatV(format, vargs);
1282 if (message != NULL) {
1283 PyObject *res;
1284 PyThreadState *tstate = get_current_tstate();
1285 if (tstate != NULL) {
1286 res = warn_explicit(tstate, category, message, filename, lineno,
1287 module, registry, NULL, NULL);
1288 Py_DECREF(message);
1289 if (res != NULL) {
1290 Py_DECREF(res);
1291 ret = 0;
1292 }
1293 }
1294 }
1295 va_end(vargs);
1296 exit:
1297 Py_XDECREF(module);
1298 Py_XDECREF(filename);
1299 return ret;
1300 }
1301
1302 void
_PyErr_WarnUnawaitedCoroutine(PyObject * coro)1303 _PyErr_WarnUnawaitedCoroutine(PyObject *coro)
1304 {
1305 /* First, we attempt to funnel the warning through
1306 warnings._warn_unawaited_coroutine.
1307
1308 This could raise an exception, due to:
1309 - a bug
1310 - some kind of shutdown-related brokenness
1311 - succeeding, but with an "error" warning filter installed, so the
1312 warning is converted into a RuntimeWarning exception
1313
1314 In the first two cases, we want to print the error (so we know what it
1315 is!), and then print a warning directly as a fallback. In the last
1316 case, we want to print the error (since it's the warning!), but *not*
1317 do a fallback. And after we print the error we can't check for what
1318 type of error it was (because PyErr_WriteUnraisable clears it), so we
1319 need a flag to keep track.
1320
1321 Since this is called from __del__ context, it's careful to never raise
1322 an exception.
1323 */
1324 int warned = 0;
1325 PyInterpreterState *interp = _PyInterpreterState_GET();
1326 assert(interp != NULL);
1327 PyObject *fn = GET_WARNINGS_ATTR(interp, _warn_unawaited_coroutine, 1);
1328 if (fn) {
1329 PyObject *res = PyObject_CallOneArg(fn, coro);
1330 Py_DECREF(fn);
1331 if (res || PyErr_ExceptionMatches(PyExc_RuntimeWarning)) {
1332 warned = 1;
1333 }
1334 Py_XDECREF(res);
1335 }
1336
1337 if (PyErr_Occurred()) {
1338 PyErr_WriteUnraisable(coro);
1339 }
1340 if (!warned) {
1341 if (_PyErr_WarnFormat(coro, PyExc_RuntimeWarning, 1,
1342 "coroutine '%S' was never awaited",
1343 ((PyCoroObject *)coro)->cr_qualname) < 0)
1344 {
1345 PyErr_WriteUnraisable(coro);
1346 }
1347 }
1348 }
1349
1350 PyDoc_STRVAR(warn_explicit_doc,
1351 "Low-level interface to warnings functionality.");
1352
1353 static PyMethodDef warnings_functions[] = {
1354 WARNINGS_WARN_METHODDEF
1355 {"warn_explicit", _PyCFunction_CAST(warnings_warn_explicit),
1356 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
1357 {"_filters_mutated", _PyCFunction_CAST(warnings_filters_mutated), METH_NOARGS,
1358 NULL},
1359 /* XXX(brett.cannon): add showwarning? */
1360 /* XXX(brett.cannon): Reasonable to add formatwarning? */
1361 {NULL, NULL} /* sentinel */
1362 };
1363
1364
1365 static int
warnings_module_exec(PyObject * module)1366 warnings_module_exec(PyObject *module)
1367 {
1368 PyInterpreterState *interp = get_current_interp();
1369 if (interp == NULL) {
1370 return -1;
1371 }
1372 WarningsState *st = warnings_get_state(interp);
1373 if (st == NULL) {
1374 return -1;
1375 }
1376 if (PyModule_AddObjectRef(module, "filters", st->filters) < 0) {
1377 return -1;
1378 }
1379 if (PyModule_AddObjectRef(module, "_onceregistry", st->once_registry) < 0) {
1380 return -1;
1381 }
1382 if (PyModule_AddObjectRef(module, "_defaultaction", st->default_action) < 0) {
1383 return -1;
1384 }
1385 return 0;
1386 }
1387
1388
1389 static PyModuleDef_Slot warnings_slots[] = {
1390 {Py_mod_exec, warnings_module_exec},
1391 {0, NULL}
1392 };
1393
1394 static struct PyModuleDef warnings_module = {
1395 PyModuleDef_HEAD_INIT,
1396 .m_name = MODULE_NAME,
1397 .m_doc = warnings__doc__,
1398 .m_size = 0,
1399 .m_methods = warnings_functions,
1400 .m_slots = warnings_slots,
1401 };
1402
1403
1404 PyMODINIT_FUNC
_PyWarnings_Init(void)1405 _PyWarnings_Init(void)
1406 {
1407 return PyModuleDef_Init(&warnings_module);
1408 }
1409
1410 // We need this to ensure that warnings still work until late in finalization.
1411 void
_PyWarnings_Fini(PyInterpreterState * interp)1412 _PyWarnings_Fini(PyInterpreterState *interp)
1413 {
1414 warnings_clear_state(&interp->warnings);
1415 }
1416