blob: 52a13dfc62ccca8c0b19dc27bce7ff53714eb55d [file] [log] [blame]
Christian Heimes33fe8092008-04-13 13:53:33 +00001#include "Python.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01002#include "pycore_pystate.h"
Christian Heimes33fe8092008-04-13 13:53:33 +00003#include "frameobject.h"
Victor Stinner22f18752016-12-09 18:08:18 +01004#include "clinic/_warnings.c.h"
Christian Heimes33fe8092008-04-13 13:53:33 +00005
6#define MODULE_NAME "_warnings"
Christian Heimes33fe8092008-04-13 13:53:33 +00007
8PyDoc_STRVAR(warnings__doc__,
9MODULE_NAME " provides basic warning filtering support.\n"
10"It is a helper module to speed up interpreter start-up.");
11
Victor Stinnerbd303c12013-11-07 23:07:29 +010012_Py_IDENTIFIER(stderr);
Victor Stinner747f48e2017-12-12 22:59:48 +010013#ifndef Py_DEBUG
Nick Coghlan9b997472018-01-08 12:45:02 +100014_Py_IDENTIFIER(default);
Victor Stinnerb98f1712017-11-23 17:13:44 +010015_Py_IDENTIFIER(ignore);
Victor Stinner747f48e2017-12-12 22:59:48 +010016#endif
Christian Heimes33fe8092008-04-13 13:53:33 +000017
Eric Snow86ea5812019-05-10 13:29:55 -040018
19/*************************************************************************/
20
21typedef struct _warnings_runtime_state WarningsState;
22
23/* Forward declaration of the _warnings module definition. */
24static struct PyModuleDef warningsmodule;
25
26/* Given a module object, get its per-module state. */
27static WarningsState *
28_Warnings_GetState()
29{
30 PyThreadState *tstate = PyThreadState_GET();
31 if (tstate == NULL) {
32 PyErr_SetString(PyExc_RuntimeError,
33 "_Warnings_GetState: could not identify current interpreter");
34 return NULL;
35 }
36 return &tstate->interp->warnings;
37}
38
39/* Clear the given warnings module state. */
40static void
41_Warnings_ClearState(WarningsState *st)
42{
43 Py_CLEAR(st->filters);
44 Py_CLEAR(st->once_registry);
45 Py_CLEAR(st->default_action);
46}
47
48#ifndef Py_DEBUG
49static PyObject *
50create_filter(PyObject *category, _Py_Identifier *id, const char *modname)
51{
52 PyObject *modname_obj = NULL;
53 PyObject *action_str = _PyUnicode_FromId(id);
54 if (action_str == NULL) {
55 return NULL;
56 }
57
58 /* Default to "no module name" for initial filter set */
59 if (modname != NULL) {
60 modname_obj = PyUnicode_InternFromString(modname);
61 if (modname_obj == NULL) {
62 return NULL;
63 }
64 } else {
65 modname_obj = Py_None;
66 }
67
68 /* This assumes the line number is zero for now. */
69 return PyTuple_Pack(5, action_str, Py_None,
70 category, modname_obj, _PyLong_Zero);
71}
72#endif
73
74static PyObject *
75init_filters(void)
76{
77#ifdef Py_DEBUG
78 /* Py_DEBUG builds show all warnings by default */
79 return PyList_New(0);
80#else
81 /* Other builds ignore a number of warning categories by default */
82 PyObject *filters = PyList_New(5);
83 if (filters == NULL) {
84 return NULL;
85 }
86
87 size_t pos = 0; /* Post-incremented in each use. */
88 PyList_SET_ITEM(filters, pos++,
89 create_filter(PyExc_DeprecationWarning, &PyId_default, "__main__"));
90 PyList_SET_ITEM(filters, pos++,
91 create_filter(PyExc_DeprecationWarning, &PyId_ignore, NULL));
92 PyList_SET_ITEM(filters, pos++,
93 create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore, NULL));
94 PyList_SET_ITEM(filters, pos++,
95 create_filter(PyExc_ImportWarning, &PyId_ignore, NULL));
96 PyList_SET_ITEM(filters, pos++,
97 create_filter(PyExc_ResourceWarning, &PyId_ignore, NULL));
98
99 for (size_t x = 0; x < pos; x++) {
100 if (PyList_GET_ITEM(filters, x) == NULL) {
101 Py_DECREF(filters);
102 return NULL;
103 }
104 }
105 return filters;
106#endif
107}
108
109/* Initialize the given warnings module state. */
110static int
111_Warnings_InitState(WarningsState *st)
112{
113 if (st->filters == NULL) {
114 st->filters = init_filters();
115 if (st->filters == NULL) {
116 goto error;
117 }
118 }
119
120 if (st->once_registry == NULL) {
121 st->once_registry = PyDict_New();
122 if (st->once_registry == NULL) {
123 goto error;
124 }
125 }
126
127 if (st->default_action == NULL) {
128 st->default_action = PyUnicode_FromString("default");
129 if (st->default_action == NULL) {
130 goto error;
131 }
132 }
133
134 st->filters_version = 0;
135
136 return 0;
137
138error:
139 _Warnings_ClearState(st);
140 return -1;
141}
142
143
144/*************************************************************************/
145
Christian Heimes33fe8092008-04-13 13:53:33 +0000146static int
147check_matched(PyObject *obj, PyObject *arg)
148{
149 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200150 _Py_IDENTIFIER(match);
Christian Heimes33fe8092008-04-13 13:53:33 +0000151 int rc;
152
Nick Coghlan9b997472018-01-08 12:45:02 +1000153 /* A 'None' filter always matches */
Christian Heimes33fe8092008-04-13 13:53:33 +0000154 if (obj == Py_None)
155 return 1;
Nick Coghlan9b997472018-01-08 12:45:02 +1000156
157 /* An internal plain text default filter must match exactly */
158 if (PyUnicode_CheckExact(obj)) {
159 int cmp_result = PyUnicode_Compare(obj, arg);
160 if (cmp_result == -1 && PyErr_Occurred()) {
161 return -1;
162 }
163 return !cmp_result;
164 }
165
166 /* Otherwise assume a regex filter and call its match() method */
Victor Stinner55ba38a2016-12-09 16:09:30 +0100167 result = _PyObject_CallMethodIdObjArgs(obj, &PyId_match, arg, NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000168 if (result == NULL)
169 return -1;
170
171 rc = PyObject_IsTrue(result);
172 Py_DECREF(result);
173 return rc;
174}
175
176/*
177 Returns a new reference.
178 A NULL return value can mean false or an error.
179*/
180static PyObject *
Victor Stinner82656272017-11-22 23:51:42 +0100181get_warnings_attr(_Py_Identifier *attr_id, int try_import)
Christian Heimes33fe8092008-04-13 13:53:33 +0000182{
Victor Stinner82656272017-11-22 23:51:42 +0100183 PyObject *warnings_str;
Victor Stinnere98445a2016-03-23 00:54:48 +0100184 PyObject *warnings_module, *obj;
Victor Stinner82656272017-11-22 23:51:42 +0100185 _Py_IDENTIFIER(warnings);
Christian Heimes33fe8092008-04-13 13:53:33 +0000186
Victor Stinner82656272017-11-22 23:51:42 +0100187 warnings_str = _PyUnicode_FromId(&PyId_warnings);
Christian Heimes33fe8092008-04-13 13:53:33 +0000188 if (warnings_str == NULL) {
Victor Stinner82656272017-11-22 23:51:42 +0100189 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000190 }
191
Victor Stinnere98445a2016-03-23 00:54:48 +0100192 /* don't try to import after the start of the Python finallization */
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600193 if (try_import && !_Py_IsFinalizing()) {
Victor Stinnere98445a2016-03-23 00:54:48 +0100194 warnings_module = PyImport_Import(warnings_str);
195 if (warnings_module == NULL) {
196 /* Fallback to the C implementation if we cannot get
197 the Python implementation */
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200198 if (PyErr_ExceptionMatches(PyExc_ImportError)) {
199 PyErr_Clear();
200 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000201 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +0100202 }
203 }
204 else {
Nathaniel J. Smithdba976b2018-01-26 11:28:31 -0800205 /* if we're so late into Python finalization that the module dict is
206 gone, then we can't even use PyImport_GetModule without triggering
207 an interpreter abort.
208 */
Victor Stinnercaba55b2018-08-03 15:33:52 +0200209 if (!_PyInterpreterState_GET_UNSAFE()->modules) {
Nathaniel J. Smithdba976b2018-01-26 11:28:31 -0800210 return NULL;
211 }
Eric Snow3f9eee62017-09-15 16:35:20 -0600212 warnings_module = PyImport_GetModule(warnings_str);
Victor Stinner023654f2016-03-23 17:48:22 +0100213 if (warnings_module == NULL)
214 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +0100215 }
216
Serhiy Storchakaf320be72018-01-25 10:49:40 +0200217 (void)_PyObject_LookupAttrId(warnings_module, attr_id, &obj);
Victor Stinnere98445a2016-03-23 00:54:48 +0100218 Py_DECREF(warnings_module);
219 return obj;
Christian Heimes33fe8092008-04-13 13:53:33 +0000220}
221
222
Neal Norwitz32dde222008-04-15 06:43:13 +0000223static PyObject *
Eric Snow86ea5812019-05-10 13:29:55 -0400224get_once_registry(WarningsState *st)
Christian Heimes33fe8092008-04-13 13:53:33 +0000225{
226 PyObject *registry;
Victor Stinner82656272017-11-22 23:51:42 +0100227 _Py_IDENTIFIER(onceregistry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000228
Victor Stinner82656272017-11-22 23:51:42 +0100229 registry = get_warnings_attr(&PyId_onceregistry, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000230 if (registry == NULL) {
231 if (PyErr_Occurred())
232 return NULL;
Eric Snow86ea5812019-05-10 13:29:55 -0400233 assert(st->once_registry);
234 return st->once_registry;
Christian Heimes33fe8092008-04-13 13:53:33 +0000235 }
Oren Milman252033d2017-09-11 09:28:39 +0300236 if (!PyDict_Check(registry)) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200237 PyErr_Format(PyExc_TypeError,
238 MODULE_NAME ".onceregistry must be a dict, "
239 "not '%.200s'",
240 Py_TYPE(registry)->tp_name);
Oren Milman252033d2017-09-11 09:28:39 +0300241 Py_DECREF(registry);
242 return NULL;
243 }
Eric Snow86ea5812019-05-10 13:29:55 -0400244 Py_SETREF(st->once_registry, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000245 return registry;
246}
247
248
Brett Cannon0759dd62009-04-01 18:13:07 +0000249static PyObject *
Eric Snow86ea5812019-05-10 13:29:55 -0400250get_default_action(WarningsState *st)
Brett Cannon0759dd62009-04-01 18:13:07 +0000251{
252 PyObject *default_action;
Victor Stinner82656272017-11-22 23:51:42 +0100253 _Py_IDENTIFIER(defaultaction);
Brett Cannon0759dd62009-04-01 18:13:07 +0000254
Victor Stinner82656272017-11-22 23:51:42 +0100255 default_action = get_warnings_attr(&PyId_defaultaction, 0);
Brett Cannon0759dd62009-04-01 18:13:07 +0000256 if (default_action == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 if (PyErr_Occurred()) {
258 return NULL;
259 }
Eric Snow86ea5812019-05-10 13:29:55 -0400260 assert(st->default_action);
261 return st->default_action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000262 }
Oren Milman9d984fd2017-09-12 00:18:09 +0300263 if (!PyUnicode_Check(default_action)) {
264 PyErr_Format(PyExc_TypeError,
265 MODULE_NAME ".defaultaction must be a string, "
266 "not '%.200s'",
267 Py_TYPE(default_action)->tp_name);
268 Py_DECREF(default_action);
269 return NULL;
270 }
Eric Snow86ea5812019-05-10 13:29:55 -0400271 Py_SETREF(st->default_action, default_action);
Brett Cannon0759dd62009-04-01 18:13:07 +0000272 return default_action;
273}
274
275
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400276/* The item is a new reference. */
Victor Stinnera4c704b2013-10-29 23:43:41 +0100277static PyObject*
Christian Heimes33fe8092008-04-13 13:53:33 +0000278get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
279 PyObject *module, PyObject **item)
280{
Brett Cannon0759dd62009-04-01 18:13:07 +0000281 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000282 Py_ssize_t i;
283 PyObject *warnings_filters;
Victor Stinner82656272017-11-22 23:51:42 +0100284 _Py_IDENTIFIER(filters);
Eric Snow86ea5812019-05-10 13:29:55 -0400285 WarningsState *st = _Warnings_GetState();
286 if (st == NULL) {
287 return NULL;
288 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000289
Victor Stinner82656272017-11-22 23:51:42 +0100290 warnings_filters = get_warnings_attr(&PyId_filters, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000291 if (warnings_filters == NULL) {
292 if (PyErr_Occurred())
293 return NULL;
294 }
295 else {
Eric Snow86ea5812019-05-10 13:29:55 -0400296 Py_SETREF(st->filters, warnings_filters);
Christian Heimes33fe8092008-04-13 13:53:33 +0000297 }
298
Eric Snow86ea5812019-05-10 13:29:55 -0400299 PyObject *filters = st->filters;
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600300 if (filters == NULL || !PyList_Check(filters)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000301 PyErr_SetString(PyExc_ValueError,
302 MODULE_NAME ".filters must be a list");
303 return NULL;
304 }
305
Eric Snow86ea5812019-05-10 13:29:55 -0400306 /* WarningsState.filters could change while we are iterating over it. */
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600307 for (i = 0; i < PyList_GET_SIZE(filters); i++) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000308 PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
309 Py_ssize_t ln;
310 int is_subclass, good_msg, good_mod;
311
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600312 tmp_item = PyList_GET_ITEM(filters, i);
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400313 if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000314 PyErr_Format(PyExc_ValueError,
315 MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
316 return NULL;
317 }
318
319 /* Python code: action, msg, cat, mod, ln = item */
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400320 Py_INCREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000321 action = PyTuple_GET_ITEM(tmp_item, 0);
322 msg = PyTuple_GET_ITEM(tmp_item, 1);
323 cat = PyTuple_GET_ITEM(tmp_item, 2);
324 mod = PyTuple_GET_ITEM(tmp_item, 3);
325 ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
326
Oren Milman9d984fd2017-09-12 00:18:09 +0300327 if (!PyUnicode_Check(action)) {
328 PyErr_Format(PyExc_TypeError,
329 "action must be a string, not '%.200s'",
330 Py_TYPE(action)->tp_name);
331 Py_DECREF(tmp_item);
332 return NULL;
333 }
334
Christian Heimes33fe8092008-04-13 13:53:33 +0000335 good_msg = check_matched(msg, text);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400336 if (good_msg == -1) {
337 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100338 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400339 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100340
Christian Heimes33fe8092008-04-13 13:53:33 +0000341 good_mod = check_matched(mod, module);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400342 if (good_mod == -1) {
343 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100344 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400345 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100346
Christian Heimes33fe8092008-04-13 13:53:33 +0000347 is_subclass = PyObject_IsSubclass(category, cat);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400348 if (is_subclass == -1) {
349 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100350 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400351 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100352
Christian Heimes33fe8092008-04-13 13:53:33 +0000353 ln = PyLong_AsSsize_t(ln_obj);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400354 if (ln == -1 && PyErr_Occurred()) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400355 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000356 return NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400357 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000358
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400359 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
360 *item = tmp_item;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100361 return action;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400362 }
363
364 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000365 }
366
Eric Snow86ea5812019-05-10 13:29:55 -0400367 action = get_default_action(st);
Brett Cannon0759dd62009-04-01 18:13:07 +0000368 if (action != NULL) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400369 Py_INCREF(Py_None);
370 *item = Py_None;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100371 return action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000372 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000373
Christian Heimes33fe8092008-04-13 13:53:33 +0000374 return NULL;
375}
376
Brett Cannon0759dd62009-04-01 18:13:07 +0000377
Christian Heimes33fe8092008-04-13 13:53:33 +0000378static int
379already_warned(PyObject *registry, PyObject *key, int should_set)
380{
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200381 PyObject *version_obj, *already_warned;
382 _Py_IDENTIFIER(version);
Christian Heimes33fe8092008-04-13 13:53:33 +0000383
384 if (key == NULL)
385 return -1;
386
Eric Snow86ea5812019-05-10 13:29:55 -0400387 WarningsState *st = _Warnings_GetState();
388 if (st == NULL) {
389 return -1;
390 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200391 version_obj = _PyDict_GetItemIdWithError(registry, &PyId_version);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200392 if (version_obj == NULL
393 || !PyLong_CheckExact(version_obj)
Eric Snow86ea5812019-05-10 13:29:55 -0400394 || PyLong_AsLong(version_obj) != st->filters_version)
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200395 {
396 if (PyErr_Occurred()) {
397 return -1;
398 }
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200399 PyDict_Clear(registry);
Eric Snow86ea5812019-05-10 13:29:55 -0400400 version_obj = PyLong_FromLong(st->filters_version);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200401 if (version_obj == NULL)
402 return -1;
403 if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
404 Py_DECREF(version_obj);
405 return -1;
406 }
407 Py_DECREF(version_obj);
408 }
409 else {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200410 already_warned = PyDict_GetItemWithError(registry, key);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200411 if (already_warned != NULL) {
412 int rc = PyObject_IsTrue(already_warned);
413 if (rc != 0)
414 return rc;
415 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200416 else if (PyErr_Occurred()) {
417 return -1;
418 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000419 }
420
421 /* This warning wasn't found in the registry, set it. */
422 if (should_set)
423 return PyDict_SetItem(registry, key, Py_True);
424 return 0;
425}
426
427/* New reference. */
428static PyObject *
429normalize_module(PyObject *filename)
430{
431 PyObject *module;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100432 int kind;
433 void *data;
Christian Heimes33fe8092008-04-13 13:53:33 +0000434 Py_ssize_t len;
435
Victor Stinner9e30aa52011-11-21 02:49:52 +0100436 len = PyUnicode_GetLength(filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000437 if (len < 0)
438 return NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100439
440 if (len == 0)
441 return PyUnicode_FromString("<unknown>");
442
443 kind = PyUnicode_KIND(filename);
444 data = PyUnicode_DATA(filename);
445
446 /* if filename.endswith(".py"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000447 if (len >= 3 &&
Victor Stinnera4c704b2013-10-29 23:43:41 +0100448 PyUnicode_READ(kind, data, len-3) == '.' &&
449 PyUnicode_READ(kind, data, len-2) == 'p' &&
450 PyUnicode_READ(kind, data, len-1) == 'y')
451 {
Victor Stinner9e30aa52011-11-21 02:49:52 +0100452 module = PyUnicode_Substring(filename, 0, len-3);
Christian Heimes33fe8092008-04-13 13:53:33 +0000453 }
454 else {
455 module = filename;
456 Py_INCREF(module);
457 }
458 return module;
459}
460
461static int
462update_registry(PyObject *registry, PyObject *text, PyObject *category,
463 int add_zero)
464{
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300465 PyObject *altkey;
Christian Heimes33fe8092008-04-13 13:53:33 +0000466 int rc;
467
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300468 if (add_zero)
469 altkey = PyTuple_Pack(3, text, category, _PyLong_Zero);
Christian Heimes33fe8092008-04-13 13:53:33 +0000470 else
471 altkey = PyTuple_Pack(2, text, category);
472
473 rc = already_warned(registry, altkey, 1);
Christian Heimes33fe8092008-04-13 13:53:33 +0000474 Py_XDECREF(altkey);
475 return rc;
476}
477
478static void
Victor Stinner914cde82016-03-19 01:03:51 +0100479show_warning(PyObject *filename, int lineno, PyObject *text,
480 PyObject *category, PyObject *sourceline)
Christian Heimes33fe8092008-04-13 13:53:33 +0000481{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 PyObject *f_stderr;
483 PyObject *name;
Christian Heimes33fe8092008-04-13 13:53:33 +0000484 char lineno_str[128];
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200485 _Py_IDENTIFIER(__name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000486
487 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
488
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200489 name = _PyObject_GetAttrId(category, &PyId___name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000490 if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100491 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000492
Victor Stinnerbd303c12013-11-07 23:07:29 +0100493 f_stderr = _PySys_GetObjectId(&PyId_stderr);
Christian Heimes33fe8092008-04-13 13:53:33 +0000494 if (f_stderr == NULL) {
495 fprintf(stderr, "lost sys.stderr\n");
Victor Stinnerae233ea2013-10-31 14:51:38 +0100496 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000497 }
498
499 /* Print "filename:lineno: category: text\n" */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100500 if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
501 goto error;
502 if (PyFile_WriteString(lineno_str, f_stderr) < 0)
503 goto error;
504 if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
505 goto error;
506 if (PyFile_WriteString(": ", f_stderr) < 0)
507 goto error;
508 if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
509 goto error;
510 if (PyFile_WriteString("\n", f_stderr) < 0)
511 goto error;
512 Py_CLEAR(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000513
514 /* Print " source_line\n" */
Christian Heimes33fe8092008-04-13 13:53:33 +0000515 if (sourceline) {
Victor Stinnera4c704b2013-10-29 23:43:41 +0100516 int kind;
517 void *data;
518 Py_ssize_t i, len;
519 Py_UCS4 ch;
520 PyObject *truncated;
Christian Heimes33fe8092008-04-13 13:53:33 +0000521
Victor Stinnera4c704b2013-10-29 23:43:41 +0100522 if (PyUnicode_READY(sourceline) < 1)
523 goto error;
524
525 kind = PyUnicode_KIND(sourceline);
526 data = PyUnicode_DATA(sourceline);
527 len = PyUnicode_GET_LENGTH(sourceline);
528 for (i=0; i<len; i++) {
529 ch = PyUnicode_READ(kind, data, i);
530 if (ch != ' ' && ch != '\t' && ch != '\014')
531 break;
532 }
533
534 truncated = PyUnicode_Substring(sourceline, i, len);
535 if (truncated == NULL)
536 goto error;
537
538 PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
539 Py_DECREF(truncated);
Christian Heimes33fe8092008-04-13 13:53:33 +0000540 PyFile_WriteString("\n", f_stderr);
541 }
Victor Stinner78e2c982013-07-16 01:54:37 +0200542 else {
543 _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
544 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100545
546error:
Victor Stinnerae233ea2013-10-31 14:51:38 +0100547 Py_XDECREF(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000548 PyErr_Clear();
549}
550
Victor Stinner1231a462016-03-19 00:47:17 +0100551static int
552call_show_warning(PyObject *category, PyObject *text, PyObject *message,
553 PyObject *filename, int lineno, PyObject *lineno_obj,
Victor Stinner914cde82016-03-19 01:03:51 +0100554 PyObject *sourceline, PyObject *source)
Victor Stinner1231a462016-03-19 00:47:17 +0100555{
556 PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
Victor Stinner82656272017-11-22 23:51:42 +0100557 _Py_IDENTIFIER(_showwarnmsg);
558 _Py_IDENTIFIER(WarningMessage);
Victor Stinner1231a462016-03-19 00:47:17 +0100559
Victor Stinnere98445a2016-03-23 00:54:48 +0100560 /* If the source parameter is set, try to get the Python implementation.
561 The Python implementation is able to log the traceback where the source
luzpaza5293b42017-11-05 07:37:50 -0600562 was allocated, whereas the C implementation doesn't. */
Victor Stinner82656272017-11-22 23:51:42 +0100563 show_fn = get_warnings_attr(&PyId__showwarnmsg, source != NULL);
Victor Stinner1231a462016-03-19 00:47:17 +0100564 if (show_fn == NULL) {
565 if (PyErr_Occurred())
566 return -1;
567 show_warning(filename, lineno, text, category, sourceline);
568 return 0;
569 }
570
571 if (!PyCallable_Check(show_fn)) {
572 PyErr_SetString(PyExc_TypeError,
573 "warnings._showwarnmsg() must be set to a callable");
574 goto error;
575 }
576
Victor Stinner82656272017-11-22 23:51:42 +0100577 warnmsg_cls = get_warnings_attr(&PyId_WarningMessage, 0);
Victor Stinner1231a462016-03-19 00:47:17 +0100578 if (warnmsg_cls == NULL) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200579 if (!PyErr_Occurred()) {
580 PyErr_SetString(PyExc_RuntimeError,
581 "unable to get warnings.WarningMessage");
582 }
Victor Stinner1231a462016-03-19 00:47:17 +0100583 goto error;
584 }
585
586 msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
Victor Stinner914cde82016-03-19 01:03:51 +0100587 filename, lineno_obj, Py_None, Py_None, source,
Victor Stinner1231a462016-03-19 00:47:17 +0100588 NULL);
589 Py_DECREF(warnmsg_cls);
590 if (msg == NULL)
591 goto error;
592
Victor Stinnerde4ae3d2016-12-04 22:59:09 +0100593 res = PyObject_CallFunctionObjArgs(show_fn, msg, NULL);
Victor Stinner1231a462016-03-19 00:47:17 +0100594 Py_DECREF(show_fn);
595 Py_DECREF(msg);
596
597 if (res == NULL)
598 return -1;
599
600 Py_DECREF(res);
601 return 0;
602
603error:
604 Py_XDECREF(show_fn);
605 return -1;
606}
607
Christian Heimes33fe8092008-04-13 13:53:33 +0000608static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609warn_explicit(PyObject *category, PyObject *message,
Christian Heimes33fe8092008-04-13 13:53:33 +0000610 PyObject *filename, int lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100611 PyObject *module, PyObject *registry, PyObject *sourceline,
612 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000613{
614 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400615 PyObject *item = NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100616 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000617 int rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100619 /* module can be None if a warning is emitted late during Python shutdown.
620 In this case, the Python warnings module was probably unloaded, filters
621 are no more available to choose as action. It is safer to ignore the
622 warning and do nothing. */
623 if (module == Py_None)
624 Py_RETURN_NONE;
625
Brett Cannondb734912008-06-27 00:52:15 +0000626 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
Oren Milman252033d2017-09-11 09:28:39 +0300627 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
Brett Cannondb734912008-06-27 00:52:15 +0000628 return NULL;
629 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000630
631 /* Normalize module. */
632 if (module == NULL) {
633 module = normalize_module(filename);
634 if (module == NULL)
635 return NULL;
636 }
637 else
638 Py_INCREF(module);
639
640 /* Normalize message. */
641 Py_INCREF(message); /* DECREF'ed in cleanup. */
642 rc = PyObject_IsInstance(message, PyExc_Warning);
643 if (rc == -1) {
644 goto cleanup;
645 }
646 if (rc == 1) {
647 text = PyObject_Str(message);
Hirokazu Yamamoto1c0c0032009-07-17 06:55:42 +0000648 if (text == NULL)
649 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000650 category = (PyObject*)message->ob_type;
651 }
652 else {
653 text = message;
Victor Stinner7bfb42d2016-12-05 17:04:32 +0100654 message = PyObject_CallFunctionObjArgs(category, message, NULL);
Brett Cannondb734912008-06-27 00:52:15 +0000655 if (message == NULL)
656 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000657 }
658
659 lineno_obj = PyLong_FromLong(lineno);
660 if (lineno_obj == NULL)
661 goto cleanup;
662
Victor Stinner22f18752016-12-09 18:08:18 +0100663 if (source == Py_None) {
664 source = NULL;
665 }
666
Christian Heimes33fe8092008-04-13 13:53:33 +0000667 /* Create key. */
668 key = PyTuple_Pack(3, text, category, lineno_obj);
669 if (key == NULL)
670 goto cleanup;
671
Brett Cannondb734912008-06-27 00:52:15 +0000672 if ((registry != NULL) && (registry != Py_None)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000673 rc = already_warned(registry, key, 0);
674 if (rc == -1)
675 goto cleanup;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 else if (rc == 1)
Christian Heimes33fe8092008-04-13 13:53:33 +0000677 goto return_none;
678 /* Else this warning hasn't been generated before. */
679 }
680
681 action = get_filter(category, text, lineno, module, &item);
682 if (action == NULL)
683 goto cleanup;
684
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200685 if (_PyUnicode_EqualToASCIIString(action, "error")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000686 PyErr_SetObject(category, message);
687 goto cleanup;
688 }
689
Victor Stinnerc9758782017-11-27 16:57:07 +0100690 if (_PyUnicode_EqualToASCIIString(action, "ignore")) {
691 goto return_none;
692 }
693
Christian Heimes33fe8092008-04-13 13:53:33 +0000694 /* Store in the registry that we've been here, *except* when the action
695 is "always". */
696 rc = 0;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200697 if (!_PyUnicode_EqualToASCIIString(action, "always")) {
Brett Cannondb734912008-06-27 00:52:15 +0000698 if (registry != NULL && registry != Py_None &&
Victor Stinnerc9758782017-11-27 16:57:07 +0100699 PyDict_SetItem(registry, key, Py_True) < 0)
700 {
Christian Heimes33fe8092008-04-13 13:53:33 +0000701 goto cleanup;
Victor Stinnerc9758782017-11-27 16:57:07 +0100702 }
703
704 if (_PyUnicode_EqualToASCIIString(action, "once")) {
Brett Cannondb734912008-06-27 00:52:15 +0000705 if (registry == NULL || registry == Py_None) {
Eric Snow86ea5812019-05-10 13:29:55 -0400706 WarningsState *st = _Warnings_GetState();
707 if (st == NULL) {
708 goto cleanup;
709 }
710 registry = get_once_registry(st);
Christian Heimes33fe8092008-04-13 13:53:33 +0000711 if (registry == NULL)
712 goto cleanup;
713 }
Eric Snow86ea5812019-05-10 13:29:55 -0400714 /* WarningsState.once_registry[(text, category)] = 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000716 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200717 else if (_PyUnicode_EqualToASCIIString(action, "module")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000718 /* registry[(text, category, 0)] = 1 */
Brett Cannondb734912008-06-27 00:52:15 +0000719 if (registry != NULL && registry != Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000721 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200722 else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000723 PyErr_Format(PyExc_RuntimeError,
Victor Stinnera4c704b2013-10-29 23:43:41 +0100724 "Unrecognized action (%R) in warnings.filters:\n %R",
725 action, item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000726 goto cleanup;
727 }
728 }
729
Christian Heimes1a8501c2008-10-02 19:56:01 +0000730 if (rc == 1) /* Already warned for this module. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000731 goto return_none;
732 if (rc == 0) {
Victor Stinner1231a462016-03-19 00:47:17 +0100733 if (call_show_warning(category, text, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100734 lineno_obj, sourceline, source) < 0)
Victor Stinner1231a462016-03-19 00:47:17 +0100735 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000736 }
737 else /* if (rc == -1) */
738 goto cleanup;
739
740 return_none:
741 result = Py_None;
742 Py_INCREF(result);
743
744 cleanup:
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400745 Py_XDECREF(item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000746 Py_XDECREF(key);
747 Py_XDECREF(text);
748 Py_XDECREF(lineno_obj);
749 Py_DECREF(module);
Brett Cannondb734912008-06-27 00:52:15 +0000750 Py_XDECREF(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000751 return result; /* Py_None or NULL. */
752}
753
Larry Hastings714e4932015-09-06 00:39:37 -0700754static int
755is_internal_frame(PyFrameObject *frame)
756{
757 static PyObject *importlib_string = NULL;
758 static PyObject *bootstrap_string = NULL;
759 PyObject *filename;
760 int contains;
761
762 if (importlib_string == NULL) {
763 importlib_string = PyUnicode_FromString("importlib");
764 if (importlib_string == NULL) {
765 return 0;
766 }
767
768 bootstrap_string = PyUnicode_FromString("_bootstrap");
769 if (bootstrap_string == NULL) {
770 Py_DECREF(importlib_string);
771 return 0;
772 }
773 Py_INCREF(importlib_string);
774 Py_INCREF(bootstrap_string);
775 }
776
777 if (frame == NULL || frame->f_code == NULL ||
778 frame->f_code->co_filename == NULL) {
779 return 0;
780 }
781 filename = frame->f_code->co_filename;
782 if (!PyUnicode_Check(filename)) {
783 return 0;
784 }
785 contains = PyUnicode_Contains(filename, importlib_string);
786 if (contains < 0) {
787 return 0;
788 }
789 else if (contains > 0) {
790 contains = PyUnicode_Contains(filename, bootstrap_string);
791 if (contains < 0) {
792 return 0;
793 }
794 else if (contains > 0) {
795 return 1;
796 }
797 }
798
799 return 0;
800}
801
802static PyFrameObject *
803next_external_frame(PyFrameObject *frame)
804{
805 do {
806 frame = frame->f_back;
807 } while (frame != NULL && is_internal_frame(frame));
808
809 return frame;
810}
811
Christian Heimes33fe8092008-04-13 13:53:33 +0000812/* filename, module, and registry are new refs, globals is borrowed */
813/* Returns 0 on error (no new refs), 1 on success */
814static int
815setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
816 PyObject **module, PyObject **registry)
817{
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200818 _Py_IDENTIFIER(__warningregistry__);
819 _Py_IDENTIFIER(__name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000820 PyObject *globals;
821
Thomas Kluyver11a89662018-06-08 21:28:37 +0200822 /* Setup globals, filename and lineno. */
Victor Stinner50b48572018-11-01 01:51:40 +0100823 PyFrameObject *f = _PyThreadState_GET()->frame;
Larry Hastings714e4932015-09-06 00:39:37 -0700824 // Stack level comparisons to Python code is off by one as there is no
825 // warnings-related stack level to avoid.
826 if (stack_level <= 0 || is_internal_frame(f)) {
827 while (--stack_level > 0 && f != NULL) {
828 f = f->f_back;
829 }
830 }
831 else {
832 while (--stack_level > 0 && f != NULL) {
833 f = next_external_frame(f);
834 }
835 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000836
837 if (f == NULL) {
Victor Stinnercaba55b2018-08-03 15:33:52 +0200838 globals = _PyInterpreterState_GET_UNSAFE()->sysdict;
Thomas Kluyver11a89662018-06-08 21:28:37 +0200839 *filename = PyUnicode_FromString("sys");
Christian Heimes33fe8092008-04-13 13:53:33 +0000840 *lineno = 1;
841 }
842 else {
843 globals = f->f_globals;
Thomas Kluyver11a89662018-06-08 21:28:37 +0200844 *filename = f->f_code->co_filename;
845 Py_INCREF(*filename);
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000846 *lineno = PyFrame_GetLineNumber(f);
Christian Heimes33fe8092008-04-13 13:53:33 +0000847 }
848
849 *module = NULL;
850
851 /* Setup registry. */
852 assert(globals != NULL);
853 assert(PyDict_Check(globals));
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200854 *registry = _PyDict_GetItemIdWithError(globals, &PyId___warningregistry__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000855 if (*registry == NULL) {
856 int rc;
857
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200858 if (PyErr_Occurred()) {
Pablo Galindo394dc0d2020-03-03 01:13:10 +0000859 goto handle_error;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200860 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000861 *registry = PyDict_New();
862 if (*registry == NULL)
Pablo Galindo394dc0d2020-03-03 01:13:10 +0000863 goto handle_error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000864
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200865 rc = _PyDict_SetItemId(globals, &PyId___warningregistry__, *registry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000866 if (rc < 0)
867 goto handle_error;
868 }
869 else
870 Py_INCREF(*registry);
871
872 /* Setup module. */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200873 *module = _PyDict_GetItemIdWithError(globals, &PyId___name__);
Oren Milman5d3e8002017-09-24 21:28:42 +0300874 if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) {
875 Py_INCREF(*module);
876 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200877 else if (PyErr_Occurred()) {
878 goto handle_error;
879 }
Oren Milman5d3e8002017-09-24 21:28:42 +0300880 else {
Christian Heimes33fe8092008-04-13 13:53:33 +0000881 *module = PyUnicode_FromString("<string>");
882 if (*module == NULL)
883 goto handle_error;
884 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000885
Christian Heimes33fe8092008-04-13 13:53:33 +0000886 return 1;
887
888 handle_error:
Christian Heimes33fe8092008-04-13 13:53:33 +0000889 Py_XDECREF(*registry);
890 Py_XDECREF(*module);
Miss Islington (bot)57fb2922020-03-03 10:01:09 -0800891 Py_DECREF(*filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000892 return 0;
893}
894
895static PyObject *
896get_category(PyObject *message, PyObject *category)
897{
898 int rc;
899
900 /* Get category. */
901 rc = PyObject_IsInstance(message, PyExc_Warning);
902 if (rc == -1)
903 return NULL;
904
905 if (rc == 1)
906 category = (PyObject*)message->ob_type;
Berker Peksagd8089e02014-07-11 19:50:25 +0300907 else if (category == NULL || category == Py_None)
Christian Heimes33fe8092008-04-13 13:53:33 +0000908 category = PyExc_UserWarning;
909
910 /* Validate category. */
911 rc = PyObject_IsSubclass(category, PyExc_Warning);
Berker Peksagd8089e02014-07-11 19:50:25 +0300912 /* category is not a subclass of PyExc_Warning or
913 PyObject_IsSubclass raised an error */
914 if (rc == -1 || rc == 0) {
915 PyErr_Format(PyExc_TypeError,
916 "category must be a Warning subclass, not '%s'",
917 Py_TYPE(category)->tp_name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000918 return NULL;
919 }
920
921 return category;
922}
923
924static PyObject *
Victor Stinner914cde82016-03-19 01:03:51 +0100925do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
926 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000927{
928 PyObject *filename, *module, *registry, *res;
929 int lineno;
930
931 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
932 return NULL;
933
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100934 res = warn_explicit(category, message, filename, lineno, module, registry,
Victor Stinner914cde82016-03-19 01:03:51 +0100935 NULL, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000936 Py_DECREF(filename);
937 Py_DECREF(registry);
938 Py_DECREF(module);
939 return res;
940}
941
Victor Stinner22f18752016-12-09 18:08:18 +0100942/*[clinic input]
943warn as warnings_warn
944
945 message: object
946 category: object = None
947 stacklevel: Py_ssize_t = 1
948 source: object = None
949
950Issue a warning, or maybe ignore it or raise an exception.
951[clinic start generated code]*/
952
Christian Heimes33fe8092008-04-13 13:53:33 +0000953static PyObject *
Victor Stinner22f18752016-12-09 18:08:18 +0100954warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
955 Py_ssize_t stacklevel, PyObject *source)
956/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
Christian Heimes33fe8092008-04-13 13:53:33 +0000957{
Christian Heimes33fe8092008-04-13 13:53:33 +0000958 category = get_category(message, category);
959 if (category == NULL)
960 return NULL;
Victor Stinner22f18752016-12-09 18:08:18 +0100961 return do_warn(message, category, stacklevel, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000962}
963
964static PyObject *
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200965get_source_line(PyObject *module_globals, int lineno)
966{
967 _Py_IDENTIFIER(get_source);
968 _Py_IDENTIFIER(__loader__);
969 _Py_IDENTIFIER(__name__);
970 PyObject *loader;
971 PyObject *module_name;
972 PyObject *get_source;
973 PyObject *source;
974 PyObject *source_list;
975 PyObject *source_line;
976
977 /* Check/get the requisite pieces needed for the loader. */
978 loader = _PyDict_GetItemIdWithError(module_globals, &PyId___loader__);
979 if (loader == NULL) {
980 return NULL;
981 }
982 Py_INCREF(loader);
983 module_name = _PyDict_GetItemIdWithError(module_globals, &PyId___name__);
984 if (!module_name) {
985 Py_DECREF(loader);
986 return NULL;
987 }
988 Py_INCREF(module_name);
989
990 /* Make sure the loader implements the optional get_source() method. */
Serhiy Storchakaf320be72018-01-25 10:49:40 +0200991 (void)_PyObject_LookupAttrId(loader, &PyId_get_source, &get_source);
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200992 Py_DECREF(loader);
993 if (!get_source) {
994 Py_DECREF(module_name);
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200995 return NULL;
996 }
997 /* Call get_source() to get the source code. */
998 source = PyObject_CallFunctionObjArgs(get_source, module_name, NULL);
999 Py_DECREF(get_source);
1000 Py_DECREF(module_name);
1001 if (!source) {
1002 return NULL;
1003 }
1004 if (source == Py_None) {
1005 Py_DECREF(source);
1006 return NULL;
1007 }
1008
1009 /* Split the source into lines. */
1010 source_list = PyUnicode_Splitlines(source, 0);
1011 Py_DECREF(source);
1012 if (!source_list) {
1013 return NULL;
1014 }
1015
1016 /* Get the source line. */
1017 source_line = PyList_GetItem(source_list, lineno-1);
1018 Py_XINCREF(source_line);
1019 Py_DECREF(source_list);
1020 return source_line;
1021}
1022
1023static PyObject *
Christian Heimes33fe8092008-04-13 13:53:33 +00001024warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
1025{
1026 static char *kwd_list[] = {"message", "category", "filename", "lineno",
Victor Stinner914cde82016-03-19 01:03:51 +01001027 "module", "registry", "module_globals",
1028 "source", 0};
Christian Heimes33fe8092008-04-13 13:53:33 +00001029 PyObject *message;
1030 PyObject *category;
1031 PyObject *filename;
1032 int lineno;
1033 PyObject *module = NULL;
1034 PyObject *registry = NULL;
1035 PyObject *module_globals = NULL;
Victor Stinner914cde82016-03-19 01:03:51 +01001036 PyObject *sourceobj = NULL;
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001037 PyObject *source_line = NULL;
1038 PyObject *returned;
Christian Heimes33fe8092008-04-13 13:53:33 +00001039
Victor Stinner914cde82016-03-19 01:03:51 +01001040 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
Christian Heimes33fe8092008-04-13 13:53:33 +00001041 kwd_list, &message, &category, &filename, &lineno, &module,
Victor Stinner914cde82016-03-19 01:03:51 +01001042 &registry, &module_globals, &sourceobj))
Christian Heimes33fe8092008-04-13 13:53:33 +00001043 return NULL;
1044
Victor Stinnerb0565622018-05-15 20:42:12 +02001045 if (module_globals && module_globals != Py_None) {
1046 if (!PyDict_Check(module_globals)) {
1047 PyErr_Format(PyExc_TypeError,
1048 "module_globals must be a dict, not '%.200s'",
1049 Py_TYPE(module_globals)->tp_name);
1050 return NULL;
1051 }
1052
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001053 source_line = get_source_line(module_globals, lineno);
1054 if (source_line == NULL && PyErr_Occurred()) {
Christian Heimes33fe8092008-04-13 13:53:33 +00001055 return NULL;
1056 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001057 }
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001058 returned = warn_explicit(category, message, filename, lineno, module,
1059 registry, source_line, sourceobj);
1060 Py_XDECREF(source_line);
1061 return returned;
Christian Heimes33fe8092008-04-13 13:53:33 +00001062}
1063
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001064static PyObject *
1065warnings_filters_mutated(PyObject *self, PyObject *args)
1066{
Eric Snow86ea5812019-05-10 13:29:55 -04001067 WarningsState *st = _Warnings_GetState();
1068 if (st == NULL) {
1069 return NULL;
1070 }
1071 st->filters_version++;
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001072 Py_RETURN_NONE;
1073}
1074
Christian Heimes33fe8092008-04-13 13:53:33 +00001075
1076/* Function to issue a warning message; may raise an exception. */
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001077
1078static int
1079warn_unicode(PyObject *category, PyObject *message,
Victor Stinner914cde82016-03-19 01:03:51 +01001080 Py_ssize_t stack_level, PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +00001081{
1082 PyObject *res;
Christian Heimes33fe8092008-04-13 13:53:33 +00001083
1084 if (category == NULL)
1085 category = PyExc_RuntimeWarning;
1086
Victor Stinner914cde82016-03-19 01:03:51 +01001087 res = do_warn(message, category, stack_level, source);
Christian Heimes33fe8092008-04-13 13:53:33 +00001088 if (res == NULL)
1089 return -1;
1090 Py_DECREF(res);
1091
1092 return 0;
1093}
1094
Victor Stinner914cde82016-03-19 01:03:51 +01001095static int
1096_PyErr_WarnFormatV(PyObject *source,
1097 PyObject *category, Py_ssize_t stack_level,
1098 const char *format, va_list vargs)
1099{
1100 PyObject *message;
1101 int res;
1102
1103 message = PyUnicode_FromFormatV(format, vargs);
1104 if (message == NULL)
1105 return -1;
1106
1107 res = warn_unicode(category, message, stack_level, source);
1108 Py_DECREF(message);
1109 return res;
1110}
1111
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001112int
1113PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
1114 const char *format, ...)
1115{
Victor Stinner914cde82016-03-19 01:03:51 +01001116 int res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001117 va_list vargs;
1118
1119#ifdef HAVE_STDARG_PROTOTYPES
1120 va_start(vargs, format);
1121#else
1122 va_start(vargs);
1123#endif
Victor Stinner914cde82016-03-19 01:03:51 +01001124 res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001125 va_end(vargs);
Victor Stinner914cde82016-03-19 01:03:51 +01001126 return res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001127}
1128
1129int
Victor Stinner914cde82016-03-19 01:03:51 +01001130PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
1131 const char *format, ...)
1132{
1133 int res;
1134 va_list vargs;
1135
1136#ifdef HAVE_STDARG_PROTOTYPES
1137 va_start(vargs, format);
1138#else
1139 va_start(vargs);
1140#endif
1141 res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
1142 stack_level, format, vargs);
1143 va_end(vargs);
1144 return res;
1145}
1146
1147
1148int
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001149PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
1150{
1151 int ret;
1152 PyObject *message = PyUnicode_FromString(text);
1153 if (message == NULL)
1154 return -1;
Victor Stinner914cde82016-03-19 01:03:51 +01001155 ret = warn_unicode(category, message, stack_level, NULL);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001156 Py_DECREF(message);
1157 return ret;
1158}
1159
Ezio Melotti42da6632011-03-15 05:18:48 +02001160/* PyErr_Warn is only for backwards compatibility and will be removed.
Christian Heimes33fe8092008-04-13 13:53:33 +00001161 Use PyErr_WarnEx instead. */
1162
1163#undef PyErr_Warn
1164
Benjamin Petersone5024512018-09-12 12:06:42 -07001165int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001166PyErr_Warn(PyObject *category, const char *text)
Christian Heimes33fe8092008-04-13 13:53:33 +00001167{
1168 return PyErr_WarnEx(category, text, 1);
1169}
1170
1171/* Warning with explicit origin */
1172int
Victor Stinner14e461d2013-08-26 22:28:21 +02001173PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1174 PyObject *filename, int lineno,
1175 PyObject *module, PyObject *registry)
1176{
1177 PyObject *res;
1178 if (category == NULL)
1179 category = PyExc_RuntimeWarning;
1180 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001181 module, registry, NULL, NULL);
Victor Stinner14e461d2013-08-26 22:28:21 +02001182 if (res == NULL)
1183 return -1;
1184 Py_DECREF(res);
1185 return 0;
1186}
1187
1188int
Christian Heimes33fe8092008-04-13 13:53:33 +00001189PyErr_WarnExplicit(PyObject *category, const char *text,
1190 const char *filename_str, int lineno,
1191 const char *module_str, PyObject *registry)
1192{
Christian Heimes33fe8092008-04-13 13:53:33 +00001193 PyObject *message = PyUnicode_FromString(text);
Victor Stinnercb428f02010-12-27 20:10:36 +00001194 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
Christian Heimes33fe8092008-04-13 13:53:33 +00001195 PyObject *module = NULL;
1196 int ret = -1;
1197
1198 if (message == NULL || filename == NULL)
1199 goto exit;
1200 if (module_str != NULL) {
1201 module = PyUnicode_FromString(module_str);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001202 if (module == NULL)
1203 goto exit;
Christian Heimes33fe8092008-04-13 13:53:33 +00001204 }
1205
Victor Stinner14e461d2013-08-26 22:28:21 +02001206 ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1207 module, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +00001208
1209 exit:
1210 Py_XDECREF(message);
1211 Py_XDECREF(module);
1212 Py_XDECREF(filename);
1213 return ret;
1214}
1215
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001216int
1217PyErr_WarnExplicitFormat(PyObject *category,
1218 const char *filename_str, int lineno,
1219 const char *module_str, PyObject *registry,
1220 const char *format, ...)
1221{
1222 PyObject *message;
1223 PyObject *module = NULL;
1224 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1225 int ret = -1;
1226 va_list vargs;
1227
1228 if (filename == NULL)
1229 goto exit;
1230 if (module_str != NULL) {
1231 module = PyUnicode_FromString(module_str);
1232 if (module == NULL)
1233 goto exit;
1234 }
1235
1236#ifdef HAVE_STDARG_PROTOTYPES
1237 va_start(vargs, format);
1238#else
1239 va_start(vargs);
1240#endif
1241 message = PyUnicode_FromFormatV(format, vargs);
1242 if (message != NULL) {
1243 PyObject *res;
1244 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001245 module, registry, NULL, NULL);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001246 Py_DECREF(message);
1247 if (res != NULL) {
1248 Py_DECREF(res);
1249 ret = 0;
1250 }
1251 }
1252 va_end(vargs);
1253exit:
1254 Py_XDECREF(module);
1255 Py_XDECREF(filename);
1256 return ret;
1257}
1258
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001259void
1260_PyErr_WarnUnawaitedCoroutine(PyObject *coro)
1261{
1262 /* First, we attempt to funnel the warning through
1263 warnings._warn_unawaited_coroutine.
1264
1265 This could raise an exception, due to:
1266 - a bug
1267 - some kind of shutdown-related brokenness
1268 - succeeding, but with an "error" warning filter installed, so the
1269 warning is converted into a RuntimeWarning exception
1270
1271 In the first two cases, we want to print the error (so we know what it
1272 is!), and then print a warning directly as a fallback. In the last
1273 case, we want to print the error (since it's the warning!), but *not*
1274 do a fallback. And after we print the error we can't check for what
1275 type of error it was (because PyErr_WriteUnraisable clears it), so we
1276 need a flag to keep track.
1277
1278 Since this is called from __del__ context, it's careful to never raise
1279 an exception.
1280 */
1281 _Py_IDENTIFIER(_warn_unawaited_coroutine);
1282 int warned = 0;
1283 PyObject *fn = get_warnings_attr(&PyId__warn_unawaited_coroutine, 1);
1284 if (fn) {
1285 PyObject *res = PyObject_CallFunctionObjArgs(fn, coro, NULL);
1286 Py_DECREF(fn);
1287 if (res || PyErr_ExceptionMatches(PyExc_RuntimeWarning)) {
1288 warned = 1;
1289 }
1290 Py_XDECREF(res);
1291 }
1292
1293 if (PyErr_Occurred()) {
1294 PyErr_WriteUnraisable(coro);
1295 }
1296 if (!warned) {
Yury Selivanov35103342018-01-21 20:47:04 -05001297 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
1298 "coroutine '%.50S' was never awaited",
1299 ((PyCoroObject *)coro)->cr_qualname) < 0)
1300 {
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001301 PyErr_WriteUnraisable(coro);
1302 }
1303 }
1304}
Christian Heimes33fe8092008-04-13 13:53:33 +00001305
Christian Heimes33fe8092008-04-13 13:53:33 +00001306PyDoc_STRVAR(warn_explicit_doc,
Miss Islington (bot)aa9d5b82019-10-08 02:16:06 -07001307"Low-level interface to warnings functionality.");
Christian Heimes33fe8092008-04-13 13:53:33 +00001308
1309static PyMethodDef warnings_functions[] = {
Victor Stinner22f18752016-12-09 18:08:18 +01001310 WARNINGS_WARN_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001311 {"warn_explicit", (PyCFunction)(void(*)(void))warnings_warn_explicit,
Christian Heimes33fe8092008-04-13 13:53:33 +00001312 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001313 {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
1314 NULL},
Christian Heimes1a8501c2008-10-02 19:56:01 +00001315 /* XXX(brett.cannon): add showwarning? */
1316 /* XXX(brett.cannon): Reasonable to add formatwarning? */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 {NULL, NULL} /* sentinel */
Christian Heimes33fe8092008-04-13 13:53:33 +00001318};
1319
1320
Martin v. Löwis1a214512008-06-11 05:26:20 +00001321static struct PyModuleDef warningsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 PyModuleDef_HEAD_INIT,
Eric Snow86ea5812019-05-10 13:29:55 -04001323 MODULE_NAME, /* m_name */
1324 warnings__doc__, /* m_doc */
1325 0, /* m_size */
1326 warnings_functions, /* m_methods */
1327 NULL, /* m_reload */
1328 NULL, /* m_traverse */
1329 NULL, /* m_clear */
1330 NULL /* m_free */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001331};
1332
Christian Heimes33fe8092008-04-13 13:53:33 +00001333
Victor Stinner5d862462017-12-19 11:35:58 +01001334PyMODINIT_FUNC
1335_PyWarnings_Init(void)
Christian Heimes33fe8092008-04-13 13:53:33 +00001336{
Brett Cannon0759dd62009-04-01 18:13:07 +00001337 PyObject *m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001338
Martin v. Löwis1a214512008-06-11 05:26:20 +00001339 m = PyModule_Create(&warningsmodule);
Eric Snow86ea5812019-05-10 13:29:55 -04001340 if (m == NULL) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00001341 return NULL;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001342 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001343
Eric Snow86ea5812019-05-10 13:29:55 -04001344 WarningsState *st = _Warnings_GetState();
1345 if (st == NULL) {
1346 goto error;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001347 }
Eric Snow86ea5812019-05-10 13:29:55 -04001348 if (_Warnings_InitState(st) < 0) {
1349 goto error;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001350 }
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001351
Eric Snow86ea5812019-05-10 13:29:55 -04001352 Py_INCREF(st->filters);
1353 if (PyModule_AddObject(m, "filters", st->filters) < 0) {
1354 goto error;
1355 }
1356
1357 Py_INCREF(st->once_registry);
1358 if (PyModule_AddObject(m, "_onceregistry", st->once_registry) < 0) {
1359 goto error;
1360 }
1361
1362 Py_INCREF(st->default_action);
1363 if (PyModule_AddObject(m, "_defaultaction", st->default_action) < 0) {
1364 goto error;
1365 }
1366
Martin v. Löwis1a214512008-06-11 05:26:20 +00001367 return m;
Eric Snow86ea5812019-05-10 13:29:55 -04001368
1369error:
1370 if (st != NULL) {
1371 _Warnings_ClearState(st);
1372 }
1373 Py_DECREF(m);
1374 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001375}
Victor Stinner87d23a02019-04-26 05:49:26 +02001376
Eric Snow86ea5812019-05-10 13:29:55 -04001377// We need this to ensure that warnings still work until late in finalization.
Victor Stinner87d23a02019-04-26 05:49:26 +02001378void
Eric Snow86ea5812019-05-10 13:29:55 -04001379_PyWarnings_Fini(PyInterpreterState *interp)
Victor Stinner87d23a02019-04-26 05:49:26 +02001380{
Eric Snow86ea5812019-05-10 13:29:55 -04001381 _Warnings_ClearState(&interp->warnings);
Victor Stinner87d23a02019-04-26 05:49:26 +02001382}