blob: f4ef0bb4b121432bd12b4116f11df79d7a6843fc [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 Stinner4a3fe082020-04-14 14:26:24 +02003#include "pycore_interp.h" // PyInterpreterState.warnings
Victor Stinner4d231bc2019-11-14 13:36:21 +01004#include "pycore_pyerrors.h"
Victor Stinnere5014be2020-04-14 17:52:15 +02005#include "pycore_pystate.h" // _PyThreadState_GET()
Christian Heimes33fe8092008-04-13 13:53:33 +00006#include "frameobject.h"
Victor Stinner22f18752016-12-09 18:08:18 +01007#include "clinic/_warnings.c.h"
Christian Heimes33fe8092008-04-13 13:53:33 +00008
9#define MODULE_NAME "_warnings"
Christian Heimes33fe8092008-04-13 13:53:33 +000010
11PyDoc_STRVAR(warnings__doc__,
12MODULE_NAME " provides basic warning filtering support.\n"
13"It is a helper module to speed up interpreter start-up.");
14
Victor Stinnerbd303c12013-11-07 23:07:29 +010015_Py_IDENTIFIER(stderr);
Victor Stinner747f48e2017-12-12 22:59:48 +010016#ifndef Py_DEBUG
Nick Coghlan9b997472018-01-08 12:45:02 +100017_Py_IDENTIFIER(default);
Victor Stinnerb98f1712017-11-23 17:13:44 +010018_Py_IDENTIFIER(ignore);
Victor Stinner747f48e2017-12-12 22:59:48 +010019#endif
Christian Heimes33fe8092008-04-13 13:53:33 +000020
Eric Snow86ea5812019-05-10 13:29:55 -040021
22/*************************************************************************/
23
24typedef struct _warnings_runtime_state WarningsState;
25
26/* Forward declaration of the _warnings module definition. */
27static struct PyModuleDef warningsmodule;
28
Hai Shi46874c22020-01-30 17:20:25 -060029_Py_IDENTIFIER(__name__);
30
Eric Snow86ea5812019-05-10 13:29:55 -040031/* Given a module object, get its per-module state. */
32static WarningsState *
Victor Stinner66b79732020-03-02 15:02:18 +010033warnings_get_state(void)
Eric Snow86ea5812019-05-10 13:29:55 -040034{
Victor Stinner4d231bc2019-11-14 13:36:21 +010035 PyThreadState *tstate = _PyThreadState_GET();
Eric Snow86ea5812019-05-10 13:29:55 -040036 if (tstate == NULL) {
Victor Stinner4d231bc2019-11-14 13:36:21 +010037 _PyErr_SetString(tstate, PyExc_RuntimeError,
Victor Stinner66b79732020-03-02 15:02:18 +010038 "warnings_get_state: could not identify "
Victor Stinner4d231bc2019-11-14 13:36:21 +010039 "current interpreter");
Eric Snow86ea5812019-05-10 13:29:55 -040040 return NULL;
41 }
42 return &tstate->interp->warnings;
43}
44
45/* Clear the given warnings module state. */
46static void
Victor Stinner66b79732020-03-02 15:02:18 +010047warnings_clear_state(WarningsState *st)
Eric Snow86ea5812019-05-10 13:29:55 -040048{
49 Py_CLEAR(st->filters);
50 Py_CLEAR(st->once_registry);
51 Py_CLEAR(st->default_action);
52}
53
54#ifndef Py_DEBUG
55static PyObject *
56create_filter(PyObject *category, _Py_Identifier *id, const char *modname)
57{
58 PyObject *modname_obj = NULL;
59 PyObject *action_str = _PyUnicode_FromId(id);
60 if (action_str == NULL) {
61 return NULL;
62 }
63
64 /* Default to "no module name" for initial filter set */
65 if (modname != NULL) {
66 modname_obj = PyUnicode_InternFromString(modname);
67 if (modname_obj == NULL) {
68 return NULL;
69 }
70 } else {
71 modname_obj = Py_None;
72 }
73
74 /* This assumes the line number is zero for now. */
75 return PyTuple_Pack(5, action_str, Py_None,
76 category, modname_obj, _PyLong_Zero);
77}
78#endif
79
80static PyObject *
81init_filters(void)
82{
83#ifdef Py_DEBUG
84 /* Py_DEBUG builds show all warnings by default */
85 return PyList_New(0);
86#else
87 /* Other builds ignore a number of warning categories by default */
88 PyObject *filters = PyList_New(5);
89 if (filters == NULL) {
90 return NULL;
91 }
92
93 size_t pos = 0; /* Post-incremented in each use. */
94 PyList_SET_ITEM(filters, pos++,
95 create_filter(PyExc_DeprecationWarning, &PyId_default, "__main__"));
96 PyList_SET_ITEM(filters, pos++,
97 create_filter(PyExc_DeprecationWarning, &PyId_ignore, NULL));
98 PyList_SET_ITEM(filters, pos++,
99 create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore, NULL));
100 PyList_SET_ITEM(filters, pos++,
101 create_filter(PyExc_ImportWarning, &PyId_ignore, NULL));
102 PyList_SET_ITEM(filters, pos++,
103 create_filter(PyExc_ResourceWarning, &PyId_ignore, NULL));
104
105 for (size_t x = 0; x < pos; x++) {
106 if (PyList_GET_ITEM(filters, x) == NULL) {
107 Py_DECREF(filters);
108 return NULL;
109 }
110 }
111 return filters;
112#endif
113}
114
115/* Initialize the given warnings module state. */
116static int
Victor Stinner66b79732020-03-02 15:02:18 +0100117warnings_init_state(WarningsState *st)
Eric Snow86ea5812019-05-10 13:29:55 -0400118{
119 if (st->filters == NULL) {
120 st->filters = init_filters();
121 if (st->filters == NULL) {
122 goto error;
123 }
124 }
125
126 if (st->once_registry == NULL) {
127 st->once_registry = PyDict_New();
128 if (st->once_registry == NULL) {
129 goto error;
130 }
131 }
132
133 if (st->default_action == NULL) {
134 st->default_action = PyUnicode_FromString("default");
135 if (st->default_action == NULL) {
136 goto error;
137 }
138 }
139
140 st->filters_version = 0;
141
142 return 0;
143
144error:
Victor Stinner66b79732020-03-02 15:02:18 +0100145 warnings_clear_state(st);
Eric Snow86ea5812019-05-10 13:29:55 -0400146 return -1;
147}
148
149
150/*************************************************************************/
151
Christian Heimes33fe8092008-04-13 13:53:33 +0000152static int
153check_matched(PyObject *obj, PyObject *arg)
154{
155 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200156 _Py_IDENTIFIER(match);
Christian Heimes33fe8092008-04-13 13:53:33 +0000157 int rc;
158
Nick Coghlan9b997472018-01-08 12:45:02 +1000159 /* A 'None' filter always matches */
Christian Heimes33fe8092008-04-13 13:53:33 +0000160 if (obj == Py_None)
161 return 1;
Nick Coghlan9b997472018-01-08 12:45:02 +1000162
163 /* An internal plain text default filter must match exactly */
164 if (PyUnicode_CheckExact(obj)) {
165 int cmp_result = PyUnicode_Compare(obj, arg);
166 if (cmp_result == -1 && PyErr_Occurred()) {
167 return -1;
168 }
169 return !cmp_result;
170 }
171
172 /* Otherwise assume a regex filter and call its match() method */
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200173 result = _PyObject_CallMethodIdOneArg(obj, &PyId_match, arg);
Christian Heimes33fe8092008-04-13 13:53:33 +0000174 if (result == NULL)
175 return -1;
176
177 rc = PyObject_IsTrue(result);
178 Py_DECREF(result);
179 return rc;
180}
181
182/*
183 Returns a new reference.
184 A NULL return value can mean false or an error.
185*/
186static PyObject *
Victor Stinner82656272017-11-22 23:51:42 +0100187get_warnings_attr(_Py_Identifier *attr_id, int try_import)
Christian Heimes33fe8092008-04-13 13:53:33 +0000188{
Victor Stinner82656272017-11-22 23:51:42 +0100189 PyObject *warnings_str;
Victor Stinnere98445a2016-03-23 00:54:48 +0100190 PyObject *warnings_module, *obj;
Victor Stinner82656272017-11-22 23:51:42 +0100191 _Py_IDENTIFIER(warnings);
Christian Heimes33fe8092008-04-13 13:53:33 +0000192
Victor Stinner82656272017-11-22 23:51:42 +0100193 warnings_str = _PyUnicode_FromId(&PyId_warnings);
Christian Heimes33fe8092008-04-13 13:53:33 +0000194 if (warnings_str == NULL) {
Victor Stinner82656272017-11-22 23:51:42 +0100195 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000196 }
197
Victor Stinnere98445a2016-03-23 00:54:48 +0100198 /* don't try to import after the start of the Python finallization */
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600199 if (try_import && !_Py_IsFinalizing()) {
Victor Stinnere98445a2016-03-23 00:54:48 +0100200 warnings_module = PyImport_Import(warnings_str);
201 if (warnings_module == NULL) {
202 /* Fallback to the C implementation if we cannot get
203 the Python implementation */
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200204 if (PyErr_ExceptionMatches(PyExc_ImportError)) {
205 PyErr_Clear();
206 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000207 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +0100208 }
209 }
210 else {
Nathaniel J. Smithdba976b2018-01-26 11:28:31 -0800211 /* if we're so late into Python finalization that the module dict is
212 gone, then we can't even use PyImport_GetModule without triggering
213 an interpreter abort.
214 */
Victor Stinner81a7be32020-04-14 15:14:01 +0200215 if (!_PyInterpreterState_GET()->modules) {
Nathaniel J. Smithdba976b2018-01-26 11:28:31 -0800216 return NULL;
217 }
Eric Snow3f9eee62017-09-15 16:35:20 -0600218 warnings_module = PyImport_GetModule(warnings_str);
Victor Stinner023654f2016-03-23 17:48:22 +0100219 if (warnings_module == NULL)
220 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +0100221 }
222
Serhiy Storchakaf320be72018-01-25 10:49:40 +0200223 (void)_PyObject_LookupAttrId(warnings_module, attr_id, &obj);
Victor Stinnere98445a2016-03-23 00:54:48 +0100224 Py_DECREF(warnings_module);
225 return obj;
Christian Heimes33fe8092008-04-13 13:53:33 +0000226}
227
228
Neal Norwitz32dde222008-04-15 06:43:13 +0000229static PyObject *
Eric Snow86ea5812019-05-10 13:29:55 -0400230get_once_registry(WarningsState *st)
Christian Heimes33fe8092008-04-13 13:53:33 +0000231{
232 PyObject *registry;
Victor Stinner82656272017-11-22 23:51:42 +0100233 _Py_IDENTIFIER(onceregistry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000234
Victor Stinner82656272017-11-22 23:51:42 +0100235 registry = get_warnings_attr(&PyId_onceregistry, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000236 if (registry == NULL) {
237 if (PyErr_Occurred())
238 return NULL;
Eric Snow86ea5812019-05-10 13:29:55 -0400239 assert(st->once_registry);
240 return st->once_registry;
Christian Heimes33fe8092008-04-13 13:53:33 +0000241 }
Oren Milman252033d2017-09-11 09:28:39 +0300242 if (!PyDict_Check(registry)) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200243 PyErr_Format(PyExc_TypeError,
244 MODULE_NAME ".onceregistry must be a dict, "
245 "not '%.200s'",
246 Py_TYPE(registry)->tp_name);
Oren Milman252033d2017-09-11 09:28:39 +0300247 Py_DECREF(registry);
248 return NULL;
249 }
Eric Snow86ea5812019-05-10 13:29:55 -0400250 Py_SETREF(st->once_registry, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000251 return registry;
252}
253
254
Brett Cannon0759dd62009-04-01 18:13:07 +0000255static PyObject *
Eric Snow86ea5812019-05-10 13:29:55 -0400256get_default_action(WarningsState *st)
Brett Cannon0759dd62009-04-01 18:13:07 +0000257{
258 PyObject *default_action;
Victor Stinner82656272017-11-22 23:51:42 +0100259 _Py_IDENTIFIER(defaultaction);
Brett Cannon0759dd62009-04-01 18:13:07 +0000260
Victor Stinner82656272017-11-22 23:51:42 +0100261 default_action = get_warnings_attr(&PyId_defaultaction, 0);
Brett Cannon0759dd62009-04-01 18:13:07 +0000262 if (default_action == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 if (PyErr_Occurred()) {
264 return NULL;
265 }
Eric Snow86ea5812019-05-10 13:29:55 -0400266 assert(st->default_action);
267 return st->default_action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000268 }
Oren Milman9d984fd2017-09-12 00:18:09 +0300269 if (!PyUnicode_Check(default_action)) {
270 PyErr_Format(PyExc_TypeError,
271 MODULE_NAME ".defaultaction must be a string, "
272 "not '%.200s'",
273 Py_TYPE(default_action)->tp_name);
274 Py_DECREF(default_action);
275 return NULL;
276 }
Eric Snow86ea5812019-05-10 13:29:55 -0400277 Py_SETREF(st->default_action, default_action);
Brett Cannon0759dd62009-04-01 18:13:07 +0000278 return default_action;
279}
280
281
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400282/* The item is a new reference. */
Victor Stinnera4c704b2013-10-29 23:43:41 +0100283static PyObject*
Christian Heimes33fe8092008-04-13 13:53:33 +0000284get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
285 PyObject *module, PyObject **item)
286{
Brett Cannon0759dd62009-04-01 18:13:07 +0000287 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000288 Py_ssize_t i;
289 PyObject *warnings_filters;
Victor Stinner82656272017-11-22 23:51:42 +0100290 _Py_IDENTIFIER(filters);
Victor Stinner66b79732020-03-02 15:02:18 +0100291 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -0400292 if (st == NULL) {
293 return NULL;
294 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000295
Victor Stinner82656272017-11-22 23:51:42 +0100296 warnings_filters = get_warnings_attr(&PyId_filters, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000297 if (warnings_filters == NULL) {
298 if (PyErr_Occurred())
299 return NULL;
300 }
301 else {
Eric Snow86ea5812019-05-10 13:29:55 -0400302 Py_SETREF(st->filters, warnings_filters);
Christian Heimes33fe8092008-04-13 13:53:33 +0000303 }
304
Eric Snow86ea5812019-05-10 13:29:55 -0400305 PyObject *filters = st->filters;
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600306 if (filters == NULL || !PyList_Check(filters)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000307 PyErr_SetString(PyExc_ValueError,
308 MODULE_NAME ".filters must be a list");
309 return NULL;
310 }
311
Eric Snow86ea5812019-05-10 13:29:55 -0400312 /* WarningsState.filters could change while we are iterating over it. */
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600313 for (i = 0; i < PyList_GET_SIZE(filters); i++) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000314 PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
315 Py_ssize_t ln;
316 int is_subclass, good_msg, good_mod;
317
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600318 tmp_item = PyList_GET_ITEM(filters, i);
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400319 if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000320 PyErr_Format(PyExc_ValueError,
321 MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
322 return NULL;
323 }
324
325 /* Python code: action, msg, cat, mod, ln = item */
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400326 Py_INCREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000327 action = PyTuple_GET_ITEM(tmp_item, 0);
328 msg = PyTuple_GET_ITEM(tmp_item, 1);
329 cat = PyTuple_GET_ITEM(tmp_item, 2);
330 mod = PyTuple_GET_ITEM(tmp_item, 3);
331 ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
332
Oren Milman9d984fd2017-09-12 00:18:09 +0300333 if (!PyUnicode_Check(action)) {
334 PyErr_Format(PyExc_TypeError,
335 "action must be a string, not '%.200s'",
336 Py_TYPE(action)->tp_name);
337 Py_DECREF(tmp_item);
338 return NULL;
339 }
340
Christian Heimes33fe8092008-04-13 13:53:33 +0000341 good_msg = check_matched(msg, text);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400342 if (good_msg == -1) {
343 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100344 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400345 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100346
Christian Heimes33fe8092008-04-13 13:53:33 +0000347 good_mod = check_matched(mod, module);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400348 if (good_mod == -1) {
349 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100350 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400351 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100352
Christian Heimes33fe8092008-04-13 13:53:33 +0000353 is_subclass = PyObject_IsSubclass(category, cat);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400354 if (is_subclass == -1) {
355 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100356 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400357 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100358
Christian Heimes33fe8092008-04-13 13:53:33 +0000359 ln = PyLong_AsSsize_t(ln_obj);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400360 if (ln == -1 && PyErr_Occurred()) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400361 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000362 return NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400363 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000364
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400365 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
366 *item = tmp_item;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100367 return action;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400368 }
369
370 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000371 }
372
Eric Snow86ea5812019-05-10 13:29:55 -0400373 action = get_default_action(st);
Brett Cannon0759dd62009-04-01 18:13:07 +0000374 if (action != NULL) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400375 Py_INCREF(Py_None);
376 *item = Py_None;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100377 return action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000378 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000379
Christian Heimes33fe8092008-04-13 13:53:33 +0000380 return NULL;
381}
382
Brett Cannon0759dd62009-04-01 18:13:07 +0000383
Christian Heimes33fe8092008-04-13 13:53:33 +0000384static int
385already_warned(PyObject *registry, PyObject *key, int should_set)
386{
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200387 PyObject *version_obj, *already_warned;
388 _Py_IDENTIFIER(version);
Christian Heimes33fe8092008-04-13 13:53:33 +0000389
390 if (key == NULL)
391 return -1;
392
Victor Stinner66b79732020-03-02 15:02:18 +0100393 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -0400394 if (st == NULL) {
395 return -1;
396 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200397 version_obj = _PyDict_GetItemIdWithError(registry, &PyId_version);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200398 if (version_obj == NULL
399 || !PyLong_CheckExact(version_obj)
Eric Snow86ea5812019-05-10 13:29:55 -0400400 || PyLong_AsLong(version_obj) != st->filters_version)
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200401 {
402 if (PyErr_Occurred()) {
403 return -1;
404 }
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200405 PyDict_Clear(registry);
Eric Snow86ea5812019-05-10 13:29:55 -0400406 version_obj = PyLong_FromLong(st->filters_version);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200407 if (version_obj == NULL)
408 return -1;
409 if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
410 Py_DECREF(version_obj);
411 return -1;
412 }
413 Py_DECREF(version_obj);
414 }
415 else {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200416 already_warned = PyDict_GetItemWithError(registry, key);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200417 if (already_warned != NULL) {
418 int rc = PyObject_IsTrue(already_warned);
419 if (rc != 0)
420 return rc;
421 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200422 else if (PyErr_Occurred()) {
423 return -1;
424 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000425 }
426
427 /* This warning wasn't found in the registry, set it. */
428 if (should_set)
429 return PyDict_SetItem(registry, key, Py_True);
430 return 0;
431}
432
433/* New reference. */
434static PyObject *
435normalize_module(PyObject *filename)
436{
437 PyObject *module;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100438 int kind;
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300439 const void *data;
Christian Heimes33fe8092008-04-13 13:53:33 +0000440 Py_ssize_t len;
441
Victor Stinner9e30aa52011-11-21 02:49:52 +0100442 len = PyUnicode_GetLength(filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000443 if (len < 0)
444 return NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100445
446 if (len == 0)
447 return PyUnicode_FromString("<unknown>");
448
449 kind = PyUnicode_KIND(filename);
450 data = PyUnicode_DATA(filename);
451
452 /* if filename.endswith(".py"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000453 if (len >= 3 &&
Victor Stinnera4c704b2013-10-29 23:43:41 +0100454 PyUnicode_READ(kind, data, len-3) == '.' &&
455 PyUnicode_READ(kind, data, len-2) == 'p' &&
456 PyUnicode_READ(kind, data, len-1) == 'y')
457 {
Victor Stinner9e30aa52011-11-21 02:49:52 +0100458 module = PyUnicode_Substring(filename, 0, len-3);
Christian Heimes33fe8092008-04-13 13:53:33 +0000459 }
460 else {
461 module = filename;
462 Py_INCREF(module);
463 }
464 return module;
465}
466
467static int
468update_registry(PyObject *registry, PyObject *text, PyObject *category,
469 int add_zero)
470{
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300471 PyObject *altkey;
Christian Heimes33fe8092008-04-13 13:53:33 +0000472 int rc;
473
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300474 if (add_zero)
475 altkey = PyTuple_Pack(3, text, category, _PyLong_Zero);
Christian Heimes33fe8092008-04-13 13:53:33 +0000476 else
477 altkey = PyTuple_Pack(2, text, category);
478
479 rc = already_warned(registry, altkey, 1);
Christian Heimes33fe8092008-04-13 13:53:33 +0000480 Py_XDECREF(altkey);
481 return rc;
482}
483
484static void
Victor Stinner914cde82016-03-19 01:03:51 +0100485show_warning(PyObject *filename, int lineno, PyObject *text,
486 PyObject *category, PyObject *sourceline)
Christian Heimes33fe8092008-04-13 13:53:33 +0000487{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 PyObject *f_stderr;
489 PyObject *name;
Christian Heimes33fe8092008-04-13 13:53:33 +0000490 char lineno_str[128];
491
492 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
493
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200494 name = _PyObject_GetAttrId(category, &PyId___name__);
Hai Shi57c78102020-03-14 21:40:58 +0800495 if (name == NULL) {
Victor Stinnerae233ea2013-10-31 14:51:38 +0100496 goto error;
Hai Shi57c78102020-03-14 21:40:58 +0800497 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000498
Victor Stinnerbd303c12013-11-07 23:07:29 +0100499 f_stderr = _PySys_GetObjectId(&PyId_stderr);
Christian Heimes33fe8092008-04-13 13:53:33 +0000500 if (f_stderr == NULL) {
501 fprintf(stderr, "lost sys.stderr\n");
Victor Stinnerae233ea2013-10-31 14:51:38 +0100502 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000503 }
504
505 /* Print "filename:lineno: category: text\n" */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100506 if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
507 goto error;
508 if (PyFile_WriteString(lineno_str, f_stderr) < 0)
509 goto error;
510 if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
511 goto error;
512 if (PyFile_WriteString(": ", f_stderr) < 0)
513 goto error;
514 if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
515 goto error;
516 if (PyFile_WriteString("\n", f_stderr) < 0)
517 goto error;
518 Py_CLEAR(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000519
520 /* Print " source_line\n" */
Christian Heimes33fe8092008-04-13 13:53:33 +0000521 if (sourceline) {
Victor Stinnera4c704b2013-10-29 23:43:41 +0100522 int kind;
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300523 const void *data;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100524 Py_ssize_t i, len;
525 Py_UCS4 ch;
526 PyObject *truncated;
Christian Heimes33fe8092008-04-13 13:53:33 +0000527
Victor Stinnera4c704b2013-10-29 23:43:41 +0100528 if (PyUnicode_READY(sourceline) < 1)
529 goto error;
530
531 kind = PyUnicode_KIND(sourceline);
532 data = PyUnicode_DATA(sourceline);
533 len = PyUnicode_GET_LENGTH(sourceline);
534 for (i=0; i<len; i++) {
535 ch = PyUnicode_READ(kind, data, i);
536 if (ch != ' ' && ch != '\t' && ch != '\014')
537 break;
538 }
539
540 truncated = PyUnicode_Substring(sourceline, i, len);
541 if (truncated == NULL)
542 goto error;
543
544 PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
545 Py_DECREF(truncated);
Christian Heimes33fe8092008-04-13 13:53:33 +0000546 PyFile_WriteString("\n", f_stderr);
547 }
Victor Stinner78e2c982013-07-16 01:54:37 +0200548 else {
549 _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
550 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100551
552error:
Victor Stinnerae233ea2013-10-31 14:51:38 +0100553 Py_XDECREF(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000554 PyErr_Clear();
555}
556
Victor Stinner1231a462016-03-19 00:47:17 +0100557static int
558call_show_warning(PyObject *category, PyObject *text, PyObject *message,
559 PyObject *filename, int lineno, PyObject *lineno_obj,
Victor Stinner914cde82016-03-19 01:03:51 +0100560 PyObject *sourceline, PyObject *source)
Victor Stinner1231a462016-03-19 00:47:17 +0100561{
562 PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
Victor Stinner82656272017-11-22 23:51:42 +0100563 _Py_IDENTIFIER(_showwarnmsg);
564 _Py_IDENTIFIER(WarningMessage);
Victor Stinner1231a462016-03-19 00:47:17 +0100565
Victor Stinnere98445a2016-03-23 00:54:48 +0100566 /* If the source parameter is set, try to get the Python implementation.
567 The Python implementation is able to log the traceback where the source
luzpaza5293b42017-11-05 07:37:50 -0600568 was allocated, whereas the C implementation doesn't. */
Victor Stinner82656272017-11-22 23:51:42 +0100569 show_fn = get_warnings_attr(&PyId__showwarnmsg, source != NULL);
Victor Stinner1231a462016-03-19 00:47:17 +0100570 if (show_fn == NULL) {
571 if (PyErr_Occurred())
572 return -1;
573 show_warning(filename, lineno, text, category, sourceline);
574 return 0;
575 }
576
577 if (!PyCallable_Check(show_fn)) {
578 PyErr_SetString(PyExc_TypeError,
579 "warnings._showwarnmsg() must be set to a callable");
580 goto error;
581 }
582
Victor Stinner82656272017-11-22 23:51:42 +0100583 warnmsg_cls = get_warnings_attr(&PyId_WarningMessage, 0);
Victor Stinner1231a462016-03-19 00:47:17 +0100584 if (warnmsg_cls == NULL) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200585 if (!PyErr_Occurred()) {
586 PyErr_SetString(PyExc_RuntimeError,
587 "unable to get warnings.WarningMessage");
588 }
Victor Stinner1231a462016-03-19 00:47:17 +0100589 goto error;
590 }
591
592 msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
Victor Stinner914cde82016-03-19 01:03:51 +0100593 filename, lineno_obj, Py_None, Py_None, source,
Victor Stinner1231a462016-03-19 00:47:17 +0100594 NULL);
595 Py_DECREF(warnmsg_cls);
596 if (msg == NULL)
597 goto error;
598
Petr Viktorinffd97532020-02-11 17:46:57 +0100599 res = PyObject_CallOneArg(show_fn, msg);
Victor Stinner1231a462016-03-19 00:47:17 +0100600 Py_DECREF(show_fn);
601 Py_DECREF(msg);
602
603 if (res == NULL)
604 return -1;
605
606 Py_DECREF(res);
607 return 0;
608
609error:
610 Py_XDECREF(show_fn);
611 return -1;
612}
613
Christian Heimes33fe8092008-04-13 13:53:33 +0000614static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615warn_explicit(PyObject *category, PyObject *message,
Christian Heimes33fe8092008-04-13 13:53:33 +0000616 PyObject *filename, int lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100617 PyObject *module, PyObject *registry, PyObject *sourceline,
618 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000619{
620 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400621 PyObject *item = NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100622 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000623 int rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100625 /* module can be None if a warning is emitted late during Python shutdown.
626 In this case, the Python warnings module was probably unloaded, filters
627 are no more available to choose as action. It is safer to ignore the
628 warning and do nothing. */
629 if (module == Py_None)
630 Py_RETURN_NONE;
631
Brett Cannondb734912008-06-27 00:52:15 +0000632 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
Oren Milman252033d2017-09-11 09:28:39 +0300633 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
Brett Cannondb734912008-06-27 00:52:15 +0000634 return NULL;
635 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000636
637 /* Normalize module. */
638 if (module == NULL) {
639 module = normalize_module(filename);
640 if (module == NULL)
641 return NULL;
642 }
643 else
644 Py_INCREF(module);
645
646 /* Normalize message. */
647 Py_INCREF(message); /* DECREF'ed in cleanup. */
648 rc = PyObject_IsInstance(message, PyExc_Warning);
649 if (rc == -1) {
650 goto cleanup;
651 }
652 if (rc == 1) {
653 text = PyObject_Str(message);
Hirokazu Yamamoto1c0c0032009-07-17 06:55:42 +0000654 if (text == NULL)
655 goto cleanup;
Victor Stinnera102ed72020-02-07 02:24:48 +0100656 category = (PyObject*)Py_TYPE(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000657 }
658 else {
659 text = message;
Petr Viktorinffd97532020-02-11 17:46:57 +0100660 message = PyObject_CallOneArg(category, message);
Brett Cannondb734912008-06-27 00:52:15 +0000661 if (message == NULL)
662 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000663 }
664
665 lineno_obj = PyLong_FromLong(lineno);
666 if (lineno_obj == NULL)
667 goto cleanup;
668
Victor Stinner22f18752016-12-09 18:08:18 +0100669 if (source == Py_None) {
670 source = NULL;
671 }
672
Christian Heimes33fe8092008-04-13 13:53:33 +0000673 /* Create key. */
674 key = PyTuple_Pack(3, text, category, lineno_obj);
675 if (key == NULL)
676 goto cleanup;
677
Brett Cannondb734912008-06-27 00:52:15 +0000678 if ((registry != NULL) && (registry != Py_None)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000679 rc = already_warned(registry, key, 0);
680 if (rc == -1)
681 goto cleanup;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682 else if (rc == 1)
Christian Heimes33fe8092008-04-13 13:53:33 +0000683 goto return_none;
684 /* Else this warning hasn't been generated before. */
685 }
686
687 action = get_filter(category, text, lineno, module, &item);
688 if (action == NULL)
689 goto cleanup;
690
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200691 if (_PyUnicode_EqualToASCIIString(action, "error")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000692 PyErr_SetObject(category, message);
693 goto cleanup;
694 }
695
Victor Stinnerc9758782017-11-27 16:57:07 +0100696 if (_PyUnicode_EqualToASCIIString(action, "ignore")) {
697 goto return_none;
698 }
699
Christian Heimes33fe8092008-04-13 13:53:33 +0000700 /* Store in the registry that we've been here, *except* when the action
701 is "always". */
702 rc = 0;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200703 if (!_PyUnicode_EqualToASCIIString(action, "always")) {
Brett Cannondb734912008-06-27 00:52:15 +0000704 if (registry != NULL && registry != Py_None &&
Victor Stinnerc9758782017-11-27 16:57:07 +0100705 PyDict_SetItem(registry, key, Py_True) < 0)
706 {
Christian Heimes33fe8092008-04-13 13:53:33 +0000707 goto cleanup;
Victor Stinnerc9758782017-11-27 16:57:07 +0100708 }
709
710 if (_PyUnicode_EqualToASCIIString(action, "once")) {
Brett Cannondb734912008-06-27 00:52:15 +0000711 if (registry == NULL || registry == Py_None) {
Victor Stinner66b79732020-03-02 15:02:18 +0100712 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -0400713 if (st == NULL) {
714 goto cleanup;
715 }
716 registry = get_once_registry(st);
Christian Heimes33fe8092008-04-13 13:53:33 +0000717 if (registry == NULL)
718 goto cleanup;
719 }
Eric Snow86ea5812019-05-10 13:29:55 -0400720 /* WarningsState.once_registry[(text, category)] = 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000722 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200723 else if (_PyUnicode_EqualToASCIIString(action, "module")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000724 /* registry[(text, category, 0)] = 1 */
Brett Cannondb734912008-06-27 00:52:15 +0000725 if (registry != NULL && registry != Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000727 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200728 else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000729 PyErr_Format(PyExc_RuntimeError,
Victor Stinnera4c704b2013-10-29 23:43:41 +0100730 "Unrecognized action (%R) in warnings.filters:\n %R",
731 action, item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000732 goto cleanup;
733 }
734 }
735
Christian Heimes1a8501c2008-10-02 19:56:01 +0000736 if (rc == 1) /* Already warned for this module. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000737 goto return_none;
738 if (rc == 0) {
Victor Stinner1231a462016-03-19 00:47:17 +0100739 if (call_show_warning(category, text, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100740 lineno_obj, sourceline, source) < 0)
Victor Stinner1231a462016-03-19 00:47:17 +0100741 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000742 }
743 else /* if (rc == -1) */
744 goto cleanup;
745
746 return_none:
747 result = Py_None;
748 Py_INCREF(result);
749
750 cleanup:
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400751 Py_XDECREF(item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000752 Py_XDECREF(key);
753 Py_XDECREF(text);
754 Py_XDECREF(lineno_obj);
755 Py_DECREF(module);
Brett Cannondb734912008-06-27 00:52:15 +0000756 Py_XDECREF(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000757 return result; /* Py_None or NULL. */
758}
759
Larry Hastings714e4932015-09-06 00:39:37 -0700760static int
761is_internal_frame(PyFrameObject *frame)
762{
763 static PyObject *importlib_string = NULL;
764 static PyObject *bootstrap_string = NULL;
765 PyObject *filename;
766 int contains;
767
768 if (importlib_string == NULL) {
769 importlib_string = PyUnicode_FromString("importlib");
770 if (importlib_string == NULL) {
771 return 0;
772 }
773
774 bootstrap_string = PyUnicode_FromString("_bootstrap");
775 if (bootstrap_string == NULL) {
776 Py_DECREF(importlib_string);
777 return 0;
778 }
779 Py_INCREF(importlib_string);
780 Py_INCREF(bootstrap_string);
781 }
782
783 if (frame == NULL || frame->f_code == NULL ||
784 frame->f_code->co_filename == NULL) {
785 return 0;
786 }
787 filename = frame->f_code->co_filename;
788 if (!PyUnicode_Check(filename)) {
789 return 0;
790 }
791 contains = PyUnicode_Contains(filename, importlib_string);
792 if (contains < 0) {
793 return 0;
794 }
795 else if (contains > 0) {
796 contains = PyUnicode_Contains(filename, bootstrap_string);
797 if (contains < 0) {
798 return 0;
799 }
800 else if (contains > 0) {
801 return 1;
802 }
803 }
804
805 return 0;
806}
807
808static PyFrameObject *
809next_external_frame(PyFrameObject *frame)
810{
811 do {
812 frame = frame->f_back;
813 } while (frame != NULL && is_internal_frame(frame));
814
815 return frame;
816}
817
Christian Heimes33fe8092008-04-13 13:53:33 +0000818/* filename, module, and registry are new refs, globals is borrowed */
819/* Returns 0 on error (no new refs), 1 on success */
820static int
821setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
822 PyObject **module, PyObject **registry)
823{
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200824 _Py_IDENTIFIER(__warningregistry__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000825 PyObject *globals;
826
Thomas Kluyver11a89662018-06-08 21:28:37 +0200827 /* Setup globals, filename and lineno. */
Victor Stinner50b48572018-11-01 01:51:40 +0100828 PyFrameObject *f = _PyThreadState_GET()->frame;
Larry Hastings714e4932015-09-06 00:39:37 -0700829 // Stack level comparisons to Python code is off by one as there is no
830 // warnings-related stack level to avoid.
831 if (stack_level <= 0 || is_internal_frame(f)) {
832 while (--stack_level > 0 && f != NULL) {
833 f = f->f_back;
834 }
835 }
836 else {
837 while (--stack_level > 0 && f != NULL) {
838 f = next_external_frame(f);
839 }
840 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000841
842 if (f == NULL) {
Victor Stinner81a7be32020-04-14 15:14:01 +0200843 globals = _PyInterpreterState_GET()->sysdict;
Thomas Kluyver11a89662018-06-08 21:28:37 +0200844 *filename = PyUnicode_FromString("sys");
Christian Heimes33fe8092008-04-13 13:53:33 +0000845 *lineno = 1;
846 }
847 else {
848 globals = f->f_globals;
Thomas Kluyver11a89662018-06-08 21:28:37 +0200849 *filename = f->f_code->co_filename;
850 Py_INCREF(*filename);
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000851 *lineno = PyFrame_GetLineNumber(f);
Christian Heimes33fe8092008-04-13 13:53:33 +0000852 }
853
854 *module = NULL;
855
856 /* Setup registry. */
857 assert(globals != NULL);
858 assert(PyDict_Check(globals));
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200859 *registry = _PyDict_GetItemIdWithError(globals, &PyId___warningregistry__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000860 if (*registry == NULL) {
861 int rc;
862
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200863 if (PyErr_Occurred()) {
Serhiy Storchaka2d2f8552020-03-02 22:05:08 +0200864 goto handle_error;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200865 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000866 *registry = PyDict_New();
867 if (*registry == NULL)
Serhiy Storchaka2d2f8552020-03-02 22:05:08 +0200868 goto handle_error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000869
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200870 rc = _PyDict_SetItemId(globals, &PyId___warningregistry__, *registry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000871 if (rc < 0)
872 goto handle_error;
873 }
874 else
875 Py_INCREF(*registry);
876
877 /* Setup module. */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200878 *module = _PyDict_GetItemIdWithError(globals, &PyId___name__);
Oren Milman5d3e8002017-09-24 21:28:42 +0300879 if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) {
880 Py_INCREF(*module);
881 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200882 else if (PyErr_Occurred()) {
883 goto handle_error;
884 }
Oren Milman5d3e8002017-09-24 21:28:42 +0300885 else {
Christian Heimes33fe8092008-04-13 13:53:33 +0000886 *module = PyUnicode_FromString("<string>");
887 if (*module == NULL)
888 goto handle_error;
889 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000890
Christian Heimes33fe8092008-04-13 13:53:33 +0000891 return 1;
892
893 handle_error:
Christian Heimes33fe8092008-04-13 13:53:33 +0000894 Py_XDECREF(*registry);
895 Py_XDECREF(*module);
Serhiy Storchakaae75a292020-03-03 19:43:29 +0200896 Py_DECREF(*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
Victor Stinner8d84adc2020-03-31 17:25:12 +02001133static int
1134_PyErr_WarnFormat(PyObject *source, PyObject *category, 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, category, stack_level, format, vargs);
1146 va_end(vargs);
1147 return res;
1148}
1149
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001150int
Victor Stinner914cde82016-03-19 01:03:51 +01001151PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
1152 const char *format, ...)
1153{
1154 int res;
1155 va_list vargs;
1156
1157#ifdef HAVE_STDARG_PROTOTYPES
1158 va_start(vargs, format);
1159#else
1160 va_start(vargs);
1161#endif
1162 res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
1163 stack_level, format, vargs);
1164 va_end(vargs);
1165 return res;
1166}
1167
1168
1169int
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001170PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
1171{
1172 int ret;
1173 PyObject *message = PyUnicode_FromString(text);
1174 if (message == NULL)
1175 return -1;
Victor Stinner914cde82016-03-19 01:03:51 +01001176 ret = warn_unicode(category, message, stack_level, NULL);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001177 Py_DECREF(message);
1178 return ret;
1179}
1180
Ezio Melotti42da6632011-03-15 05:18:48 +02001181/* PyErr_Warn is only for backwards compatibility and will be removed.
Christian Heimes33fe8092008-04-13 13:53:33 +00001182 Use PyErr_WarnEx instead. */
1183
1184#undef PyErr_Warn
1185
Benjamin Petersone5024512018-09-12 12:06:42 -07001186int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001187PyErr_Warn(PyObject *category, const char *text)
Christian Heimes33fe8092008-04-13 13:53:33 +00001188{
1189 return PyErr_WarnEx(category, text, 1);
1190}
1191
1192/* Warning with explicit origin */
1193int
Victor Stinner14e461d2013-08-26 22:28:21 +02001194PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1195 PyObject *filename, int lineno,
1196 PyObject *module, PyObject *registry)
1197{
1198 PyObject *res;
1199 if (category == NULL)
1200 category = PyExc_RuntimeWarning;
1201 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001202 module, registry, NULL, NULL);
Victor Stinner14e461d2013-08-26 22:28:21 +02001203 if (res == NULL)
1204 return -1;
1205 Py_DECREF(res);
1206 return 0;
1207}
1208
1209int
Christian Heimes33fe8092008-04-13 13:53:33 +00001210PyErr_WarnExplicit(PyObject *category, const char *text,
1211 const char *filename_str, int lineno,
1212 const char *module_str, PyObject *registry)
1213{
Christian Heimes33fe8092008-04-13 13:53:33 +00001214 PyObject *message = PyUnicode_FromString(text);
Victor Stinnercb428f02010-12-27 20:10:36 +00001215 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
Christian Heimes33fe8092008-04-13 13:53:33 +00001216 PyObject *module = NULL;
1217 int ret = -1;
1218
1219 if (message == NULL || filename == NULL)
1220 goto exit;
1221 if (module_str != NULL) {
1222 module = PyUnicode_FromString(module_str);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001223 if (module == NULL)
1224 goto exit;
Christian Heimes33fe8092008-04-13 13:53:33 +00001225 }
1226
Victor Stinner14e461d2013-08-26 22:28:21 +02001227 ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1228 module, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +00001229
1230 exit:
1231 Py_XDECREF(message);
1232 Py_XDECREF(module);
1233 Py_XDECREF(filename);
1234 return ret;
1235}
1236
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001237int
1238PyErr_WarnExplicitFormat(PyObject *category,
1239 const char *filename_str, int lineno,
1240 const char *module_str, PyObject *registry,
1241 const char *format, ...)
1242{
1243 PyObject *message;
1244 PyObject *module = NULL;
1245 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1246 int ret = -1;
1247 va_list vargs;
1248
1249 if (filename == NULL)
1250 goto exit;
1251 if (module_str != NULL) {
1252 module = PyUnicode_FromString(module_str);
1253 if (module == NULL)
1254 goto exit;
1255 }
1256
1257#ifdef HAVE_STDARG_PROTOTYPES
1258 va_start(vargs, format);
1259#else
1260 va_start(vargs);
1261#endif
1262 message = PyUnicode_FromFormatV(format, vargs);
1263 if (message != NULL) {
1264 PyObject *res;
1265 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001266 module, registry, NULL, NULL);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001267 Py_DECREF(message);
1268 if (res != NULL) {
1269 Py_DECREF(res);
1270 ret = 0;
1271 }
1272 }
1273 va_end(vargs);
1274exit:
1275 Py_XDECREF(module);
1276 Py_XDECREF(filename);
1277 return ret;
1278}
1279
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001280void
1281_PyErr_WarnUnawaitedCoroutine(PyObject *coro)
1282{
1283 /* First, we attempt to funnel the warning through
1284 warnings._warn_unawaited_coroutine.
1285
1286 This could raise an exception, due to:
1287 - a bug
1288 - some kind of shutdown-related brokenness
1289 - succeeding, but with an "error" warning filter installed, so the
1290 warning is converted into a RuntimeWarning exception
1291
1292 In the first two cases, we want to print the error (so we know what it
1293 is!), and then print a warning directly as a fallback. In the last
1294 case, we want to print the error (since it's the warning!), but *not*
1295 do a fallback. And after we print the error we can't check for what
1296 type of error it was (because PyErr_WriteUnraisable clears it), so we
1297 need a flag to keep track.
1298
1299 Since this is called from __del__ context, it's careful to never raise
1300 an exception.
1301 */
1302 _Py_IDENTIFIER(_warn_unawaited_coroutine);
1303 int warned = 0;
1304 PyObject *fn = get_warnings_attr(&PyId__warn_unawaited_coroutine, 1);
1305 if (fn) {
Petr Viktorinffd97532020-02-11 17:46:57 +01001306 PyObject *res = PyObject_CallOneArg(fn, coro);
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001307 Py_DECREF(fn);
1308 if (res || PyErr_ExceptionMatches(PyExc_RuntimeWarning)) {
1309 warned = 1;
1310 }
1311 Py_XDECREF(res);
1312 }
1313
1314 if (PyErr_Occurred()) {
1315 PyErr_WriteUnraisable(coro);
1316 }
1317 if (!warned) {
Victor Stinner8d84adc2020-03-31 17:25:12 +02001318 if (_PyErr_WarnFormat(coro, PyExc_RuntimeWarning, 1,
1319 "coroutine '%S' was never awaited",
1320 ((PyCoroObject *)coro)->cr_qualname) < 0)
Yury Selivanov35103342018-01-21 20:47:04 -05001321 {
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001322 PyErr_WriteUnraisable(coro);
1323 }
1324 }
1325}
Christian Heimes33fe8092008-04-13 13:53:33 +00001326
Christian Heimes33fe8092008-04-13 13:53:33 +00001327PyDoc_STRVAR(warn_explicit_doc,
Hansraj Das5dfbb4d2019-10-08 14:26:07 +05301328"Low-level interface to warnings functionality.");
Christian Heimes33fe8092008-04-13 13:53:33 +00001329
1330static PyMethodDef warnings_functions[] = {
Victor Stinner22f18752016-12-09 18:08:18 +01001331 WARNINGS_WARN_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001332 {"warn_explicit", (PyCFunction)(void(*)(void))warnings_warn_explicit,
Christian Heimes33fe8092008-04-13 13:53:33 +00001333 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001334 {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
1335 NULL},
Christian Heimes1a8501c2008-10-02 19:56:01 +00001336 /* XXX(brett.cannon): add showwarning? */
1337 /* XXX(brett.cannon): Reasonable to add formatwarning? */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 {NULL, NULL} /* sentinel */
Christian Heimes33fe8092008-04-13 13:53:33 +00001339};
1340
1341
Martin v. Löwis1a214512008-06-11 05:26:20 +00001342static struct PyModuleDef warningsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 PyModuleDef_HEAD_INIT,
Eric Snow86ea5812019-05-10 13:29:55 -04001344 MODULE_NAME, /* m_name */
1345 warnings__doc__, /* m_doc */
1346 0, /* m_size */
1347 warnings_functions, /* m_methods */
1348 NULL, /* m_reload */
1349 NULL, /* m_traverse */
1350 NULL, /* m_clear */
1351 NULL /* m_free */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001352};
1353
Christian Heimes33fe8092008-04-13 13:53:33 +00001354
Victor Stinner66b79732020-03-02 15:02:18 +01001355PyStatus
1356_PyWarnings_InitState(PyThreadState *tstate)
1357{
1358 if (warnings_init_state(&tstate->interp->warnings) < 0) {
1359 return _PyStatus_ERR("can't initialize warnings");
1360 }
1361 return _PyStatus_OK();
1362}
1363
1364
Victor Stinner5d862462017-12-19 11:35:58 +01001365PyMODINIT_FUNC
1366_PyWarnings_Init(void)
Christian Heimes33fe8092008-04-13 13:53:33 +00001367{
Brett Cannon0759dd62009-04-01 18:13:07 +00001368 PyObject *m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001369
Martin v. Löwis1a214512008-06-11 05:26:20 +00001370 m = PyModule_Create(&warningsmodule);
Eric Snow86ea5812019-05-10 13:29:55 -04001371 if (m == NULL) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00001372 return NULL;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001373 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001374
Victor Stinner66b79732020-03-02 15:02:18 +01001375 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -04001376 if (st == NULL) {
1377 goto error;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001378 }
Victor Stinner66b79732020-03-02 15:02:18 +01001379 if (warnings_init_state(st) < 0) {
Eric Snow86ea5812019-05-10 13:29:55 -04001380 goto error;
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001381 }
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001382
Eric Snow86ea5812019-05-10 13:29:55 -04001383 Py_INCREF(st->filters);
1384 if (PyModule_AddObject(m, "filters", st->filters) < 0) {
1385 goto error;
1386 }
1387
1388 Py_INCREF(st->once_registry);
1389 if (PyModule_AddObject(m, "_onceregistry", st->once_registry) < 0) {
1390 goto error;
1391 }
1392
1393 Py_INCREF(st->default_action);
1394 if (PyModule_AddObject(m, "_defaultaction", st->default_action) < 0) {
1395 goto error;
1396 }
1397
Martin v. Löwis1a214512008-06-11 05:26:20 +00001398 return m;
Eric Snow86ea5812019-05-10 13:29:55 -04001399
1400error:
1401 if (st != NULL) {
Victor Stinner66b79732020-03-02 15:02:18 +01001402 warnings_clear_state(st);
Eric Snow86ea5812019-05-10 13:29:55 -04001403 }
1404 Py_DECREF(m);
1405 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001406}
Victor Stinner87d23a02019-04-26 05:49:26 +02001407
Eric Snow86ea5812019-05-10 13:29:55 -04001408// We need this to ensure that warnings still work until late in finalization.
Victor Stinner87d23a02019-04-26 05:49:26 +02001409void
Eric Snow86ea5812019-05-10 13:29:55 -04001410_PyWarnings_Fini(PyInterpreterState *interp)
Victor Stinner87d23a02019-04-26 05:49:26 +02001411{
Victor Stinner66b79732020-03-02 15:02:18 +01001412 warnings_clear_state(&interp->warnings);
Victor Stinner87d23a02019-04-26 05:49:26 +02001413}