Branch data Line data Source code
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 : 36528 : check_interp(PyInterpreterState *interp)
23 : : {
24 [ - + ]: 36528 : if (interp == NULL) {
25 : 0 : PyErr_SetString(PyExc_RuntimeError,
26 : : "warnings_get_state: could not identify "
27 : : "current interpreter");
28 : 0 : return 0;
29 : : }
30 : 36528 : return 1;
31 : : }
32 : :
33 : : static inline PyInterpreterState *
34 : 27787 : get_current_interp(void)
35 : : {
36 : 27787 : PyInterpreterState *interp = _PyInterpreterState_GET();
37 [ + - ]: 27787 : return check_interp(interp) ? interp : NULL;
38 : : }
39 : :
40 : : static inline PyThreadState *
41 : 8741 : get_current_tstate(void)
42 : : {
43 : 8741 : PyThreadState *tstate = _PyThreadState_GET();
44 [ - + ]: 8741 : if (tstate == NULL) {
45 : 0 : (void)check_interp(NULL);
46 : 0 : return NULL;
47 : : }
48 [ + - ]: 8741 : return check_interp(tstate->interp) ? tstate : NULL;
49 : : }
50 : :
51 : : /* Given a module object, get its per-module state. */
52 : : static WarningsState *
53 : 36545 : warnings_get_state(PyInterpreterState *interp)
54 : : {
55 : 36545 : return &interp->warnings;
56 : : }
57 : :
58 : : /* Clear the given warnings module state. */
59 : : static void
60 : 3125 : warnings_clear_state(WarningsState *st)
61 : : {
62 [ + - ]: 3125 : Py_CLEAR(st->filters);
63 [ + - ]: 3125 : Py_CLEAR(st->once_registry);
64 [ + - ]: 3125 : Py_CLEAR(st->default_action);
65 : 3125 : }
66 : :
67 : : #ifndef Py_DEBUG
68 : : static PyObject *
69 : 15690 : create_filter(PyObject *category, PyObject *action_str, const char *modname)
70 : : {
71 : 15690 : PyObject *modname_obj = NULL;
72 : :
73 : : /* Default to "no module name" for initial filter set */
74 [ + + ]: 15690 : if (modname != NULL) {
75 : 3138 : modname_obj = PyUnicode_InternFromString(modname);
76 [ - + ]: 3138 : if (modname_obj == NULL) {
77 : 0 : return NULL;
78 : : }
79 : : } else {
80 : 12552 : modname_obj = Py_NewRef(Py_None);
81 : : }
82 : :
83 : : /* This assumes the line number is zero for now. */
84 : 15690 : PyObject *filter = PyTuple_Pack(5, action_str, Py_None,
85 : : category, modname_obj, _PyLong_GetZero());
86 : 15690 : Py_DECREF(modname_obj);
87 : 15690 : return filter;
88 : : }
89 : : #endif
90 : :
91 : : static PyObject *
92 : 3138 : 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 : 3138 : PyObject *filters = PyList_New(5);
100 [ - + ]: 3138 : if (filters == NULL) {
101 : 0 : return NULL;
102 : : }
103 : :
104 : 3138 : 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 : 3138 : ADD(PyExc_DeprecationWarning, default, "__main__");
109 : 3138 : ADD(PyExc_DeprecationWarning, ignore, NULL);
110 : 3138 : ADD(PyExc_PendingDeprecationWarning, ignore, NULL);
111 : 3138 : ADD(PyExc_ImportWarning, ignore, NULL);
112 : 3138 : ADD(PyExc_ResourceWarning, ignore, NULL);
113 : : #undef ADD
114 : :
115 [ + + ]: 18828 : for (size_t x = 0; x < pos; x++) {
116 [ - + ]: 15690 : if (PyList_GET_ITEM(filters, x) == NULL) {
117 : 0 : Py_DECREF(filters);
118 : 0 : return NULL;
119 : : }
120 : : }
121 : 3138 : return filters;
122 : : #endif
123 : : }
124 : :
125 : : /* Initialize the given warnings module state. */
126 : : int
127 : 3138 : _PyWarnings_InitState(PyInterpreterState *interp)
128 : : {
129 : 3138 : WarningsState *st = &interp->warnings;
130 : :
131 [ + - ]: 3138 : if (st->filters == NULL) {
132 : 3138 : st->filters = init_filters(interp);
133 [ - + ]: 3138 : if (st->filters == NULL) {
134 : 0 : return -1;
135 : : }
136 : : }
137 : :
138 [ + - ]: 3138 : if (st->once_registry == NULL) {
139 : 3138 : st->once_registry = PyDict_New();
140 [ - + ]: 3138 : if (st->once_registry == NULL) {
141 : 0 : return -1;
142 : : }
143 : : }
144 : :
145 [ + - ]: 3138 : if (st->default_action == NULL) {
146 : 3138 : st->default_action = PyUnicode_FromString("default");
147 [ - + ]: 3138 : if (st->default_action == NULL) {
148 : 0 : return -1;
149 : : }
150 : : }
151 : :
152 : 3138 : st->filters_version = 0;
153 : 3138 : return 0;
154 : : }
155 : :
156 : :
157 : : /*************************************************************************/
158 : :
159 : : static int
160 : 10482 : check_matched(PyInterpreterState *interp, PyObject *obj, PyObject *arg)
161 : : {
162 : : PyObject *result;
163 : : int rc;
164 : :
165 : : /* A 'None' filter always matches */
166 [ + + ]: 10482 : if (obj == Py_None)
167 : 10242 : return 1;
168 : :
169 : : /* An internal plain text default filter must match exactly */
170 [ + + ]: 240 : if (PyUnicode_CheckExact(obj)) {
171 : 55 : int cmp_result = PyUnicode_Compare(obj, arg);
172 [ + + - + ]: 55 : if (cmp_result == -1 && PyErr_Occurred()) {
173 : 0 : return -1;
174 : : }
175 : 55 : return !cmp_result;
176 : : }
177 : :
178 : : /* Otherwise assume a regex filter and call its match() method */
179 : 185 : result = PyObject_CallMethodOneArg(obj, &_Py_ID(match), arg);
180 [ - + ]: 185 : if (result == NULL)
181 : 0 : return -1;
182 : :
183 : 185 : rc = PyObject_IsTrue(result);
184 : 185 : Py_DECREF(result);
185 : 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 : 11695 : 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 [ + + + + ]: 11695 : if (try_import && !_Py_IsFinalizing()) {
202 : 130 : warnings_module = PyImport_Import(&_Py_ID(warnings));
203 [ - + ]: 130 : if (warnings_module == NULL) {
204 : : /* Fallback to the C implementation if we cannot get
205 : : the Python implementation */
206 [ # # ]: 0 : if (PyErr_ExceptionMatches(PyExc_ImportError)) {
207 : 0 : PyErr_Clear();
208 : : }
209 : 0 : 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 [ + + ]: 11565 : if (!interp->modules) {
218 : 2 : return NULL;
219 : : }
220 : 11563 : warnings_module = PyImport_GetModule(&_Py_ID(warnings));
221 [ + + ]: 11563 : if (warnings_module == NULL)
222 : 16 : return NULL;
223 : : }
224 : :
225 : 11677 : (void)_PyObject_LookupAttr(warnings_module, attr, &obj);
226 : 11677 : Py_DECREF(warnings_module);
227 : 11677 : return obj;
228 : : }
229 : :
230 : :
231 : : static PyObject *
232 : 7 : get_once_registry(PyInterpreterState *interp)
233 : : {
234 : : PyObject *registry;
235 : :
236 : 7 : WarningsState *st = warnings_get_state(interp);
237 [ - + ]: 7 : if (st == NULL) {
238 : 0 : return NULL;
239 : : }
240 : :
241 : 7 : registry = GET_WARNINGS_ATTR(interp, onceregistry, 0);
242 [ + + ]: 7 : if (registry == NULL) {
243 [ - + ]: 1 : if (PyErr_Occurred())
244 : 0 : return NULL;
245 : : assert(st->once_registry);
246 : 1 : return st->once_registry;
247 : : }
248 [ + + ]: 6 : if (!PyDict_Check(registry)) {
249 : 1 : PyErr_Format(PyExc_TypeError,
250 : : MODULE_NAME ".onceregistry must be a dict, "
251 : : "not '%.200s'",
252 : 1 : Py_TYPE(registry)->tp_name);
253 : 1 : Py_DECREF(registry);
254 : 1 : return NULL;
255 : : }
256 : 5 : Py_SETREF(st->once_registry, registry);
257 : 5 : return registry;
258 : : }
259 : :
260 : :
261 : : static PyObject *
262 : 39 : get_default_action(PyInterpreterState *interp)
263 : : {
264 : : PyObject *default_action;
265 : :
266 : 39 : WarningsState *st = warnings_get_state(interp);
267 [ - + ]: 39 : if (st == NULL) {
268 : 0 : return NULL;
269 : : }
270 : :
271 : 39 : default_action = GET_WARNINGS_ATTR(interp, defaultaction, 0);
272 [ + + ]: 39 : if (default_action == NULL) {
273 [ - + ]: 2 : if (PyErr_Occurred()) {
274 : 0 : return NULL;
275 : : }
276 : : assert(st->default_action);
277 : 2 : return st->default_action;
278 : : }
279 [ + + ]: 37 : if (!PyUnicode_Check(default_action)) {
280 : 1 : PyErr_Format(PyExc_TypeError,
281 : : MODULE_NAME ".defaultaction must be a string, "
282 : : "not '%.200s'",
283 : 1 : Py_TYPE(default_action)->tp_name);
284 : 1 : Py_DECREF(default_action);
285 : 1 : return NULL;
286 : : }
287 : 36 : Py_SETREF(st->default_action, default_action);
288 : 36 : return default_action;
289 : : }
290 : :
291 : :
292 : : /* The item is a new reference. */
293 : : static PyObject*
294 : 4837 : 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 : 4837 : WarningsState *st = warnings_get_state(interp);
302 [ - + ]: 4837 : if (st == NULL) {
303 : 0 : return NULL;
304 : : }
305 : :
306 : 4837 : warnings_filters = GET_WARNINGS_ATTR(interp, filters, 0);
307 [ + + ]: 4837 : if (warnings_filters == NULL) {
308 [ - + ]: 11 : if (PyErr_Occurred())
309 : 0 : return NULL;
310 : : }
311 : : else {
312 : 4826 : Py_SETREF(st->filters, warnings_filters);
313 : : }
314 : :
315 : 4837 : PyObject *filters = st->filters;
316 [ + - - + ]: 4837 : if (filters == NULL || !PyList_Check(filters)) {
317 : 0 : PyErr_SetString(PyExc_ValueError,
318 : : MODULE_NAME ".filters must be a list");
319 : 0 : return NULL;
320 : : }
321 : :
322 : : /* WarningsState.filters could change while we are iterating over it. */
323 [ + + ]: 5281 : 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 : 5242 : tmp_item = PyList_GET_ITEM(filters, i);
329 [ + - - + ]: 5242 : if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
330 : 0 : PyErr_Format(PyExc_ValueError,
331 : : MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
332 : 0 : return NULL;
333 : : }
334 : :
335 : : /* Python code: action, msg, cat, mod, ln = item */
336 : 5242 : Py_INCREF(tmp_item);
337 : 5242 : action = PyTuple_GET_ITEM(tmp_item, 0);
338 : 5242 : msg = PyTuple_GET_ITEM(tmp_item, 1);
339 : 5242 : cat = PyTuple_GET_ITEM(tmp_item, 2);
340 : 5242 : mod = PyTuple_GET_ITEM(tmp_item, 3);
341 : 5242 : ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
342 : :
343 [ + + ]: 5242 : if (!PyUnicode_Check(action)) {
344 : 1 : PyErr_Format(PyExc_TypeError,
345 : : "action must be a string, not '%.200s'",
346 : 1 : Py_TYPE(action)->tp_name);
347 : 1 : Py_DECREF(tmp_item);
348 : 1 : return NULL;
349 : : }
350 : :
351 : 5241 : good_msg = check_matched(interp, msg, text);
352 [ - + ]: 5241 : if (good_msg == -1) {
353 : 0 : Py_DECREF(tmp_item);
354 : 0 : return NULL;
355 : : }
356 : :
357 : 5241 : good_mod = check_matched(interp, mod, module);
358 [ - + ]: 5241 : if (good_mod == -1) {
359 : 0 : Py_DECREF(tmp_item);
360 : 0 : return NULL;
361 : : }
362 : :
363 : 5241 : is_subclass = PyObject_IsSubclass(category, cat);
364 [ - + ]: 5241 : if (is_subclass == -1) {
365 : 0 : Py_DECREF(tmp_item);
366 : 0 : return NULL;
367 : : }
368 : :
369 : 5241 : ln = PyLong_AsSsize_t(ln_obj);
370 [ - + - - ]: 5241 : if (ln == -1 && PyErr_Occurred()) {
371 : 0 : Py_DECREF(tmp_item);
372 : 0 : return NULL;
373 : : }
374 : :
375 [ + + + + : 5241 : if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
+ + - + -
- ]
376 : 4797 : *item = tmp_item;
377 : 4797 : return action;
378 : : }
379 : :
380 : 444 : Py_DECREF(tmp_item);
381 : : }
382 : :
383 : 39 : action = get_default_action(interp);
384 [ + + ]: 39 : if (action != NULL) {
385 : 38 : Py_INCREF(Py_None);
386 : 38 : *item = Py_None;
387 : 38 : return action;
388 : : }
389 : :
390 : 1 : return NULL;
391 : : }
392 : :
393 : :
394 : : static int
395 : 3875 : already_warned(PyInterpreterState *interp, PyObject *registry, PyObject *key,
396 : : int should_set)
397 : : {
398 : : PyObject *version_obj, *already_warned;
399 : :
400 [ - + ]: 3875 : if (key == NULL)
401 : 0 : return -1;
402 : :
403 : 3875 : WarningsState *st = warnings_get_state(interp);
404 [ - + ]: 3875 : if (st == NULL) {
405 : 0 : return -1;
406 : : }
407 : 3875 : version_obj = _PyDict_GetItemWithError(registry, &_Py_ID(version));
408 [ + + ]: 3875 : if (version_obj == NULL
409 [ + - ]: 2299 : || !PyLong_CheckExact(version_obj)
410 [ + + ]: 2299 : || PyLong_AsLong(version_obj) != st->filters_version)
411 : : {
412 [ - + ]: 2194 : if (PyErr_Occurred()) {
413 : 0 : return -1;
414 : : }
415 : 2194 : PyDict_Clear(registry);
416 : 2194 : version_obj = PyLong_FromLong(st->filters_version);
417 [ - + ]: 2194 : if (version_obj == NULL)
418 : 0 : return -1;
419 [ - + ]: 2194 : if (PyDict_SetItem(registry, &_Py_ID(version), version_obj) < 0) {
420 : 0 : Py_DECREF(version_obj);
421 : 0 : return -1;
422 : : }
423 : 2194 : Py_DECREF(version_obj);
424 : : }
425 : : else {
426 : 1681 : already_warned = PyDict_GetItemWithError(registry, key);
427 [ + + ]: 1681 : if (already_warned != NULL) {
428 : 38 : int rc = PyObject_IsTrue(already_warned);
429 [ + - ]: 38 : if (rc != 0)
430 : 38 : return rc;
431 : : }
432 [ - + ]: 1643 : else if (PyErr_Occurred()) {
433 : 0 : return -1;
434 : : }
435 : : }
436 : :
437 : : /* This warning wasn't found in the registry, set it. */
438 [ + + ]: 3837 : if (should_set)
439 : 19 : return PyDict_SetItem(registry, key, Py_True);
440 : 3818 : return 0;
441 : : }
442 : :
443 : : /* New reference. */
444 : : static PyObject *
445 : 1019 : normalize_module(PyObject *filename)
446 : : {
447 : : PyObject *module;
448 : : int kind;
449 : : const void *data;
450 : : Py_ssize_t len;
451 : :
452 : 1019 : len = PyUnicode_GetLength(filename);
453 [ - + ]: 1019 : if (len < 0)
454 : 0 : return NULL;
455 : :
456 [ - + ]: 1019 : if (len == 0)
457 : 0 : return PyUnicode_FromString("<unknown>");
458 : :
459 : 1019 : kind = PyUnicode_KIND(filename);
460 : 1019 : data = PyUnicode_DATA(filename);
461 : :
462 : : /* if filename.endswith(".py"): */
463 [ + - + + ]: 2038 : if (len >= 3 &&
464 [ + - ]: 1024 : PyUnicode_READ(kind, data, len-3) == '.' &&
465 [ + - ]: 10 : PyUnicode_READ(kind, data, len-2) == 'p' &&
466 : 5 : PyUnicode_READ(kind, data, len-1) == 'y')
467 : : {
468 : 5 : module = PyUnicode_Substring(filename, 0, len-3);
469 : : }
470 : : else {
471 : 1014 : module = filename;
472 : 1014 : Py_INCREF(module);
473 : : }
474 : 1019 : return module;
475 : : }
476 : :
477 : : static int
478 : 24 : update_registry(PyInterpreterState *interp, PyObject *registry, PyObject *text,
479 : : PyObject *category, int add_zero)
480 : : {
481 : : PyObject *altkey;
482 : : int rc;
483 : :
484 [ - + ]: 24 : if (add_zero)
485 : 0 : altkey = PyTuple_Pack(3, text, category, _PyLong_GetZero());
486 : : else
487 : 24 : altkey = PyTuple_Pack(2, text, category);
488 : :
489 : 24 : rc = already_warned(interp, registry, altkey, 1);
490 : 24 : Py_XDECREF(altkey);
491 : 24 : return rc;
492 : : }
493 : :
494 : : static void
495 : 6 : 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 : 6 : PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
503 : :
504 : 6 : name = PyObject_GetAttr(category, &_Py_ID(__name__));
505 [ - + ]: 6 : if (name == NULL) {
506 : 0 : goto error;
507 : : }
508 : :
509 : 6 : f_stderr = _PySys_GetAttr(tstate, &_Py_ID(stderr));
510 [ - + ]: 6 : if (f_stderr == NULL) {
511 : 0 : fprintf(stderr, "lost sys.stderr\n");
512 : 0 : goto error;
513 : : }
514 : :
515 : : /* Print "filename:lineno: category: text\n" */
516 [ - + ]: 6 : if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
517 : 0 : goto error;
518 [ - + ]: 6 : if (PyFile_WriteString(lineno_str, f_stderr) < 0)
519 : 0 : goto error;
520 [ - + ]: 6 : if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
521 : 0 : goto error;
522 [ - + ]: 6 : if (PyFile_WriteString(": ", f_stderr) < 0)
523 : 0 : goto error;
524 [ - + ]: 6 : if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
525 : 0 : goto error;
526 [ - + ]: 6 : if (PyFile_WriteString("\n", f_stderr) < 0)
527 : 0 : goto error;
528 [ + - ]: 6 : Py_CLEAR(name);
529 : :
530 : : /* Print " source_line\n" */
531 [ + + ]: 6 : if (sourceline) {
532 : : int kind;
533 : : const void *data;
534 : : Py_ssize_t i, len;
535 : : Py_UCS4 ch;
536 : : PyObject *truncated;
537 : :
538 [ + - ]: 1 : if (PyUnicode_READY(sourceline) < 1)
539 : 1 : goto error;
540 : :
541 : 0 : kind = PyUnicode_KIND(sourceline);
542 : 0 : data = PyUnicode_DATA(sourceline);
543 : 0 : len = PyUnicode_GET_LENGTH(sourceline);
544 [ # # ]: 0 : for (i=0; i<len; i++) {
545 : 0 : ch = PyUnicode_READ(kind, data, i);
546 [ # # # # : 0 : if (ch != ' ' && ch != '\t' && ch != '\014')
# # ]
547 : 0 : break;
548 : : }
549 : :
550 : 0 : truncated = PyUnicode_Substring(sourceline, i, len);
551 [ # # ]: 0 : if (truncated == NULL)
552 : 0 : goto error;
553 : :
554 : 0 : PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
555 : 0 : Py_DECREF(truncated);
556 : 0 : PyFile_WriteString("\n", f_stderr);
557 : : }
558 : : else {
559 : 5 : _Py_DisplaySourceLine(f_stderr, filename, lineno, 2, NULL, NULL);
560 : : }
561 : :
562 : 6 : error:
563 : 6 : Py_XDECREF(name);
564 : 6 : PyErr_Clear();
565 : 6 : }
566 : :
567 : : static int
568 : 3389 : 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 : 3389 : PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
574 : 3389 : 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 : 3389 : show_fn = GET_WARNINGS_ATTR(interp, _showwarnmsg, source != NULL);
580 [ + + ]: 3389 : if (show_fn == NULL) {
581 [ - + ]: 6 : if (PyErr_Occurred())
582 : 0 : return -1;
583 : 6 : show_warning(tstate, filename, lineno, text, category, sourceline);
584 : 6 : return 0;
585 : : }
586 : :
587 [ - + ]: 3383 : if (!PyCallable_Check(show_fn)) {
588 : 0 : PyErr_SetString(PyExc_TypeError,
589 : : "warnings._showwarnmsg() must be set to a callable");
590 : 0 : goto error;
591 : : }
592 : :
593 : 3383 : warnmsg_cls = GET_WARNINGS_ATTR(interp, WarningMessage, 0);
594 [ - + ]: 3383 : if (warnmsg_cls == NULL) {
595 [ # # ]: 0 : if (!PyErr_Occurred()) {
596 : 0 : PyErr_SetString(PyExc_RuntimeError,
597 : : "unable to get warnings.WarningMessage");
598 : : }
599 : 0 : goto error;
600 : : }
601 : :
602 : 3383 : msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
603 : : filename, lineno_obj, Py_None, Py_None, source,
604 : : NULL);
605 : 3383 : Py_DECREF(warnmsg_cls);
606 [ - + ]: 3383 : if (msg == NULL)
607 : 0 : goto error;
608 : :
609 : 3383 : res = PyObject_CallOneArg(show_fn, msg);
610 : 3383 : Py_DECREF(show_fn);
611 : 3383 : Py_DECREF(msg);
612 : :
613 [ + + ]: 3383 : if (res == NULL)
614 : 1 : return -1;
615 : :
616 : 3382 : Py_DECREF(res);
617 : 3382 : return 0;
618 : :
619 : 0 : error:
620 : 0 : Py_XDECREF(show_fn);
621 : 0 : return -1;
622 : : }
623 : :
624 : : static PyObject *
625 : 4881 : 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 : 4881 : PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
631 : 4881 : PyObject *item = NULL;
632 : : PyObject *action;
633 : : int rc;
634 : 4881 : 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 [ + + ]: 4881 : if (module == Py_None)
641 : 10 : Py_RETURN_NONE;
642 : :
643 [ + + + + : 4871 : if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
- + ]
644 : 0 : PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
645 : 0 : return NULL;
646 : : }
647 : :
648 : : /* Normalize module. */
649 [ + + ]: 4871 : if (module == NULL) {
650 : 1019 : module = normalize_module(filename);
651 [ - + ]: 1019 : if (module == NULL)
652 : 0 : return NULL;
653 : : }
654 : : else
655 : 3852 : Py_INCREF(module);
656 : :
657 : : /* Normalize message. */
658 : 4871 : Py_INCREF(message); /* DECREF'ed in cleanup. */
659 : 4871 : rc = PyObject_IsInstance(message, PyExc_Warning);
660 [ - + ]: 4871 : if (rc == -1) {
661 : 0 : goto cleanup;
662 : : }
663 [ + + ]: 4871 : if (rc == 1) {
664 : 18 : text = PyObject_Str(message);
665 [ + + ]: 18 : if (text == NULL)
666 : 1 : goto cleanup;
667 : 17 : category = (PyObject*)Py_TYPE(message);
668 : : }
669 : : else {
670 : 4853 : text = message;
671 : 4853 : message = PyObject_CallOneArg(category, message);
672 [ - + ]: 4853 : if (message == NULL)
673 : 0 : goto cleanup;
674 : : }
675 : :
676 : 4870 : lineno_obj = PyLong_FromLong(lineno);
677 [ - + ]: 4870 : if (lineno_obj == NULL)
678 : 0 : goto cleanup;
679 : :
680 [ + + ]: 4870 : if (source == Py_None) {
681 : 2158 : source = NULL;
682 : : }
683 : :
684 : : /* Create key. */
685 : 4870 : key = PyTuple_Pack(3, text, category, lineno_obj);
686 [ - + ]: 4870 : if (key == NULL)
687 : 0 : goto cleanup;
688 : :
689 [ + + + + ]: 4870 : if ((registry != NULL) && (registry != Py_None)) {
690 : 3851 : rc = already_warned(interp, registry, key, 0);
691 [ - + ]: 3851 : if (rc == -1)
692 : 0 : goto cleanup;
693 [ + + ]: 3851 : else if (rc == 1)
694 : 33 : goto return_none;
695 : : /* Else this warning hasn't been generated before. */
696 : : }
697 : :
698 : 4837 : action = get_filter(interp, category, text, lineno, module, &item);
699 [ + + ]: 4837 : if (action == NULL)
700 : 2 : goto cleanup;
701 : :
702 [ + + ]: 4835 : if (_PyUnicode_EqualToASCIIString(action, "error")) {
703 : 165 : PyErr_SetObject(category, message);
704 : 165 : goto cleanup;
705 : : }
706 : :
707 [ + + ]: 4670 : if (_PyUnicode_EqualToASCIIString(action, "ignore")) {
708 : 1275 : goto return_none;
709 : : }
710 : :
711 : : /* Store in the registry that we've been here, *except* when the action
712 : : is "always". */
713 : 3395 : rc = 0;
714 [ + + ]: 3395 : if (!_PyUnicode_EqualToASCIIString(action, "always")) {
715 [ + + + + : 364 : if (registry != NULL && registry != Py_None &&
- + ]
716 : 176 : PyDict_SetItem(registry, key, Py_True) < 0)
717 : : {
718 : 0 : goto cleanup;
719 : : }
720 : :
721 [ + + ]: 188 : if (_PyUnicode_EqualToASCIIString(action, "once")) {
722 [ + + + + ]: 23 : if (registry == NULL || registry == Py_None) {
723 : 7 : registry = get_once_registry(interp);
724 [ + + ]: 7 : if (registry == NULL)
725 : 1 : goto cleanup;
726 : : }
727 : : /* WarningsState.once_registry[(text, category)] = 1 */
728 : 22 : rc = update_registry(interp, registry, text, category, 0);
729 : : }
730 [ + + ]: 165 : else if (_PyUnicode_EqualToASCIIString(action, "module")) {
731 : : /* registry[(text, category, 0)] = 1 */
732 [ + - + - ]: 2 : if (registry != NULL && registry != Py_None)
733 : 2 : rc = update_registry(interp, registry, text, category, 0);
734 : : }
735 [ - + ]: 163 : else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
736 : 0 : PyErr_Format(PyExc_RuntimeError,
737 : : "Unrecognized action (%R) in warnings.filters:\n %R",
738 : : action, item);
739 : 0 : goto cleanup;
740 : : }
741 : : }
742 : :
743 [ + + ]: 3394 : if (rc == 1) /* Already warned for this module. */
744 : 5 : goto return_none;
745 [ + - ]: 3389 : if (rc == 0) {
746 [ + + ]: 3389 : if (call_show_warning(tstate, category, text, message, filename,
747 : : lineno, lineno_obj, sourceline, source) < 0)
748 : 1 : goto cleanup;
749 : : }
750 : : else /* if (rc == -1) */
751 : 0 : goto cleanup;
752 : :
753 : 4701 : return_none:
754 : 4701 : result = Py_None;
755 : 4701 : Py_INCREF(result);
756 : :
757 : 4871 : cleanup:
758 : 4871 : Py_XDECREF(item);
759 : 4871 : Py_XDECREF(key);
760 : 4871 : Py_XDECREF(text);
761 : 4871 : Py_XDECREF(lineno_obj);
762 : 4871 : Py_DECREF(module);
763 : 4871 : Py_XDECREF(message);
764 : 4871 : return result; /* Py_None or NULL. */
765 : : }
766 : :
767 : : static int
768 : 7354 : is_internal_frame(PyFrameObject *frame)
769 : : {
770 [ + + ]: 7354 : if (frame == NULL) {
771 : 14 : return 0;
772 : : }
773 : :
774 : 7340 : PyCodeObject *code = PyFrame_GetCode(frame);
775 : 7340 : PyObject *filename = code->co_filename;
776 : 7340 : Py_DECREF(code);
777 : :
778 [ - + ]: 7340 : if (filename == NULL) {
779 : 0 : return 0;
780 : : }
781 [ - + ]: 7340 : if (!PyUnicode_Check(filename)) {
782 : 0 : return 0;
783 : : }
784 : :
785 : 7340 : int contains = PyUnicode_Contains(filename, &_Py_ID(importlib));
786 [ - + ]: 7340 : if (contains < 0) {
787 : 0 : return 0;
788 : : }
789 [ + + ]: 7340 : else if (contains > 0) {
790 : 1480 : contains = PyUnicode_Contains(filename, &_Py_ID(_bootstrap));
791 [ - + ]: 1480 : if (contains < 0) {
792 : 0 : return 0;
793 : : }
794 [ + + ]: 1480 : else if (contains > 0) {
795 : 1247 : return 1;
796 : : }
797 : : }
798 : :
799 : 6093 : return 0;
800 : : }
801 : :
802 : : static PyFrameObject *
803 : 2695 : next_external_frame(PyFrameObject *frame)
804 : : {
805 : : do {
806 : 3497 : PyFrameObject *back = PyFrame_GetBack(frame);
807 : 3497 : Py_DECREF(frame);
808 : 3497 : frame = back;
809 [ + + + + ]: 3497 : } while (frame != NULL && is_internal_frame(frame));
810 : :
811 : 2695 : 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
817 : 3859 : 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 : 3859 : PyThreadState *tstate = get_current_tstate();
824 [ - + ]: 3859 : if (tstate == NULL) {
825 : 0 : return 0;
826 : : }
827 : 3859 : PyInterpreterState *interp = tstate->interp;
828 : 3859 : 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 [ + + + + ]: 3859 : if (stack_level <= 0 || is_internal_frame(f)) {
832 [ + + + - ]: 534 : while (--stack_level > 0 && f != NULL) {
833 : 88 : PyFrameObject *back = PyFrame_GetBack(f);
834 : 88 : Py_DECREF(f);
835 : 88 : f = back;
836 : : }
837 : : }
838 : : else {
839 [ + + + + ]: 6108 : while (--stack_level > 0 && f != NULL) {
840 : 2695 : f = next_external_frame(f);
841 : : }
842 : : }
843 : :
844 [ + + ]: 3859 : if (f == NULL) {
845 : 15 : globals = interp->sysdict;
846 : 15 : *filename = PyUnicode_FromString("sys");
847 : 15 : *lineno = 1;
848 : : }
849 : : else {
850 : 3844 : globals = f->f_frame->f_globals;
851 : 3844 : *filename = f->f_frame->f_code->co_filename;
852 : 3844 : Py_INCREF(*filename);
853 : 3844 : *lineno = PyFrame_GetLineNumber(f);
854 : 3844 : Py_DECREF(f);
855 : : }
856 : :
857 : 3859 : *module = NULL;
858 : :
859 : : /* Setup registry. */
860 : : assert(globals != NULL);
861 : : assert(PyDict_Check(globals));
862 : 3859 : *registry = _PyDict_GetItemWithError(globals, &_Py_ID(__warningregistry__));
863 [ + + ]: 3859 : if (*registry == NULL) {
864 : : int rc;
865 : :
866 [ - + ]: 408 : if (_PyErr_Occurred(tstate)) {
867 : 0 : goto handle_error;
868 : : }
869 : 408 : *registry = PyDict_New();
870 [ - + ]: 408 : if (*registry == NULL)
871 : 0 : goto handle_error;
872 : :
873 : 408 : rc = PyDict_SetItem(globals, &_Py_ID(__warningregistry__), *registry);
874 [ - + ]: 408 : if (rc < 0)
875 : 0 : goto handle_error;
876 : : }
877 : : else
878 : 3451 : Py_INCREF(*registry);
879 : :
880 : : /* Setup module. */
881 : 3859 : *module = _PyDict_GetItemWithError(globals, &_Py_ID(__name__));
882 [ + + + + : 3859 : if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) {
+ - ]
883 : 3846 : Py_INCREF(*module);
884 : : }
885 [ - + ]: 13 : else if (_PyErr_Occurred(tstate)) {
886 : 0 : goto handle_error;
887 : : }
888 : : else {
889 : 13 : *module = PyUnicode_FromString("<string>");
890 [ - + ]: 13 : if (*module == NULL)
891 : 0 : goto handle_error;
892 : : }
893 : :
894 : 3859 : return 1;
895 : :
896 : 0 : handle_error:
897 : 0 : Py_XDECREF(*registry);
898 : 0 : Py_XDECREF(*module);
899 : 0 : Py_DECREF(*filename);
900 : 0 : return 0;
901 : : }
902 : :
903 : : static PyObject *
904 : 2236 : get_category(PyObject *message, PyObject *category)
905 : : {
906 : : int rc;
907 : :
908 : : /* Get category. */
909 : 2236 : rc = PyObject_IsInstance(message, PyExc_Warning);
910 [ - + ]: 2236 : if (rc == -1)
911 : 0 : return NULL;
912 : :
913 [ + + ]: 2236 : if (rc == 1)
914 : 8 : category = (PyObject*)Py_TYPE(message);
915 [ + - + + ]: 2228 : else if (category == NULL || category == Py_None)
916 : 966 : category = PyExc_UserWarning;
917 : :
918 : : /* Validate category. */
919 : 2236 : rc = PyObject_IsSubclass(category, PyExc_Warning);
920 : : /* category is not a subclass of PyExc_Warning or
921 : : PyObject_IsSubclass raised an error */
922 [ + + + + ]: 2236 : if (rc == -1 || rc == 0) {
923 : 3 : PyErr_Format(PyExc_TypeError,
924 : : "category must be a Warning subclass, not '%s'",
925 : 3 : Py_TYPE(category)->tp_name);
926 : 3 : return NULL;
927 : : }
928 : :
929 : 2233 : return category;
930 : : }
931 : :
932 : : static PyObject *
933 : 3859 : 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 : 3859 : PyThreadState *tstate = get_current_tstate();
940 [ - + ]: 3859 : if (tstate == NULL) {
941 : 0 : return NULL;
942 : : }
943 : :
944 [ - + ]: 3859 : if (!setup_context(stack_level, &filename, &lineno, &module, ®istry))
945 : 0 : return NULL;
946 : :
947 : 3859 : res = warn_explicit(tstate, category, message, filename, lineno, module, registry,
948 : : NULL, source);
949 : 3859 : Py_DECREF(filename);
950 : 3859 : Py_DECREF(registry);
951 : 3859 : Py_DECREF(module);
952 : 3859 : 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 *
967 : 2236 : 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 : 2236 : category = get_category(message, category);
972 [ + + ]: 2236 : if (category == NULL)
973 : 3 : return NULL;
974 : 2233 : return do_warn(message, category, stacklevel, source);
975 : : }
976 : :
977 : : static PyObject *
978 : 3 : 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 : 3 : loader = _PyDict_GetItemWithError(module_globals, &_Py_ID(__loader__));
989 [ + + ]: 3 : if (loader == NULL) {
990 : 1 : return NULL;
991 : : }
992 : 2 : Py_INCREF(loader);
993 : 2 : module_name = _PyDict_GetItemWithError(module_globals, &_Py_ID(__name__));
994 [ - + ]: 2 : if (!module_name) {
995 : 0 : Py_DECREF(loader);
996 : 0 : return NULL;
997 : : }
998 : 2 : Py_INCREF(module_name);
999 : :
1000 : : /* Make sure the loader implements the optional get_source() method. */
1001 : 2 : (void)_PyObject_LookupAttr(loader, &_Py_ID(get_source), &get_source);
1002 : 2 : Py_DECREF(loader);
1003 [ - + ]: 2 : if (!get_source) {
1004 : 0 : Py_DECREF(module_name);
1005 : 0 : return NULL;
1006 : : }
1007 : : /* Call get_source() to get the source code. */
1008 : 2 : source = PyObject_CallOneArg(get_source, module_name);
1009 : 2 : Py_DECREF(get_source);
1010 : 2 : Py_DECREF(module_name);
1011 [ - + ]: 2 : if (!source) {
1012 : 0 : return NULL;
1013 : : }
1014 [ - + ]: 2 : if (source == Py_None) {
1015 : 0 : Py_DECREF(source);
1016 : 0 : return NULL;
1017 : : }
1018 : :
1019 : : /* Split the source into lines. */
1020 : 2 : source_list = PyUnicode_Splitlines(source, 0);
1021 : 2 : Py_DECREF(source);
1022 [ - + ]: 2 : if (!source_list) {
1023 : 0 : return NULL;
1024 : : }
1025 : :
1026 : : /* Get the source line. */
1027 : 2 : source_line = PyList_GetItem(source_list, lineno-1);
1028 : 2 : Py_XINCREF(source_line);
1029 : 2 : Py_DECREF(source_list);
1030 : 2 : return source_line;
1031 : : }
1032 : :
1033 : : static PyObject *
1034 : 23 : 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 : 23 : PyObject *module = NULL;
1044 : 23 : PyObject *registry = NULL;
1045 : 23 : PyObject *module_globals = NULL;
1046 : 23 : PyObject *sourceobj = NULL;
1047 : 23 : PyObject *source_line = NULL;
1048 : : PyObject *returned;
1049 : :
1050 [ + + ]: 23 : if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
1051 : : kwd_list, &message, &category, &filename, &lineno, &module,
1052 : : ®istry, &module_globals, &sourceobj))
1053 : 3 : return NULL;
1054 : :
1055 : 20 : PyThreadState *tstate = get_current_tstate();
1056 [ - + ]: 20 : if (tstate == NULL) {
1057 : 0 : return NULL;
1058 : : }
1059 : :
1060 [ + + + + ]: 20 : if (module_globals && module_globals != Py_None) {
1061 [ + + ]: 4 : if (!PyDict_Check(module_globals)) {
1062 : 1 : PyErr_Format(PyExc_TypeError,
1063 : : "module_globals must be a dict, not '%.200s'",
1064 : 1 : Py_TYPE(module_globals)->tp_name);
1065 : 1 : return NULL;
1066 : : }
1067 : :
1068 : 3 : source_line = get_source_line(tstate->interp, module_globals, lineno);
1069 [ + + - + ]: 3 : if (source_line == NULL && PyErr_Occurred()) {
1070 : 0 : return NULL;
1071 : : }
1072 : : }
1073 : 19 : returned = warn_explicit(tstate, category, message, filename, lineno, module,
1074 : : registry, source_line, sourceobj);
1075 : 19 : Py_XDECREF(source_line);
1076 : 19 : return returned;
1077 : : }
1078 : :
1079 : : static PyObject *
1080 : 24650 : warnings_filters_mutated(PyObject *self, PyObject *Py_UNUSED(args))
1081 : : {
1082 : 24650 : PyInterpreterState *interp = get_current_interp();
1083 [ - + ]: 24650 : if (interp == NULL) {
1084 : 0 : return NULL;
1085 : : }
1086 : 24650 : WarningsState *st = warnings_get_state(interp);
1087 [ - + ]: 24650 : if (st == NULL) {
1088 : 0 : return NULL;
1089 : : }
1090 : 24650 : st->filters_version++;
1091 : 24650 : Py_RETURN_NONE;
1092 : : }
1093 : :
1094 : :
1095 : : /* Function to issue a warning message; may raise an exception. */
1096 : :
1097 : : static int
1098 : 1626 : warn_unicode(PyObject *category, PyObject *message,
1099 : : Py_ssize_t stack_level, PyObject *source)
1100 : : {
1101 : : PyObject *res;
1102 : :
1103 [ - + ]: 1626 : if (category == NULL)
1104 : 0 : category = PyExc_RuntimeWarning;
1105 : :
1106 : 1626 : res = do_warn(message, category, stack_level, source);
1107 [ + + ]: 1626 : if (res == NULL)
1108 : 3 : return -1;
1109 : 1623 : Py_DECREF(res);
1110 : :
1111 : 1623 : return 0;
1112 : : }
1113 : :
1114 : : static int
1115 : 731 : _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 : 731 : message = PyUnicode_FromFormatV(format, vargs);
1123 [ + + ]: 731 : if (message == NULL)
1124 : 12 : return -1;
1125 : :
1126 : 719 : res = warn_unicode(category, message, stack_level, source);
1127 : 719 : Py_DECREF(message);
1128 : 719 : return res;
1129 : : }
1130 : :
1131 : : int
1132 : 675 : PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
1133 : : const char *format, ...)
1134 : : {
1135 : : int res;
1136 : : va_list vargs;
1137 : :
1138 : 675 : va_start(vargs, format);
1139 : 675 : res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
1140 : 675 : va_end(vargs);
1141 : 675 : return res;
1142 : : }
1143 : :
1144 : : static int
1145 : 5 : _PyErr_WarnFormat(PyObject *source, PyObject *category, Py_ssize_t stack_level,
1146 : : const char *format, ...)
1147 : : {
1148 : : int res;
1149 : : va_list vargs;
1150 : :
1151 : 5 : va_start(vargs, format);
1152 : 5 : res = _PyErr_WarnFormatV(source, category, stack_level, format, vargs);
1153 : 5 : va_end(vargs);
1154 : 5 : return res;
1155 : : }
1156 : :
1157 : : int
1158 : 51 : PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
1159 : : const char *format, ...)
1160 : : {
1161 : : int res;
1162 : : va_list vargs;
1163 : :
1164 : 51 : va_start(vargs, format);
1165 : 51 : res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
1166 : : stack_level, format, vargs);
1167 : 51 : va_end(vargs);
1168 : 51 : return res;
1169 : : }
1170 : :
1171 : :
1172 : : int
1173 : 907 : PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
1174 : : {
1175 : : int ret;
1176 : 907 : PyObject *message = PyUnicode_FromString(text);
1177 [ - + ]: 907 : if (message == NULL)
1178 : 0 : return -1;
1179 : 907 : ret = warn_unicode(category, message, stack_level, NULL);
1180 : 907 : Py_DECREF(message);
1181 : 907 : return ret;
1182 : : }
1183 : :
1184 : : /* PyErr_Warn is only for backwards compatibility and will be removed.
1185 : : Use PyErr_WarnEx instead. */
1186 : :
1187 : : #undef PyErr_Warn
1188 : :
1189 : : int
1190 : 0 : PyErr_Warn(PyObject *category, const char *text)
1191 : : {
1192 : 0 : return PyErr_WarnEx(category, text, 1);
1193 : : }
1194 : :
1195 : : /* Warning with explicit origin */
1196 : : int
1197 : 1000 : PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1198 : : PyObject *filename, int lineno,
1199 : : PyObject *module, PyObject *registry)
1200 : : {
1201 : : PyObject *res;
1202 [ - + ]: 1000 : if (category == NULL)
1203 : 0 : category = PyExc_RuntimeWarning;
1204 : 1000 : PyThreadState *tstate = get_current_tstate();
1205 [ - + ]: 1000 : if (tstate == NULL) {
1206 : 0 : return -1;
1207 : : }
1208 : 1000 : res = warn_explicit(tstate, category, message, filename, lineno,
1209 : : module, registry, NULL, NULL);
1210 [ + + ]: 1000 : if (res == NULL)
1211 : 136 : return -1;
1212 : 864 : Py_DECREF(res);
1213 : 864 : return 0;
1214 : : }
1215 : :
1216 : : int
1217 : 0 : PyErr_WarnExplicit(PyObject *category, const char *text,
1218 : : const char *filename_str, int lineno,
1219 : : const char *module_str, PyObject *registry)
1220 : : {
1221 : 0 : PyObject *message = PyUnicode_FromString(text);
1222 : 0 : PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1223 : 0 : PyObject *module = NULL;
1224 : 0 : int ret = -1;
1225 : :
1226 [ # # # # ]: 0 : if (message == NULL || filename == NULL)
1227 : 0 : goto exit;
1228 [ # # ]: 0 : if (module_str != NULL) {
1229 : 0 : module = PyUnicode_FromString(module_str);
1230 [ # # ]: 0 : if (module == NULL)
1231 : 0 : goto exit;
1232 : : }
1233 : :
1234 : 0 : ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1235 : : module, registry);
1236 : :
1237 : 0 : exit:
1238 : 0 : Py_XDECREF(message);
1239 : 0 : Py_XDECREF(module);
1240 : 0 : Py_XDECREF(filename);
1241 : 0 : return ret;
1242 : : }
1243 : :
1244 : : int
1245 : 3 : PyErr_WarnExplicitFormat(PyObject *category,
1246 : : const char *filename_str, int lineno,
1247 : : const char *module_str, PyObject *registry,
1248 : : const char *format, ...)
1249 : : {
1250 : : PyObject *message;
1251 : 3 : PyObject *module = NULL;
1252 : 3 : PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1253 : 3 : int ret = -1;
1254 : : va_list vargs;
1255 : :
1256 [ - + ]: 3 : if (filename == NULL)
1257 : 0 : goto exit;
1258 [ + - ]: 3 : if (module_str != NULL) {
1259 : 3 : module = PyUnicode_FromString(module_str);
1260 [ - + ]: 3 : if (module == NULL)
1261 : 0 : goto exit;
1262 : : }
1263 : :
1264 : 3 : va_start(vargs, format);
1265 : 3 : message = PyUnicode_FromFormatV(format, vargs);
1266 [ + - ]: 3 : if (message != NULL) {
1267 : : PyObject *res;
1268 : 3 : PyThreadState *tstate = get_current_tstate();
1269 [ + - ]: 3 : if (tstate != NULL) {
1270 : 3 : res = warn_explicit(tstate, category, message, filename, lineno,
1271 : : module, registry, NULL, NULL);
1272 : 3 : Py_DECREF(message);
1273 [ + - ]: 3 : if (res != NULL) {
1274 : 3 : Py_DECREF(res);
1275 : 3 : ret = 0;
1276 : : }
1277 : : }
1278 : : }
1279 : 3 : va_end(vargs);
1280 : 3 : exit:
1281 : 3 : Py_XDECREF(module);
1282 : 3 : Py_XDECREF(filename);
1283 : 3 : return ret;
1284 : : }
1285 : :
1286 : : void
1287 : 40 : _PyErr_WarnUnawaitedCoroutine(PyObject *coro)
1288 : : {
1289 : : /* First, we attempt to funnel the warning through
1290 : : warnings._warn_unawaited_coroutine.
1291 : :
1292 : : This could raise an exception, due to:
1293 : : - a bug
1294 : : - some kind of shutdown-related brokenness
1295 : : - succeeding, but with an "error" warning filter installed, so the
1296 : : warning is converted into a RuntimeWarning exception
1297 : :
1298 : : In the first two cases, we want to print the error (so we know what it
1299 : : is!), and then print a warning directly as a fallback. In the last
1300 : : case, we want to print the error (since it's the warning!), but *not*
1301 : : do a fallback. And after we print the error we can't check for what
1302 : : type of error it was (because PyErr_WriteUnraisable clears it), so we
1303 : : need a flag to keep track.
1304 : :
1305 : : Since this is called from __del__ context, it's careful to never raise
1306 : : an exception.
1307 : : */
1308 : 40 : int warned = 0;
1309 : 40 : PyInterpreterState *interp = _PyInterpreterState_GET();
1310 : : assert(interp != NULL);
1311 : 40 : PyObject *fn = GET_WARNINGS_ATTR(interp, _warn_unawaited_coroutine, 1);
1312 [ + + ]: 40 : if (fn) {
1313 : 36 : PyObject *res = PyObject_CallOneArg(fn, coro);
1314 : 36 : Py_DECREF(fn);
1315 [ + + + + ]: 36 : if (res || PyErr_ExceptionMatches(PyExc_RuntimeWarning)) {
1316 : 35 : warned = 1;
1317 : : }
1318 : 36 : Py_XDECREF(res);
1319 : : }
1320 : :
1321 [ + + ]: 40 : if (PyErr_Occurred()) {
1322 : 2 : PyErr_WriteUnraisable(coro);
1323 : : }
1324 [ + + ]: 40 : if (!warned) {
1325 [ - + ]: 5 : if (_PyErr_WarnFormat(coro, PyExc_RuntimeWarning, 1,
1326 : : "coroutine '%S' was never awaited",
1327 : : ((PyCoroObject *)coro)->cr_qualname) < 0)
1328 : : {
1329 : 0 : PyErr_WriteUnraisable(coro);
1330 : : }
1331 : : }
1332 : 40 : }
1333 : :
1334 : : PyDoc_STRVAR(warn_explicit_doc,
1335 : : "Low-level interface to warnings functionality.");
1336 : :
1337 : : static PyMethodDef warnings_functions[] = {
1338 : : WARNINGS_WARN_METHODDEF
1339 : : {"warn_explicit", _PyCFunction_CAST(warnings_warn_explicit),
1340 : : METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
1341 : : {"_filters_mutated", _PyCFunction_CAST(warnings_filters_mutated), METH_NOARGS,
1342 : : NULL},
1343 : : /* XXX(brett.cannon): add showwarning? */
1344 : : /* XXX(brett.cannon): Reasonable to add formatwarning? */
1345 : : {NULL, NULL} /* sentinel */
1346 : : };
1347 : :
1348 : :
1349 : : static int
1350 : 3137 : warnings_module_exec(PyObject *module)
1351 : : {
1352 : 3137 : PyInterpreterState *interp = get_current_interp();
1353 [ - + ]: 3137 : if (interp == NULL) {
1354 : 0 : return -1;
1355 : : }
1356 : 3137 : WarningsState *st = warnings_get_state(interp);
1357 [ - + ]: 3137 : if (st == NULL) {
1358 : 0 : return -1;
1359 : : }
1360 [ - + ]: 3137 : if (PyModule_AddObjectRef(module, "filters", st->filters) < 0) {
1361 : 0 : return -1;
1362 : : }
1363 [ - + ]: 3137 : if (PyModule_AddObjectRef(module, "_onceregistry", st->once_registry) < 0) {
1364 : 0 : return -1;
1365 : : }
1366 [ - + ]: 3137 : if (PyModule_AddObjectRef(module, "_defaultaction", st->default_action) < 0) {
1367 : 0 : return -1;
1368 : : }
1369 : 3137 : return 0;
1370 : : }
1371 : :
1372 : :
1373 : : static PyModuleDef_Slot warnings_slots[] = {
1374 : : {Py_mod_exec, warnings_module_exec},
1375 : : {0, NULL}
1376 : : };
1377 : :
1378 : : static struct PyModuleDef warnings_module = {
1379 : : PyModuleDef_HEAD_INIT,
1380 : : .m_name = MODULE_NAME,
1381 : : .m_doc = warnings__doc__,
1382 : : .m_size = 0,
1383 : : .m_methods = warnings_functions,
1384 : : .m_slots = warnings_slots,
1385 : : };
1386 : :
1387 : :
1388 : : PyMODINIT_FUNC
1389 : 3137 : _PyWarnings_Init(void)
1390 : : {
1391 : 3137 : return PyModuleDef_Init(&warnings_module);
1392 : : }
1393 : :
1394 : : // We need this to ensure that warnings still work until late in finalization.
1395 : : void
1396 : 3125 : _PyWarnings_Fini(PyInterpreterState *interp)
1397 : : {
1398 : 3125 : warnings_clear_state(&interp->warnings);
1399 : 3125 : }
|