blob: 92378faa61f3e3fc3794496b5148cee504b74bf5 [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:
892 /* filename not XDECREF'ed here as there is no way to jump here with a
893 dangling reference. */
894 Py_XDECREF(*registry);
895 Py_XDECREF(*module);
Serhiy Storchaka2d2f8552020-03-02 22:05:08 +0200896 Py_XDECREF(*filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000897 return 0;
898}
899
900static PyObject *
901get_category(PyObject *message, PyObject *category)
902{
903 int rc;
904
905 /* Get category. */
906 rc = PyObject_IsInstance(message, PyExc_Warning);
907 if (rc == -1)
908 return NULL;
909
910 if (rc == 1)
Victor Stinnera102ed72020-02-07 02:24:48 +0100911 category = (PyObject*)Py_TYPE(message);
Berker Peksagd8089e02014-07-11 19:50:25 +0300912 else if (category == NULL || category == Py_None)
Christian Heimes33fe8092008-04-13 13:53:33 +0000913 category = PyExc_UserWarning;
914
915 /* Validate category. */
916 rc = PyObject_IsSubclass(category, PyExc_Warning);
Berker Peksagd8089e02014-07-11 19:50:25 +0300917 /* category is not a subclass of PyExc_Warning or
918 PyObject_IsSubclass raised an error */
919 if (rc == -1 || rc == 0) {
920 PyErr_Format(PyExc_TypeError,
921 "category must be a Warning subclass, not '%s'",
922 Py_TYPE(category)->tp_name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000923 return NULL;
924 }
925
926 return category;
927}
928
929static PyObject *
Victor Stinner914cde82016-03-19 01:03:51 +0100930do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
931 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000932{
933 PyObject *filename, *module, *registry, *res;
934 int lineno;
935
936 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
937 return NULL;
938
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100939 res = warn_explicit(category, message, filename, lineno, module, registry,
Victor Stinner914cde82016-03-19 01:03:51 +0100940 NULL, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000941 Py_DECREF(filename);
942 Py_DECREF(registry);
943 Py_DECREF(module);
944 return res;
945}
946
Victor Stinner22f18752016-12-09 18:08:18 +0100947/*[clinic input]
948warn as warnings_warn
949
950 message: object
951 category: object = None
952 stacklevel: Py_ssize_t = 1
953 source: object = None
954
955Issue a warning, or maybe ignore it or raise an exception.
956[clinic start generated code]*/
957
Christian Heimes33fe8092008-04-13 13:53:33 +0000958static PyObject *
Victor Stinner22f18752016-12-09 18:08:18 +0100959warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
960 Py_ssize_t stacklevel, PyObject *source)
961/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
Christian Heimes33fe8092008-04-13 13:53:33 +0000962{
Christian Heimes33fe8092008-04-13 13:53:33 +0000963 category = get_category(message, category);
964 if (category == NULL)
965 return NULL;
Victor Stinner22f18752016-12-09 18:08:18 +0100966 return do_warn(message, category, stacklevel, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000967}
968
969static PyObject *
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200970get_source_line(PyObject *module_globals, int lineno)
971{
972 _Py_IDENTIFIER(get_source);
973 _Py_IDENTIFIER(__loader__);
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200974 PyObject *loader;
975 PyObject *module_name;
976 PyObject *get_source;
977 PyObject *source;
978 PyObject *source_list;
979 PyObject *source_line;
980
981 /* Check/get the requisite pieces needed for the loader. */
982 loader = _PyDict_GetItemIdWithError(module_globals, &PyId___loader__);
983 if (loader == NULL) {
984 return NULL;
985 }
986 Py_INCREF(loader);
987 module_name = _PyDict_GetItemIdWithError(module_globals, &PyId___name__);
988 if (!module_name) {
989 Py_DECREF(loader);
990 return NULL;
991 }
992 Py_INCREF(module_name);
993
994 /* Make sure the loader implements the optional get_source() method. */
Serhiy Storchakaf320be72018-01-25 10:49:40 +0200995 (void)_PyObject_LookupAttrId(loader, &PyId_get_source, &get_source);
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200996 Py_DECREF(loader);
997 if (!get_source) {
998 Py_DECREF(module_name);
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200999 return NULL;
1000 }
1001 /* Call get_source() to get the source code. */
Petr Viktorinffd97532020-02-11 17:46:57 +01001002 source = PyObject_CallOneArg(get_source, module_name);
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001003 Py_DECREF(get_source);
1004 Py_DECREF(module_name);
1005 if (!source) {
1006 return NULL;
1007 }
1008 if (source == Py_None) {
1009 Py_DECREF(source);
1010 return NULL;
1011 }
1012
1013 /* Split the source into lines. */
1014 source_list = PyUnicode_Splitlines(source, 0);
1015 Py_DECREF(source);
1016 if (!source_list) {
1017 return NULL;
1018 }
1019
1020 /* Get the source line. */
1021 source_line = PyList_GetItem(source_list, lineno-1);
1022 Py_XINCREF(source_line);
1023 Py_DECREF(source_list);
1024 return source_line;
1025}
1026
1027static PyObject *
Christian Heimes33fe8092008-04-13 13:53:33 +00001028warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
1029{
1030 static char *kwd_list[] = {"message", "category", "filename", "lineno",
Victor Stinner914cde82016-03-19 01:03:51 +01001031 "module", "registry", "module_globals",
1032 "source", 0};
Christian Heimes33fe8092008-04-13 13:53:33 +00001033 PyObject *message;
1034 PyObject *category;
1035 PyObject *filename;
1036 int lineno;
1037 PyObject *module = NULL;
1038 PyObject *registry = NULL;
1039 PyObject *module_globals = NULL;
Victor Stinner914cde82016-03-19 01:03:51 +01001040 PyObject *sourceobj = NULL;
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001041 PyObject *source_line = NULL;
1042 PyObject *returned;
Christian Heimes33fe8092008-04-13 13:53:33 +00001043
Victor Stinner914cde82016-03-19 01:03:51 +01001044 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
Christian Heimes33fe8092008-04-13 13:53:33 +00001045 kwd_list, &message, &category, &filename, &lineno, &module,
Victor Stinner914cde82016-03-19 01:03:51 +01001046 &registry, &module_globals, &sourceobj))
Christian Heimes33fe8092008-04-13 13:53:33 +00001047 return NULL;
1048
Victor Stinnerb0565622018-05-15 20:42:12 +02001049 if (module_globals && module_globals != Py_None) {
1050 if (!PyDict_Check(module_globals)) {
1051 PyErr_Format(PyExc_TypeError,
1052 "module_globals must be a dict, not '%.200s'",
1053 Py_TYPE(module_globals)->tp_name);
1054 return NULL;
1055 }
1056
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001057 source_line = get_source_line(module_globals, lineno);
1058 if (source_line == NULL && PyErr_Occurred()) {
Christian Heimes33fe8092008-04-13 13:53:33 +00001059 return NULL;
1060 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001061 }
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001062 returned = warn_explicit(category, message, filename, lineno, module,
1063 registry, source_line, sourceobj);
1064 Py_XDECREF(source_line);
1065 return returned;
Christian Heimes33fe8092008-04-13 13:53:33 +00001066}
1067
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001068static PyObject *
1069warnings_filters_mutated(PyObject *self, PyObject *args)
1070{
Victor Stinner66b79732020-03-02 15:02:18 +01001071 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -04001072 if (st == NULL) {
1073 return NULL;
1074 }
1075 st->filters_version++;
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001076 Py_RETURN_NONE;
1077}
1078
Christian Heimes33fe8092008-04-13 13:53:33 +00001079
1080/* Function to issue a warning message; may raise an exception. */
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001081
1082static int
1083warn_unicode(PyObject *category, PyObject *message,
Victor Stinner914cde82016-03-19 01:03:51 +01001084 Py_ssize_t stack_level, PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +00001085{
1086 PyObject *res;
Christian Heimes33fe8092008-04-13 13:53:33 +00001087
1088 if (category == NULL)
1089 category = PyExc_RuntimeWarning;
1090
Victor Stinner914cde82016-03-19 01:03:51 +01001091 res = do_warn(message, category, stack_level, source);
Christian Heimes33fe8092008-04-13 13:53:33 +00001092 if (res == NULL)
1093 return -1;
1094 Py_DECREF(res);
1095
1096 return 0;
1097}
1098
Victor Stinner914cde82016-03-19 01:03:51 +01001099static int
1100_PyErr_WarnFormatV(PyObject *source,
1101 PyObject *category, Py_ssize_t stack_level,
1102 const char *format, va_list vargs)
1103{
1104 PyObject *message;
1105 int res;
1106
1107 message = PyUnicode_FromFormatV(format, vargs);
1108 if (message == NULL)
1109 return -1;
1110
1111 res = warn_unicode(category, message, stack_level, source);
1112 Py_DECREF(message);
1113 return res;
1114}
1115
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001116int
1117PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
1118 const char *format, ...)
1119{
Victor Stinner914cde82016-03-19 01:03:51 +01001120 int res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001121 va_list vargs;
1122
1123#ifdef HAVE_STDARG_PROTOTYPES
1124 va_start(vargs, format);
1125#else
1126 va_start(vargs);
1127#endif
Victor Stinner914cde82016-03-19 01:03:51 +01001128 res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001129 va_end(vargs);
Victor Stinner914cde82016-03-19 01:03:51 +01001130 return res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001131}
1132
1133int
Victor Stinner914cde82016-03-19 01:03:51 +01001134PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
1135 const char *format, ...)
1136{
1137 int res;
1138 va_list vargs;
1139
1140#ifdef HAVE_STDARG_PROTOTYPES
1141 va_start(vargs, format);
1142#else
1143 va_start(vargs);
1144#endif
1145 res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
1146 stack_level, format, vargs);
1147 va_end(vargs);
1148 return res;
1149}
1150
1151
1152int
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001153PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
1154{
1155 int ret;
1156 PyObject *message = PyUnicode_FromString(text);
1157 if (message == NULL)
1158 return -1;
Victor Stinner914cde82016-03-19 01:03:51 +01001159 ret = warn_unicode(category, message, stack_level, NULL);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001160 Py_DECREF(message);
1161 return ret;
1162}
1163
Ezio Melotti42da6632011-03-15 05:18:48 +02001164/* PyErr_Warn is only for backwards compatibility and will be removed.
Christian Heimes33fe8092008-04-13 13:53:33 +00001165 Use PyErr_WarnEx instead. */
1166
1167#undef PyErr_Warn
1168
Benjamin Petersone5024512018-09-12 12:06:42 -07001169int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001170PyErr_Warn(PyObject *category, const char *text)
Christian Heimes33fe8092008-04-13 13:53:33 +00001171{
1172 return PyErr_WarnEx(category, text, 1);
1173}
1174
1175/* Warning with explicit origin */
1176int
Victor Stinner14e461d2013-08-26 22:28:21 +02001177PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1178 PyObject *filename, int lineno,
1179 PyObject *module, PyObject *registry)
1180{
1181 PyObject *res;
1182 if (category == NULL)
1183 category = PyExc_RuntimeWarning;
1184 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001185 module, registry, NULL, NULL);
Victor Stinner14e461d2013-08-26 22:28:21 +02001186 if (res == NULL)
1187 return -1;
1188 Py_DECREF(res);
1189 return 0;
1190}
1191
1192int
Christian Heimes33fe8092008-04-13 13:53:33 +00001193PyErr_WarnExplicit(PyObject *category, const char *text,
1194 const char *filename_str, int lineno,
1195 const char *module_str, PyObject *registry)
1196{
Christian Heimes33fe8092008-04-13 13:53:33 +00001197 PyObject *message = PyUnicode_FromString(text);
Victor Stinnercb428f02010-12-27 20:10:36 +00001198 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
Christian Heimes33fe8092008-04-13 13:53:33 +00001199 PyObject *module = NULL;
1200 int ret = -1;
1201
1202 if (message == NULL || filename == NULL)
1203 goto exit;
1204 if (module_str != NULL) {
1205 module = PyUnicode_FromString(module_str);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001206 if (module == NULL)
1207 goto exit;
Christian Heimes33fe8092008-04-13 13:53:33 +00001208 }
1209
Victor Stinner14e461d2013-08-26 22:28:21 +02001210 ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1211 module, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +00001212
1213 exit:
1214 Py_XDECREF(message);
1215 Py_XDECREF(module);
1216 Py_XDECREF(filename);
1217 return ret;
1218}
1219
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001220int
1221PyErr_WarnExplicitFormat(PyObject *category,
1222 const char *filename_str, int lineno,
1223 const char *module_str, PyObject *registry,
1224 const char *format, ...)
1225{
1226 PyObject *message;
1227 PyObject *module = NULL;
1228 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1229 int ret = -1;
1230 va_list vargs;
1231
1232 if (filename == NULL)
1233 goto exit;
1234 if (module_str != NULL) {
1235 module = PyUnicode_FromString(module_str);
1236 if (module == NULL)
1237 goto exit;
1238 }
1239
1240#ifdef HAVE_STDARG_PROTOTYPES
1241 va_start(vargs, format);
1242#else
1243 va_start(vargs);
1244#endif
1245 message = PyUnicode_FromFormatV(format, vargs);
1246 if (message != NULL) {
1247 PyObject *res;
1248 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001249 module, registry, NULL, NULL);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001250 Py_DECREF(message);
1251 if (res != NULL) {
1252 Py_DECREF(res);
1253 ret = 0;
1254 }
1255 }
1256 va_end(vargs);
1257exit:
1258 Py_XDECREF(module);
1259 Py_XDECREF(filename);
1260 return ret;
1261}
1262
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001263void
1264_PyErr_WarnUnawaitedCoroutine(PyObject *coro)
1265{
1266 /* First, we attempt to funnel the warning through
1267 warnings._warn_unawaited_coroutine.
1268
1269 This could raise an exception, due to:
1270 - a bug
1271 - some kind of shutdown-related brokenness
1272 - succeeding, but with an "error" warning filter installed, so the
1273 warning is converted into a RuntimeWarning exception
1274
1275 In the first two cases, we want to print the error (so we know what it
1276 is!), and then print a warning directly as a fallback. In the last
1277 case, we want to print the error (since it's the warning!), but *not*
1278 do a fallback. And after we print the error we can't check for what
1279 type of error it was (because PyErr_WriteUnraisable clears it), so we
1280 need a flag to keep track.
1281
1282 Since this is called from __del__ context, it's careful to never raise
1283 an exception.
1284 */
1285 _Py_IDENTIFIER(_warn_unawaited_coroutine);
1286 int warned = 0;
1287 PyObject *fn = get_warnings_attr(&PyId__warn_unawaited_coroutine, 1);
1288 if (fn) {
Petr Viktorinffd97532020-02-11 17:46:57 +01001289 PyObject *res = PyObject_CallOneArg(fn, coro);
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001290 Py_DECREF(fn);
1291 if (res || PyErr_ExceptionMatches(PyExc_RuntimeWarning)) {
1292 warned = 1;
1293 }
1294 Py_XDECREF(res);
1295 }
1296
1297 if (PyErr_Occurred()) {
1298 PyErr_WriteUnraisable(coro);
1299 }
1300 if (!warned) {
Yury Selivanov35103342018-01-21 20:47:04 -05001301 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
1302 "coroutine '%.50S' was never awaited",
1303 ((PyCoroObject *)coro)->cr_qualname) < 0)
1304 {
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001305 PyErr_WriteUnraisable(coro);
1306 }
1307 }
1308}
Christian Heimes33fe8092008-04-13 13:53:33 +00001309
Christian Heimes33fe8092008-04-13 13:53:33 +00001310PyDoc_STRVAR(warn_explicit_doc,
Hansraj Das5dfbb4d2019-10-08 14:26:07 +05301311"Low-level interface to warnings functionality.");
Christian Heimes33fe8092008-04-13 13:53:33 +00001312
1313static PyMethodDef warnings_functions[] = {
Victor Stinner22f18752016-12-09 18:08:18 +01001314 WARNINGS_WARN_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001315 {"warn_explicit", (PyCFunction)(void(*)(void))warnings_warn_explicit,
Christian Heimes33fe8092008-04-13 13:53:33 +00001316 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001317 {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
1318 NULL},
Christian Heimes1a8501c2008-10-02 19:56:01 +00001319 /* XXX(brett.cannon): add showwarning? */
1320 /* XXX(brett.cannon): Reasonable to add formatwarning? */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 {NULL, NULL} /* sentinel */
Christian Heimes33fe8092008-04-13 13:53:33 +00001322};
1323
1324
Martin v. Löwis1a214512008-06-11 05:26:20 +00001325static struct PyModuleDef warningsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 PyModuleDef_HEAD_INIT,
Eric Snow86ea5812019-05-10 13:29:55 -04001327 MODULE_NAME, /* m_name */
1328 warnings__doc__, /* m_doc */
1329 0, /* m_size */
1330 warnings_functions, /* m_methods */
1331 NULL, /* m_reload */
1332 NULL, /* m_traverse */
1333 NULL, /* m_clear */
1334 NULL /* m_free */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001335};
1336
Christian Heimes33fe8092008-04-13 13:53:33 +00001337
Victor Stinner66b79732020-03-02 15:02:18 +01001338PyStatus
1339_PyWarnings_InitState(PyThreadState *tstate)
1340{
1341 if (warnings_init_state(&tstate->interp->warnings) < 0) {
1342 return _PyStatus_ERR("can't initialize warnings");
1343 }
1344 return _PyStatus_OK();
1345}
1346
1347
Victor Stinner5d862462017-12-19 11:35:58 +01001348PyMODINIT_FUNC
1349_PyWarnings_Init(void)
Christian Heimes33fe8092008-04-13 13:53:33 +00001350{
Brett Cannon0759dd62009-04-01 18:13:07 +00001351 PyObject *m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001352
Martin v. Löwis1a214512008-06-11 05:26:20 +00001353 m = PyModule_Create(&warningsmodule);
Eric Snow86ea5812019-05-10 13:29:55 -04001354 if (m == NULL) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00001355 return NULL;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001356 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001357
Victor Stinner66b79732020-03-02 15:02:18 +01001358 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -04001359 if (st == NULL) {
1360 goto error;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001361 }
Victor Stinner66b79732020-03-02 15:02:18 +01001362 if (warnings_init_state(st) < 0) {
Eric Snow86ea5812019-05-10 13:29:55 -04001363 goto error;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001364 }
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001365
Eric Snow86ea5812019-05-10 13:29:55 -04001366 Py_INCREF(st->filters);
1367 if (PyModule_AddObject(m, "filters", st->filters) < 0) {
1368 goto error;
1369 }
1370
1371 Py_INCREF(st->once_registry);
1372 if (PyModule_AddObject(m, "_onceregistry", st->once_registry) < 0) {
1373 goto error;
1374 }
1375
1376 Py_INCREF(st->default_action);
1377 if (PyModule_AddObject(m, "_defaultaction", st->default_action) < 0) {
1378 goto error;
1379 }
1380
Martin v. Löwis1a214512008-06-11 05:26:20 +00001381 return m;
Eric Snow86ea5812019-05-10 13:29:55 -04001382
1383error:
1384 if (st != NULL) {
Victor Stinner66b79732020-03-02 15:02:18 +01001385 warnings_clear_state(st);
Eric Snow86ea5812019-05-10 13:29:55 -04001386 }
1387 Py_DECREF(m);
1388 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001389}
Victor Stinner87d23a02019-04-26 05:49:26 +02001390
Eric Snow86ea5812019-05-10 13:29:55 -04001391// We need this to ensure that warnings still work until late in finalization.
Victor Stinner87d23a02019-04-26 05:49:26 +02001392void
Eric Snow86ea5812019-05-10 13:29:55 -04001393_PyWarnings_Fini(PyInterpreterState *interp)
Victor Stinner87d23a02019-04-26 05:49:26 +02001394{
Victor Stinner66b79732020-03-02 15:02:18 +01001395 warnings_clear_state(&interp->warnings);
Victor Stinner87d23a02019-04-26 05:49:26 +02001396}