blob: 021400f5580d6abaa9d6136c9f9acd2be875daa3 [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 Stinnerc9bc2902020-10-27 02:24:34 +01004#include "pycore_long.h" // _PyLong_GetZero()
Victor Stinner4d231bc2019-11-14 13:36:21 +01005#include "pycore_pyerrors.h"
Victor Stinnere5014be2020-04-14 17:52:15 +02006#include "pycore_pystate.h" // _PyThreadState_GET()
Victor Stinner70364772020-04-29 03:28:46 +02007#include "frameobject.h" // PyFrame_GetBack()
Victor Stinner22f18752016-12-09 18:08:18 +01008#include "clinic/_warnings.c.h"
Christian Heimes33fe8092008-04-13 13:53:33 +00009
10#define MODULE_NAME "_warnings"
Christian Heimes33fe8092008-04-13 13:53:33 +000011
12PyDoc_STRVAR(warnings__doc__,
13MODULE_NAME " provides basic warning filtering support.\n"
14"It is a helper module to speed up interpreter start-up.");
15
Victor Stinnerbd303c12013-11-07 23:07:29 +010016_Py_IDENTIFIER(stderr);
Victor Stinner747f48e2017-12-12 22:59:48 +010017#ifndef Py_DEBUG
Nick Coghlan9b997472018-01-08 12:45:02 +100018_Py_IDENTIFIER(default);
Victor Stinnerb98f1712017-11-23 17:13:44 +010019_Py_IDENTIFIER(ignore);
Victor Stinner747f48e2017-12-12 22:59:48 +010020#endif
Christian Heimes33fe8092008-04-13 13:53:33 +000021
Eric Snow86ea5812019-05-10 13:29:55 -040022
23/*************************************************************************/
24
25typedef struct _warnings_runtime_state WarningsState;
26
Hai Shi46874c22020-01-30 17:20:25 -060027_Py_IDENTIFIER(__name__);
28
Eric Snow86ea5812019-05-10 13:29:55 -040029/* Given a module object, get its per-module state. */
30static WarningsState *
Victor Stinner66b79732020-03-02 15:02:18 +010031warnings_get_state(void)
Eric Snow86ea5812019-05-10 13:29:55 -040032{
Victor Stinner1bcc32f2020-06-10 20:08:26 +020033 PyInterpreterState *interp = _PyInterpreterState_GET();
34 if (interp == NULL) {
35 PyErr_SetString(PyExc_RuntimeError,
36 "warnings_get_state: could not identify "
37 "current interpreter");
Eric Snow86ea5812019-05-10 13:29:55 -040038 return NULL;
39 }
Victor Stinner1bcc32f2020-06-10 20:08:26 +020040 return &interp->warnings;
Eric Snow86ea5812019-05-10 13:29:55 -040041}
42
43/* Clear the given warnings module state. */
44static void
Victor Stinner66b79732020-03-02 15:02:18 +010045warnings_clear_state(WarningsState *st)
Eric Snow86ea5812019-05-10 13:29:55 -040046{
47 Py_CLEAR(st->filters);
48 Py_CLEAR(st->once_registry);
49 Py_CLEAR(st->default_action);
50}
51
52#ifndef Py_DEBUG
53static PyObject *
54create_filter(PyObject *category, _Py_Identifier *id, const char *modname)
55{
56 PyObject *modname_obj = NULL;
57 PyObject *action_str = _PyUnicode_FromId(id);
58 if (action_str == NULL) {
59 return NULL;
60 }
61
62 /* Default to "no module name" for initial filter set */
63 if (modname != NULL) {
64 modname_obj = PyUnicode_InternFromString(modname);
65 if (modname_obj == NULL) {
66 return NULL;
67 }
68 } else {
Victor Stinnerd1e38d42020-11-18 15:57:10 +010069 modname_obj = Py_NewRef(Py_None);
Eric Snow86ea5812019-05-10 13:29:55 -040070 }
71
72 /* This assumes the line number is zero for now. */
Victor Stinnerd1e38d42020-11-18 15:57:10 +010073 PyObject *filter = PyTuple_Pack(5, action_str, Py_None,
74 category, modname_obj, _PyLong_GetZero());
75 Py_DECREF(modname_obj);
76 return filter;
Eric Snow86ea5812019-05-10 13:29:55 -040077}
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. */
Victor Stinneref75a622020-11-12 15:14:13 +0100116int
117_PyWarnings_InitState(PyThreadState *tstate)
Eric Snow86ea5812019-05-10 13:29:55 -0400118{
Victor Stinneref75a622020-11-12 15:14:13 +0100119 WarningsState *st = &tstate->interp->warnings;
120
Eric Snow86ea5812019-05-10 13:29:55 -0400121 if (st->filters == NULL) {
122 st->filters = init_filters();
123 if (st->filters == NULL) {
Victor Stinneref75a622020-11-12 15:14:13 +0100124 return -1;
Eric Snow86ea5812019-05-10 13:29:55 -0400125 }
126 }
127
128 if (st->once_registry == NULL) {
129 st->once_registry = PyDict_New();
130 if (st->once_registry == NULL) {
Victor Stinneref75a622020-11-12 15:14:13 +0100131 return -1;
Eric Snow86ea5812019-05-10 13:29:55 -0400132 }
133 }
134
135 if (st->default_action == NULL) {
136 st->default_action = PyUnicode_FromString("default");
137 if (st->default_action == NULL) {
Victor Stinneref75a622020-11-12 15:14:13 +0100138 return -1;
Eric Snow86ea5812019-05-10 13:29:55 -0400139 }
140 }
141
142 st->filters_version = 0;
Eric Snow86ea5812019-05-10 13:29:55 -0400143 return 0;
Eric Snow86ea5812019-05-10 13:29:55 -0400144}
145
146
147/*************************************************************************/
148
Christian Heimes33fe8092008-04-13 13:53:33 +0000149static int
150check_matched(PyObject *obj, PyObject *arg)
151{
152 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200153 _Py_IDENTIFIER(match);
Christian Heimes33fe8092008-04-13 13:53:33 +0000154 int rc;
155
Nick Coghlan9b997472018-01-08 12:45:02 +1000156 /* A 'None' filter always matches */
Christian Heimes33fe8092008-04-13 13:53:33 +0000157 if (obj == Py_None)
158 return 1;
Nick Coghlan9b997472018-01-08 12:45:02 +1000159
160 /* An internal plain text default filter must match exactly */
161 if (PyUnicode_CheckExact(obj)) {
162 int cmp_result = PyUnicode_Compare(obj, arg);
163 if (cmp_result == -1 && PyErr_Occurred()) {
164 return -1;
165 }
166 return !cmp_result;
167 }
168
169 /* Otherwise assume a regex filter and call its match() method */
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200170 result = _PyObject_CallMethodIdOneArg(obj, &PyId_match, arg);
Christian Heimes33fe8092008-04-13 13:53:33 +0000171 if (result == NULL)
172 return -1;
173
174 rc = PyObject_IsTrue(result);
175 Py_DECREF(result);
176 return rc;
177}
178
179/*
180 Returns a new reference.
181 A NULL return value can mean false or an error.
182*/
183static PyObject *
Victor Stinner82656272017-11-22 23:51:42 +0100184get_warnings_attr(_Py_Identifier *attr_id, int try_import)
Christian Heimes33fe8092008-04-13 13:53:33 +0000185{
Victor Stinner82656272017-11-22 23:51:42 +0100186 PyObject *warnings_str;
Victor Stinnere98445a2016-03-23 00:54:48 +0100187 PyObject *warnings_module, *obj;
Victor Stinner82656272017-11-22 23:51:42 +0100188 _Py_IDENTIFIER(warnings);
Christian Heimes33fe8092008-04-13 13:53:33 +0000189
Victor Stinner82656272017-11-22 23:51:42 +0100190 warnings_str = _PyUnicode_FromId(&PyId_warnings);
Christian Heimes33fe8092008-04-13 13:53:33 +0000191 if (warnings_str == NULL) {
Victor Stinner82656272017-11-22 23:51:42 +0100192 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000193 }
194
Victor Stinnere98445a2016-03-23 00:54:48 +0100195 /* don't try to import after the start of the Python finallization */
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600196 if (try_import && !_Py_IsFinalizing()) {
Victor Stinnere98445a2016-03-23 00:54:48 +0100197 warnings_module = PyImport_Import(warnings_str);
198 if (warnings_module == NULL) {
199 /* Fallback to the C implementation if we cannot get
200 the Python implementation */
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200201 if (PyErr_ExceptionMatches(PyExc_ImportError)) {
202 PyErr_Clear();
203 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000204 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +0100205 }
206 }
207 else {
Nathaniel J. Smithdba976b2018-01-26 11:28:31 -0800208 /* if we're so late into Python finalization that the module dict is
209 gone, then we can't even use PyImport_GetModule without triggering
210 an interpreter abort.
211 */
Victor Stinner81a7be32020-04-14 15:14:01 +0200212 if (!_PyInterpreterState_GET()->modules) {
Nathaniel J. Smithdba976b2018-01-26 11:28:31 -0800213 return NULL;
214 }
Eric Snow3f9eee62017-09-15 16:35:20 -0600215 warnings_module = PyImport_GetModule(warnings_str);
Victor Stinner023654f2016-03-23 17:48:22 +0100216 if (warnings_module == NULL)
217 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +0100218 }
219
Serhiy Storchakaf320be72018-01-25 10:49:40 +0200220 (void)_PyObject_LookupAttrId(warnings_module, attr_id, &obj);
Victor Stinnere98445a2016-03-23 00:54:48 +0100221 Py_DECREF(warnings_module);
222 return obj;
Christian Heimes33fe8092008-04-13 13:53:33 +0000223}
224
225
Neal Norwitz32dde222008-04-15 06:43:13 +0000226static PyObject *
Eric Snow86ea5812019-05-10 13:29:55 -0400227get_once_registry(WarningsState *st)
Christian Heimes33fe8092008-04-13 13:53:33 +0000228{
229 PyObject *registry;
Victor Stinner82656272017-11-22 23:51:42 +0100230 _Py_IDENTIFIER(onceregistry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000231
Victor Stinner82656272017-11-22 23:51:42 +0100232 registry = get_warnings_attr(&PyId_onceregistry, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000233 if (registry == NULL) {
234 if (PyErr_Occurred())
235 return NULL;
Eric Snow86ea5812019-05-10 13:29:55 -0400236 assert(st->once_registry);
237 return st->once_registry;
Christian Heimes33fe8092008-04-13 13:53:33 +0000238 }
Oren Milman252033d2017-09-11 09:28:39 +0300239 if (!PyDict_Check(registry)) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200240 PyErr_Format(PyExc_TypeError,
241 MODULE_NAME ".onceregistry must be a dict, "
242 "not '%.200s'",
243 Py_TYPE(registry)->tp_name);
Oren Milman252033d2017-09-11 09:28:39 +0300244 Py_DECREF(registry);
245 return NULL;
246 }
Eric Snow86ea5812019-05-10 13:29:55 -0400247 Py_SETREF(st->once_registry, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000248 return registry;
249}
250
251
Brett Cannon0759dd62009-04-01 18:13:07 +0000252static PyObject *
Eric Snow86ea5812019-05-10 13:29:55 -0400253get_default_action(WarningsState *st)
Brett Cannon0759dd62009-04-01 18:13:07 +0000254{
255 PyObject *default_action;
Victor Stinner82656272017-11-22 23:51:42 +0100256 _Py_IDENTIFIER(defaultaction);
Brett Cannon0759dd62009-04-01 18:13:07 +0000257
Victor Stinner82656272017-11-22 23:51:42 +0100258 default_action = get_warnings_attr(&PyId_defaultaction, 0);
Brett Cannon0759dd62009-04-01 18:13:07 +0000259 if (default_action == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 if (PyErr_Occurred()) {
261 return NULL;
262 }
Eric Snow86ea5812019-05-10 13:29:55 -0400263 assert(st->default_action);
264 return st->default_action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000265 }
Oren Milman9d984fd2017-09-12 00:18:09 +0300266 if (!PyUnicode_Check(default_action)) {
267 PyErr_Format(PyExc_TypeError,
268 MODULE_NAME ".defaultaction must be a string, "
269 "not '%.200s'",
270 Py_TYPE(default_action)->tp_name);
271 Py_DECREF(default_action);
272 return NULL;
273 }
Eric Snow86ea5812019-05-10 13:29:55 -0400274 Py_SETREF(st->default_action, default_action);
Brett Cannon0759dd62009-04-01 18:13:07 +0000275 return default_action;
276}
277
278
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400279/* The item is a new reference. */
Victor Stinnera4c704b2013-10-29 23:43:41 +0100280static PyObject*
Christian Heimes33fe8092008-04-13 13:53:33 +0000281get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
282 PyObject *module, PyObject **item)
283{
Brett Cannon0759dd62009-04-01 18:13:07 +0000284 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000285 Py_ssize_t i;
286 PyObject *warnings_filters;
Victor Stinner82656272017-11-22 23:51:42 +0100287 _Py_IDENTIFIER(filters);
Victor Stinner66b79732020-03-02 15:02:18 +0100288 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -0400289 if (st == NULL) {
290 return NULL;
291 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000292
Victor Stinner82656272017-11-22 23:51:42 +0100293 warnings_filters = get_warnings_attr(&PyId_filters, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000294 if (warnings_filters == NULL) {
295 if (PyErr_Occurred())
296 return NULL;
297 }
298 else {
Eric Snow86ea5812019-05-10 13:29:55 -0400299 Py_SETREF(st->filters, warnings_filters);
Christian Heimes33fe8092008-04-13 13:53:33 +0000300 }
301
Eric Snow86ea5812019-05-10 13:29:55 -0400302 PyObject *filters = st->filters;
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600303 if (filters == NULL || !PyList_Check(filters)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000304 PyErr_SetString(PyExc_ValueError,
305 MODULE_NAME ".filters must be a list");
306 return NULL;
307 }
308
Eric Snow86ea5812019-05-10 13:29:55 -0400309 /* WarningsState.filters could change while we are iterating over it. */
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600310 for (i = 0; i < PyList_GET_SIZE(filters); i++) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000311 PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
312 Py_ssize_t ln;
313 int is_subclass, good_msg, good_mod;
314
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600315 tmp_item = PyList_GET_ITEM(filters, i);
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400316 if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000317 PyErr_Format(PyExc_ValueError,
318 MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
319 return NULL;
320 }
321
322 /* Python code: action, msg, cat, mod, ln = item */
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400323 Py_INCREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000324 action = PyTuple_GET_ITEM(tmp_item, 0);
325 msg = PyTuple_GET_ITEM(tmp_item, 1);
326 cat = PyTuple_GET_ITEM(tmp_item, 2);
327 mod = PyTuple_GET_ITEM(tmp_item, 3);
328 ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
329
Oren Milman9d984fd2017-09-12 00:18:09 +0300330 if (!PyUnicode_Check(action)) {
331 PyErr_Format(PyExc_TypeError,
332 "action must be a string, not '%.200s'",
333 Py_TYPE(action)->tp_name);
334 Py_DECREF(tmp_item);
335 return NULL;
336 }
337
Christian Heimes33fe8092008-04-13 13:53:33 +0000338 good_msg = check_matched(msg, text);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400339 if (good_msg == -1) {
340 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100341 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400342 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100343
Christian Heimes33fe8092008-04-13 13:53:33 +0000344 good_mod = check_matched(mod, module);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400345 if (good_mod == -1) {
346 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100347 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400348 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100349
Christian Heimes33fe8092008-04-13 13:53:33 +0000350 is_subclass = PyObject_IsSubclass(category, cat);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400351 if (is_subclass == -1) {
352 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100353 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400354 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100355
Christian Heimes33fe8092008-04-13 13:53:33 +0000356 ln = PyLong_AsSsize_t(ln_obj);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400357 if (ln == -1 && PyErr_Occurred()) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400358 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000359 return NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400360 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000361
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400362 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
363 *item = tmp_item;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100364 return action;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400365 }
366
367 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000368 }
369
Eric Snow86ea5812019-05-10 13:29:55 -0400370 action = get_default_action(st);
Brett Cannon0759dd62009-04-01 18:13:07 +0000371 if (action != NULL) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400372 Py_INCREF(Py_None);
373 *item = Py_None;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100374 return action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000375 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000376
Christian Heimes33fe8092008-04-13 13:53:33 +0000377 return NULL;
378}
379
Brett Cannon0759dd62009-04-01 18:13:07 +0000380
Christian Heimes33fe8092008-04-13 13:53:33 +0000381static int
382already_warned(PyObject *registry, PyObject *key, int should_set)
383{
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200384 PyObject *version_obj, *already_warned;
385 _Py_IDENTIFIER(version);
Christian Heimes33fe8092008-04-13 13:53:33 +0000386
387 if (key == NULL)
388 return -1;
389
Victor Stinner66b79732020-03-02 15:02:18 +0100390 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -0400391 if (st == NULL) {
392 return -1;
393 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200394 version_obj = _PyDict_GetItemIdWithError(registry, &PyId_version);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200395 if (version_obj == NULL
396 || !PyLong_CheckExact(version_obj)
Eric Snow86ea5812019-05-10 13:29:55 -0400397 || PyLong_AsLong(version_obj) != st->filters_version)
Serhiy Storchaka8905fcc2018-12-11 08:38:03 +0200398 {
399 if (PyErr_Occurred()) {
400 return -1;
401 }
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200402 PyDict_Clear(registry);
Eric Snow86ea5812019-05-10 13:29:55 -0400403 version_obj = PyLong_FromLong(st->filters_version);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200404 if (version_obj == NULL)
405 return -1;
406 if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
407 Py_DECREF(version_obj);
408 return -1;
409 }
410 Py_DECREF(version_obj);
411 }
412 else {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200413 already_warned = PyDict_GetItemWithError(registry, key);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200414 if (already_warned != NULL) {
415 int rc = PyObject_IsTrue(already_warned);
416 if (rc != 0)
417 return rc;
418 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200419 else if (PyErr_Occurred()) {
420 return -1;
421 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000422 }
423
424 /* This warning wasn't found in the registry, set it. */
425 if (should_set)
426 return PyDict_SetItem(registry, key, Py_True);
427 return 0;
428}
429
430/* New reference. */
431static PyObject *
432normalize_module(PyObject *filename)
433{
434 PyObject *module;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100435 int kind;
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300436 const void *data;
Christian Heimes33fe8092008-04-13 13:53:33 +0000437 Py_ssize_t len;
438
Victor Stinner9e30aa52011-11-21 02:49:52 +0100439 len = PyUnicode_GetLength(filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000440 if (len < 0)
441 return NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100442
443 if (len == 0)
444 return PyUnicode_FromString("<unknown>");
445
446 kind = PyUnicode_KIND(filename);
447 data = PyUnicode_DATA(filename);
448
449 /* if filename.endswith(".py"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000450 if (len >= 3 &&
Victor Stinnera4c704b2013-10-29 23:43:41 +0100451 PyUnicode_READ(kind, data, len-3) == '.' &&
452 PyUnicode_READ(kind, data, len-2) == 'p' &&
453 PyUnicode_READ(kind, data, len-1) == 'y')
454 {
Victor Stinner9e30aa52011-11-21 02:49:52 +0100455 module = PyUnicode_Substring(filename, 0, len-3);
Christian Heimes33fe8092008-04-13 13:53:33 +0000456 }
457 else {
458 module = filename;
459 Py_INCREF(module);
460 }
461 return module;
462}
463
464static int
465update_registry(PyObject *registry, PyObject *text, PyObject *category,
466 int add_zero)
467{
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300468 PyObject *altkey;
Christian Heimes33fe8092008-04-13 13:53:33 +0000469 int rc;
470
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300471 if (add_zero)
Victor Stinnerc9bc2902020-10-27 02:24:34 +0100472 altkey = PyTuple_Pack(3, text, category, _PyLong_GetZero());
Christian Heimes33fe8092008-04-13 13:53:33 +0000473 else
474 altkey = PyTuple_Pack(2, text, category);
475
476 rc = already_warned(registry, altkey, 1);
Christian Heimes33fe8092008-04-13 13:53:33 +0000477 Py_XDECREF(altkey);
478 return rc;
479}
480
481static void
Victor Stinner914cde82016-03-19 01:03:51 +0100482show_warning(PyObject *filename, int lineno, PyObject *text,
483 PyObject *category, PyObject *sourceline)
Christian Heimes33fe8092008-04-13 13:53:33 +0000484{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 PyObject *f_stderr;
486 PyObject *name;
Christian Heimes33fe8092008-04-13 13:53:33 +0000487 char lineno_str[128];
488
489 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
490
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200491 name = _PyObject_GetAttrId(category, &PyId___name__);
Hai Shi57c78102020-03-14 21:40:58 +0800492 if (name == NULL) {
Victor Stinnerae233ea2013-10-31 14:51:38 +0100493 goto error;
Hai Shi57c78102020-03-14 21:40:58 +0800494 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000495
Victor Stinnerbd303c12013-11-07 23:07:29 +0100496 f_stderr = _PySys_GetObjectId(&PyId_stderr);
Christian Heimes33fe8092008-04-13 13:53:33 +0000497 if (f_stderr == NULL) {
498 fprintf(stderr, "lost sys.stderr\n");
Victor Stinnerae233ea2013-10-31 14:51:38 +0100499 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000500 }
501
502 /* Print "filename:lineno: category: text\n" */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100503 if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
504 goto error;
505 if (PyFile_WriteString(lineno_str, f_stderr) < 0)
506 goto error;
507 if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
508 goto error;
509 if (PyFile_WriteString(": ", f_stderr) < 0)
510 goto error;
511 if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
512 goto error;
513 if (PyFile_WriteString("\n", f_stderr) < 0)
514 goto error;
515 Py_CLEAR(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000516
517 /* Print " source_line\n" */
Christian Heimes33fe8092008-04-13 13:53:33 +0000518 if (sourceline) {
Victor Stinnera4c704b2013-10-29 23:43:41 +0100519 int kind;
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300520 const void *data;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100521 Py_ssize_t i, len;
522 Py_UCS4 ch;
523 PyObject *truncated;
Christian Heimes33fe8092008-04-13 13:53:33 +0000524
Victor Stinnera4c704b2013-10-29 23:43:41 +0100525 if (PyUnicode_READY(sourceline) < 1)
526 goto error;
527
528 kind = PyUnicode_KIND(sourceline);
529 data = PyUnicode_DATA(sourceline);
530 len = PyUnicode_GET_LENGTH(sourceline);
531 for (i=0; i<len; i++) {
532 ch = PyUnicode_READ(kind, data, i);
533 if (ch != ' ' && ch != '\t' && ch != '\014')
534 break;
535 }
536
537 truncated = PyUnicode_Substring(sourceline, i, len);
538 if (truncated == NULL)
539 goto error;
540
541 PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
542 Py_DECREF(truncated);
Christian Heimes33fe8092008-04-13 13:53:33 +0000543 PyFile_WriteString("\n", f_stderr);
544 }
Victor Stinner78e2c982013-07-16 01:54:37 +0200545 else {
546 _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
547 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100548
549error:
Victor Stinnerae233ea2013-10-31 14:51:38 +0100550 Py_XDECREF(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000551 PyErr_Clear();
552}
553
Victor Stinner1231a462016-03-19 00:47:17 +0100554static int
555call_show_warning(PyObject *category, PyObject *text, PyObject *message,
556 PyObject *filename, int lineno, PyObject *lineno_obj,
Victor Stinner914cde82016-03-19 01:03:51 +0100557 PyObject *sourceline, PyObject *source)
Victor Stinner1231a462016-03-19 00:47:17 +0100558{
559 PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
Victor Stinner82656272017-11-22 23:51:42 +0100560 _Py_IDENTIFIER(_showwarnmsg);
561 _Py_IDENTIFIER(WarningMessage);
Victor Stinner1231a462016-03-19 00:47:17 +0100562
Victor Stinnere98445a2016-03-23 00:54:48 +0100563 /* If the source parameter is set, try to get the Python implementation.
564 The Python implementation is able to log the traceback where the source
luzpaza5293b42017-11-05 07:37:50 -0600565 was allocated, whereas the C implementation doesn't. */
Victor Stinner82656272017-11-22 23:51:42 +0100566 show_fn = get_warnings_attr(&PyId__showwarnmsg, source != NULL);
Victor Stinner1231a462016-03-19 00:47:17 +0100567 if (show_fn == NULL) {
568 if (PyErr_Occurred())
569 return -1;
570 show_warning(filename, lineno, text, category, sourceline);
571 return 0;
572 }
573
574 if (!PyCallable_Check(show_fn)) {
575 PyErr_SetString(PyExc_TypeError,
576 "warnings._showwarnmsg() must be set to a callable");
577 goto error;
578 }
579
Victor Stinner82656272017-11-22 23:51:42 +0100580 warnmsg_cls = get_warnings_attr(&PyId_WarningMessage, 0);
Victor Stinner1231a462016-03-19 00:47:17 +0100581 if (warnmsg_cls == NULL) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200582 if (!PyErr_Occurred()) {
583 PyErr_SetString(PyExc_RuntimeError,
584 "unable to get warnings.WarningMessage");
585 }
Victor Stinner1231a462016-03-19 00:47:17 +0100586 goto error;
587 }
588
589 msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
Victor Stinner914cde82016-03-19 01:03:51 +0100590 filename, lineno_obj, Py_None, Py_None, source,
Victor Stinner1231a462016-03-19 00:47:17 +0100591 NULL);
592 Py_DECREF(warnmsg_cls);
593 if (msg == NULL)
594 goto error;
595
Petr Viktorinffd97532020-02-11 17:46:57 +0100596 res = PyObject_CallOneArg(show_fn, msg);
Victor Stinner1231a462016-03-19 00:47:17 +0100597 Py_DECREF(show_fn);
598 Py_DECREF(msg);
599
600 if (res == NULL)
601 return -1;
602
603 Py_DECREF(res);
604 return 0;
605
606error:
607 Py_XDECREF(show_fn);
608 return -1;
609}
610
Christian Heimes33fe8092008-04-13 13:53:33 +0000611static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612warn_explicit(PyObject *category, PyObject *message,
Christian Heimes33fe8092008-04-13 13:53:33 +0000613 PyObject *filename, int lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100614 PyObject *module, PyObject *registry, PyObject *sourceline,
615 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000616{
617 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400618 PyObject *item = NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100619 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000620 int rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100622 /* module can be None if a warning is emitted late during Python shutdown.
623 In this case, the Python warnings module was probably unloaded, filters
624 are no more available to choose as action. It is safer to ignore the
625 warning and do nothing. */
626 if (module == Py_None)
627 Py_RETURN_NONE;
628
Brett Cannondb734912008-06-27 00:52:15 +0000629 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
Oren Milman252033d2017-09-11 09:28:39 +0300630 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
Brett Cannondb734912008-06-27 00:52:15 +0000631 return NULL;
632 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000633
634 /* Normalize module. */
635 if (module == NULL) {
636 module = normalize_module(filename);
637 if (module == NULL)
638 return NULL;
639 }
640 else
641 Py_INCREF(module);
642
643 /* Normalize message. */
644 Py_INCREF(message); /* DECREF'ed in cleanup. */
645 rc = PyObject_IsInstance(message, PyExc_Warning);
646 if (rc == -1) {
647 goto cleanup;
648 }
649 if (rc == 1) {
650 text = PyObject_Str(message);
Hirokazu Yamamoto1c0c0032009-07-17 06:55:42 +0000651 if (text == NULL)
652 goto cleanup;
Victor Stinnera102ed72020-02-07 02:24:48 +0100653 category = (PyObject*)Py_TYPE(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000654 }
655 else {
656 text = message;
Petr Viktorinffd97532020-02-11 17:46:57 +0100657 message = PyObject_CallOneArg(category, message);
Brett Cannondb734912008-06-27 00:52:15 +0000658 if (message == NULL)
659 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000660 }
661
662 lineno_obj = PyLong_FromLong(lineno);
663 if (lineno_obj == NULL)
664 goto cleanup;
665
Victor Stinner22f18752016-12-09 18:08:18 +0100666 if (source == Py_None) {
667 source = NULL;
668 }
669
Christian Heimes33fe8092008-04-13 13:53:33 +0000670 /* Create key. */
671 key = PyTuple_Pack(3, text, category, lineno_obj);
672 if (key == NULL)
673 goto cleanup;
674
Brett Cannondb734912008-06-27 00:52:15 +0000675 if ((registry != NULL) && (registry != Py_None)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000676 rc = already_warned(registry, key, 0);
677 if (rc == -1)
678 goto cleanup;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 else if (rc == 1)
Christian Heimes33fe8092008-04-13 13:53:33 +0000680 goto return_none;
681 /* Else this warning hasn't been generated before. */
682 }
683
684 action = get_filter(category, text, lineno, module, &item);
685 if (action == NULL)
686 goto cleanup;
687
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200688 if (_PyUnicode_EqualToASCIIString(action, "error")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000689 PyErr_SetObject(category, message);
690 goto cleanup;
691 }
692
Victor Stinnerc9758782017-11-27 16:57:07 +0100693 if (_PyUnicode_EqualToASCIIString(action, "ignore")) {
694 goto return_none;
695 }
696
Christian Heimes33fe8092008-04-13 13:53:33 +0000697 /* Store in the registry that we've been here, *except* when the action
698 is "always". */
699 rc = 0;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200700 if (!_PyUnicode_EqualToASCIIString(action, "always")) {
Brett Cannondb734912008-06-27 00:52:15 +0000701 if (registry != NULL && registry != Py_None &&
Victor Stinnerc9758782017-11-27 16:57:07 +0100702 PyDict_SetItem(registry, key, Py_True) < 0)
703 {
Christian Heimes33fe8092008-04-13 13:53:33 +0000704 goto cleanup;
Victor Stinnerc9758782017-11-27 16:57:07 +0100705 }
706
707 if (_PyUnicode_EqualToASCIIString(action, "once")) {
Brett Cannondb734912008-06-27 00:52:15 +0000708 if (registry == NULL || registry == Py_None) {
Victor Stinner66b79732020-03-02 15:02:18 +0100709 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -0400710 if (st == NULL) {
711 goto cleanup;
712 }
713 registry = get_once_registry(st);
Christian Heimes33fe8092008-04-13 13:53:33 +0000714 if (registry == NULL)
715 goto cleanup;
716 }
Eric Snow86ea5812019-05-10 13:29:55 -0400717 /* WarningsState.once_registry[(text, category)] = 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000719 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200720 else if (_PyUnicode_EqualToASCIIString(action, "module")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000721 /* registry[(text, category, 0)] = 1 */
Brett Cannondb734912008-06-27 00:52:15 +0000722 if (registry != NULL && registry != Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000724 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200725 else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000726 PyErr_Format(PyExc_RuntimeError,
Victor Stinnera4c704b2013-10-29 23:43:41 +0100727 "Unrecognized action (%R) in warnings.filters:\n %R",
728 action, item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000729 goto cleanup;
730 }
731 }
732
Christian Heimes1a8501c2008-10-02 19:56:01 +0000733 if (rc == 1) /* Already warned for this module. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000734 goto return_none;
735 if (rc == 0) {
Victor Stinner1231a462016-03-19 00:47:17 +0100736 if (call_show_warning(category, text, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100737 lineno_obj, sourceline, source) < 0)
Victor Stinner1231a462016-03-19 00:47:17 +0100738 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000739 }
740 else /* if (rc == -1) */
741 goto cleanup;
742
743 return_none:
744 result = Py_None;
745 Py_INCREF(result);
746
747 cleanup:
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400748 Py_XDECREF(item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000749 Py_XDECREF(key);
750 Py_XDECREF(text);
751 Py_XDECREF(lineno_obj);
752 Py_DECREF(module);
Brett Cannondb734912008-06-27 00:52:15 +0000753 Py_XDECREF(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000754 return result; /* Py_None or NULL. */
755}
756
Larry Hastings714e4932015-09-06 00:39:37 -0700757static int
758is_internal_frame(PyFrameObject *frame)
759{
760 static PyObject *importlib_string = NULL;
761 static PyObject *bootstrap_string = NULL;
Larry Hastings714e4932015-09-06 00:39:37 -0700762 int contains;
763
764 if (importlib_string == NULL) {
765 importlib_string = PyUnicode_FromString("importlib");
766 if (importlib_string == NULL) {
767 return 0;
768 }
769
770 bootstrap_string = PyUnicode_FromString("_bootstrap");
771 if (bootstrap_string == NULL) {
772 Py_DECREF(importlib_string);
773 return 0;
774 }
775 Py_INCREF(importlib_string);
776 Py_INCREF(bootstrap_string);
777 }
778
Victor Stinnera42ca742020-04-28 19:01:31 +0200779 if (frame == NULL) {
Larry Hastings714e4932015-09-06 00:39:37 -0700780 return 0;
781 }
Victor Stinnera42ca742020-04-28 19:01:31 +0200782
783 PyCodeObject *code = PyFrame_GetCode(frame);
Victor Stinnera42ca742020-04-28 19:01:31 +0200784 PyObject *filename = code->co_filename;
Victor Stinner8852ad42020-04-29 01:28:13 +0200785 Py_DECREF(code);
786
Victor Stinnera42ca742020-04-28 19:01:31 +0200787 if (filename == NULL) {
788 return 0;
789 }
Larry Hastings714e4932015-09-06 00:39:37 -0700790 if (!PyUnicode_Check(filename)) {
791 return 0;
792 }
Victor Stinnera42ca742020-04-28 19:01:31 +0200793
Larry Hastings714e4932015-09-06 00:39:37 -0700794 contains = PyUnicode_Contains(filename, importlib_string);
795 if (contains < 0) {
796 return 0;
797 }
798 else if (contains > 0) {
799 contains = PyUnicode_Contains(filename, bootstrap_string);
800 if (contains < 0) {
801 return 0;
802 }
803 else if (contains > 0) {
804 return 1;
805 }
806 }
807
808 return 0;
809}
810
811static PyFrameObject *
812next_external_frame(PyFrameObject *frame)
813{
814 do {
Victor Stinner70364772020-04-29 03:28:46 +0200815 PyFrameObject *back = PyFrame_GetBack(frame);
816 Py_DECREF(frame);
817 frame = back;
Larry Hastings714e4932015-09-06 00:39:37 -0700818 } while (frame != NULL && is_internal_frame(frame));
819
820 return frame;
821}
822
Christian Heimes33fe8092008-04-13 13:53:33 +0000823/* filename, module, and registry are new refs, globals is borrowed */
824/* Returns 0 on error (no new refs), 1 on success */
825static int
826setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
827 PyObject **module, PyObject **registry)
828{
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200829 _Py_IDENTIFIER(__warningregistry__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000830 PyObject *globals;
831
Thomas Kluyver11a89662018-06-08 21:28:37 +0200832 /* Setup globals, filename and lineno. */
Victor Stinner70364772020-04-29 03:28:46 +0200833 PyThreadState *tstate = _PyThreadState_GET();
834 PyFrameObject *f = PyThreadState_GetFrame(tstate);
Larry Hastings714e4932015-09-06 00:39:37 -0700835 // Stack level comparisons to Python code is off by one as there is no
836 // warnings-related stack level to avoid.
837 if (stack_level <= 0 || is_internal_frame(f)) {
838 while (--stack_level > 0 && f != NULL) {
Victor Stinner70364772020-04-29 03:28:46 +0200839 PyFrameObject *back = PyFrame_GetBack(f);
840 Py_DECREF(f);
841 f = back;
Larry Hastings714e4932015-09-06 00:39:37 -0700842 }
843 }
844 else {
845 while (--stack_level > 0 && f != NULL) {
846 f = next_external_frame(f);
847 }
848 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000849
850 if (f == NULL) {
Victor Stinner45df61f2020-11-02 23:17:46 +0100851 globals = tstate->interp->sysdict;
Thomas Kluyver11a89662018-06-08 21:28:37 +0200852 *filename = PyUnicode_FromString("sys");
Christian Heimes33fe8092008-04-13 13:53:33 +0000853 *lineno = 1;
854 }
855 else {
856 globals = f->f_globals;
Victor Stinner8852ad42020-04-29 01:28:13 +0200857 PyCodeObject *code = PyFrame_GetCode(f);
858 *filename = code->co_filename;
859 Py_DECREF(code);
Thomas Kluyver11a89662018-06-08 21:28:37 +0200860 Py_INCREF(*filename);
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000861 *lineno = PyFrame_GetLineNumber(f);
Victor Stinner70364772020-04-29 03:28:46 +0200862 Py_DECREF(f);
Christian Heimes33fe8092008-04-13 13:53:33 +0000863 }
864
865 *module = NULL;
866
867 /* Setup registry. */
868 assert(globals != NULL);
869 assert(PyDict_Check(globals));
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200870 *registry = _PyDict_GetItemIdWithError(globals, &PyId___warningregistry__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000871 if (*registry == NULL) {
872 int rc;
873
Victor Stinner70364772020-04-29 03:28:46 +0200874 if (_PyErr_Occurred(tstate)) {
Serhiy Storchaka2d2f8552020-03-02 22:05:08 +0200875 goto handle_error;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200876 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000877 *registry = PyDict_New();
878 if (*registry == NULL)
Serhiy Storchaka2d2f8552020-03-02 22:05:08 +0200879 goto handle_error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000880
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200881 rc = _PyDict_SetItemId(globals, &PyId___warningregistry__, *registry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000882 if (rc < 0)
883 goto handle_error;
884 }
885 else
886 Py_INCREF(*registry);
887
888 /* Setup module. */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200889 *module = _PyDict_GetItemIdWithError(globals, &PyId___name__);
Oren Milman5d3e8002017-09-24 21:28:42 +0300890 if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) {
891 Py_INCREF(*module);
892 }
Victor Stinner70364772020-04-29 03:28:46 +0200893 else if (_PyErr_Occurred(tstate)) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200894 goto handle_error;
895 }
Oren Milman5d3e8002017-09-24 21:28:42 +0300896 else {
Christian Heimes33fe8092008-04-13 13:53:33 +0000897 *module = PyUnicode_FromString("<string>");
898 if (*module == NULL)
899 goto handle_error;
900 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000901
Christian Heimes33fe8092008-04-13 13:53:33 +0000902 return 1;
903
904 handle_error:
Christian Heimes33fe8092008-04-13 13:53:33 +0000905 Py_XDECREF(*registry);
906 Py_XDECREF(*module);
Serhiy Storchakaae75a292020-03-03 19:43:29 +0200907 Py_DECREF(*filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000908 return 0;
909}
910
911static PyObject *
912get_category(PyObject *message, PyObject *category)
913{
914 int rc;
915
916 /* Get category. */
917 rc = PyObject_IsInstance(message, PyExc_Warning);
918 if (rc == -1)
919 return NULL;
920
921 if (rc == 1)
Victor Stinnera102ed72020-02-07 02:24:48 +0100922 category = (PyObject*)Py_TYPE(message);
Berker Peksagd8089e02014-07-11 19:50:25 +0300923 else if (category == NULL || category == Py_None)
Christian Heimes33fe8092008-04-13 13:53:33 +0000924 category = PyExc_UserWarning;
925
926 /* Validate category. */
927 rc = PyObject_IsSubclass(category, PyExc_Warning);
Berker Peksagd8089e02014-07-11 19:50:25 +0300928 /* category is not a subclass of PyExc_Warning or
929 PyObject_IsSubclass raised an error */
930 if (rc == -1 || rc == 0) {
931 PyErr_Format(PyExc_TypeError,
932 "category must be a Warning subclass, not '%s'",
933 Py_TYPE(category)->tp_name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000934 return NULL;
935 }
936
937 return category;
938}
939
940static PyObject *
Victor Stinner914cde82016-03-19 01:03:51 +0100941do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
942 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000943{
944 PyObject *filename, *module, *registry, *res;
945 int lineno;
946
947 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
948 return NULL;
949
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100950 res = warn_explicit(category, message, filename, lineno, module, registry,
Victor Stinner914cde82016-03-19 01:03:51 +0100951 NULL, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000952 Py_DECREF(filename);
953 Py_DECREF(registry);
954 Py_DECREF(module);
955 return res;
956}
957
Victor Stinner22f18752016-12-09 18:08:18 +0100958/*[clinic input]
959warn as warnings_warn
960
961 message: object
962 category: object = None
963 stacklevel: Py_ssize_t = 1
964 source: object = None
965
966Issue a warning, or maybe ignore it or raise an exception.
967[clinic start generated code]*/
968
Christian Heimes33fe8092008-04-13 13:53:33 +0000969static PyObject *
Victor Stinner22f18752016-12-09 18:08:18 +0100970warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
971 Py_ssize_t stacklevel, PyObject *source)
972/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
Christian Heimes33fe8092008-04-13 13:53:33 +0000973{
Christian Heimes33fe8092008-04-13 13:53:33 +0000974 category = get_category(message, category);
975 if (category == NULL)
976 return NULL;
Victor Stinner22f18752016-12-09 18:08:18 +0100977 return do_warn(message, category, stacklevel, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000978}
979
980static PyObject *
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200981get_source_line(PyObject *module_globals, int lineno)
982{
983 _Py_IDENTIFIER(get_source);
984 _Py_IDENTIFIER(__loader__);
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200985 PyObject *loader;
986 PyObject *module_name;
987 PyObject *get_source;
988 PyObject *source;
989 PyObject *source_list;
990 PyObject *source_line;
991
992 /* Check/get the requisite pieces needed for the loader. */
993 loader = _PyDict_GetItemIdWithError(module_globals, &PyId___loader__);
994 if (loader == NULL) {
995 return NULL;
996 }
997 Py_INCREF(loader);
998 module_name = _PyDict_GetItemIdWithError(module_globals, &PyId___name__);
999 if (!module_name) {
1000 Py_DECREF(loader);
1001 return NULL;
1002 }
1003 Py_INCREF(module_name);
1004
1005 /* Make sure the loader implements the optional get_source() method. */
Serhiy Storchakaf320be72018-01-25 10:49:40 +02001006 (void)_PyObject_LookupAttrId(loader, &PyId_get_source, &get_source);
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001007 Py_DECREF(loader);
1008 if (!get_source) {
1009 Py_DECREF(module_name);
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001010 return NULL;
1011 }
1012 /* Call get_source() to get the source code. */
Petr Viktorinffd97532020-02-11 17:46:57 +01001013 source = PyObject_CallOneArg(get_source, module_name);
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001014 Py_DECREF(get_source);
1015 Py_DECREF(module_name);
1016 if (!source) {
1017 return NULL;
1018 }
1019 if (source == Py_None) {
1020 Py_DECREF(source);
1021 return NULL;
1022 }
1023
1024 /* Split the source into lines. */
1025 source_list = PyUnicode_Splitlines(source, 0);
1026 Py_DECREF(source);
1027 if (!source_list) {
1028 return NULL;
1029 }
1030
1031 /* Get the source line. */
1032 source_line = PyList_GetItem(source_list, lineno-1);
1033 Py_XINCREF(source_line);
1034 Py_DECREF(source_list);
1035 return source_line;
1036}
1037
1038static PyObject *
Christian Heimes33fe8092008-04-13 13:53:33 +00001039warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
1040{
1041 static char *kwd_list[] = {"message", "category", "filename", "lineno",
Victor Stinner914cde82016-03-19 01:03:51 +01001042 "module", "registry", "module_globals",
1043 "source", 0};
Christian Heimes33fe8092008-04-13 13:53:33 +00001044 PyObject *message;
1045 PyObject *category;
1046 PyObject *filename;
1047 int lineno;
1048 PyObject *module = NULL;
1049 PyObject *registry = NULL;
1050 PyObject *module_globals = NULL;
Victor Stinner914cde82016-03-19 01:03:51 +01001051 PyObject *sourceobj = NULL;
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001052 PyObject *source_line = NULL;
1053 PyObject *returned;
Christian Heimes33fe8092008-04-13 13:53:33 +00001054
Victor Stinner914cde82016-03-19 01:03:51 +01001055 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
Christian Heimes33fe8092008-04-13 13:53:33 +00001056 kwd_list, &message, &category, &filename, &lineno, &module,
Victor Stinner914cde82016-03-19 01:03:51 +01001057 &registry, &module_globals, &sourceobj))
Christian Heimes33fe8092008-04-13 13:53:33 +00001058 return NULL;
1059
Victor Stinnerb0565622018-05-15 20:42:12 +02001060 if (module_globals && module_globals != Py_None) {
1061 if (!PyDict_Check(module_globals)) {
1062 PyErr_Format(PyExc_TypeError,
1063 "module_globals must be a dict, not '%.200s'",
1064 Py_TYPE(module_globals)->tp_name);
1065 return NULL;
1066 }
1067
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001068 source_line = get_source_line(module_globals, lineno);
1069 if (source_line == NULL && PyErr_Occurred()) {
Christian Heimes33fe8092008-04-13 13:53:33 +00001070 return NULL;
1071 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001072 }
Serhiy Storchakad4f84802017-11-11 15:19:47 +02001073 returned = warn_explicit(category, message, filename, lineno, module,
1074 registry, source_line, sourceobj);
1075 Py_XDECREF(source_line);
1076 return returned;
Christian Heimes33fe8092008-04-13 13:53:33 +00001077}
1078
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001079static PyObject *
1080warnings_filters_mutated(PyObject *self, PyObject *args)
1081{
Victor Stinner66b79732020-03-02 15:02:18 +01001082 WarningsState *st = warnings_get_state();
Eric Snow86ea5812019-05-10 13:29:55 -04001083 if (st == NULL) {
1084 return NULL;
1085 }
1086 st->filters_version++;
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001087 Py_RETURN_NONE;
1088}
1089
Christian Heimes33fe8092008-04-13 13:53:33 +00001090
1091/* Function to issue a warning message; may raise an exception. */
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001092
1093static int
1094warn_unicode(PyObject *category, PyObject *message,
Victor Stinner914cde82016-03-19 01:03:51 +01001095 Py_ssize_t stack_level, PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +00001096{
1097 PyObject *res;
Christian Heimes33fe8092008-04-13 13:53:33 +00001098
1099 if (category == NULL)
1100 category = PyExc_RuntimeWarning;
1101
Victor Stinner914cde82016-03-19 01:03:51 +01001102 res = do_warn(message, category, stack_level, source);
Christian Heimes33fe8092008-04-13 13:53:33 +00001103 if (res == NULL)
1104 return -1;
1105 Py_DECREF(res);
1106
1107 return 0;
1108}
1109
Victor Stinner914cde82016-03-19 01:03:51 +01001110static int
1111_PyErr_WarnFormatV(PyObject *source,
1112 PyObject *category, Py_ssize_t stack_level,
1113 const char *format, va_list vargs)
1114{
1115 PyObject *message;
1116 int res;
1117
1118 message = PyUnicode_FromFormatV(format, vargs);
1119 if (message == NULL)
1120 return -1;
1121
1122 res = warn_unicode(category, message, stack_level, source);
1123 Py_DECREF(message);
1124 return res;
1125}
1126
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001127int
1128PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
1129 const char *format, ...)
1130{
Victor Stinner914cde82016-03-19 01:03:51 +01001131 int res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001132 va_list vargs;
1133
1134#ifdef HAVE_STDARG_PROTOTYPES
1135 va_start(vargs, format);
1136#else
1137 va_start(vargs);
1138#endif
Victor Stinner914cde82016-03-19 01:03:51 +01001139 res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001140 va_end(vargs);
Victor Stinner914cde82016-03-19 01:03:51 +01001141 return res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001142}
1143
Victor Stinner8d84adc2020-03-31 17:25:12 +02001144static int
1145_PyErr_WarnFormat(PyObject *source, PyObject *category, Py_ssize_t stack_level,
1146 const char *format, ...)
1147{
1148 int res;
1149 va_list vargs;
1150
1151#ifdef HAVE_STDARG_PROTOTYPES
1152 va_start(vargs, format);
1153#else
1154 va_start(vargs);
1155#endif
1156 res = _PyErr_WarnFormatV(source, category, stack_level, format, vargs);
1157 va_end(vargs);
1158 return res;
1159}
1160
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001161int
Victor Stinner914cde82016-03-19 01:03:51 +01001162PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
1163 const char *format, ...)
1164{
1165 int res;
1166 va_list vargs;
1167
1168#ifdef HAVE_STDARG_PROTOTYPES
1169 va_start(vargs, format);
1170#else
1171 va_start(vargs);
1172#endif
1173 res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
1174 stack_level, format, vargs);
1175 va_end(vargs);
1176 return res;
1177}
1178
1179
1180int
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001181PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
1182{
1183 int ret;
1184 PyObject *message = PyUnicode_FromString(text);
1185 if (message == NULL)
1186 return -1;
Victor Stinner914cde82016-03-19 01:03:51 +01001187 ret = warn_unicode(category, message, stack_level, NULL);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001188 Py_DECREF(message);
1189 return ret;
1190}
1191
Ezio Melotti42da6632011-03-15 05:18:48 +02001192/* PyErr_Warn is only for backwards compatibility and will be removed.
Christian Heimes33fe8092008-04-13 13:53:33 +00001193 Use PyErr_WarnEx instead. */
1194
1195#undef PyErr_Warn
1196
Benjamin Petersone5024512018-09-12 12:06:42 -07001197int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001198PyErr_Warn(PyObject *category, const char *text)
Christian Heimes33fe8092008-04-13 13:53:33 +00001199{
1200 return PyErr_WarnEx(category, text, 1);
1201}
1202
1203/* Warning with explicit origin */
1204int
Victor Stinner14e461d2013-08-26 22:28:21 +02001205PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1206 PyObject *filename, int lineno,
1207 PyObject *module, PyObject *registry)
1208{
1209 PyObject *res;
1210 if (category == NULL)
1211 category = PyExc_RuntimeWarning;
1212 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001213 module, registry, NULL, NULL);
Victor Stinner14e461d2013-08-26 22:28:21 +02001214 if (res == NULL)
1215 return -1;
1216 Py_DECREF(res);
1217 return 0;
1218}
1219
1220int
Christian Heimes33fe8092008-04-13 13:53:33 +00001221PyErr_WarnExplicit(PyObject *category, const char *text,
1222 const char *filename_str, int lineno,
1223 const char *module_str, PyObject *registry)
1224{
Christian Heimes33fe8092008-04-13 13:53:33 +00001225 PyObject *message = PyUnicode_FromString(text);
Victor Stinnercb428f02010-12-27 20:10:36 +00001226 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
Christian Heimes33fe8092008-04-13 13:53:33 +00001227 PyObject *module = NULL;
1228 int ret = -1;
1229
1230 if (message == NULL || filename == NULL)
1231 goto exit;
1232 if (module_str != NULL) {
1233 module = PyUnicode_FromString(module_str);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001234 if (module == NULL)
1235 goto exit;
Christian Heimes33fe8092008-04-13 13:53:33 +00001236 }
1237
Victor Stinner14e461d2013-08-26 22:28:21 +02001238 ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1239 module, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +00001240
1241 exit:
1242 Py_XDECREF(message);
1243 Py_XDECREF(module);
1244 Py_XDECREF(filename);
1245 return ret;
1246}
1247
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001248int
1249PyErr_WarnExplicitFormat(PyObject *category,
1250 const char *filename_str, int lineno,
1251 const char *module_str, PyObject *registry,
1252 const char *format, ...)
1253{
1254 PyObject *message;
1255 PyObject *module = NULL;
1256 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1257 int ret = -1;
1258 va_list vargs;
1259
1260 if (filename == NULL)
1261 goto exit;
1262 if (module_str != NULL) {
1263 module = PyUnicode_FromString(module_str);
1264 if (module == NULL)
1265 goto exit;
1266 }
1267
1268#ifdef HAVE_STDARG_PROTOTYPES
1269 va_start(vargs, format);
1270#else
1271 va_start(vargs);
1272#endif
1273 message = PyUnicode_FromFormatV(format, vargs);
1274 if (message != NULL) {
1275 PyObject *res;
1276 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001277 module, registry, NULL, NULL);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001278 Py_DECREF(message);
1279 if (res != NULL) {
1280 Py_DECREF(res);
1281 ret = 0;
1282 }
1283 }
1284 va_end(vargs);
1285exit:
1286 Py_XDECREF(module);
1287 Py_XDECREF(filename);
1288 return ret;
1289}
1290
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001291void
1292_PyErr_WarnUnawaitedCoroutine(PyObject *coro)
1293{
1294 /* First, we attempt to funnel the warning through
1295 warnings._warn_unawaited_coroutine.
1296
1297 This could raise an exception, due to:
1298 - a bug
1299 - some kind of shutdown-related brokenness
1300 - succeeding, but with an "error" warning filter installed, so the
1301 warning is converted into a RuntimeWarning exception
1302
1303 In the first two cases, we want to print the error (so we know what it
1304 is!), and then print a warning directly as a fallback. In the last
1305 case, we want to print the error (since it's the warning!), but *not*
1306 do a fallback. And after we print the error we can't check for what
1307 type of error it was (because PyErr_WriteUnraisable clears it), so we
1308 need a flag to keep track.
1309
1310 Since this is called from __del__ context, it's careful to never raise
1311 an exception.
1312 */
1313 _Py_IDENTIFIER(_warn_unawaited_coroutine);
1314 int warned = 0;
1315 PyObject *fn = get_warnings_attr(&PyId__warn_unawaited_coroutine, 1);
1316 if (fn) {
Petr Viktorinffd97532020-02-11 17:46:57 +01001317 PyObject *res = PyObject_CallOneArg(fn, coro);
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001318 Py_DECREF(fn);
1319 if (res || PyErr_ExceptionMatches(PyExc_RuntimeWarning)) {
1320 warned = 1;
1321 }
1322 Py_XDECREF(res);
1323 }
1324
1325 if (PyErr_Occurred()) {
1326 PyErr_WriteUnraisable(coro);
1327 }
1328 if (!warned) {
Victor Stinner8d84adc2020-03-31 17:25:12 +02001329 if (_PyErr_WarnFormat(coro, PyExc_RuntimeWarning, 1,
1330 "coroutine '%S' was never awaited",
1331 ((PyCoroObject *)coro)->cr_qualname) < 0)
Yury Selivanov35103342018-01-21 20:47:04 -05001332 {
Nathaniel J. Smithfc2f4072018-01-21 06:44:07 -08001333 PyErr_WriteUnraisable(coro);
1334 }
1335 }
1336}
Christian Heimes33fe8092008-04-13 13:53:33 +00001337
Christian Heimes33fe8092008-04-13 13:53:33 +00001338PyDoc_STRVAR(warn_explicit_doc,
Hansraj Das5dfbb4d2019-10-08 14:26:07 +05301339"Low-level interface to warnings functionality.");
Christian Heimes33fe8092008-04-13 13:53:33 +00001340
1341static PyMethodDef warnings_functions[] = {
Victor Stinner22f18752016-12-09 18:08:18 +01001342 WARNINGS_WARN_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001343 {"warn_explicit", (PyCFunction)(void(*)(void))warnings_warn_explicit,
Christian Heimes33fe8092008-04-13 13:53:33 +00001344 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001345 {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
1346 NULL},
Christian Heimes1a8501c2008-10-02 19:56:01 +00001347 /* XXX(brett.cannon): add showwarning? */
1348 /* XXX(brett.cannon): Reasonable to add formatwarning? */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 {NULL, NULL} /* sentinel */
Christian Heimes33fe8092008-04-13 13:53:33 +00001350};
1351
1352
Victor Stinner6f4635f2020-11-19 00:19:06 +01001353static int
1354warnings_module_exec(PyObject *module)
1355{
1356 WarningsState *st = warnings_get_state();
1357 if (st == NULL) {
1358 return -1;
1359 }
1360 if (PyModule_AddObjectRef(module, "filters", st->filters) < 0) {
1361 return -1;
1362 }
1363 if (PyModule_AddObjectRef(module, "_onceregistry", st->once_registry) < 0) {
1364 return -1;
1365 }
1366 if (PyModule_AddObjectRef(module, "_defaultaction", st->default_action) < 0) {
1367 return -1;
1368 }
1369 return 0;
1370}
1371
1372
1373static PyModuleDef_Slot warnings_slots[] = {
1374 {Py_mod_exec, warnings_module_exec},
1375 {0, NULL}
1376};
1377
1378static struct PyModuleDef warnings_module = {
1379 PyModuleDef_HEAD_INIT,
1380 .m_name = MODULE_NAME,
1381 .m_doc = warnings__doc__,
1382 .m_size = 0,
1383 .m_methods = warnings_functions,
1384 .m_slots = warnings_slots,
Martin v. Löwis1a214512008-06-11 05:26:20 +00001385};
1386
Christian Heimes33fe8092008-04-13 13:53:33 +00001387
Victor Stinner5d862462017-12-19 11:35:58 +01001388PyMODINIT_FUNC
1389_PyWarnings_Init(void)
Christian Heimes33fe8092008-04-13 13:53:33 +00001390{
Victor Stinner6f4635f2020-11-19 00:19:06 +01001391 return PyModuleDef_Init(&warnings_module);
Christian Heimes33fe8092008-04-13 13:53:33 +00001392}
Victor Stinner87d23a02019-04-26 05:49:26 +02001393
Eric Snow86ea5812019-05-10 13:29:55 -04001394// We need this to ensure that warnings still work until late in finalization.
Victor Stinner87d23a02019-04-26 05:49:26 +02001395void
Eric Snow86ea5812019-05-10 13:29:55 -04001396_PyWarnings_Fini(PyInterpreterState *interp)
Victor Stinner87d23a02019-04-26 05:49:26 +02001397{
Victor Stinner66b79732020-03-02 15:02:18 +01001398 warnings_clear_state(&interp->warnings);
Victor Stinner87d23a02019-04-26 05:49:26 +02001399}