blob: 39f8033cd906a6cacc973955645b2e28de5e9588 [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__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000494 if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100495 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000496
Victor Stinnerbd303c12013-11-07 23:07:29 +0100497 f_stderr = _PySys_GetObjectId(&PyId_stderr);
Christian Heimes33fe8092008-04-13 13:53:33 +0000498 if (f_stderr == NULL) {
499 fprintf(stderr, "lost sys.stderr\n");
Victor Stinnerae233ea2013-10-31 14:51:38 +0100500 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000501 }
502
503 /* Print "filename:lineno: category: text\n" */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100504 if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
505 goto error;
506 if (PyFile_WriteString(lineno_str, f_stderr) < 0)
507 goto error;
508 if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
509 goto error;
510 if (PyFile_WriteString(": ", f_stderr) < 0)
511 goto error;
512 if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
513 goto error;
514 if (PyFile_WriteString("\n", f_stderr) < 0)
515 goto error;
516 Py_CLEAR(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000517
518 /* Print " source_line\n" */
Christian Heimes33fe8092008-04-13 13:53:33 +0000519 if (sourceline) {
Victor Stinnera4c704b2013-10-29 23:43:41 +0100520 int kind;
521 void *data;
522 Py_ssize_t i, len;
523 Py_UCS4 ch;
524 PyObject *truncated;
Christian Heimes33fe8092008-04-13 13:53:33 +0000525
Victor Stinnera4c704b2013-10-29 23:43:41 +0100526 if (PyUnicode_READY(sourceline) < 1)
527 goto error;
528
529 kind = PyUnicode_KIND(sourceline);
530 data = PyUnicode_DATA(sourceline);
531 len = PyUnicode_GET_LENGTH(sourceline);
532 for (i=0; i<len; i++) {
533 ch = PyUnicode_READ(kind, data, i);
534 if (ch != ' ' && ch != '\t' && ch != '\014')
535 break;
536 }
537
538 truncated = PyUnicode_Substring(sourceline, i, len);
539 if (truncated == NULL)
540 goto error;
541
542 PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
543 Py_DECREF(truncated);
Christian Heimes33fe8092008-04-13 13:53:33 +0000544 PyFile_WriteString("\n", f_stderr);
545 }
Victor Stinner78e2c982013-07-16 01:54:37 +0200546 else {
547 _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
548 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100549
550error:
Victor Stinnerae233ea2013-10-31 14:51:38 +0100551 Py_XDECREF(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000552 PyErr_Clear();
553}
554
Victor Stinner1231a462016-03-19 00:47:17 +0100555static int
556call_show_warning(PyObject *category, PyObject *text, PyObject *message,
557 PyObject *filename, int lineno, PyObject *lineno_obj,
Victor Stinner914cde82016-03-19 01:03:51 +0100558 PyObject *sourceline, PyObject *source)
Victor Stinner1231a462016-03-19 00:47:17 +0100559{
560 PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
Victor Stinner82656272017-11-22 23:51:42 +0100561 _Py_IDENTIFIER(_showwarnmsg);
562 _Py_IDENTIFIER(WarningMessage);
Victor Stinner1231a462016-03-19 00:47:17 +0100563
Victor Stinnere98445a2016-03-23 00:54:48 +0100564 /* If the source parameter is set, try to get the Python implementation.
565 The Python implementation is able to log the traceback where the source
luzpaza5293b42017-11-05 07:37:50 -0600566 was allocated, whereas the C implementation doesn't. */
Victor Stinner82656272017-11-22 23:51:42 +0100567 show_fn = get_warnings_attr(&PyId__showwarnmsg, source != NULL);
Victor Stinner1231a462016-03-19 00:47:17 +0100568 if (show_fn == NULL) {
569 if (PyErr_Occurred())
570 return -1;
571 show_warning(filename, lineno, text, category, sourceline);
572 return 0;
573 }
574
575 if (!PyCallable_Check(show_fn)) {
576 PyErr_SetString(PyExc_TypeError,
577 "warnings._showwarnmsg() must be set to a callable");
578 goto error;
579 }
580
Victor Stinner82656272017-11-22 23:51:42 +0100581 warnmsg_cls = get_warnings_attr(&PyId_WarningMessage, 0);
Victor Stinner1231a462016-03-19 00:47:17 +0100582 if (warnmsg_cls == NULL) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200583 if (!PyErr_Occurred()) {
584 PyErr_SetString(PyExc_RuntimeError,
585 "unable to get warnings.WarningMessage");
586 }
Victor Stinner1231a462016-03-19 00:47:17 +0100587 goto error;
588 }
589
590 msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
Victor Stinner914cde82016-03-19 01:03:51 +0100591 filename, lineno_obj, Py_None, Py_None, source,
Victor Stinner1231a462016-03-19 00:47:17 +0100592 NULL);
593 Py_DECREF(warnmsg_cls);
594 if (msg == NULL)
595 goto error;
596
Petr Viktorinffd97532020-02-11 17:46:57 +0100597 res = PyObject_CallOneArg(show_fn, msg);
Victor Stinner1231a462016-03-19 00:47:17 +0100598 Py_DECREF(show_fn);
599 Py_DECREF(msg);
600
601 if (res == NULL)
602 return -1;
603
604 Py_DECREF(res);
605 return 0;
606
607error:
608 Py_XDECREF(show_fn);
609 return -1;
610}
611
Christian Heimes33fe8092008-04-13 13:53:33 +0000612static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613warn_explicit(PyObject *category, PyObject *message,
Christian Heimes33fe8092008-04-13 13:53:33 +0000614 PyObject *filename, int lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100615 PyObject *module, PyObject *registry, PyObject *sourceline,
616 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000617{
618 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400619 PyObject *item = NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100620 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000621 int rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100623 /* module can be None if a warning is emitted late during Python shutdown.
624 In this case, the Python warnings module was probably unloaded, filters
625 are no more available to choose as action. It is safer to ignore the
626 warning and do nothing. */
627 if (module == Py_None)
628 Py_RETURN_NONE;
629
Brett Cannondb734912008-06-27 00:52:15 +0000630 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
Oren Milman252033d2017-09-11 09:28:39 +0300631 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
Brett Cannondb734912008-06-27 00:52:15 +0000632 return NULL;
633 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000634
635 /* Normalize module. */
636 if (module == NULL) {
637 module = normalize_module(filename);
638 if (module == NULL)
639 return NULL;
640 }
641 else
642 Py_INCREF(module);
643
644 /* Normalize message. */
645 Py_INCREF(message); /* DECREF'ed in cleanup. */
646 rc = PyObject_IsInstance(message, PyExc_Warning);
647 if (rc == -1) {
648 goto cleanup;
649 }
650 if (rc == 1) {
651 text = PyObject_Str(message);
Hirokazu Yamamoto1c0c0032009-07-17 06:55:42 +0000652 if (text == NULL)
653 goto cleanup;
Victor Stinnera102ed72020-02-07 02:24:48 +0100654 category = (PyObject*)Py_TYPE(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000655 }
656 else {
657 text = message;
Petr Viktorinffd97532020-02-11 17:46:57 +0100658 message = PyObject_CallOneArg(category, message);
Brett Cannondb734912008-06-27 00:52:15 +0000659 if (message == NULL)
660 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000661 }
662
663 lineno_obj = PyLong_FromLong(lineno);
664 if (lineno_obj == NULL)
665 goto cleanup;
666
Victor Stinner22f18752016-12-09 18:08:18 +0100667 if (source == Py_None) {
668 source = NULL;
669 }
670
Christian Heimes33fe8092008-04-13 13:53:33 +0000671 /* Create key. */
672 key = PyTuple_Pack(3, text, category, lineno_obj);
673 if (key == NULL)
674 goto cleanup;
675
Brett Cannondb734912008-06-27 00:52:15 +0000676 if ((registry != NULL) && (registry != Py_None)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000677 rc = already_warned(registry, key, 0);
678 if (rc == -1)
679 goto cleanup;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 else if (rc == 1)
Christian Heimes33fe8092008-04-13 13:53:33 +0000681 goto return_none;
682 /* Else this warning hasn't been generated before. */
683 }
684
685 action = get_filter(category, text, lineno, module, &item);
686 if (action == NULL)
687 goto cleanup;
688
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200689 if (_PyUnicode_EqualToASCIIString(action, "error")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000690 PyErr_SetObject(category, message);
691 goto cleanup;
692 }
693
Victor Stinnerc9758782017-11-27 16:57:07 +0100694 if (_PyUnicode_EqualToASCIIString(action, "ignore")) {
695 goto return_none;
696 }
697
Christian Heimes33fe8092008-04-13 13:53:33 +0000698 /* Store in the registry that we've been here, *except* when the action
699 is "always". */
700 rc = 0;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200701 if (!_PyUnicode_EqualToASCIIString(action, "always")) {
Brett Cannondb734912008-06-27 00:52:15 +0000702 if (registry != NULL && registry != Py_None &&
Victor Stinnerc9758782017-11-27 16:57:07 +0100703 PyDict_SetItem(registry, key, Py_True) < 0)
704 {
Christian Heimes33fe8092008-04-13 13:53:33 +0000705 goto cleanup;
Victor Stinnerc9758782017-11-27 16:57:07 +0100706 }
707
708 if (_PyUnicode_EqualToASCIIString(action, "once")) {
Brett Cannondb734912008-06-27 00:52:15 +0000709 if (registry == NULL || registry == Py_None) {
Victor Stinner66b79732020-03-02 15:02:18 +0100710 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -0400711 if (st == NULL) {
712 goto cleanup;
713 }
714 registry = get_once_registry(st);
Christian Heimes33fe8092008-04-13 13:53:33 +0000715 if (registry == NULL)
716 goto cleanup;
717 }
Eric Snow86ea5812019-05-10 13:29:55 -0400718 /* WarningsState.once_registry[(text, category)] = 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000720 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200721 else if (_PyUnicode_EqualToASCIIString(action, "module")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000722 /* registry[(text, category, 0)] = 1 */
Brett Cannondb734912008-06-27 00:52:15 +0000723 if (registry != NULL && registry != Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000725 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200726 else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000727 PyErr_Format(PyExc_RuntimeError,
Victor Stinnera4c704b2013-10-29 23:43:41 +0100728 "Unrecognized action (%R) in warnings.filters:\n %R",
729 action, item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000730 goto cleanup;
731 }
732 }
733
Christian Heimes1a8501c2008-10-02 19:56:01 +0000734 if (rc == 1) /* Already warned for this module. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000735 goto return_none;
736 if (rc == 0) {
Victor Stinner1231a462016-03-19 00:47:17 +0100737 if (call_show_warning(category, text, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100738 lineno_obj, sourceline, source) < 0)
Victor Stinner1231a462016-03-19 00:47:17 +0100739 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000740 }
741 else /* if (rc == -1) */
742 goto cleanup;
743
744 return_none:
745 result = Py_None;
746 Py_INCREF(result);
747
748 cleanup:
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400749 Py_XDECREF(item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000750 Py_XDECREF(key);
751 Py_XDECREF(text);
752 Py_XDECREF(lineno_obj);
753 Py_DECREF(module);
Brett Cannondb734912008-06-27 00:52:15 +0000754 Py_XDECREF(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000755 return result; /* Py_None or NULL. */
756}
757
Larry Hastings714e4932015-09-06 00:39:37 -0700758static int
759is_internal_frame(PyFrameObject *frame)
760{
761 static PyObject *importlib_string = NULL;
762 static PyObject *bootstrap_string = NULL;
763 PyObject *filename;
764 int contains;
765
766 if (importlib_string == NULL) {
767 importlib_string = PyUnicode_FromString("importlib");
768 if (importlib_string == NULL) {
769 return 0;
770 }
771
772 bootstrap_string = PyUnicode_FromString("_bootstrap");
773 if (bootstrap_string == NULL) {
774 Py_DECREF(importlib_string);
775 return 0;
776 }
777 Py_INCREF(importlib_string);
778 Py_INCREF(bootstrap_string);
779 }
780
781 if (frame == NULL || frame->f_code == NULL ||
782 frame->f_code->co_filename == NULL) {
783 return 0;
784 }
785 filename = frame->f_code->co_filename;
786 if (!PyUnicode_Check(filename)) {
787 return 0;
788 }
789 contains = PyUnicode_Contains(filename, importlib_string);
790 if (contains < 0) {
791 return 0;
792 }
793 else if (contains > 0) {
794 contains = PyUnicode_Contains(filename, bootstrap_string);
795 if (contains < 0) {
796 return 0;
797 }
798 else if (contains > 0) {
799 return 1;
800 }
801 }
802
803 return 0;
804}
805
806static PyFrameObject *
807next_external_frame(PyFrameObject *frame)
808{
809 do {
810 frame = frame->f_back;
811 } while (frame != NULL && is_internal_frame(frame));
812
813 return frame;
814}
815
Christian Heimes33fe8092008-04-13 13:53:33 +0000816/* filename, module, and registry are new refs, globals is borrowed */
817/* Returns 0 on error (no new refs), 1 on success */
818static int
819setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
820 PyObject **module, PyObject **registry)
821{
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200822 _Py_IDENTIFIER(__warningregistry__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000823 PyObject *globals;
824
Thomas Kluyver11a89662018-06-08 21:28:37 +0200825 /* Setup globals, filename and lineno. */
Victor Stinner50b48572018-11-01 01:51:40 +0100826 PyFrameObject *f = _PyThreadState_GET()->frame;
Larry Hastings714e4932015-09-06 00:39:37 -0700827 // Stack level comparisons to Python code is off by one as there is no
828 // warnings-related stack level to avoid.
829 if (stack_level <= 0 || is_internal_frame(f)) {
830 while (--stack_level > 0 && f != NULL) {
831 f = f->f_back;
832 }
833 }
834 else {
835 while (--stack_level > 0 && f != NULL) {
836 f = next_external_frame(f);
837 }
838 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000839
840 if (f == NULL) {
Victor Stinnercaba55b2018-08-03 15:33:52 +0200841 globals = _PyInterpreterState_GET_UNSAFE()->sysdict;
Thomas Kluyver11a89662018-06-08 21:28:37 +0200842 *filename = PyUnicode_FromString("sys");
Christian Heimes33fe8092008-04-13 13:53:33 +0000843 *lineno = 1;
844 }
845 else {
846 globals = f->f_globals;
Thomas Kluyver11a89662018-06-08 21:28:37 +0200847 *filename = f->f_code->co_filename;
848 Py_INCREF(*filename);
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000849 *lineno = PyFrame_GetLineNumber(f);
Christian Heimes33fe8092008-04-13 13:53:33 +0000850 }
851
852 *module = NULL;
853
854 /* Setup registry. */
855 assert(globals != NULL);
856 assert(PyDict_Check(globals));
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200857 *registry = _PyDict_GetItemIdWithError(globals, &PyId___warningregistry__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000858 if (*registry == NULL) {
859 int rc;
860
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200861 if (PyErr_Occurred()) {
Serhiy Storchaka2d2f8552020-03-02 22:05:08 +0200862 goto handle_error;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200863 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000864 *registry = PyDict_New();
865 if (*registry == NULL)
Serhiy Storchaka2d2f8552020-03-02 22:05:08 +0200866 goto handle_error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000867
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200868 rc = _PyDict_SetItemId(globals, &PyId___warningregistry__, *registry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000869 if (rc < 0)
870 goto handle_error;
871 }
872 else
873 Py_INCREF(*registry);
874
875 /* Setup module. */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200876 *module = _PyDict_GetItemIdWithError(globals, &PyId___name__);
Oren Milman5d3e8002017-09-24 21:28:42 +0300877 if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) {
878 Py_INCREF(*module);
879 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200880 else if (PyErr_Occurred()) {
881 goto handle_error;
882 }
Oren Milman5d3e8002017-09-24 21:28:42 +0300883 else {
Christian Heimes33fe8092008-04-13 13:53:33 +0000884 *module = PyUnicode_FromString("<string>");
885 if (*module == NULL)
886 goto handle_error;
887 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000888
Christian Heimes33fe8092008-04-13 13:53:33 +0000889 return 1;
890
891 handle_error:
Christian Heimes33fe8092008-04-13 13:53:33 +0000892 Py_XDECREF(*registry);
893 Py_XDECREF(*module);
Serhiy Storchakaae75a292020-03-03 19:43:29 +0200894 Py_DECREF(*filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000895 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{
Victor Stinner66b79732020-03-02 15:02:18 +01001069 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -04001070 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 Stinner66b79732020-03-02 15:02:18 +01001336PyStatus
1337_PyWarnings_InitState(PyThreadState *tstate)
1338{
1339 if (warnings_init_state(&tstate->interp->warnings) < 0) {
1340 return _PyStatus_ERR("can't initialize warnings");
1341 }
1342 return _PyStatus_OK();
1343}
1344
1345
Victor Stinner5d862462017-12-19 11:35:58 +01001346PyMODINIT_FUNC
1347_PyWarnings_Init(void)
Christian Heimes33fe8092008-04-13 13:53:33 +00001348{
Brett Cannon0759dd62009-04-01 18:13:07 +00001349 PyObject *m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001350
Martin v. Löwis1a214512008-06-11 05:26:20 +00001351 m = PyModule_Create(&warningsmodule);
Eric Snow86ea5812019-05-10 13:29:55 -04001352 if (m == NULL) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00001353 return NULL;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001354 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001355
Victor Stinner66b79732020-03-02 15:02:18 +01001356 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -04001357 if (st == NULL) {
1358 goto error;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001359 }
Victor Stinner66b79732020-03-02 15:02:18 +01001360 if (warnings_init_state(st) < 0) {
Eric Snow86ea5812019-05-10 13:29:55 -04001361 goto error;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001362 }
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001363
Eric Snow86ea5812019-05-10 13:29:55 -04001364 Py_INCREF(st->filters);
1365 if (PyModule_AddObject(m, "filters", st->filters) < 0) {
1366 goto error;
1367 }
1368
1369 Py_INCREF(st->once_registry);
1370 if (PyModule_AddObject(m, "_onceregistry", st->once_registry) < 0) {
1371 goto error;
1372 }
1373
1374 Py_INCREF(st->default_action);
1375 if (PyModule_AddObject(m, "_defaultaction", st->default_action) < 0) {
1376 goto error;
1377 }
1378
Martin v. Löwis1a214512008-06-11 05:26:20 +00001379 return m;
Eric Snow86ea5812019-05-10 13:29:55 -04001380
1381error:
1382 if (st != NULL) {
Victor Stinner66b79732020-03-02 15:02:18 +01001383 warnings_clear_state(st);
Eric Snow86ea5812019-05-10 13:29:55 -04001384 }
1385 Py_DECREF(m);
1386 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001387}
Victor Stinner87d23a02019-04-26 05:49:26 +02001388
Eric Snow86ea5812019-05-10 13:29:55 -04001389// We need this to ensure that warnings still work until late in finalization.
Victor Stinner87d23a02019-04-26 05:49:26 +02001390void
Eric Snow86ea5812019-05-10 13:29:55 -04001391_PyWarnings_Fini(PyInterpreterState *interp)
Victor Stinner87d23a02019-04-26 05:49:26 +02001392{
Victor Stinner66b79732020-03-02 15:02:18 +01001393 warnings_clear_state(&interp->warnings);
Victor Stinner87d23a02019-04-26 05:49:26 +02001394}