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