blob: 87269dd4dbc9eef4ae9350ef12af2bf0f28d20c4 [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:
889 /* filename not XDECREF'ed here as there is no way to jump here with a
890 dangling reference. */
891 Py_XDECREF(*registry);
892 Py_XDECREF(*module);
Pablo Galindo394dc0d2020-03-03 01:13:10 +0000893 Py_XDECREF(*filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000894 return 0;
895}
896
897static PyObject *
898get_category(PyObject *message, PyObject *category)
899{
900 int rc;
901
902 /* Get category. */
903 rc = PyObject_IsInstance(message, PyExc_Warning);
904 if (rc == -1)
905 return NULL;
906
907 if (rc == 1)
908 category = (PyObject*)message->ob_type;
Berker Peksagd8089e02014-07-11 19:50:25 +0300909 else if (category == NULL || category == Py_None)
Christian Heimes33fe8092008-04-13 13:53:33 +0000910 category = PyExc_UserWarning;
911
912 /* Validate category. */
913 rc = PyObject_IsSubclass(category, PyExc_Warning);
Berker Peksagd8089e02014-07-11 19:50:25 +0300914 /* category is not a subclass of PyExc_Warning or
915 PyObject_IsSubclass raised an error */
916 if (rc == -1 || rc == 0) {
917 PyErr_Format(PyExc_TypeError,
918 "category must be a Warning subclass, not '%s'",
919 Py_TYPE(category)->tp_name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000920 return NULL;
921 }
922
923 return category;
924}
925
926static PyObject *
Victor Stinner914cde82016-03-19 01:03:51 +0100927do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
928 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000929{
930 PyObject *filename, *module, *registry, *res;
931 int lineno;
932
933 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
934 return NULL;
935
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100936 res = warn_explicit(category, message, filename, lineno, module, registry,
Victor Stinner914cde82016-03-19 01:03:51 +0100937 NULL, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000938 Py_DECREF(filename);
939 Py_DECREF(registry);
940 Py_DECREF(module);
941 return res;
942}
943
Victor Stinner22f18752016-12-09 18:08:18 +0100944/*[clinic input]
945warn as warnings_warn
946
947 message: object
948 category: object = None
949 stacklevel: Py_ssize_t = 1
950 source: object = None
951
952Issue a warning, or maybe ignore it or raise an exception.
953[clinic start generated code]*/
954
Christian Heimes33fe8092008-04-13 13:53:33 +0000955static PyObject *
Victor Stinner22f18752016-12-09 18:08:18 +0100956warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
957 Py_ssize_t stacklevel, PyObject *source)
958/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
Christian Heimes33fe8092008-04-13 13:53:33 +0000959{
Christian Heimes33fe8092008-04-13 13:53:33 +0000960 category = get_category(message, category);
961 if (category == NULL)
962 return NULL;
Victor Stinner22f18752016-12-09 18:08:18 +0100963 return do_warn(message, category, stacklevel, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000964}
965
966static PyObject *
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200967get_source_line(PyObject *module_globals, int lineno)
968{
969 _Py_IDENTIFIER(get_source);
970 _Py_IDENTIFIER(__loader__);
971 _Py_IDENTIFIER(__name__);
972 PyObject *loader;
973 PyObject *module_name;
974 PyObject *get_source;
975 PyObject *source;
976 PyObject *source_list;
977 PyObject *source_line;
978
979 /* Check/get the requisite pieces needed for the loader. */
980 loader = _PyDict_GetItemIdWithError(module_globals, &PyId___loader__);
981 if (loader == NULL) {
982 return NULL;
983 }
984 Py_INCREF(loader);
985 module_name = _PyDict_GetItemIdWithError(module_globals, &PyId___name__);
986 if (!module_name) {
987 Py_DECREF(loader);
988 return NULL;
989 }
990 Py_INCREF(module_name);
991
992 /* Make sure the loader implements the optional get_source() method. */
Serhiy Storchakaf320be72018-01-25 10:49:40 +0200993 (void)_PyObject_LookupAttrId(loader, &PyId_get_source, &get_source);
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200994 Py_DECREF(loader);
995 if (!get_source) {
996 Py_DECREF(module_name);
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200997 return NULL;
998 }
999 /* Call get_source() to get the source code. */
1000 source = PyObject_CallFunctionObjArgs(get_source, module_name, NULL);
1001 Py_DECREF(get_source);
1002 Py_DECREF(module_name);
1003 if (!source) {
1004 return NULL;
1005 }
1006 if (source == Py_None) {
1007 Py_DECREF(source);
1008 return NULL;
1009 }
1010
1011 /* Split the source into lines. */
1012 source_list = PyUnicode_Splitlines(source, 0);
1013 Py_DECREF(source);
1014 if (!source_list) {
1015 return NULL;
1016 }
1017
1018 /* Get the source line. */
1019 source_line = PyList_GetItem(source_list, lineno-1);
1020 Py_XINCREF(source_line);
1021 Py_DECREF(source_list);
1022 return source_line;
1023}
1024
1025static PyObject *
Christian Heimes33fe8092008-04-13 13:53:33 +00001026warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
1027{
1028 static char *kwd_list[] = {"message", "category", "filename", "lineno",
Victor Stinner914cde82016-03-19 01:03:51 +01001029 "module", "registry", "module_globals",
1030 "source", 0};
Christian Heimes33fe8092008-04-13 13:53:33 +00001031 PyObject *message;
1032 PyObject *category;
1033 PyObject *filename;
1034 int lineno;
1035 PyObject *module = NULL;
1036 PyObject *registry = NULL;
1037 PyObject *module_globals = NULL;
Victor Stinner914cde82016-03-19 01:03:51 +01001038 PyObject *sourceobj = NULL;
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001039 PyObject *source_line = NULL;
1040 PyObject *returned;
Christian Heimes33fe8092008-04-13 13:53:33 +00001041
Victor Stinner914cde82016-03-19 01:03:51 +01001042 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
Christian Heimes33fe8092008-04-13 13:53:33 +00001043 kwd_list, &message, &category, &filename, &lineno, &module,
Victor Stinner914cde82016-03-19 01:03:51 +01001044 &registry, &module_globals, &sourceobj))
Christian Heimes33fe8092008-04-13 13:53:33 +00001045 return NULL;
1046
Victor Stinnerb0565622018-05-15 20:42:12 +02001047 if (module_globals && module_globals != Py_None) {
1048 if (!PyDict_Check(module_globals)) {
1049 PyErr_Format(PyExc_TypeError,
1050 "module_globals must be a dict, not '%.200s'",
1051 Py_TYPE(module_globals)->tp_name);
1052 return NULL;
1053 }
1054
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001055 source_line = get_source_line(module_globals, lineno);
1056 if (source_line == NULL && PyErr_Occurred()) {
Christian Heimes33fe8092008-04-13 13:53:33 +00001057 return NULL;
1058 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001059 }
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001060 returned = warn_explicit(category, message, filename, lineno, module,
1061 registry, source_line, sourceobj);
1062 Py_XDECREF(source_line);
1063 return returned;
Christian Heimes33fe8092008-04-13 13:53:33 +00001064}
1065
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001066static PyObject *
1067warnings_filters_mutated(PyObject *self, PyObject *args)
1068{
Eric Snow86ea5812019-05-10 13:29:55 -04001069 WarningsState *st = _Warnings_GetState();
1070 if (st == NULL) {
1071 return NULL;
1072 }
1073 st->filters_version++;
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001074 Py_RETURN_NONE;
1075}
1076
Christian Heimes33fe8092008-04-13 13:53:33 +00001077
1078/* Function to issue a warning message; may raise an exception. */
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001079
1080static int
1081warn_unicode(PyObject *category, PyObject *message,
Victor Stinner914cde82016-03-19 01:03:51 +01001082 Py_ssize_t stack_level, PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +00001083{
1084 PyObject *res;
Christian Heimes33fe8092008-04-13 13:53:33 +00001085
1086 if (category == NULL)
1087 category = PyExc_RuntimeWarning;
1088
Victor Stinner914cde82016-03-19 01:03:51 +01001089 res = do_warn(message, category, stack_level, source);
Christian Heimes33fe8092008-04-13 13:53:33 +00001090 if (res == NULL)
1091 return -1;
1092 Py_DECREF(res);
1093
1094 return 0;
1095}
1096
Victor Stinner914cde82016-03-19 01:03:51 +01001097static int
1098_PyErr_WarnFormatV(PyObject *source,
1099 PyObject *category, Py_ssize_t stack_level,
1100 const char *format, va_list vargs)
1101{
1102 PyObject *message;
1103 int res;
1104
1105 message = PyUnicode_FromFormatV(format, vargs);
1106 if (message == NULL)
1107 return -1;
1108
1109 res = warn_unicode(category, message, stack_level, source);
1110 Py_DECREF(message);
1111 return res;
1112}
1113
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001114int
1115PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
1116 const char *format, ...)
1117{
Victor Stinner914cde82016-03-19 01:03:51 +01001118 int res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001119 va_list vargs;
1120
1121#ifdef HAVE_STDARG_PROTOTYPES
1122 va_start(vargs, format);
1123#else
1124 va_start(vargs);
1125#endif
Victor Stinner914cde82016-03-19 01:03:51 +01001126 res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001127 va_end(vargs);
Victor Stinner914cde82016-03-19 01:03:51 +01001128 return res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001129}
1130
1131int
Victor Stinner914cde82016-03-19 01:03:51 +01001132PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
1133 const char *format, ...)
1134{
1135 int res;
1136 va_list vargs;
1137
1138#ifdef HAVE_STDARG_PROTOTYPES
1139 va_start(vargs, format);
1140#else
1141 va_start(vargs);
1142#endif
1143 res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
1144 stack_level, format, vargs);
1145 va_end(vargs);
1146 return res;
1147}
1148
1149
1150int
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001151PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
1152{
1153 int ret;
1154 PyObject *message = PyUnicode_FromString(text);
1155 if (message == NULL)
1156 return -1;
Victor Stinner914cde82016-03-19 01:03:51 +01001157 ret = warn_unicode(category, message, stack_level, NULL);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001158 Py_DECREF(message);
1159 return ret;
1160}
1161
Ezio Melotti42da6632011-03-15 05:18:48 +02001162/* PyErr_Warn is only for backwards compatibility and will be removed.
Christian Heimes33fe8092008-04-13 13:53:33 +00001163 Use PyErr_WarnEx instead. */
1164
1165#undef PyErr_Warn
1166
Benjamin Petersone5024512018-09-12 12:06:42 -07001167int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001168PyErr_Warn(PyObject *category, const char *text)
Christian Heimes33fe8092008-04-13 13:53:33 +00001169{
1170 return PyErr_WarnEx(category, text, 1);
1171}
1172
1173/* Warning with explicit origin */
1174int
Victor Stinner14e461d2013-08-26 22:28:21 +02001175PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1176 PyObject *filename, int lineno,
1177 PyObject *module, PyObject *registry)
1178{
1179 PyObject *res;
1180 if (category == NULL)
1181 category = PyExc_RuntimeWarning;
1182 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001183 module, registry, NULL, NULL);
Victor Stinner14e461d2013-08-26 22:28:21 +02001184 if (res == NULL)
1185 return -1;
1186 Py_DECREF(res);
1187 return 0;
1188}
1189
1190int
Christian Heimes33fe8092008-04-13 13:53:33 +00001191PyErr_WarnExplicit(PyObject *category, const char *text,
1192 const char *filename_str, int lineno,
1193 const char *module_str, PyObject *registry)
1194{
Christian Heimes33fe8092008-04-13 13:53:33 +00001195 PyObject *message = PyUnicode_FromString(text);
Victor Stinnercb428f02010-12-27 20:10:36 +00001196 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
Christian Heimes33fe8092008-04-13 13:53:33 +00001197 PyObject *module = NULL;
1198 int ret = -1;
1199
1200 if (message == NULL || filename == NULL)
1201 goto exit;
1202 if (module_str != NULL) {
1203 module = PyUnicode_FromString(module_str);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001204 if (module == NULL)
1205 goto exit;
Christian Heimes33fe8092008-04-13 13:53:33 +00001206 }
1207
Victor Stinner14e461d2013-08-26 22:28:21 +02001208 ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1209 module, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +00001210
1211 exit:
1212 Py_XDECREF(message);
1213 Py_XDECREF(module);
1214 Py_XDECREF(filename);
1215 return ret;
1216}
1217
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001218int
1219PyErr_WarnExplicitFormat(PyObject *category,
1220 const char *filename_str, int lineno,
1221 const char *module_str, PyObject *registry,
1222 const char *format, ...)
1223{
1224 PyObject *message;
1225 PyObject *module = NULL;
1226 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1227 int ret = -1;
1228 va_list vargs;
1229
1230 if (filename == NULL)
1231 goto exit;
1232 if (module_str != NULL) {
1233 module = PyUnicode_FromString(module_str);
1234 if (module == NULL)
1235 goto exit;
1236 }
1237
1238#ifdef HAVE_STDARG_PROTOTYPES
1239 va_start(vargs, format);
1240#else
1241 va_start(vargs);
1242#endif
1243 message = PyUnicode_FromFormatV(format, vargs);
1244 if (message != NULL) {
1245 PyObject *res;
1246 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001247 module, registry, NULL, NULL);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001248 Py_DECREF(message);
1249 if (res != NULL) {
1250 Py_DECREF(res);
1251 ret = 0;
1252 }
1253 }
1254 va_end(vargs);
1255exit:
1256 Py_XDECREF(module);
1257 Py_XDECREF(filename);
1258 return ret;
1259}
1260
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001261void
1262_PyErr_WarnUnawaitedCoroutine(PyObject *coro)
1263{
1264 /* First, we attempt to funnel the warning through
1265 warnings._warn_unawaited_coroutine.
1266
1267 This could raise an exception, due to:
1268 - a bug
1269 - some kind of shutdown-related brokenness
1270 - succeeding, but with an "error" warning filter installed, so the
1271 warning is converted into a RuntimeWarning exception
1272
1273 In the first two cases, we want to print the error (so we know what it
1274 is!), and then print a warning directly as a fallback. In the last
1275 case, we want to print the error (since it's the warning!), but *not*
1276 do a fallback. And after we print the error we can't check for what
1277 type of error it was (because PyErr_WriteUnraisable clears it), so we
1278 need a flag to keep track.
1279
1280 Since this is called from __del__ context, it's careful to never raise
1281 an exception.
1282 */
1283 _Py_IDENTIFIER(_warn_unawaited_coroutine);
1284 int warned = 0;
1285 PyObject *fn = get_warnings_attr(&PyId__warn_unawaited_coroutine, 1);
1286 if (fn) {
1287 PyObject *res = PyObject_CallFunctionObjArgs(fn, coro, NULL);
1288 Py_DECREF(fn);
1289 if (res || PyErr_ExceptionMatches(PyExc_RuntimeWarning)) {
1290 warned = 1;
1291 }
1292 Py_XDECREF(res);
1293 }
1294
1295 if (PyErr_Occurred()) {
1296 PyErr_WriteUnraisable(coro);
1297 }
1298 if (!warned) {
Yury Selivanov35103342018-01-21 20:47:04 -05001299 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
1300 "coroutine '%.50S' was never awaited",
1301 ((PyCoroObject *)coro)->cr_qualname) < 0)
1302 {
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001303 PyErr_WriteUnraisable(coro);
1304 }
1305 }
1306}
Christian Heimes33fe8092008-04-13 13:53:33 +00001307
Christian Heimes33fe8092008-04-13 13:53:33 +00001308PyDoc_STRVAR(warn_explicit_doc,
Miss Islington (bot)aa9d5b82019-10-08 02:16:06 -07001309"Low-level interface to warnings functionality.");
Christian Heimes33fe8092008-04-13 13:53:33 +00001310
1311static PyMethodDef warnings_functions[] = {
Victor Stinner22f18752016-12-09 18:08:18 +01001312 WARNINGS_WARN_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001313 {"warn_explicit", (PyCFunction)(void(*)(void))warnings_warn_explicit,
Christian Heimes33fe8092008-04-13 13:53:33 +00001314 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001315 {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
1316 NULL},
Christian Heimes1a8501c2008-10-02 19:56:01 +00001317 /* XXX(brett.cannon): add showwarning? */
1318 /* XXX(brett.cannon): Reasonable to add formatwarning? */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 {NULL, NULL} /* sentinel */
Christian Heimes33fe8092008-04-13 13:53:33 +00001320};
1321
1322
Martin v. Löwis1a214512008-06-11 05:26:20 +00001323static struct PyModuleDef warningsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 PyModuleDef_HEAD_INIT,
Eric Snow86ea5812019-05-10 13:29:55 -04001325 MODULE_NAME, /* m_name */
1326 warnings__doc__, /* m_doc */
1327 0, /* m_size */
1328 warnings_functions, /* m_methods */
1329 NULL, /* m_reload */
1330 NULL, /* m_traverse */
1331 NULL, /* m_clear */
1332 NULL /* m_free */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001333};
1334
Christian Heimes33fe8092008-04-13 13:53:33 +00001335
Victor Stinner5d862462017-12-19 11:35:58 +01001336PyMODINIT_FUNC
1337_PyWarnings_Init(void)
Christian Heimes33fe8092008-04-13 13:53:33 +00001338{
Brett Cannon0759dd62009-04-01 18:13:07 +00001339 PyObject *m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001340
Martin v. Löwis1a214512008-06-11 05:26:20 +00001341 m = PyModule_Create(&warningsmodule);
Eric Snow86ea5812019-05-10 13:29:55 -04001342 if (m == NULL) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00001343 return NULL;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001344 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001345
Eric Snow86ea5812019-05-10 13:29:55 -04001346 WarningsState *st = _Warnings_GetState();
1347 if (st == NULL) {
1348 goto error;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001349 }
Eric Snow86ea5812019-05-10 13:29:55 -04001350 if (_Warnings_InitState(st) < 0) {
1351 goto error;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001352 }
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001353
Eric Snow86ea5812019-05-10 13:29:55 -04001354 Py_INCREF(st->filters);
1355 if (PyModule_AddObject(m, "filters", st->filters) < 0) {
1356 goto error;
1357 }
1358
1359 Py_INCREF(st->once_registry);
1360 if (PyModule_AddObject(m, "_onceregistry", st->once_registry) < 0) {
1361 goto error;
1362 }
1363
1364 Py_INCREF(st->default_action);
1365 if (PyModule_AddObject(m, "_defaultaction", st->default_action) < 0) {
1366 goto error;
1367 }
1368
Martin v. Löwis1a214512008-06-11 05:26:20 +00001369 return m;
Eric Snow86ea5812019-05-10 13:29:55 -04001370
1371error:
1372 if (st != NULL) {
1373 _Warnings_ClearState(st);
1374 }
1375 Py_DECREF(m);
1376 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001377}
Victor Stinner87d23a02019-04-26 05:49:26 +02001378
Eric Snow86ea5812019-05-10 13:29:55 -04001379// We need this to ensure that warnings still work until late in finalization.
Victor Stinner87d23a02019-04-26 05:49:26 +02001380void
Eric Snow86ea5812019-05-10 13:29:55 -04001381_PyWarnings_Fini(PyInterpreterState *interp)
Victor Stinner87d23a02019-04-26 05:49:26 +02001382{
Eric Snow86ea5812019-05-10 13:29:55 -04001383 _Warnings_ClearState(&interp->warnings);
Victor Stinner87d23a02019-04-26 05:49:26 +02001384}