blob: 834ceb18459469e4dbc0e06c9466f62dea367713 [file] [log] [blame]
Christian Heimes33fe8092008-04-13 13:53:33 +00001#include "Python.h"
Victor Stinner66b79732020-03-02 15:02:18 +01002#include "pycore_initconfig.h"
Victor Stinner4d231bc2019-11-14 13:36:21 +01003#include "pycore_pyerrors.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01004#include "pycore_pystate.h"
Christian Heimes33fe8092008-04-13 13:53:33 +00005#include "frameobject.h"
Victor Stinner22f18752016-12-09 18:08:18 +01006#include "clinic/_warnings.c.h"
Christian Heimes33fe8092008-04-13 13:53:33 +00007
8#define MODULE_NAME "_warnings"
Christian Heimes33fe8092008-04-13 13:53:33 +00009
10PyDoc_STRVAR(warnings__doc__,
11MODULE_NAME " provides basic warning filtering support.\n"
12"It is a helper module to speed up interpreter start-up.");
13
Victor Stinnerbd303c12013-11-07 23:07:29 +010014_Py_IDENTIFIER(stderr);
Victor Stinner747f48e2017-12-12 22:59:48 +010015#ifndef Py_DEBUG
Nick Coghlan9b997472018-01-08 12:45:02 +100016_Py_IDENTIFIER(default);
Victor Stinnerb98f1712017-11-23 17:13:44 +010017_Py_IDENTIFIER(ignore);
Victor Stinner747f48e2017-12-12 22:59:48 +010018#endif
Christian Heimes33fe8092008-04-13 13:53:33 +000019
Eric Snow86ea5812019-05-10 13:29:55 -040020
21/*************************************************************************/
22
23typedef struct _warnings_runtime_state WarningsState;
24
25/* Forward declaration of the _warnings module definition. */
26static struct PyModuleDef warningsmodule;
27
Hai Shi46874c22020-01-30 17:20:25 -060028_Py_IDENTIFIER(__name__);
29
Eric Snow86ea5812019-05-10 13:29:55 -040030/* Given a module object, get its per-module state. */
31static WarningsState *
Victor Stinner66b79732020-03-02 15:02:18 +010032warnings_get_state(void)
Eric Snow86ea5812019-05-10 13:29:55 -040033{
Victor Stinner4d231bc2019-11-14 13:36:21 +010034 PyThreadState *tstate = _PyThreadState_GET();
Eric Snow86ea5812019-05-10 13:29:55 -040035 if (tstate == NULL) {
Victor Stinner4d231bc2019-11-14 13:36:21 +010036 _PyErr_SetString(tstate, PyExc_RuntimeError,
Victor Stinner66b79732020-03-02 15:02:18 +010037 "warnings_get_state: could not identify "
Victor Stinner4d231bc2019-11-14 13:36:21 +010038 "current interpreter");
Eric Snow86ea5812019-05-10 13:29:55 -040039 return NULL;
40 }
41 return &tstate->interp->warnings;
42}
43
44/* Clear the given warnings module state. */
45static void
Victor Stinner66b79732020-03-02 15:02:18 +010046warnings_clear_state(WarningsState *st)
Eric Snow86ea5812019-05-10 13:29:55 -040047{
48 Py_CLEAR(st->filters);
49 Py_CLEAR(st->once_registry);
50 Py_CLEAR(st->default_action);
51}
52
53#ifndef Py_DEBUG
54static PyObject *
55create_filter(PyObject *category, _Py_Identifier *id, const char *modname)
56{
57 PyObject *modname_obj = NULL;
58 PyObject *action_str = _PyUnicode_FromId(id);
59 if (action_str == NULL) {
60 return NULL;
61 }
62
63 /* Default to "no module name" for initial filter set */
64 if (modname != NULL) {
65 modname_obj = PyUnicode_InternFromString(modname);
66 if (modname_obj == NULL) {
67 return NULL;
68 }
69 } else {
70 modname_obj = Py_None;
71 }
72
73 /* This assumes the line number is zero for now. */
74 return PyTuple_Pack(5, action_str, Py_None,
75 category, modname_obj, _PyLong_Zero);
76}
77#endif
78
79static PyObject *
80init_filters(void)
81{
82#ifdef Py_DEBUG
83 /* Py_DEBUG builds show all warnings by default */
84 return PyList_New(0);
85#else
86 /* Other builds ignore a number of warning categories by default */
87 PyObject *filters = PyList_New(5);
88 if (filters == NULL) {
89 return NULL;
90 }
91
92 size_t pos = 0; /* Post-incremented in each use. */
93 PyList_SET_ITEM(filters, pos++,
94 create_filter(PyExc_DeprecationWarning, &PyId_default, "__main__"));
95 PyList_SET_ITEM(filters, pos++,
96 create_filter(PyExc_DeprecationWarning, &PyId_ignore, NULL));
97 PyList_SET_ITEM(filters, pos++,
98 create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore, NULL));
99 PyList_SET_ITEM(filters, pos++,
100 create_filter(PyExc_ImportWarning, &PyId_ignore, NULL));
101 PyList_SET_ITEM(filters, pos++,
102 create_filter(PyExc_ResourceWarning, &PyId_ignore, NULL));
103
104 for (size_t x = 0; x < pos; x++) {
105 if (PyList_GET_ITEM(filters, x) == NULL) {
106 Py_DECREF(filters);
107 return NULL;
108 }
109 }
110 return filters;
111#endif
112}
113
114/* Initialize the given warnings module state. */
115static int
Victor Stinner66b79732020-03-02 15:02:18 +0100116warnings_init_state(WarningsState *st)
Eric Snow86ea5812019-05-10 13:29:55 -0400117{
118 if (st->filters == NULL) {
119 st->filters = init_filters();
120 if (st->filters == NULL) {
121 goto error;
122 }
123 }
124
125 if (st->once_registry == NULL) {
126 st->once_registry = PyDict_New();
127 if (st->once_registry == NULL) {
128 goto error;
129 }
130 }
131
132 if (st->default_action == NULL) {
133 st->default_action = PyUnicode_FromString("default");
134 if (st->default_action == NULL) {
135 goto error;
136 }
137 }
138
139 st->filters_version = 0;
140
141 return 0;
142
143error:
Victor Stinner66b79732020-03-02 15:02:18 +0100144 warnings_clear_state(st);
Eric Snow86ea5812019-05-10 13:29:55 -0400145 return -1;
146}
147
148
149/*************************************************************************/
150
Christian Heimes33fe8092008-04-13 13:53:33 +0000151static int
152check_matched(PyObject *obj, PyObject *arg)
153{
154 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200155 _Py_IDENTIFIER(match);
Christian Heimes33fe8092008-04-13 13:53:33 +0000156 int rc;
157
Nick Coghlan9b997472018-01-08 12:45:02 +1000158 /* A 'None' filter always matches */
Christian Heimes33fe8092008-04-13 13:53:33 +0000159 if (obj == Py_None)
160 return 1;
Nick Coghlan9b997472018-01-08 12:45:02 +1000161
162 /* An internal plain text default filter must match exactly */
163 if (PyUnicode_CheckExact(obj)) {
164 int cmp_result = PyUnicode_Compare(obj, arg);
165 if (cmp_result == -1 && PyErr_Occurred()) {
166 return -1;
167 }
168 return !cmp_result;
169 }
170
171 /* Otherwise assume a regex filter and call its match() method */
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200172 result = _PyObject_CallMethodIdOneArg(obj, &PyId_match, arg);
Christian Heimes33fe8092008-04-13 13:53:33 +0000173 if (result == NULL)
174 return -1;
175
176 rc = PyObject_IsTrue(result);
177 Py_DECREF(result);
178 return rc;
179}
180
181/*
182 Returns a new reference.
183 A NULL return value can mean false or an error.
184*/
185static PyObject *
Victor Stinner82656272017-11-22 23:51:42 +0100186get_warnings_attr(_Py_Identifier *attr_id, int try_import)
Christian Heimes33fe8092008-04-13 13:53:33 +0000187{
Victor Stinner82656272017-11-22 23:51:42 +0100188 PyObject *warnings_str;
Victor Stinnere98445a2016-03-23 00:54:48 +0100189 PyObject *warnings_module, *obj;
Victor Stinner82656272017-11-22 23:51:42 +0100190 _Py_IDENTIFIER(warnings);
Christian Heimes33fe8092008-04-13 13:53:33 +0000191
Victor Stinner82656272017-11-22 23:51:42 +0100192 warnings_str = _PyUnicode_FromId(&PyId_warnings);
Christian Heimes33fe8092008-04-13 13:53:33 +0000193 if (warnings_str == NULL) {
Victor Stinner82656272017-11-22 23:51:42 +0100194 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000195 }
196
Victor Stinnere98445a2016-03-23 00:54:48 +0100197 /* don't try to import after the start of the Python finallization */
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600198 if (try_import && !_Py_IsFinalizing()) {
Victor Stinnere98445a2016-03-23 00:54:48 +0100199 warnings_module = PyImport_Import(warnings_str);
200 if (warnings_module == NULL) {
201 /* Fallback to the C implementation if we cannot get
202 the Python implementation */
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200203 if (PyErr_ExceptionMatches(PyExc_ImportError)) {
204 PyErr_Clear();
205 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000206 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +0100207 }
208 }
209 else {
Nathaniel J. Smithdba976b2018-01-26 11:28:31 -0800210 /* if we're so late into Python finalization that the module dict is
211 gone, then we can't even use PyImport_GetModule without triggering
212 an interpreter abort.
213 */
Victor Stinnercaba55b2018-08-03 15:33:52 +0200214 if (!_PyInterpreterState_GET_UNSAFE()->modules) {
Nathaniel J. Smithdba976b2018-01-26 11:28:31 -0800215 return NULL;
216 }
Eric Snow3f9eee62017-09-15 16:35:20 -0600217 warnings_module = PyImport_GetModule(warnings_str);
Victor Stinner023654f2016-03-23 17:48:22 +0100218 if (warnings_module == NULL)
219 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +0100220 }
221
Serhiy Storchakaf320be72018-01-25 10:49:40 +0200222 (void)_PyObject_LookupAttrId(warnings_module, attr_id, &obj);
Victor Stinnere98445a2016-03-23 00:54:48 +0100223 Py_DECREF(warnings_module);
224 return obj;
Christian Heimes33fe8092008-04-13 13:53:33 +0000225}
226
227
Neal Norwitz32dde222008-04-15 06:43:13 +0000228static PyObject *
Eric Snow86ea5812019-05-10 13:29:55 -0400229get_once_registry(WarningsState *st)
Christian Heimes33fe8092008-04-13 13:53:33 +0000230{
231 PyObject *registry;
Victor Stinner82656272017-11-22 23:51:42 +0100232 _Py_IDENTIFIER(onceregistry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000233
Victor Stinner82656272017-11-22 23:51:42 +0100234 registry = get_warnings_attr(&PyId_onceregistry, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000235 if (registry == NULL) {
236 if (PyErr_Occurred())
237 return NULL;
Eric Snow86ea5812019-05-10 13:29:55 -0400238 assert(st->once_registry);
239 return st->once_registry;
Christian Heimes33fe8092008-04-13 13:53:33 +0000240 }
Oren Milman252033d2017-09-11 09:28:39 +0300241 if (!PyDict_Check(registry)) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200242 PyErr_Format(PyExc_TypeError,
243 MODULE_NAME ".onceregistry must be a dict, "
244 "not '%.200s'",
245 Py_TYPE(registry)->tp_name);
Oren Milman252033d2017-09-11 09:28:39 +0300246 Py_DECREF(registry);
247 return NULL;
248 }
Eric Snow86ea5812019-05-10 13:29:55 -0400249 Py_SETREF(st->once_registry, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000250 return registry;
251}
252
253
Brett Cannon0759dd62009-04-01 18:13:07 +0000254static PyObject *
Eric Snow86ea5812019-05-10 13:29:55 -0400255get_default_action(WarningsState *st)
Brett Cannon0759dd62009-04-01 18:13:07 +0000256{
257 PyObject *default_action;
Victor Stinner82656272017-11-22 23:51:42 +0100258 _Py_IDENTIFIER(defaultaction);
Brett Cannon0759dd62009-04-01 18:13:07 +0000259
Victor Stinner82656272017-11-22 23:51:42 +0100260 default_action = get_warnings_attr(&PyId_defaultaction, 0);
Brett Cannon0759dd62009-04-01 18:13:07 +0000261 if (default_action == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 if (PyErr_Occurred()) {
263 return NULL;
264 }
Eric Snow86ea5812019-05-10 13:29:55 -0400265 assert(st->default_action);
266 return st->default_action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000267 }
Oren Milman9d984fd2017-09-12 00:18:09 +0300268 if (!PyUnicode_Check(default_action)) {
269 PyErr_Format(PyExc_TypeError,
270 MODULE_NAME ".defaultaction must be a string, "
271 "not '%.200s'",
272 Py_TYPE(default_action)->tp_name);
273 Py_DECREF(default_action);
274 return NULL;
275 }
Eric Snow86ea5812019-05-10 13:29:55 -0400276 Py_SETREF(st->default_action, default_action);
Brett Cannon0759dd62009-04-01 18:13:07 +0000277 return default_action;
278}
279
280
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400281/* The item is a new reference. */
Victor Stinnera4c704b2013-10-29 23:43:41 +0100282static PyObject*
Christian Heimes33fe8092008-04-13 13:53:33 +0000283get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
284 PyObject *module, PyObject **item)
285{
Brett Cannon0759dd62009-04-01 18:13:07 +0000286 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000287 Py_ssize_t i;
288 PyObject *warnings_filters;
Victor Stinner82656272017-11-22 23:51:42 +0100289 _Py_IDENTIFIER(filters);
Victor Stinner66b79732020-03-02 15:02:18 +0100290 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -0400291 if (st == NULL) {
292 return NULL;
293 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000294
Victor Stinner82656272017-11-22 23:51:42 +0100295 warnings_filters = get_warnings_attr(&PyId_filters, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000296 if (warnings_filters == NULL) {
297 if (PyErr_Occurred())
298 return NULL;
299 }
300 else {
Eric Snow86ea5812019-05-10 13:29:55 -0400301 Py_SETREF(st->filters, warnings_filters);
Christian Heimes33fe8092008-04-13 13:53:33 +0000302 }
303
Eric Snow86ea5812019-05-10 13:29:55 -0400304 PyObject *filters = st->filters;
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600305 if (filters == NULL || !PyList_Check(filters)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000306 PyErr_SetString(PyExc_ValueError,
307 MODULE_NAME ".filters must be a list");
308 return NULL;
309 }
310
Eric Snow86ea5812019-05-10 13:29:55 -0400311 /* WarningsState.filters could change while we are iterating over it. */
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600312 for (i = 0; i < PyList_GET_SIZE(filters); i++) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000313 PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
314 Py_ssize_t ln;
315 int is_subclass, good_msg, good_mod;
316
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600317 tmp_item = PyList_GET_ITEM(filters, i);
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400318 if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000319 PyErr_Format(PyExc_ValueError,
320 MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
321 return NULL;
322 }
323
324 /* Python code: action, msg, cat, mod, ln = item */
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400325 Py_INCREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000326 action = PyTuple_GET_ITEM(tmp_item, 0);
327 msg = PyTuple_GET_ITEM(tmp_item, 1);
328 cat = PyTuple_GET_ITEM(tmp_item, 2);
329 mod = PyTuple_GET_ITEM(tmp_item, 3);
330 ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
331
Oren Milman9d984fd2017-09-12 00:18:09 +0300332 if (!PyUnicode_Check(action)) {
333 PyErr_Format(PyExc_TypeError,
334 "action must be a string, not '%.200s'",
335 Py_TYPE(action)->tp_name);
336 Py_DECREF(tmp_item);
337 return NULL;
338 }
339
Christian Heimes33fe8092008-04-13 13:53:33 +0000340 good_msg = check_matched(msg, text);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400341 if (good_msg == -1) {
342 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100343 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400344 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100345
Christian Heimes33fe8092008-04-13 13:53:33 +0000346 good_mod = check_matched(mod, module);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400347 if (good_mod == -1) {
348 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100349 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400350 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100351
Christian Heimes33fe8092008-04-13 13:53:33 +0000352 is_subclass = PyObject_IsSubclass(category, cat);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400353 if (is_subclass == -1) {
354 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100355 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400356 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100357
Christian Heimes33fe8092008-04-13 13:53:33 +0000358 ln = PyLong_AsSsize_t(ln_obj);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400359 if (ln == -1 && PyErr_Occurred()) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400360 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000361 return NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400362 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000363
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400364 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
365 *item = tmp_item;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100366 return action;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400367 }
368
369 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000370 }
371
Eric Snow86ea5812019-05-10 13:29:55 -0400372 action = get_default_action(st);
Brett Cannon0759dd62009-04-01 18:13:07 +0000373 if (action != NULL) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400374 Py_INCREF(Py_None);
375 *item = Py_None;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100376 return action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000377 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000378
Christian Heimes33fe8092008-04-13 13:53:33 +0000379 return NULL;
380}
381
Brett Cannon0759dd62009-04-01 18:13:07 +0000382
Christian Heimes33fe8092008-04-13 13:53:33 +0000383static int
384already_warned(PyObject *registry, PyObject *key, int should_set)
385{
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200386 PyObject *version_obj, *already_warned;
387 _Py_IDENTIFIER(version);
Christian Heimes33fe8092008-04-13 13:53:33 +0000388
389 if (key == NULL)
390 return -1;
391
Victor Stinner66b79732020-03-02 15:02:18 +0100392 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -0400393 if (st == NULL) {
394 return -1;
395 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200396 version_obj = _PyDict_GetItemIdWithError(registry, &PyId_version);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200397 if (version_obj == NULL
398 || !PyLong_CheckExact(version_obj)
Eric Snow86ea5812019-05-10 13:29:55 -0400399 || PyLong_AsLong(version_obj) != st->filters_version)
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200400 {
401 if (PyErr_Occurred()) {
402 return -1;
403 }
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200404 PyDict_Clear(registry);
Eric Snow86ea5812019-05-10 13:29:55 -0400405 version_obj = PyLong_FromLong(st->filters_version);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200406 if (version_obj == NULL)
407 return -1;
408 if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
409 Py_DECREF(version_obj);
410 return -1;
411 }
412 Py_DECREF(version_obj);
413 }
414 else {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200415 already_warned = PyDict_GetItemWithError(registry, key);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200416 if (already_warned != NULL) {
417 int rc = PyObject_IsTrue(already_warned);
418 if (rc != 0)
419 return rc;
420 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200421 else if (PyErr_Occurred()) {
422 return -1;
423 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000424 }
425
426 /* This warning wasn't found in the registry, set it. */
427 if (should_set)
428 return PyDict_SetItem(registry, key, Py_True);
429 return 0;
430}
431
432/* New reference. */
433static PyObject *
434normalize_module(PyObject *filename)
435{
436 PyObject *module;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100437 int kind;
438 void *data;
Christian Heimes33fe8092008-04-13 13:53:33 +0000439 Py_ssize_t len;
440
Victor Stinner9e30aa52011-11-21 02:49:52 +0100441 len = PyUnicode_GetLength(filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000442 if (len < 0)
443 return NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100444
445 if (len == 0)
446 return PyUnicode_FromString("<unknown>");
447
448 kind = PyUnicode_KIND(filename);
449 data = PyUnicode_DATA(filename);
450
451 /* if filename.endswith(".py"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000452 if (len >= 3 &&
Victor Stinnera4c704b2013-10-29 23:43:41 +0100453 PyUnicode_READ(kind, data, len-3) == '.' &&
454 PyUnicode_READ(kind, data, len-2) == 'p' &&
455 PyUnicode_READ(kind, data, len-1) == 'y')
456 {
Victor Stinner9e30aa52011-11-21 02:49:52 +0100457 module = PyUnicode_Substring(filename, 0, len-3);
Christian Heimes33fe8092008-04-13 13:53:33 +0000458 }
459 else {
460 module = filename;
461 Py_INCREF(module);
462 }
463 return module;
464}
465
466static int
467update_registry(PyObject *registry, PyObject *text, PyObject *category,
468 int add_zero)
469{
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300470 PyObject *altkey;
Christian Heimes33fe8092008-04-13 13:53:33 +0000471 int rc;
472
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300473 if (add_zero)
474 altkey = PyTuple_Pack(3, text, category, _PyLong_Zero);
Christian Heimes33fe8092008-04-13 13:53:33 +0000475 else
476 altkey = PyTuple_Pack(2, text, category);
477
478 rc = already_warned(registry, altkey, 1);
Christian Heimes33fe8092008-04-13 13:53:33 +0000479 Py_XDECREF(altkey);
480 return rc;
481}
482
483static void
Victor Stinner914cde82016-03-19 01:03:51 +0100484show_warning(PyObject *filename, int lineno, PyObject *text,
485 PyObject *category, PyObject *sourceline)
Christian Heimes33fe8092008-04-13 13:53:33 +0000486{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 PyObject *f_stderr;
488 PyObject *name;
Christian Heimes33fe8092008-04-13 13:53:33 +0000489 char lineno_str[128];
490
491 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
492
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200493 name = _PyObject_GetAttrId(category, &PyId___name__);
Hai Shi57c78102020-03-14 21:40:58 +0800494 if (name == NULL) {
Victor Stinnerae233ea2013-10-31 14:51:38 +0100495 goto error;
Hai Shi57c78102020-03-14 21:40:58 +0800496 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000497
Victor Stinnerbd303c12013-11-07 23:07:29 +0100498 f_stderr = _PySys_GetObjectId(&PyId_stderr);
Christian Heimes33fe8092008-04-13 13:53:33 +0000499 if (f_stderr == NULL) {
500 fprintf(stderr, "lost sys.stderr\n");
Victor Stinnerae233ea2013-10-31 14:51:38 +0100501 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000502 }
503
504 /* Print "filename:lineno: category: text\n" */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100505 if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
506 goto error;
507 if (PyFile_WriteString(lineno_str, f_stderr) < 0)
508 goto error;
509 if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
510 goto error;
511 if (PyFile_WriteString(": ", f_stderr) < 0)
512 goto error;
513 if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
514 goto error;
515 if (PyFile_WriteString("\n", f_stderr) < 0)
516 goto error;
517 Py_CLEAR(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000518
519 /* Print " source_line\n" */
Christian Heimes33fe8092008-04-13 13:53:33 +0000520 if (sourceline) {
Victor Stinnera4c704b2013-10-29 23:43:41 +0100521 int kind;
522 void *data;
523 Py_ssize_t i, len;
524 Py_UCS4 ch;
525 PyObject *truncated;
Christian Heimes33fe8092008-04-13 13:53:33 +0000526
Victor Stinnera4c704b2013-10-29 23:43:41 +0100527 if (PyUnicode_READY(sourceline) < 1)
528 goto error;
529
530 kind = PyUnicode_KIND(sourceline);
531 data = PyUnicode_DATA(sourceline);
532 len = PyUnicode_GET_LENGTH(sourceline);
533 for (i=0; i<len; i++) {
534 ch = PyUnicode_READ(kind, data, i);
535 if (ch != ' ' && ch != '\t' && ch != '\014')
536 break;
537 }
538
539 truncated = PyUnicode_Substring(sourceline, i, len);
540 if (truncated == NULL)
541 goto error;
542
543 PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
544 Py_DECREF(truncated);
Christian Heimes33fe8092008-04-13 13:53:33 +0000545 PyFile_WriteString("\n", f_stderr);
546 }
Victor Stinner78e2c982013-07-16 01:54:37 +0200547 else {
548 _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
549 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100550
551error:
Victor Stinnerae233ea2013-10-31 14:51:38 +0100552 Py_XDECREF(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000553 PyErr_Clear();
554}
555
Victor Stinner1231a462016-03-19 00:47:17 +0100556static int
557call_show_warning(PyObject *category, PyObject *text, PyObject *message,
558 PyObject *filename, int lineno, PyObject *lineno_obj,
Victor Stinner914cde82016-03-19 01:03:51 +0100559 PyObject *sourceline, PyObject *source)
Victor Stinner1231a462016-03-19 00:47:17 +0100560{
561 PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
Victor Stinner82656272017-11-22 23:51:42 +0100562 _Py_IDENTIFIER(_showwarnmsg);
563 _Py_IDENTIFIER(WarningMessage);
Victor Stinner1231a462016-03-19 00:47:17 +0100564
Victor Stinnere98445a2016-03-23 00:54:48 +0100565 /* If the source parameter is set, try to get the Python implementation.
566 The Python implementation is able to log the traceback where the source
luzpaza5293b42017-11-05 07:37:50 -0600567 was allocated, whereas the C implementation doesn't. */
Victor Stinner82656272017-11-22 23:51:42 +0100568 show_fn = get_warnings_attr(&PyId__showwarnmsg, source != NULL);
Victor Stinner1231a462016-03-19 00:47:17 +0100569 if (show_fn == NULL) {
570 if (PyErr_Occurred())
571 return -1;
572 show_warning(filename, lineno, text, category, sourceline);
573 return 0;
574 }
575
576 if (!PyCallable_Check(show_fn)) {
577 PyErr_SetString(PyExc_TypeError,
578 "warnings._showwarnmsg() must be set to a callable");
579 goto error;
580 }
581
Victor Stinner82656272017-11-22 23:51:42 +0100582 warnmsg_cls = get_warnings_attr(&PyId_WarningMessage, 0);
Victor Stinner1231a462016-03-19 00:47:17 +0100583 if (warnmsg_cls == NULL) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200584 if (!PyErr_Occurred()) {
585 PyErr_SetString(PyExc_RuntimeError,
586 "unable to get warnings.WarningMessage");
587 }
Victor Stinner1231a462016-03-19 00:47:17 +0100588 goto error;
589 }
590
591 msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
Victor Stinner914cde82016-03-19 01:03:51 +0100592 filename, lineno_obj, Py_None, Py_None, source,
Victor Stinner1231a462016-03-19 00:47:17 +0100593 NULL);
594 Py_DECREF(warnmsg_cls);
595 if (msg == NULL)
596 goto error;
597
Petr Viktorinffd97532020-02-11 17:46:57 +0100598 res = PyObject_CallOneArg(show_fn, msg);
Victor Stinner1231a462016-03-19 00:47:17 +0100599 Py_DECREF(show_fn);
600 Py_DECREF(msg);
601
602 if (res == NULL)
603 return -1;
604
605 Py_DECREF(res);
606 return 0;
607
608error:
609 Py_XDECREF(show_fn);
610 return -1;
611}
612
Christian Heimes33fe8092008-04-13 13:53:33 +0000613static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614warn_explicit(PyObject *category, PyObject *message,
Christian Heimes33fe8092008-04-13 13:53:33 +0000615 PyObject *filename, int lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100616 PyObject *module, PyObject *registry, PyObject *sourceline,
617 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000618{
619 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400620 PyObject *item = NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100621 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000622 int rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100624 /* module can be None if a warning is emitted late during Python shutdown.
625 In this case, the Python warnings module was probably unloaded, filters
626 are no more available to choose as action. It is safer to ignore the
627 warning and do nothing. */
628 if (module == Py_None)
629 Py_RETURN_NONE;
630
Brett Cannondb734912008-06-27 00:52:15 +0000631 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
Oren Milman252033d2017-09-11 09:28:39 +0300632 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
Brett Cannondb734912008-06-27 00:52:15 +0000633 return NULL;
634 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000635
636 /* Normalize module. */
637 if (module == NULL) {
638 module = normalize_module(filename);
639 if (module == NULL)
640 return NULL;
641 }
642 else
643 Py_INCREF(module);
644
645 /* Normalize message. */
646 Py_INCREF(message); /* DECREF'ed in cleanup. */
647 rc = PyObject_IsInstance(message, PyExc_Warning);
648 if (rc == -1) {
649 goto cleanup;
650 }
651 if (rc == 1) {
652 text = PyObject_Str(message);
Hirokazu Yamamoto1c0c0032009-07-17 06:55:42 +0000653 if (text == NULL)
654 goto cleanup;
Victor Stinnera102ed72020-02-07 02:24:48 +0100655 category = (PyObject*)Py_TYPE(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000656 }
657 else {
658 text = message;
Petr Viktorinffd97532020-02-11 17:46:57 +0100659 message = PyObject_CallOneArg(category, message);
Brett Cannondb734912008-06-27 00:52:15 +0000660 if (message == NULL)
661 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000662 }
663
664 lineno_obj = PyLong_FromLong(lineno);
665 if (lineno_obj == NULL)
666 goto cleanup;
667
Victor Stinner22f18752016-12-09 18:08:18 +0100668 if (source == Py_None) {
669 source = NULL;
670 }
671
Christian Heimes33fe8092008-04-13 13:53:33 +0000672 /* Create key. */
673 key = PyTuple_Pack(3, text, category, lineno_obj);
674 if (key == NULL)
675 goto cleanup;
676
Brett Cannondb734912008-06-27 00:52:15 +0000677 if ((registry != NULL) && (registry != Py_None)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000678 rc = already_warned(registry, key, 0);
679 if (rc == -1)
680 goto cleanup;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 else if (rc == 1)
Christian Heimes33fe8092008-04-13 13:53:33 +0000682 goto return_none;
683 /* Else this warning hasn't been generated before. */
684 }
685
686 action = get_filter(category, text, lineno, module, &item);
687 if (action == NULL)
688 goto cleanup;
689
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200690 if (_PyUnicode_EqualToASCIIString(action, "error")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000691 PyErr_SetObject(category, message);
692 goto cleanup;
693 }
694
Victor Stinnerc9758782017-11-27 16:57:07 +0100695 if (_PyUnicode_EqualToASCIIString(action, "ignore")) {
696 goto return_none;
697 }
698
Christian Heimes33fe8092008-04-13 13:53:33 +0000699 /* Store in the registry that we've been here, *except* when the action
700 is "always". */
701 rc = 0;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200702 if (!_PyUnicode_EqualToASCIIString(action, "always")) {
Brett Cannondb734912008-06-27 00:52:15 +0000703 if (registry != NULL && registry != Py_None &&
Victor Stinnerc9758782017-11-27 16:57:07 +0100704 PyDict_SetItem(registry, key, Py_True) < 0)
705 {
Christian Heimes33fe8092008-04-13 13:53:33 +0000706 goto cleanup;
Victor Stinnerc9758782017-11-27 16:57:07 +0100707 }
708
709 if (_PyUnicode_EqualToASCIIString(action, "once")) {
Brett Cannondb734912008-06-27 00:52:15 +0000710 if (registry == NULL || registry == Py_None) {
Victor Stinner66b79732020-03-02 15:02:18 +0100711 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -0400712 if (st == NULL) {
713 goto cleanup;
714 }
715 registry = get_once_registry(st);
Christian Heimes33fe8092008-04-13 13:53:33 +0000716 if (registry == NULL)
717 goto cleanup;
718 }
Eric Snow86ea5812019-05-10 13:29:55 -0400719 /* WarningsState.once_registry[(text, category)] = 1 */
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, "module")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000723 /* registry[(text, category, 0)] = 1 */
Brett Cannondb734912008-06-27 00:52:15 +0000724 if (registry != NULL && registry != Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000726 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200727 else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000728 PyErr_Format(PyExc_RuntimeError,
Victor Stinnera4c704b2013-10-29 23:43:41 +0100729 "Unrecognized action (%R) in warnings.filters:\n %R",
730 action, item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000731 goto cleanup;
732 }
733 }
734
Christian Heimes1a8501c2008-10-02 19:56:01 +0000735 if (rc == 1) /* Already warned for this module. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000736 goto return_none;
737 if (rc == 0) {
Victor Stinner1231a462016-03-19 00:47:17 +0100738 if (call_show_warning(category, text, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100739 lineno_obj, sourceline, source) < 0)
Victor Stinner1231a462016-03-19 00:47:17 +0100740 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000741 }
742 else /* if (rc == -1) */
743 goto cleanup;
744
745 return_none:
746 result = Py_None;
747 Py_INCREF(result);
748
749 cleanup:
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400750 Py_XDECREF(item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000751 Py_XDECREF(key);
752 Py_XDECREF(text);
753 Py_XDECREF(lineno_obj);
754 Py_DECREF(module);
Brett Cannondb734912008-06-27 00:52:15 +0000755 Py_XDECREF(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000756 return result; /* Py_None or NULL. */
757}
758
Larry Hastings714e4932015-09-06 00:39:37 -0700759static int
760is_internal_frame(PyFrameObject *frame)
761{
762 static PyObject *importlib_string = NULL;
763 static PyObject *bootstrap_string = NULL;
764 PyObject *filename;
765 int contains;
766
767 if (importlib_string == NULL) {
768 importlib_string = PyUnicode_FromString("importlib");
769 if (importlib_string == NULL) {
770 return 0;
771 }
772
773 bootstrap_string = PyUnicode_FromString("_bootstrap");
774 if (bootstrap_string == NULL) {
775 Py_DECREF(importlib_string);
776 return 0;
777 }
778 Py_INCREF(importlib_string);
779 Py_INCREF(bootstrap_string);
780 }
781
782 if (frame == NULL || frame->f_code == NULL ||
783 frame->f_code->co_filename == NULL) {
784 return 0;
785 }
786 filename = frame->f_code->co_filename;
787 if (!PyUnicode_Check(filename)) {
788 return 0;
789 }
790 contains = PyUnicode_Contains(filename, importlib_string);
791 if (contains < 0) {
792 return 0;
793 }
794 else if (contains > 0) {
795 contains = PyUnicode_Contains(filename, bootstrap_string);
796 if (contains < 0) {
797 return 0;
798 }
799 else if (contains > 0) {
800 return 1;
801 }
802 }
803
804 return 0;
805}
806
807static PyFrameObject *
808next_external_frame(PyFrameObject *frame)
809{
810 do {
811 frame = frame->f_back;
812 } while (frame != NULL && is_internal_frame(frame));
813
814 return frame;
815}
816
Christian Heimes33fe8092008-04-13 13:53:33 +0000817/* filename, module, and registry are new refs, globals is borrowed */
818/* Returns 0 on error (no new refs), 1 on success */
819static int
820setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
821 PyObject **module, PyObject **registry)
822{
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200823 _Py_IDENTIFIER(__warningregistry__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000824 PyObject *globals;
825
Thomas Kluyver11a89662018-06-08 21:28:37 +0200826 /* Setup globals, filename and lineno. */
Victor Stinner50b48572018-11-01 01:51:40 +0100827 PyFrameObject *f = _PyThreadState_GET()->frame;
Larry Hastings714e4932015-09-06 00:39:37 -0700828 // Stack level comparisons to Python code is off by one as there is no
829 // warnings-related stack level to avoid.
830 if (stack_level <= 0 || is_internal_frame(f)) {
831 while (--stack_level > 0 && f != NULL) {
832 f = f->f_back;
833 }
834 }
835 else {
836 while (--stack_level > 0 && f != NULL) {
837 f = next_external_frame(f);
838 }
839 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000840
841 if (f == NULL) {
Victor Stinnercaba55b2018-08-03 15:33:52 +0200842 globals = _PyInterpreterState_GET_UNSAFE()->sysdict;
Thomas Kluyver11a89662018-06-08 21:28:37 +0200843 *filename = PyUnicode_FromString("sys");
Christian Heimes33fe8092008-04-13 13:53:33 +0000844 *lineno = 1;
845 }
846 else {
847 globals = f->f_globals;
Thomas Kluyver11a89662018-06-08 21:28:37 +0200848 *filename = f->f_code->co_filename;
849 Py_INCREF(*filename);
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000850 *lineno = PyFrame_GetLineNumber(f);
Christian Heimes33fe8092008-04-13 13:53:33 +0000851 }
852
853 *module = NULL;
854
855 /* Setup registry. */
856 assert(globals != NULL);
857 assert(PyDict_Check(globals));
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200858 *registry = _PyDict_GetItemIdWithError(globals, &PyId___warningregistry__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000859 if (*registry == NULL) {
860 int rc;
861
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200862 if (PyErr_Occurred()) {
Serhiy Storchaka2d2f8552020-03-02 22:05:08 +0200863 goto handle_error;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200864 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000865 *registry = PyDict_New();
866 if (*registry == NULL)
Serhiy Storchaka2d2f8552020-03-02 22:05:08 +0200867 goto handle_error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000868
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200869 rc = _PyDict_SetItemId(globals, &PyId___warningregistry__, *registry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000870 if (rc < 0)
871 goto handle_error;
872 }
873 else
874 Py_INCREF(*registry);
875
876 /* Setup module. */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200877 *module = _PyDict_GetItemIdWithError(globals, &PyId___name__);
Oren Milman5d3e8002017-09-24 21:28:42 +0300878 if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) {
879 Py_INCREF(*module);
880 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200881 else if (PyErr_Occurred()) {
882 goto handle_error;
883 }
Oren Milman5d3e8002017-09-24 21:28:42 +0300884 else {
Christian Heimes33fe8092008-04-13 13:53:33 +0000885 *module = PyUnicode_FromString("<string>");
886 if (*module == NULL)
887 goto handle_error;
888 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000889
Christian Heimes33fe8092008-04-13 13:53:33 +0000890 return 1;
891
892 handle_error:
Christian Heimes33fe8092008-04-13 13:53:33 +0000893 Py_XDECREF(*registry);
894 Py_XDECREF(*module);
Serhiy Storchakaae75a292020-03-03 19:43:29 +0200895 Py_DECREF(*filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000896 return 0;
897}
898
899static PyObject *
900get_category(PyObject *message, PyObject *category)
901{
902 int rc;
903
904 /* Get category. */
905 rc = PyObject_IsInstance(message, PyExc_Warning);
906 if (rc == -1)
907 return NULL;
908
909 if (rc == 1)
Victor Stinnera102ed72020-02-07 02:24:48 +0100910 category = (PyObject*)Py_TYPE(message);
Berker Peksagd8089e02014-07-11 19:50:25 +0300911 else if (category == NULL || category == Py_None)
Christian Heimes33fe8092008-04-13 13:53:33 +0000912 category = PyExc_UserWarning;
913
914 /* Validate category. */
915 rc = PyObject_IsSubclass(category, PyExc_Warning);
Berker Peksagd8089e02014-07-11 19:50:25 +0300916 /* category is not a subclass of PyExc_Warning or
917 PyObject_IsSubclass raised an error */
918 if (rc == -1 || rc == 0) {
919 PyErr_Format(PyExc_TypeError,
920 "category must be a Warning subclass, not '%s'",
921 Py_TYPE(category)->tp_name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000922 return NULL;
923 }
924
925 return category;
926}
927
928static PyObject *
Victor Stinner914cde82016-03-19 01:03:51 +0100929do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
930 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000931{
932 PyObject *filename, *module, *registry, *res;
933 int lineno;
934
935 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
936 return NULL;
937
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100938 res = warn_explicit(category, message, filename, lineno, module, registry,
Victor Stinner914cde82016-03-19 01:03:51 +0100939 NULL, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000940 Py_DECREF(filename);
941 Py_DECREF(registry);
942 Py_DECREF(module);
943 return res;
944}
945
Victor Stinner22f18752016-12-09 18:08:18 +0100946/*[clinic input]
947warn as warnings_warn
948
949 message: object
950 category: object = None
951 stacklevel: Py_ssize_t = 1
952 source: object = None
953
954Issue a warning, or maybe ignore it or raise an exception.
955[clinic start generated code]*/
956
Christian Heimes33fe8092008-04-13 13:53:33 +0000957static PyObject *
Victor Stinner22f18752016-12-09 18:08:18 +0100958warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
959 Py_ssize_t stacklevel, PyObject *source)
960/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
Christian Heimes33fe8092008-04-13 13:53:33 +0000961{
Christian Heimes33fe8092008-04-13 13:53:33 +0000962 category = get_category(message, category);
963 if (category == NULL)
964 return NULL;
Victor Stinner22f18752016-12-09 18:08:18 +0100965 return do_warn(message, category, stacklevel, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000966}
967
968static PyObject *
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200969get_source_line(PyObject *module_globals, int lineno)
970{
971 _Py_IDENTIFIER(get_source);
972 _Py_IDENTIFIER(__loader__);
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200973 PyObject *loader;
974 PyObject *module_name;
975 PyObject *get_source;
976 PyObject *source;
977 PyObject *source_list;
978 PyObject *source_line;
979
980 /* Check/get the requisite pieces needed for the loader. */
981 loader = _PyDict_GetItemIdWithError(module_globals, &PyId___loader__);
982 if (loader == NULL) {
983 return NULL;
984 }
985 Py_INCREF(loader);
986 module_name = _PyDict_GetItemIdWithError(module_globals, &PyId___name__);
987 if (!module_name) {
988 Py_DECREF(loader);
989 return NULL;
990 }
991 Py_INCREF(module_name);
992
993 /* Make sure the loader implements the optional get_source() method. */
Serhiy Storchakaf320be72018-01-25 10:49:40 +0200994 (void)_PyObject_LookupAttrId(loader, &PyId_get_source, &get_source);
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200995 Py_DECREF(loader);
996 if (!get_source) {
997 Py_DECREF(module_name);
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200998 return NULL;
999 }
1000 /* Call get_source() to get the source code. */
Petr Viktorinffd97532020-02-11 17:46:57 +01001001 source = PyObject_CallOneArg(get_source, module_name);
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001002 Py_DECREF(get_source);
1003 Py_DECREF(module_name);
1004 if (!source) {
1005 return NULL;
1006 }
1007 if (source == Py_None) {
1008 Py_DECREF(source);
1009 return NULL;
1010 }
1011
1012 /* Split the source into lines. */
1013 source_list = PyUnicode_Splitlines(source, 0);
1014 Py_DECREF(source);
1015 if (!source_list) {
1016 return NULL;
1017 }
1018
1019 /* Get the source line. */
1020 source_line = PyList_GetItem(source_list, lineno-1);
1021 Py_XINCREF(source_line);
1022 Py_DECREF(source_list);
1023 return source_line;
1024}
1025
1026static PyObject *
Christian Heimes33fe8092008-04-13 13:53:33 +00001027warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
1028{
1029 static char *kwd_list[] = {"message", "category", "filename", "lineno",
Victor Stinner914cde82016-03-19 01:03:51 +01001030 "module", "registry", "module_globals",
1031 "source", 0};
Christian Heimes33fe8092008-04-13 13:53:33 +00001032 PyObject *message;
1033 PyObject *category;
1034 PyObject *filename;
1035 int lineno;
1036 PyObject *module = NULL;
1037 PyObject *registry = NULL;
1038 PyObject *module_globals = NULL;
Victor Stinner914cde82016-03-19 01:03:51 +01001039 PyObject *sourceobj = NULL;
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001040 PyObject *source_line = NULL;
1041 PyObject *returned;
Christian Heimes33fe8092008-04-13 13:53:33 +00001042
Victor Stinner914cde82016-03-19 01:03:51 +01001043 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
Christian Heimes33fe8092008-04-13 13:53:33 +00001044 kwd_list, &message, &category, &filename, &lineno, &module,
Victor Stinner914cde82016-03-19 01:03:51 +01001045 &registry, &module_globals, &sourceobj))
Christian Heimes33fe8092008-04-13 13:53:33 +00001046 return NULL;
1047
Victor Stinnerb0565622018-05-15 20:42:12 +02001048 if (module_globals && module_globals != Py_None) {
1049 if (!PyDict_Check(module_globals)) {
1050 PyErr_Format(PyExc_TypeError,
1051 "module_globals must be a dict, not '%.200s'",
1052 Py_TYPE(module_globals)->tp_name);
1053 return NULL;
1054 }
1055
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001056 source_line = get_source_line(module_globals, lineno);
1057 if (source_line == NULL && PyErr_Occurred()) {
Christian Heimes33fe8092008-04-13 13:53:33 +00001058 return NULL;
1059 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001060 }
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001061 returned = warn_explicit(category, message, filename, lineno, module,
1062 registry, source_line, sourceobj);
1063 Py_XDECREF(source_line);
1064 return returned;
Christian Heimes33fe8092008-04-13 13:53:33 +00001065}
1066
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001067static PyObject *
1068warnings_filters_mutated(PyObject *self, PyObject *args)
1069{
Victor Stinner66b79732020-03-02 15:02:18 +01001070 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -04001071 if (st == NULL) {
1072 return NULL;
1073 }
1074 st->filters_version++;
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001075 Py_RETURN_NONE;
1076}
1077
Christian Heimes33fe8092008-04-13 13:53:33 +00001078
1079/* Function to issue a warning message; may raise an exception. */
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001080
1081static int
1082warn_unicode(PyObject *category, PyObject *message,
Victor Stinner914cde82016-03-19 01:03:51 +01001083 Py_ssize_t stack_level, PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +00001084{
1085 PyObject *res;
Christian Heimes33fe8092008-04-13 13:53:33 +00001086
1087 if (category == NULL)
1088 category = PyExc_RuntimeWarning;
1089
Victor Stinner914cde82016-03-19 01:03:51 +01001090 res = do_warn(message, category, stack_level, source);
Christian Heimes33fe8092008-04-13 13:53:33 +00001091 if (res == NULL)
1092 return -1;
1093 Py_DECREF(res);
1094
1095 return 0;
1096}
1097
Victor Stinner914cde82016-03-19 01:03:51 +01001098static int
1099_PyErr_WarnFormatV(PyObject *source,
1100 PyObject *category, Py_ssize_t stack_level,
1101 const char *format, va_list vargs)
1102{
1103 PyObject *message;
1104 int res;
1105
1106 message = PyUnicode_FromFormatV(format, vargs);
1107 if (message == NULL)
1108 return -1;
1109
1110 res = warn_unicode(category, message, stack_level, source);
1111 Py_DECREF(message);
1112 return res;
1113}
1114
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001115int
1116PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
1117 const char *format, ...)
1118{
Victor Stinner914cde82016-03-19 01:03:51 +01001119 int res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001120 va_list vargs;
1121
1122#ifdef HAVE_STDARG_PROTOTYPES
1123 va_start(vargs, format);
1124#else
1125 va_start(vargs);
1126#endif
Victor Stinner914cde82016-03-19 01:03:51 +01001127 res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001128 va_end(vargs);
Victor Stinner914cde82016-03-19 01:03:51 +01001129 return res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001130}
1131
1132int
Victor Stinner914cde82016-03-19 01:03:51 +01001133PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
1134 const char *format, ...)
1135{
1136 int res;
1137 va_list vargs;
1138
1139#ifdef HAVE_STDARG_PROTOTYPES
1140 va_start(vargs, format);
1141#else
1142 va_start(vargs);
1143#endif
1144 res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
1145 stack_level, format, vargs);
1146 va_end(vargs);
1147 return res;
1148}
1149
1150
1151int
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001152PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
1153{
1154 int ret;
1155 PyObject *message = PyUnicode_FromString(text);
1156 if (message == NULL)
1157 return -1;
Victor Stinner914cde82016-03-19 01:03:51 +01001158 ret = warn_unicode(category, message, stack_level, NULL);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001159 Py_DECREF(message);
1160 return ret;
1161}
1162
Ezio Melotti42da6632011-03-15 05:18:48 +02001163/* PyErr_Warn is only for backwards compatibility and will be removed.
Christian Heimes33fe8092008-04-13 13:53:33 +00001164 Use PyErr_WarnEx instead. */
1165
1166#undef PyErr_Warn
1167
Benjamin Petersone5024512018-09-12 12:06:42 -07001168int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001169PyErr_Warn(PyObject *category, const char *text)
Christian Heimes33fe8092008-04-13 13:53:33 +00001170{
1171 return PyErr_WarnEx(category, text, 1);
1172}
1173
1174/* Warning with explicit origin */
1175int
Victor Stinner14e461d2013-08-26 22:28:21 +02001176PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1177 PyObject *filename, int lineno,
1178 PyObject *module, PyObject *registry)
1179{
1180 PyObject *res;
1181 if (category == NULL)
1182 category = PyExc_RuntimeWarning;
1183 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001184 module, registry, NULL, NULL);
Victor Stinner14e461d2013-08-26 22:28:21 +02001185 if (res == NULL)
1186 return -1;
1187 Py_DECREF(res);
1188 return 0;
1189}
1190
1191int
Christian Heimes33fe8092008-04-13 13:53:33 +00001192PyErr_WarnExplicit(PyObject *category, const char *text,
1193 const char *filename_str, int lineno,
1194 const char *module_str, PyObject *registry)
1195{
Christian Heimes33fe8092008-04-13 13:53:33 +00001196 PyObject *message = PyUnicode_FromString(text);
Victor Stinnercb428f02010-12-27 20:10:36 +00001197 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
Christian Heimes33fe8092008-04-13 13:53:33 +00001198 PyObject *module = NULL;
1199 int ret = -1;
1200
1201 if (message == NULL || filename == NULL)
1202 goto exit;
1203 if (module_str != NULL) {
1204 module = PyUnicode_FromString(module_str);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001205 if (module == NULL)
1206 goto exit;
Christian Heimes33fe8092008-04-13 13:53:33 +00001207 }
1208
Victor Stinner14e461d2013-08-26 22:28:21 +02001209 ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1210 module, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +00001211
1212 exit:
1213 Py_XDECREF(message);
1214 Py_XDECREF(module);
1215 Py_XDECREF(filename);
1216 return ret;
1217}
1218
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001219int
1220PyErr_WarnExplicitFormat(PyObject *category,
1221 const char *filename_str, int lineno,
1222 const char *module_str, PyObject *registry,
1223 const char *format, ...)
1224{
1225 PyObject *message;
1226 PyObject *module = NULL;
1227 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1228 int ret = -1;
1229 va_list vargs;
1230
1231 if (filename == NULL)
1232 goto exit;
1233 if (module_str != NULL) {
1234 module = PyUnicode_FromString(module_str);
1235 if (module == NULL)
1236 goto exit;
1237 }
1238
1239#ifdef HAVE_STDARG_PROTOTYPES
1240 va_start(vargs, format);
1241#else
1242 va_start(vargs);
1243#endif
1244 message = PyUnicode_FromFormatV(format, vargs);
1245 if (message != NULL) {
1246 PyObject *res;
1247 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001248 module, registry, NULL, NULL);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001249 Py_DECREF(message);
1250 if (res != NULL) {
1251 Py_DECREF(res);
1252 ret = 0;
1253 }
1254 }
1255 va_end(vargs);
1256exit:
1257 Py_XDECREF(module);
1258 Py_XDECREF(filename);
1259 return ret;
1260}
1261
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001262void
1263_PyErr_WarnUnawaitedCoroutine(PyObject *coro)
1264{
1265 /* First, we attempt to funnel the warning through
1266 warnings._warn_unawaited_coroutine.
1267
1268 This could raise an exception, due to:
1269 - a bug
1270 - some kind of shutdown-related brokenness
1271 - succeeding, but with an "error" warning filter installed, so the
1272 warning is converted into a RuntimeWarning exception
1273
1274 In the first two cases, we want to print the error (so we know what it
1275 is!), and then print a warning directly as a fallback. In the last
1276 case, we want to print the error (since it's the warning!), but *not*
1277 do a fallback. And after we print the error we can't check for what
1278 type of error it was (because PyErr_WriteUnraisable clears it), so we
1279 need a flag to keep track.
1280
1281 Since this is called from __del__ context, it's careful to never raise
1282 an exception.
1283 */
1284 _Py_IDENTIFIER(_warn_unawaited_coroutine);
1285 int warned = 0;
1286 PyObject *fn = get_warnings_attr(&PyId__warn_unawaited_coroutine, 1);
1287 if (fn) {
Petr Viktorinffd97532020-02-11 17:46:57 +01001288 PyObject *res = PyObject_CallOneArg(fn, coro);
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001289 Py_DECREF(fn);
1290 if (res || PyErr_ExceptionMatches(PyExc_RuntimeWarning)) {
1291 warned = 1;
1292 }
1293 Py_XDECREF(res);
1294 }
1295
1296 if (PyErr_Occurred()) {
1297 PyErr_WriteUnraisable(coro);
1298 }
1299 if (!warned) {
Yury Selivanov35103342018-01-21 20:47:04 -05001300 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
1301 "coroutine '%.50S' was never awaited",
1302 ((PyCoroObject *)coro)->cr_qualname) < 0)
1303 {
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001304 PyErr_WriteUnraisable(coro);
1305 }
1306 }
1307}
Christian Heimes33fe8092008-04-13 13:53:33 +00001308
Christian Heimes33fe8092008-04-13 13:53:33 +00001309PyDoc_STRVAR(warn_explicit_doc,
Hansraj Das5dfbb4d2019-10-08 14:26:07 +05301310"Low-level interface to warnings functionality.");
Christian Heimes33fe8092008-04-13 13:53:33 +00001311
1312static PyMethodDef warnings_functions[] = {
Victor Stinner22f18752016-12-09 18:08:18 +01001313 WARNINGS_WARN_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001314 {"warn_explicit", (PyCFunction)(void(*)(void))warnings_warn_explicit,
Christian Heimes33fe8092008-04-13 13:53:33 +00001315 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001316 {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
1317 NULL},
Christian Heimes1a8501c2008-10-02 19:56:01 +00001318 /* XXX(brett.cannon): add showwarning? */
1319 /* XXX(brett.cannon): Reasonable to add formatwarning? */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 {NULL, NULL} /* sentinel */
Christian Heimes33fe8092008-04-13 13:53:33 +00001321};
1322
1323
Martin v. Löwis1a214512008-06-11 05:26:20 +00001324static struct PyModuleDef warningsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 PyModuleDef_HEAD_INIT,
Eric Snow86ea5812019-05-10 13:29:55 -04001326 MODULE_NAME, /* m_name */
1327 warnings__doc__, /* m_doc */
1328 0, /* m_size */
1329 warnings_functions, /* m_methods */
1330 NULL, /* m_reload */
1331 NULL, /* m_traverse */
1332 NULL, /* m_clear */
1333 NULL /* m_free */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001334};
1335
Christian Heimes33fe8092008-04-13 13:53:33 +00001336
Victor Stinner66b79732020-03-02 15:02:18 +01001337PyStatus
1338_PyWarnings_InitState(PyThreadState *tstate)
1339{
1340 if (warnings_init_state(&tstate->interp->warnings) < 0) {
1341 return _PyStatus_ERR("can't initialize warnings");
1342 }
1343 return _PyStatus_OK();
1344}
1345
1346
Victor Stinner5d862462017-12-19 11:35:58 +01001347PyMODINIT_FUNC
1348_PyWarnings_Init(void)
Christian Heimes33fe8092008-04-13 13:53:33 +00001349{
Brett Cannon0759dd62009-04-01 18:13:07 +00001350 PyObject *m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001351
Martin v. Löwis1a214512008-06-11 05:26:20 +00001352 m = PyModule_Create(&warningsmodule);
Eric Snow86ea5812019-05-10 13:29:55 -04001353 if (m == NULL) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00001354 return NULL;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001355 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001356
Victor Stinner66b79732020-03-02 15:02:18 +01001357 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -04001358 if (st == NULL) {
1359 goto error;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001360 }
Victor Stinner66b79732020-03-02 15:02:18 +01001361 if (warnings_init_state(st) < 0) {
Eric Snow86ea5812019-05-10 13:29:55 -04001362 goto error;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001363 }
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001364
Eric Snow86ea5812019-05-10 13:29:55 -04001365 Py_INCREF(st->filters);
1366 if (PyModule_AddObject(m, "filters", st->filters) < 0) {
1367 goto error;
1368 }
1369
1370 Py_INCREF(st->once_registry);
1371 if (PyModule_AddObject(m, "_onceregistry", st->once_registry) < 0) {
1372 goto error;
1373 }
1374
1375 Py_INCREF(st->default_action);
1376 if (PyModule_AddObject(m, "_defaultaction", st->default_action) < 0) {
1377 goto error;
1378 }
1379
Martin v. Löwis1a214512008-06-11 05:26:20 +00001380 return m;
Eric Snow86ea5812019-05-10 13:29:55 -04001381
1382error:
1383 if (st != NULL) {
Victor Stinner66b79732020-03-02 15:02:18 +01001384 warnings_clear_state(st);
Eric Snow86ea5812019-05-10 13:29:55 -04001385 }
1386 Py_DECREF(m);
1387 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001388}
Victor Stinner87d23a02019-04-26 05:49:26 +02001389
Eric Snow86ea5812019-05-10 13:29:55 -04001390// We need this to ensure that warnings still work until late in finalization.
Victor Stinner87d23a02019-04-26 05:49:26 +02001391void
Eric Snow86ea5812019-05-10 13:29:55 -04001392_PyWarnings_Fini(PyInterpreterState *interp)
Victor Stinner87d23a02019-04-26 05:49:26 +02001393{
Victor Stinner66b79732020-03-02 15:02:18 +01001394 warnings_clear_state(&interp->warnings);
Victor Stinner87d23a02019-04-26 05:49:26 +02001395}