blob: acef313fc9f2507426a29f3dfd9d653cb1f14f30 [file] [log] [blame]
Christian Heimes33fe8092008-04-13 13:53:33 +00001#include "Python.h"
Victor Stinner4d231bc2019-11-14 13:36:21 +01002#include "pycore_pyerrors.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01003#include "pycore_pystate.h"
Christian Heimes33fe8092008-04-13 13:53:33 +00004#include "frameobject.h"
Victor Stinner22f18752016-12-09 18:08:18 +01005#include "clinic/_warnings.c.h"
Christian Heimes33fe8092008-04-13 13:53:33 +00006
7#define MODULE_NAME "_warnings"
Christian Heimes33fe8092008-04-13 13:53:33 +00008
9PyDoc_STRVAR(warnings__doc__,
10MODULE_NAME " provides basic warning filtering support.\n"
11"It is a helper module to speed up interpreter start-up.");
12
Victor Stinnerbd303c12013-11-07 23:07:29 +010013_Py_IDENTIFIER(stderr);
Victor Stinner747f48e2017-12-12 22:59:48 +010014#ifndef Py_DEBUG
Nick Coghlan9b997472018-01-08 12:45:02 +100015_Py_IDENTIFIER(default);
Victor Stinnerb98f1712017-11-23 17:13:44 +010016_Py_IDENTIFIER(ignore);
Victor Stinner747f48e2017-12-12 22:59:48 +010017#endif
Christian Heimes33fe8092008-04-13 13:53:33 +000018
Eric Snow86ea5812019-05-10 13:29:55 -040019
20/*************************************************************************/
21
22typedef struct _warnings_runtime_state WarningsState;
23
24/* Forward declaration of the _warnings module definition. */
25static struct PyModuleDef warningsmodule;
26
Hai Shi46874c22020-01-30 17:20:25 -060027_Py_IDENTIFIER(__name__);
28
Eric Snow86ea5812019-05-10 13:29:55 -040029/* Given a module object, get its per-module state. */
30static WarningsState *
31_Warnings_GetState()
32{
Victor Stinner4d231bc2019-11-14 13:36:21 +010033 PyThreadState *tstate = _PyThreadState_GET();
Eric Snow86ea5812019-05-10 13:29:55 -040034 if (tstate == NULL) {
Victor Stinner4d231bc2019-11-14 13:36:21 +010035 _PyErr_SetString(tstate, PyExc_RuntimeError,
36 "_Warnings_GetState: could not identify "
37 "current interpreter");
Eric Snow86ea5812019-05-10 13:29:55 -040038 return NULL;
39 }
40 return &tstate->interp->warnings;
41}
42
43/* Clear the given warnings module state. */
44static void
45_Warnings_ClearState(WarningsState *st)
46{
47 Py_CLEAR(st->filters);
48 Py_CLEAR(st->once_registry);
49 Py_CLEAR(st->default_action);
50}
51
52#ifndef Py_DEBUG
53static PyObject *
54create_filter(PyObject *category, _Py_Identifier *id, const char *modname)
55{
56 PyObject *modname_obj = NULL;
57 PyObject *action_str = _PyUnicode_FromId(id);
58 if (action_str == NULL) {
59 return NULL;
60 }
61
62 /* Default to "no module name" for initial filter set */
63 if (modname != NULL) {
64 modname_obj = PyUnicode_InternFromString(modname);
65 if (modname_obj == NULL) {
66 return NULL;
67 }
68 } else {
69 modname_obj = Py_None;
70 }
71
72 /* This assumes the line number is zero for now. */
73 return PyTuple_Pack(5, action_str, Py_None,
74 category, modname_obj, _PyLong_Zero);
75}
76#endif
77
78static PyObject *
79init_filters(void)
80{
81#ifdef Py_DEBUG
82 /* Py_DEBUG builds show all warnings by default */
83 return PyList_New(0);
84#else
85 /* Other builds ignore a number of warning categories by default */
86 PyObject *filters = PyList_New(5);
87 if (filters == NULL) {
88 return NULL;
89 }
90
91 size_t pos = 0; /* Post-incremented in each use. */
92 PyList_SET_ITEM(filters, pos++,
93 create_filter(PyExc_DeprecationWarning, &PyId_default, "__main__"));
94 PyList_SET_ITEM(filters, pos++,
95 create_filter(PyExc_DeprecationWarning, &PyId_ignore, NULL));
96 PyList_SET_ITEM(filters, pos++,
97 create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore, NULL));
98 PyList_SET_ITEM(filters, pos++,
99 create_filter(PyExc_ImportWarning, &PyId_ignore, NULL));
100 PyList_SET_ITEM(filters, pos++,
101 create_filter(PyExc_ResourceWarning, &PyId_ignore, NULL));
102
103 for (size_t x = 0; x < pos; x++) {
104 if (PyList_GET_ITEM(filters, x) == NULL) {
105 Py_DECREF(filters);
106 return NULL;
107 }
108 }
109 return filters;
110#endif
111}
112
113/* Initialize the given warnings module state. */
114static int
115_Warnings_InitState(WarningsState *st)
116{
117 if (st->filters == NULL) {
118 st->filters = init_filters();
119 if (st->filters == NULL) {
120 goto error;
121 }
122 }
123
124 if (st->once_registry == NULL) {
125 st->once_registry = PyDict_New();
126 if (st->once_registry == NULL) {
127 goto error;
128 }
129 }
130
131 if (st->default_action == NULL) {
132 st->default_action = PyUnicode_FromString("default");
133 if (st->default_action == NULL) {
134 goto error;
135 }
136 }
137
138 st->filters_version = 0;
139
140 return 0;
141
142error:
143 _Warnings_ClearState(st);
144 return -1;
145}
146
147
148/*************************************************************************/
149
Christian Heimes33fe8092008-04-13 13:53:33 +0000150static int
151check_matched(PyObject *obj, PyObject *arg)
152{
153 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200154 _Py_IDENTIFIER(match);
Christian Heimes33fe8092008-04-13 13:53:33 +0000155 int rc;
156
Nick Coghlan9b997472018-01-08 12:45:02 +1000157 /* A 'None' filter always matches */
Christian Heimes33fe8092008-04-13 13:53:33 +0000158 if (obj == Py_None)
159 return 1;
Nick Coghlan9b997472018-01-08 12:45:02 +1000160
161 /* An internal plain text default filter must match exactly */
162 if (PyUnicode_CheckExact(obj)) {
163 int cmp_result = PyUnicode_Compare(obj, arg);
164 if (cmp_result == -1 && PyErr_Occurred()) {
165 return -1;
166 }
167 return !cmp_result;
168 }
169
170 /* Otherwise assume a regex filter and call its match() method */
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200171 result = _PyObject_CallMethodIdOneArg(obj, &PyId_match, arg);
Christian Heimes33fe8092008-04-13 13:53:33 +0000172 if (result == NULL)
173 return -1;
174
175 rc = PyObject_IsTrue(result);
176 Py_DECREF(result);
177 return rc;
178}
179
180/*
181 Returns a new reference.
182 A NULL return value can mean false or an error.
183*/
184static PyObject *
Victor Stinner82656272017-11-22 23:51:42 +0100185get_warnings_attr(_Py_Identifier *attr_id, int try_import)
Christian Heimes33fe8092008-04-13 13:53:33 +0000186{
Victor Stinner82656272017-11-22 23:51:42 +0100187 PyObject *warnings_str;
Victor Stinnere98445a2016-03-23 00:54:48 +0100188 PyObject *warnings_module, *obj;
Victor Stinner82656272017-11-22 23:51:42 +0100189 _Py_IDENTIFIER(warnings);
Christian Heimes33fe8092008-04-13 13:53:33 +0000190
Victor Stinner82656272017-11-22 23:51:42 +0100191 warnings_str = _PyUnicode_FromId(&PyId_warnings);
Christian Heimes33fe8092008-04-13 13:53:33 +0000192 if (warnings_str == NULL) {
Victor Stinner82656272017-11-22 23:51:42 +0100193 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000194 }
195
Victor Stinnere98445a2016-03-23 00:54:48 +0100196 /* don't try to import after the start of the Python finallization */
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600197 if (try_import && !_Py_IsFinalizing()) {
Victor Stinnere98445a2016-03-23 00:54:48 +0100198 warnings_module = PyImport_Import(warnings_str);
199 if (warnings_module == NULL) {
200 /* Fallback to the C implementation if we cannot get
201 the Python implementation */
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200202 if (PyErr_ExceptionMatches(PyExc_ImportError)) {
203 PyErr_Clear();
204 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000205 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +0100206 }
207 }
208 else {
Nathaniel J. Smithdba976b2018-01-26 11:28:31 -0800209 /* if we're so late into Python finalization that the module dict is
210 gone, then we can't even use PyImport_GetModule without triggering
211 an interpreter abort.
212 */
Victor Stinnercaba55b2018-08-03 15:33:52 +0200213 if (!_PyInterpreterState_GET_UNSAFE()->modules) {
Nathaniel J. Smithdba976b2018-01-26 11:28:31 -0800214 return NULL;
215 }
Eric Snow3f9eee62017-09-15 16:35:20 -0600216 warnings_module = PyImport_GetModule(warnings_str);
Victor Stinner023654f2016-03-23 17:48:22 +0100217 if (warnings_module == NULL)
218 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +0100219 }
220
Serhiy Storchakaf320be72018-01-25 10:49:40 +0200221 (void)_PyObject_LookupAttrId(warnings_module, attr_id, &obj);
Victor Stinnere98445a2016-03-23 00:54:48 +0100222 Py_DECREF(warnings_module);
223 return obj;
Christian Heimes33fe8092008-04-13 13:53:33 +0000224}
225
226
Neal Norwitz32dde222008-04-15 06:43:13 +0000227static PyObject *
Eric Snow86ea5812019-05-10 13:29:55 -0400228get_once_registry(WarningsState *st)
Christian Heimes33fe8092008-04-13 13:53:33 +0000229{
230 PyObject *registry;
Victor Stinner82656272017-11-22 23:51:42 +0100231 _Py_IDENTIFIER(onceregistry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000232
Victor Stinner82656272017-11-22 23:51:42 +0100233 registry = get_warnings_attr(&PyId_onceregistry, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000234 if (registry == NULL) {
235 if (PyErr_Occurred())
236 return NULL;
Eric Snow86ea5812019-05-10 13:29:55 -0400237 assert(st->once_registry);
238 return st->once_registry;
Christian Heimes33fe8092008-04-13 13:53:33 +0000239 }
Oren Milman252033d2017-09-11 09:28:39 +0300240 if (!PyDict_Check(registry)) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200241 PyErr_Format(PyExc_TypeError,
242 MODULE_NAME ".onceregistry must be a dict, "
243 "not '%.200s'",
244 Py_TYPE(registry)->tp_name);
Oren Milman252033d2017-09-11 09:28:39 +0300245 Py_DECREF(registry);
246 return NULL;
247 }
Eric Snow86ea5812019-05-10 13:29:55 -0400248 Py_SETREF(st->once_registry, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000249 return registry;
250}
251
252
Brett Cannon0759dd62009-04-01 18:13:07 +0000253static PyObject *
Eric Snow86ea5812019-05-10 13:29:55 -0400254get_default_action(WarningsState *st)
Brett Cannon0759dd62009-04-01 18:13:07 +0000255{
256 PyObject *default_action;
Victor Stinner82656272017-11-22 23:51:42 +0100257 _Py_IDENTIFIER(defaultaction);
Brett Cannon0759dd62009-04-01 18:13:07 +0000258
Victor Stinner82656272017-11-22 23:51:42 +0100259 default_action = get_warnings_attr(&PyId_defaultaction, 0);
Brett Cannon0759dd62009-04-01 18:13:07 +0000260 if (default_action == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 if (PyErr_Occurred()) {
262 return NULL;
263 }
Eric Snow86ea5812019-05-10 13:29:55 -0400264 assert(st->default_action);
265 return st->default_action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000266 }
Oren Milman9d984fd2017-09-12 00:18:09 +0300267 if (!PyUnicode_Check(default_action)) {
268 PyErr_Format(PyExc_TypeError,
269 MODULE_NAME ".defaultaction must be a string, "
270 "not '%.200s'",
271 Py_TYPE(default_action)->tp_name);
272 Py_DECREF(default_action);
273 return NULL;
274 }
Eric Snow86ea5812019-05-10 13:29:55 -0400275 Py_SETREF(st->default_action, default_action);
Brett Cannon0759dd62009-04-01 18:13:07 +0000276 return default_action;
277}
278
279
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400280/* The item is a new reference. */
Victor Stinnera4c704b2013-10-29 23:43:41 +0100281static PyObject*
Christian Heimes33fe8092008-04-13 13:53:33 +0000282get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
283 PyObject *module, PyObject **item)
284{
Brett Cannon0759dd62009-04-01 18:13:07 +0000285 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000286 Py_ssize_t i;
287 PyObject *warnings_filters;
Victor Stinner82656272017-11-22 23:51:42 +0100288 _Py_IDENTIFIER(filters);
Eric Snow86ea5812019-05-10 13:29:55 -0400289 WarningsState *st = _Warnings_GetState();
290 if (st == NULL) {
291 return NULL;
292 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000293
Victor Stinner82656272017-11-22 23:51:42 +0100294 warnings_filters = get_warnings_attr(&PyId_filters, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000295 if (warnings_filters == NULL) {
296 if (PyErr_Occurred())
297 return NULL;
298 }
299 else {
Eric Snow86ea5812019-05-10 13:29:55 -0400300 Py_SETREF(st->filters, warnings_filters);
Christian Heimes33fe8092008-04-13 13:53:33 +0000301 }
302
Eric Snow86ea5812019-05-10 13:29:55 -0400303 PyObject *filters = st->filters;
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600304 if (filters == NULL || !PyList_Check(filters)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000305 PyErr_SetString(PyExc_ValueError,
306 MODULE_NAME ".filters must be a list");
307 return NULL;
308 }
309
Eric Snow86ea5812019-05-10 13:29:55 -0400310 /* WarningsState.filters could change while we are iterating over it. */
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600311 for (i = 0; i < PyList_GET_SIZE(filters); i++) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000312 PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
313 Py_ssize_t ln;
314 int is_subclass, good_msg, good_mod;
315
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600316 tmp_item = PyList_GET_ITEM(filters, i);
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400317 if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000318 PyErr_Format(PyExc_ValueError,
319 MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
320 return NULL;
321 }
322
323 /* Python code: action, msg, cat, mod, ln = item */
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400324 Py_INCREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000325 action = PyTuple_GET_ITEM(tmp_item, 0);
326 msg = PyTuple_GET_ITEM(tmp_item, 1);
327 cat = PyTuple_GET_ITEM(tmp_item, 2);
328 mod = PyTuple_GET_ITEM(tmp_item, 3);
329 ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
330
Oren Milman9d984fd2017-09-12 00:18:09 +0300331 if (!PyUnicode_Check(action)) {
332 PyErr_Format(PyExc_TypeError,
333 "action must be a string, not '%.200s'",
334 Py_TYPE(action)->tp_name);
335 Py_DECREF(tmp_item);
336 return NULL;
337 }
338
Christian Heimes33fe8092008-04-13 13:53:33 +0000339 good_msg = check_matched(msg, text);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400340 if (good_msg == -1) {
341 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100342 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400343 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100344
Christian Heimes33fe8092008-04-13 13:53:33 +0000345 good_mod = check_matched(mod, module);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400346 if (good_mod == -1) {
347 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100348 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400349 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100350
Christian Heimes33fe8092008-04-13 13:53:33 +0000351 is_subclass = PyObject_IsSubclass(category, cat);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400352 if (is_subclass == -1) {
353 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100354 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400355 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100356
Christian Heimes33fe8092008-04-13 13:53:33 +0000357 ln = PyLong_AsSsize_t(ln_obj);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400358 if (ln == -1 && PyErr_Occurred()) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400359 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000360 return NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400361 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000362
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400363 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
364 *item = tmp_item;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100365 return action;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400366 }
367
368 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000369 }
370
Eric Snow86ea5812019-05-10 13:29:55 -0400371 action = get_default_action(st);
Brett Cannon0759dd62009-04-01 18:13:07 +0000372 if (action != NULL) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400373 Py_INCREF(Py_None);
374 *item = Py_None;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100375 return action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000376 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000377
Christian Heimes33fe8092008-04-13 13:53:33 +0000378 return NULL;
379}
380
Brett Cannon0759dd62009-04-01 18:13:07 +0000381
Christian Heimes33fe8092008-04-13 13:53:33 +0000382static int
383already_warned(PyObject *registry, PyObject *key, int should_set)
384{
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200385 PyObject *version_obj, *already_warned;
386 _Py_IDENTIFIER(version);
Christian Heimes33fe8092008-04-13 13:53:33 +0000387
388 if (key == NULL)
389 return -1;
390
Eric Snow86ea5812019-05-10 13:29:55 -0400391 WarningsState *st = _Warnings_GetState();
392 if (st == NULL) {
393 return -1;
394 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200395 version_obj = _PyDict_GetItemIdWithError(registry, &PyId_version);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200396 if (version_obj == NULL
397 || !PyLong_CheckExact(version_obj)
Eric Snow86ea5812019-05-10 13:29:55 -0400398 || PyLong_AsLong(version_obj) != st->filters_version)
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200399 {
400 if (PyErr_Occurred()) {
401 return -1;
402 }
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200403 PyDict_Clear(registry);
Eric Snow86ea5812019-05-10 13:29:55 -0400404 version_obj = PyLong_FromLong(st->filters_version);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200405 if (version_obj == NULL)
406 return -1;
407 if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
408 Py_DECREF(version_obj);
409 return -1;
410 }
411 Py_DECREF(version_obj);
412 }
413 else {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200414 already_warned = PyDict_GetItemWithError(registry, key);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200415 if (already_warned != NULL) {
416 int rc = PyObject_IsTrue(already_warned);
417 if (rc != 0)
418 return rc;
419 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200420 else if (PyErr_Occurred()) {
421 return -1;
422 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000423 }
424
425 /* This warning wasn't found in the registry, set it. */
426 if (should_set)
427 return PyDict_SetItem(registry, key, Py_True);
428 return 0;
429}
430
431/* New reference. */
432static PyObject *
433normalize_module(PyObject *filename)
434{
435 PyObject *module;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100436 int kind;
437 void *data;
Christian Heimes33fe8092008-04-13 13:53:33 +0000438 Py_ssize_t len;
439
Victor Stinner9e30aa52011-11-21 02:49:52 +0100440 len = PyUnicode_GetLength(filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000441 if (len < 0)
442 return NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100443
444 if (len == 0)
445 return PyUnicode_FromString("<unknown>");
446
447 kind = PyUnicode_KIND(filename);
448 data = PyUnicode_DATA(filename);
449
450 /* if filename.endswith(".py"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000451 if (len >= 3 &&
Victor Stinnera4c704b2013-10-29 23:43:41 +0100452 PyUnicode_READ(kind, data, len-3) == '.' &&
453 PyUnicode_READ(kind, data, len-2) == 'p' &&
454 PyUnicode_READ(kind, data, len-1) == 'y')
455 {
Victor Stinner9e30aa52011-11-21 02:49:52 +0100456 module = PyUnicode_Substring(filename, 0, len-3);
Christian Heimes33fe8092008-04-13 13:53:33 +0000457 }
458 else {
459 module = filename;
460 Py_INCREF(module);
461 }
462 return module;
463}
464
465static int
466update_registry(PyObject *registry, PyObject *text, PyObject *category,
467 int add_zero)
468{
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300469 PyObject *altkey;
Christian Heimes33fe8092008-04-13 13:53:33 +0000470 int rc;
471
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300472 if (add_zero)
473 altkey = PyTuple_Pack(3, text, category, _PyLong_Zero);
Christian Heimes33fe8092008-04-13 13:53:33 +0000474 else
475 altkey = PyTuple_Pack(2, text, category);
476
477 rc = already_warned(registry, altkey, 1);
Christian Heimes33fe8092008-04-13 13:53:33 +0000478 Py_XDECREF(altkey);
479 return rc;
480}
481
482static void
Victor Stinner914cde82016-03-19 01:03:51 +0100483show_warning(PyObject *filename, int lineno, PyObject *text,
484 PyObject *category, PyObject *sourceline)
Christian Heimes33fe8092008-04-13 13:53:33 +0000485{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 PyObject *f_stderr;
487 PyObject *name;
Christian Heimes33fe8092008-04-13 13:53:33 +0000488 char lineno_str[128];
489
490 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
491
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200492 name = _PyObject_GetAttrId(category, &PyId___name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000493 if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100494 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000495
Victor Stinnerbd303c12013-11-07 23:07:29 +0100496 f_stderr = _PySys_GetObjectId(&PyId_stderr);
Christian Heimes33fe8092008-04-13 13:53:33 +0000497 if (f_stderr == NULL) {
498 fprintf(stderr, "lost sys.stderr\n");
Victor Stinnerae233ea2013-10-31 14:51:38 +0100499 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000500 }
501
502 /* Print "filename:lineno: category: text\n" */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100503 if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
504 goto error;
505 if (PyFile_WriteString(lineno_str, f_stderr) < 0)
506 goto error;
507 if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
508 goto error;
509 if (PyFile_WriteString(": ", f_stderr) < 0)
510 goto error;
511 if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
512 goto error;
513 if (PyFile_WriteString("\n", f_stderr) < 0)
514 goto error;
515 Py_CLEAR(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000516
517 /* Print " source_line\n" */
Christian Heimes33fe8092008-04-13 13:53:33 +0000518 if (sourceline) {
Victor Stinnera4c704b2013-10-29 23:43:41 +0100519 int kind;
520 void *data;
521 Py_ssize_t i, len;
522 Py_UCS4 ch;
523 PyObject *truncated;
Christian Heimes33fe8092008-04-13 13:53:33 +0000524
Victor Stinnera4c704b2013-10-29 23:43:41 +0100525 if (PyUnicode_READY(sourceline) < 1)
526 goto error;
527
528 kind = PyUnicode_KIND(sourceline);
529 data = PyUnicode_DATA(sourceline);
530 len = PyUnicode_GET_LENGTH(sourceline);
531 for (i=0; i<len; i++) {
532 ch = PyUnicode_READ(kind, data, i);
533 if (ch != ' ' && ch != '\t' && ch != '\014')
534 break;
535 }
536
537 truncated = PyUnicode_Substring(sourceline, i, len);
538 if (truncated == NULL)
539 goto error;
540
541 PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
542 Py_DECREF(truncated);
Christian Heimes33fe8092008-04-13 13:53:33 +0000543 PyFile_WriteString("\n", f_stderr);
544 }
Victor Stinner78e2c982013-07-16 01:54:37 +0200545 else {
546 _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
547 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100548
549error:
Victor Stinnerae233ea2013-10-31 14:51:38 +0100550 Py_XDECREF(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000551 PyErr_Clear();
552}
553
Victor Stinner1231a462016-03-19 00:47:17 +0100554static int
555call_show_warning(PyObject *category, PyObject *text, PyObject *message,
556 PyObject *filename, int lineno, PyObject *lineno_obj,
Victor Stinner914cde82016-03-19 01:03:51 +0100557 PyObject *sourceline, PyObject *source)
Victor Stinner1231a462016-03-19 00:47:17 +0100558{
559 PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
Victor Stinner82656272017-11-22 23:51:42 +0100560 _Py_IDENTIFIER(_showwarnmsg);
561 _Py_IDENTIFIER(WarningMessage);
Victor Stinner1231a462016-03-19 00:47:17 +0100562
Victor Stinnere98445a2016-03-23 00:54:48 +0100563 /* If the source parameter is set, try to get the Python implementation.
564 The Python implementation is able to log the traceback where the source
luzpaza5293b42017-11-05 07:37:50 -0600565 was allocated, whereas the C implementation doesn't. */
Victor Stinner82656272017-11-22 23:51:42 +0100566 show_fn = get_warnings_attr(&PyId__showwarnmsg, source != NULL);
Victor Stinner1231a462016-03-19 00:47:17 +0100567 if (show_fn == NULL) {
568 if (PyErr_Occurred())
569 return -1;
570 show_warning(filename, lineno, text, category, sourceline);
571 return 0;
572 }
573
574 if (!PyCallable_Check(show_fn)) {
575 PyErr_SetString(PyExc_TypeError,
576 "warnings._showwarnmsg() must be set to a callable");
577 goto error;
578 }
579
Victor Stinner82656272017-11-22 23:51:42 +0100580 warnmsg_cls = get_warnings_attr(&PyId_WarningMessage, 0);
Victor Stinner1231a462016-03-19 00:47:17 +0100581 if (warnmsg_cls == NULL) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200582 if (!PyErr_Occurred()) {
583 PyErr_SetString(PyExc_RuntimeError,
584 "unable to get warnings.WarningMessage");
585 }
Victor Stinner1231a462016-03-19 00:47:17 +0100586 goto error;
587 }
588
589 msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
Victor Stinner914cde82016-03-19 01:03:51 +0100590 filename, lineno_obj, Py_None, Py_None, source,
Victor Stinner1231a462016-03-19 00:47:17 +0100591 NULL);
592 Py_DECREF(warnmsg_cls);
593 if (msg == NULL)
594 goto error;
595
Petr Viktorinffd97532020-02-11 17:46:57 +0100596 res = PyObject_CallOneArg(show_fn, msg);
Victor Stinner1231a462016-03-19 00:47:17 +0100597 Py_DECREF(show_fn);
598 Py_DECREF(msg);
599
600 if (res == NULL)
601 return -1;
602
603 Py_DECREF(res);
604 return 0;
605
606error:
607 Py_XDECREF(show_fn);
608 return -1;
609}
610
Christian Heimes33fe8092008-04-13 13:53:33 +0000611static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612warn_explicit(PyObject *category, PyObject *message,
Christian Heimes33fe8092008-04-13 13:53:33 +0000613 PyObject *filename, int lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100614 PyObject *module, PyObject *registry, PyObject *sourceline,
615 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000616{
617 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400618 PyObject *item = NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100619 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000620 int rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100622 /* module can be None if a warning is emitted late during Python shutdown.
623 In this case, the Python warnings module was probably unloaded, filters
624 are no more available to choose as action. It is safer to ignore the
625 warning and do nothing. */
626 if (module == Py_None)
627 Py_RETURN_NONE;
628
Brett Cannondb734912008-06-27 00:52:15 +0000629 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
Oren Milman252033d2017-09-11 09:28:39 +0300630 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
Brett Cannondb734912008-06-27 00:52:15 +0000631 return NULL;
632 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000633
634 /* Normalize module. */
635 if (module == NULL) {
636 module = normalize_module(filename);
637 if (module == NULL)
638 return NULL;
639 }
640 else
641 Py_INCREF(module);
642
643 /* Normalize message. */
644 Py_INCREF(message); /* DECREF'ed in cleanup. */
645 rc = PyObject_IsInstance(message, PyExc_Warning);
646 if (rc == -1) {
647 goto cleanup;
648 }
649 if (rc == 1) {
650 text = PyObject_Str(message);
Hirokazu Yamamoto1c0c0032009-07-17 06:55:42 +0000651 if (text == NULL)
652 goto cleanup;
Victor Stinnera102ed72020-02-07 02:24:48 +0100653 category = (PyObject*)Py_TYPE(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000654 }
655 else {
656 text = message;
Petr Viktorinffd97532020-02-11 17:46:57 +0100657 message = PyObject_CallOneArg(category, message);
Brett Cannondb734912008-06-27 00:52:15 +0000658 if (message == NULL)
659 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000660 }
661
662 lineno_obj = PyLong_FromLong(lineno);
663 if (lineno_obj == NULL)
664 goto cleanup;
665
Victor Stinner22f18752016-12-09 18:08:18 +0100666 if (source == Py_None) {
667 source = NULL;
668 }
669
Christian Heimes33fe8092008-04-13 13:53:33 +0000670 /* Create key. */
671 key = PyTuple_Pack(3, text, category, lineno_obj);
672 if (key == NULL)
673 goto cleanup;
674
Brett Cannondb734912008-06-27 00:52:15 +0000675 if ((registry != NULL) && (registry != Py_None)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000676 rc = already_warned(registry, key, 0);
677 if (rc == -1)
678 goto cleanup;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 else if (rc == 1)
Christian Heimes33fe8092008-04-13 13:53:33 +0000680 goto return_none;
681 /* Else this warning hasn't been generated before. */
682 }
683
684 action = get_filter(category, text, lineno, module, &item);
685 if (action == NULL)
686 goto cleanup;
687
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200688 if (_PyUnicode_EqualToASCIIString(action, "error")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000689 PyErr_SetObject(category, message);
690 goto cleanup;
691 }
692
Victor Stinnerc9758782017-11-27 16:57:07 +0100693 if (_PyUnicode_EqualToASCIIString(action, "ignore")) {
694 goto return_none;
695 }
696
Christian Heimes33fe8092008-04-13 13:53:33 +0000697 /* Store in the registry that we've been here, *except* when the action
698 is "always". */
699 rc = 0;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200700 if (!_PyUnicode_EqualToASCIIString(action, "always")) {
Brett Cannondb734912008-06-27 00:52:15 +0000701 if (registry != NULL && registry != Py_None &&
Victor Stinnerc9758782017-11-27 16:57:07 +0100702 PyDict_SetItem(registry, key, Py_True) < 0)
703 {
Christian Heimes33fe8092008-04-13 13:53:33 +0000704 goto cleanup;
Victor Stinnerc9758782017-11-27 16:57:07 +0100705 }
706
707 if (_PyUnicode_EqualToASCIIString(action, "once")) {
Brett Cannondb734912008-06-27 00:52:15 +0000708 if (registry == NULL || registry == Py_None) {
Eric Snow86ea5812019-05-10 13:29:55 -0400709 WarningsState *st = _Warnings_GetState();
710 if (st == NULL) {
711 goto cleanup;
712 }
713 registry = get_once_registry(st);
Christian Heimes33fe8092008-04-13 13:53:33 +0000714 if (registry == NULL)
715 goto cleanup;
716 }
Eric Snow86ea5812019-05-10 13:29:55 -0400717 /* WarningsState.once_registry[(text, category)] = 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000719 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200720 else if (_PyUnicode_EqualToASCIIString(action, "module")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000721 /* registry[(text, category, 0)] = 1 */
Brett Cannondb734912008-06-27 00:52:15 +0000722 if (registry != NULL && registry != Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000724 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200725 else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000726 PyErr_Format(PyExc_RuntimeError,
Victor Stinnera4c704b2013-10-29 23:43:41 +0100727 "Unrecognized action (%R) in warnings.filters:\n %R",
728 action, item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000729 goto cleanup;
730 }
731 }
732
Christian Heimes1a8501c2008-10-02 19:56:01 +0000733 if (rc == 1) /* Already warned for this module. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000734 goto return_none;
735 if (rc == 0) {
Victor Stinner1231a462016-03-19 00:47:17 +0100736 if (call_show_warning(category, text, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100737 lineno_obj, sourceline, source) < 0)
Victor Stinner1231a462016-03-19 00:47:17 +0100738 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000739 }
740 else /* if (rc == -1) */
741 goto cleanup;
742
743 return_none:
744 result = Py_None;
745 Py_INCREF(result);
746
747 cleanup:
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400748 Py_XDECREF(item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000749 Py_XDECREF(key);
750 Py_XDECREF(text);
751 Py_XDECREF(lineno_obj);
752 Py_DECREF(module);
Brett Cannondb734912008-06-27 00:52:15 +0000753 Py_XDECREF(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000754 return result; /* Py_None or NULL. */
755}
756
Larry Hastings714e4932015-09-06 00:39:37 -0700757static int
758is_internal_frame(PyFrameObject *frame)
759{
760 static PyObject *importlib_string = NULL;
761 static PyObject *bootstrap_string = NULL;
762 PyObject *filename;
763 int contains;
764
765 if (importlib_string == NULL) {
766 importlib_string = PyUnicode_FromString("importlib");
767 if (importlib_string == NULL) {
768 return 0;
769 }
770
771 bootstrap_string = PyUnicode_FromString("_bootstrap");
772 if (bootstrap_string == NULL) {
773 Py_DECREF(importlib_string);
774 return 0;
775 }
776 Py_INCREF(importlib_string);
777 Py_INCREF(bootstrap_string);
778 }
779
780 if (frame == NULL || frame->f_code == NULL ||
781 frame->f_code->co_filename == NULL) {
782 return 0;
783 }
784 filename = frame->f_code->co_filename;
785 if (!PyUnicode_Check(filename)) {
786 return 0;
787 }
788 contains = PyUnicode_Contains(filename, importlib_string);
789 if (contains < 0) {
790 return 0;
791 }
792 else if (contains > 0) {
793 contains = PyUnicode_Contains(filename, bootstrap_string);
794 if (contains < 0) {
795 return 0;
796 }
797 else if (contains > 0) {
798 return 1;
799 }
800 }
801
802 return 0;
803}
804
805static PyFrameObject *
806next_external_frame(PyFrameObject *frame)
807{
808 do {
809 frame = frame->f_back;
810 } while (frame != NULL && is_internal_frame(frame));
811
812 return frame;
813}
814
Christian Heimes33fe8092008-04-13 13:53:33 +0000815/* filename, module, and registry are new refs, globals is borrowed */
816/* Returns 0 on error (no new refs), 1 on success */
817static int
818setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
819 PyObject **module, PyObject **registry)
820{
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200821 _Py_IDENTIFIER(__warningregistry__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000822 PyObject *globals;
823
Thomas Kluyver11a89662018-06-08 21:28:37 +0200824 /* Setup globals, filename and lineno. */
Victor Stinner50b48572018-11-01 01:51:40 +0100825 PyFrameObject *f = _PyThreadState_GET()->frame;
Larry Hastings714e4932015-09-06 00:39:37 -0700826 // Stack level comparisons to Python code is off by one as there is no
827 // warnings-related stack level to avoid.
828 if (stack_level <= 0 || is_internal_frame(f)) {
829 while (--stack_level > 0 && f != NULL) {
830 f = f->f_back;
831 }
832 }
833 else {
834 while (--stack_level > 0 && f != NULL) {
835 f = next_external_frame(f);
836 }
837 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000838
839 if (f == NULL) {
Victor Stinnercaba55b2018-08-03 15:33:52 +0200840 globals = _PyInterpreterState_GET_UNSAFE()->sysdict;
Thomas Kluyver11a89662018-06-08 21:28:37 +0200841 *filename = PyUnicode_FromString("sys");
Christian Heimes33fe8092008-04-13 13:53:33 +0000842 *lineno = 1;
843 }
844 else {
845 globals = f->f_globals;
Thomas Kluyver11a89662018-06-08 21:28:37 +0200846 *filename = f->f_code->co_filename;
847 Py_INCREF(*filename);
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000848 *lineno = PyFrame_GetLineNumber(f);
Christian Heimes33fe8092008-04-13 13:53:33 +0000849 }
850
851 *module = NULL;
852
853 /* Setup registry. */
854 assert(globals != NULL);
855 assert(PyDict_Check(globals));
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200856 *registry = _PyDict_GetItemIdWithError(globals, &PyId___warningregistry__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000857 if (*registry == NULL) {
858 int rc;
859
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200860 if (PyErr_Occurred()) {
861 return 0;
862 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000863 *registry = PyDict_New();
864 if (*registry == NULL)
865 return 0;
866
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200867 rc = _PyDict_SetItemId(globals, &PyId___warningregistry__, *registry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000868 if (rc < 0)
869 goto handle_error;
870 }
871 else
872 Py_INCREF(*registry);
873
874 /* Setup module. */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200875 *module = _PyDict_GetItemIdWithError(globals, &PyId___name__);
Oren Milman5d3e8002017-09-24 21:28:42 +0300876 if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) {
877 Py_INCREF(*module);
878 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200879 else if (PyErr_Occurred()) {
880 goto handle_error;
881 }
Oren Milman5d3e8002017-09-24 21:28:42 +0300882 else {
Christian Heimes33fe8092008-04-13 13:53:33 +0000883 *module = PyUnicode_FromString("<string>");
884 if (*module == NULL)
885 goto handle_error;
886 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000887
Christian Heimes33fe8092008-04-13 13:53:33 +0000888 return 1;
889
890 handle_error:
891 /* filename not XDECREF'ed here as there is no way to jump here with a
892 dangling reference. */
893 Py_XDECREF(*registry);
894 Py_XDECREF(*module);
895 return 0;
896}
897
898static PyObject *
899get_category(PyObject *message, PyObject *category)
900{
901 int rc;
902
903 /* Get category. */
904 rc = PyObject_IsInstance(message, PyExc_Warning);
905 if (rc == -1)
906 return NULL;
907
908 if (rc == 1)
Victor Stinnera102ed72020-02-07 02:24:48 +0100909 category = (PyObject*)Py_TYPE(message);
Berker Peksagd8089e02014-07-11 19:50:25 +0300910 else if (category == NULL || category == Py_None)
Christian Heimes33fe8092008-04-13 13:53:33 +0000911 category = PyExc_UserWarning;
912
913 /* Validate category. */
914 rc = PyObject_IsSubclass(category, PyExc_Warning);
Berker Peksagd8089e02014-07-11 19:50:25 +0300915 /* category is not a subclass of PyExc_Warning or
916 PyObject_IsSubclass raised an error */
917 if (rc == -1 || rc == 0) {
918 PyErr_Format(PyExc_TypeError,
919 "category must be a Warning subclass, not '%s'",
920 Py_TYPE(category)->tp_name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000921 return NULL;
922 }
923
924 return category;
925}
926
927static PyObject *
Victor Stinner914cde82016-03-19 01:03:51 +0100928do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
929 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000930{
931 PyObject *filename, *module, *registry, *res;
932 int lineno;
933
934 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
935 return NULL;
936
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100937 res = warn_explicit(category, message, filename, lineno, module, registry,
Victor Stinner914cde82016-03-19 01:03:51 +0100938 NULL, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000939 Py_DECREF(filename);
940 Py_DECREF(registry);
941 Py_DECREF(module);
942 return res;
943}
944
Victor Stinner22f18752016-12-09 18:08:18 +0100945/*[clinic input]
946warn as warnings_warn
947
948 message: object
949 category: object = None
950 stacklevel: Py_ssize_t = 1
951 source: object = None
952
953Issue a warning, or maybe ignore it or raise an exception.
954[clinic start generated code]*/
955
Christian Heimes33fe8092008-04-13 13:53:33 +0000956static PyObject *
Victor Stinner22f18752016-12-09 18:08:18 +0100957warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
958 Py_ssize_t stacklevel, PyObject *source)
959/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
Christian Heimes33fe8092008-04-13 13:53:33 +0000960{
Christian Heimes33fe8092008-04-13 13:53:33 +0000961 category = get_category(message, category);
962 if (category == NULL)
963 return NULL;
Victor Stinner22f18752016-12-09 18:08:18 +0100964 return do_warn(message, category, stacklevel, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000965}
966
967static PyObject *
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200968get_source_line(PyObject *module_globals, int lineno)
969{
970 _Py_IDENTIFIER(get_source);
971 _Py_IDENTIFIER(__loader__);
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200972 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. */
Petr Viktorinffd97532020-02-11 17:46:57 +01001000 source = PyObject_CallOneArg(get_source, module_name);
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001001 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) {
Petr Viktorinffd97532020-02-11 17:46:57 +01001287 PyObject *res = PyObject_CallOneArg(fn, coro);
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001288 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,
Hansraj Das5dfbb4d2019-10-08 14:26:07 +05301309"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}