blob: 36d649fda10c54b35e677c8a5ed71138a3d37c47 [file] [log] [blame]
Christian Heimes33fe8092008-04-13 13:53:33 +00001#include "Python.h"
Eric Snow2ebc5ce2017-09-07 23:51:28 -06002#include "internal/pystate.h"
Christian Heimes33fe8092008-04-13 13:53:33 +00003#include "frameobject.h"
Victor Stinner22f18752016-12-09 18:08:18 +01004#include "clinic/_warnings.c.h"
Christian Heimes33fe8092008-04-13 13:53:33 +00005
6#define MODULE_NAME "_warnings"
Christian Heimes33fe8092008-04-13 13:53:33 +00007
8PyDoc_STRVAR(warnings__doc__,
9MODULE_NAME " provides basic warning filtering support.\n"
10"It is a helper module to speed up interpreter start-up.");
11
Victor Stinnerbd303c12013-11-07 23:07:29 +010012_Py_IDENTIFIER(argv);
13_Py_IDENTIFIER(stderr);
Christian Heimes33fe8092008-04-13 13:53:33 +000014
15static int
16check_matched(PyObject *obj, PyObject *arg)
17{
18 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020019 _Py_IDENTIFIER(match);
Christian Heimes33fe8092008-04-13 13:53:33 +000020 int rc;
21
22 if (obj == Py_None)
23 return 1;
Victor Stinner55ba38a2016-12-09 16:09:30 +010024 result = _PyObject_CallMethodIdObjArgs(obj, &PyId_match, arg, NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +000025 if (result == NULL)
26 return -1;
27
28 rc = PyObject_IsTrue(result);
29 Py_DECREF(result);
30 return rc;
31}
32
33/*
34 Returns a new reference.
35 A NULL return value can mean false or an error.
36*/
37static PyObject *
Victor Stinner82656272017-11-22 23:51:42 +010038get_warnings_attr(_Py_Identifier *attr_id, int try_import)
Christian Heimes33fe8092008-04-13 13:53:33 +000039{
Victor Stinner82656272017-11-22 23:51:42 +010040 PyObject *warnings_str;
Victor Stinnere98445a2016-03-23 00:54:48 +010041 PyObject *warnings_module, *obj;
Victor Stinner82656272017-11-22 23:51:42 +010042 _Py_IDENTIFIER(warnings);
Christian Heimes33fe8092008-04-13 13:53:33 +000043
Victor Stinner82656272017-11-22 23:51:42 +010044 warnings_str = _PyUnicode_FromId(&PyId_warnings);
Christian Heimes33fe8092008-04-13 13:53:33 +000045 if (warnings_str == NULL) {
Victor Stinner82656272017-11-22 23:51:42 +010046 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +000047 }
48
Victor Stinnere98445a2016-03-23 00:54:48 +010049 /* don't try to import after the start of the Python finallization */
Eric Snow2ebc5ce2017-09-07 23:51:28 -060050 if (try_import && !_Py_IsFinalizing()) {
Victor Stinnere98445a2016-03-23 00:54:48 +010051 warnings_module = PyImport_Import(warnings_str);
52 if (warnings_module == NULL) {
53 /* Fallback to the C implementation if we cannot get
54 the Python implementation */
Serhiy Storchakad4f84802017-11-11 15:19:47 +020055 if (PyErr_ExceptionMatches(PyExc_ImportError)) {
56 PyErr_Clear();
57 }
Christian Heimes33fe8092008-04-13 13:53:33 +000058 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +010059 }
60 }
61 else {
Eric Snow3f9eee62017-09-15 16:35:20 -060062 warnings_module = PyImport_GetModule(warnings_str);
Victor Stinner023654f2016-03-23 17:48:22 +010063 if (warnings_module == NULL)
64 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +010065 }
66
Victor Stinner82656272017-11-22 23:51:42 +010067 obj = _PyObject_GetAttrId(warnings_module, attr_id);
Victor Stinnere98445a2016-03-23 00:54:48 +010068 Py_DECREF(warnings_module);
Serhiy Storchakad4f84802017-11-11 15:19:47 +020069 if (obj == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
70 PyErr_Clear();
71 }
Victor Stinnere98445a2016-03-23 00:54:48 +010072 return obj;
Christian Heimes33fe8092008-04-13 13:53:33 +000073}
74
75
Neal Norwitz32dde222008-04-15 06:43:13 +000076static PyObject *
Christian Heimes33fe8092008-04-13 13:53:33 +000077get_once_registry(void)
78{
79 PyObject *registry;
Victor Stinner82656272017-11-22 23:51:42 +010080 _Py_IDENTIFIER(onceregistry);
Christian Heimes33fe8092008-04-13 13:53:33 +000081
Victor Stinner82656272017-11-22 23:51:42 +010082 registry = get_warnings_attr(&PyId_onceregistry, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +000083 if (registry == NULL) {
84 if (PyErr_Occurred())
85 return NULL;
Serhiy Storchakad4f84802017-11-11 15:19:47 +020086 assert(_PyRuntime.warnings.once_registry);
Eric Snow2ebc5ce2017-09-07 23:51:28 -060087 return _PyRuntime.warnings.once_registry;
Christian Heimes33fe8092008-04-13 13:53:33 +000088 }
Oren Milman252033d2017-09-11 09:28:39 +030089 if (!PyDict_Check(registry)) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +020090 PyErr_Format(PyExc_TypeError,
91 MODULE_NAME ".onceregistry must be a dict, "
92 "not '%.200s'",
93 Py_TYPE(registry)->tp_name);
Oren Milman252033d2017-09-11 09:28:39 +030094 Py_DECREF(registry);
95 return NULL;
96 }
Serhiy Storchakad4f84802017-11-11 15:19:47 +020097 Py_SETREF(_PyRuntime.warnings.once_registry, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +000098 return registry;
99}
100
101
Brett Cannon0759dd62009-04-01 18:13:07 +0000102static PyObject *
103get_default_action(void)
104{
105 PyObject *default_action;
Victor Stinner82656272017-11-22 23:51:42 +0100106 _Py_IDENTIFIER(defaultaction);
Brett Cannon0759dd62009-04-01 18:13:07 +0000107
Victor Stinner82656272017-11-22 23:51:42 +0100108 default_action = get_warnings_attr(&PyId_defaultaction, 0);
Brett Cannon0759dd62009-04-01 18:13:07 +0000109 if (default_action == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110 if (PyErr_Occurred()) {
111 return NULL;
112 }
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200113 assert(_PyRuntime.warnings.default_action);
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600114 return _PyRuntime.warnings.default_action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000115 }
Oren Milman9d984fd2017-09-12 00:18:09 +0300116 if (!PyUnicode_Check(default_action)) {
117 PyErr_Format(PyExc_TypeError,
118 MODULE_NAME ".defaultaction must be a string, "
119 "not '%.200s'",
120 Py_TYPE(default_action)->tp_name);
121 Py_DECREF(default_action);
122 return NULL;
123 }
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200124 Py_SETREF(_PyRuntime.warnings.default_action, default_action);
Brett Cannon0759dd62009-04-01 18:13:07 +0000125 return default_action;
126}
127
128
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400129/* The item is a new reference. */
Victor Stinnera4c704b2013-10-29 23:43:41 +0100130static PyObject*
Christian Heimes33fe8092008-04-13 13:53:33 +0000131get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
132 PyObject *module, PyObject **item)
133{
Brett Cannon0759dd62009-04-01 18:13:07 +0000134 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000135 Py_ssize_t i;
136 PyObject *warnings_filters;
Victor Stinner82656272017-11-22 23:51:42 +0100137 _Py_IDENTIFIER(filters);
Christian Heimes33fe8092008-04-13 13:53:33 +0000138
Victor Stinner82656272017-11-22 23:51:42 +0100139 warnings_filters = get_warnings_attr(&PyId_filters, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000140 if (warnings_filters == NULL) {
141 if (PyErr_Occurred())
142 return NULL;
143 }
144 else {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200145 Py_SETREF(_PyRuntime.warnings.filters, warnings_filters);
Christian Heimes33fe8092008-04-13 13:53:33 +0000146 }
147
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600148 PyObject *filters = _PyRuntime.warnings.filters;
149 if (filters == NULL || !PyList_Check(filters)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000150 PyErr_SetString(PyExc_ValueError,
151 MODULE_NAME ".filters must be a list");
152 return NULL;
153 }
154
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600155 /* _PyRuntime.warnings.filters could change while we are iterating over it. */
156 for (i = 0; i < PyList_GET_SIZE(filters); i++) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000157 PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
158 Py_ssize_t ln;
159 int is_subclass, good_msg, good_mod;
160
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600161 tmp_item = PyList_GET_ITEM(filters, i);
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400162 if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000163 PyErr_Format(PyExc_ValueError,
164 MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
165 return NULL;
166 }
167
168 /* Python code: action, msg, cat, mod, ln = item */
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400169 Py_INCREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000170 action = PyTuple_GET_ITEM(tmp_item, 0);
171 msg = PyTuple_GET_ITEM(tmp_item, 1);
172 cat = PyTuple_GET_ITEM(tmp_item, 2);
173 mod = PyTuple_GET_ITEM(tmp_item, 3);
174 ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
175
Oren Milman9d984fd2017-09-12 00:18:09 +0300176 if (!PyUnicode_Check(action)) {
177 PyErr_Format(PyExc_TypeError,
178 "action must be a string, not '%.200s'",
179 Py_TYPE(action)->tp_name);
180 Py_DECREF(tmp_item);
181 return NULL;
182 }
183
Christian Heimes33fe8092008-04-13 13:53:33 +0000184 good_msg = check_matched(msg, text);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400185 if (good_msg == -1) {
186 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100187 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400188 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100189
Christian Heimes33fe8092008-04-13 13:53:33 +0000190 good_mod = check_matched(mod, module);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400191 if (good_mod == -1) {
192 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100193 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400194 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100195
Christian Heimes33fe8092008-04-13 13:53:33 +0000196 is_subclass = PyObject_IsSubclass(category, cat);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400197 if (is_subclass == -1) {
198 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100199 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400200 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100201
Christian Heimes33fe8092008-04-13 13:53:33 +0000202 ln = PyLong_AsSsize_t(ln_obj);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400203 if (ln == -1 && PyErr_Occurred()) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400204 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000205 return NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400206 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000207
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400208 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
209 *item = tmp_item;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100210 return action;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400211 }
212
213 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000214 }
215
Brett Cannon0759dd62009-04-01 18:13:07 +0000216 action = get_default_action();
217 if (action != NULL) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400218 Py_INCREF(Py_None);
219 *item = Py_None;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100220 return action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000221 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000222
Christian Heimes33fe8092008-04-13 13:53:33 +0000223 return NULL;
224}
225
Brett Cannon0759dd62009-04-01 18:13:07 +0000226
Christian Heimes33fe8092008-04-13 13:53:33 +0000227static int
228already_warned(PyObject *registry, PyObject *key, int should_set)
229{
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200230 PyObject *version_obj, *already_warned;
231 _Py_IDENTIFIER(version);
Christian Heimes33fe8092008-04-13 13:53:33 +0000232
233 if (key == NULL)
234 return -1;
235
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200236 version_obj = _PyDict_GetItemId(registry, &PyId_version);
237 if (version_obj == NULL
238 || !PyLong_CheckExact(version_obj)
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600239 || PyLong_AsLong(version_obj) != _PyRuntime.warnings.filters_version) {
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200240 PyDict_Clear(registry);
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600241 version_obj = PyLong_FromLong(_PyRuntime.warnings.filters_version);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200242 if (version_obj == NULL)
243 return -1;
244 if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
245 Py_DECREF(version_obj);
246 return -1;
247 }
248 Py_DECREF(version_obj);
249 }
250 else {
251 already_warned = PyDict_GetItem(registry, key);
252 if (already_warned != NULL) {
253 int rc = PyObject_IsTrue(already_warned);
254 if (rc != 0)
255 return rc;
256 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000257 }
258
259 /* This warning wasn't found in the registry, set it. */
260 if (should_set)
261 return PyDict_SetItem(registry, key, Py_True);
262 return 0;
263}
264
265/* New reference. */
266static PyObject *
267normalize_module(PyObject *filename)
268{
269 PyObject *module;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100270 int kind;
271 void *data;
Christian Heimes33fe8092008-04-13 13:53:33 +0000272 Py_ssize_t len;
273
Victor Stinner9e30aa52011-11-21 02:49:52 +0100274 len = PyUnicode_GetLength(filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000275 if (len < 0)
276 return NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100277
278 if (len == 0)
279 return PyUnicode_FromString("<unknown>");
280
281 kind = PyUnicode_KIND(filename);
282 data = PyUnicode_DATA(filename);
283
284 /* if filename.endswith(".py"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000285 if (len >= 3 &&
Victor Stinnera4c704b2013-10-29 23:43:41 +0100286 PyUnicode_READ(kind, data, len-3) == '.' &&
287 PyUnicode_READ(kind, data, len-2) == 'p' &&
288 PyUnicode_READ(kind, data, len-1) == 'y')
289 {
Victor Stinner9e30aa52011-11-21 02:49:52 +0100290 module = PyUnicode_Substring(filename, 0, len-3);
Christian Heimes33fe8092008-04-13 13:53:33 +0000291 }
292 else {
293 module = filename;
294 Py_INCREF(module);
295 }
296 return module;
297}
298
299static int
300update_registry(PyObject *registry, PyObject *text, PyObject *category,
301 int add_zero)
302{
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300303 PyObject *altkey;
Christian Heimes33fe8092008-04-13 13:53:33 +0000304 int rc;
305
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300306 if (add_zero)
307 altkey = PyTuple_Pack(3, text, category, _PyLong_Zero);
Christian Heimes33fe8092008-04-13 13:53:33 +0000308 else
309 altkey = PyTuple_Pack(2, text, category);
310
311 rc = already_warned(registry, altkey, 1);
Christian Heimes33fe8092008-04-13 13:53:33 +0000312 Py_XDECREF(altkey);
313 return rc;
314}
315
316static void
Victor Stinner914cde82016-03-19 01:03:51 +0100317show_warning(PyObject *filename, int lineno, PyObject *text,
318 PyObject *category, PyObject *sourceline)
Christian Heimes33fe8092008-04-13 13:53:33 +0000319{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 PyObject *f_stderr;
321 PyObject *name;
Christian Heimes33fe8092008-04-13 13:53:33 +0000322 char lineno_str[128];
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200323 _Py_IDENTIFIER(__name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000324
325 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
326
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200327 name = _PyObject_GetAttrId(category, &PyId___name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000328 if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100329 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000330
Victor Stinnerbd303c12013-11-07 23:07:29 +0100331 f_stderr = _PySys_GetObjectId(&PyId_stderr);
Christian Heimes33fe8092008-04-13 13:53:33 +0000332 if (f_stderr == NULL) {
333 fprintf(stderr, "lost sys.stderr\n");
Victor Stinnerae233ea2013-10-31 14:51:38 +0100334 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000335 }
336
337 /* Print "filename:lineno: category: text\n" */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100338 if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
339 goto error;
340 if (PyFile_WriteString(lineno_str, f_stderr) < 0)
341 goto error;
342 if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
343 goto error;
344 if (PyFile_WriteString(": ", f_stderr) < 0)
345 goto error;
346 if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
347 goto error;
348 if (PyFile_WriteString("\n", f_stderr) < 0)
349 goto error;
350 Py_CLEAR(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000351
352 /* Print " source_line\n" */
Christian Heimes33fe8092008-04-13 13:53:33 +0000353 if (sourceline) {
Victor Stinnera4c704b2013-10-29 23:43:41 +0100354 int kind;
355 void *data;
356 Py_ssize_t i, len;
357 Py_UCS4 ch;
358 PyObject *truncated;
Christian Heimes33fe8092008-04-13 13:53:33 +0000359
Victor Stinnera4c704b2013-10-29 23:43:41 +0100360 if (PyUnicode_READY(sourceline) < 1)
361 goto error;
362
363 kind = PyUnicode_KIND(sourceline);
364 data = PyUnicode_DATA(sourceline);
365 len = PyUnicode_GET_LENGTH(sourceline);
366 for (i=0; i<len; i++) {
367 ch = PyUnicode_READ(kind, data, i);
368 if (ch != ' ' && ch != '\t' && ch != '\014')
369 break;
370 }
371
372 truncated = PyUnicode_Substring(sourceline, i, len);
373 if (truncated == NULL)
374 goto error;
375
376 PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
377 Py_DECREF(truncated);
Christian Heimes33fe8092008-04-13 13:53:33 +0000378 PyFile_WriteString("\n", f_stderr);
379 }
Victor Stinner78e2c982013-07-16 01:54:37 +0200380 else {
381 _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
382 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100383
384error:
Victor Stinnerae233ea2013-10-31 14:51:38 +0100385 Py_XDECREF(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000386 PyErr_Clear();
387}
388
Victor Stinner1231a462016-03-19 00:47:17 +0100389static int
390call_show_warning(PyObject *category, PyObject *text, PyObject *message,
391 PyObject *filename, int lineno, PyObject *lineno_obj,
Victor Stinner914cde82016-03-19 01:03:51 +0100392 PyObject *sourceline, PyObject *source)
Victor Stinner1231a462016-03-19 00:47:17 +0100393{
394 PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
Victor Stinner82656272017-11-22 23:51:42 +0100395 _Py_IDENTIFIER(_showwarnmsg);
396 _Py_IDENTIFIER(WarningMessage);
Victor Stinner1231a462016-03-19 00:47:17 +0100397
Victor Stinnere98445a2016-03-23 00:54:48 +0100398 /* If the source parameter is set, try to get the Python implementation.
399 The Python implementation is able to log the traceback where the source
luzpaza5293b42017-11-05 07:37:50 -0600400 was allocated, whereas the C implementation doesn't. */
Victor Stinner82656272017-11-22 23:51:42 +0100401 show_fn = get_warnings_attr(&PyId__showwarnmsg, source != NULL);
Victor Stinner1231a462016-03-19 00:47:17 +0100402 if (show_fn == NULL) {
403 if (PyErr_Occurred())
404 return -1;
405 show_warning(filename, lineno, text, category, sourceline);
406 return 0;
407 }
408
409 if (!PyCallable_Check(show_fn)) {
410 PyErr_SetString(PyExc_TypeError,
411 "warnings._showwarnmsg() must be set to a callable");
412 goto error;
413 }
414
Victor Stinner82656272017-11-22 23:51:42 +0100415 warnmsg_cls = get_warnings_attr(&PyId_WarningMessage, 0);
Victor Stinner1231a462016-03-19 00:47:17 +0100416 if (warnmsg_cls == NULL) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200417 if (!PyErr_Occurred()) {
418 PyErr_SetString(PyExc_RuntimeError,
419 "unable to get warnings.WarningMessage");
420 }
Victor Stinner1231a462016-03-19 00:47:17 +0100421 goto error;
422 }
423
424 msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
Victor Stinner914cde82016-03-19 01:03:51 +0100425 filename, lineno_obj, Py_None, Py_None, source,
Victor Stinner1231a462016-03-19 00:47:17 +0100426 NULL);
427 Py_DECREF(warnmsg_cls);
428 if (msg == NULL)
429 goto error;
430
Victor Stinnerde4ae3d2016-12-04 22:59:09 +0100431 res = PyObject_CallFunctionObjArgs(show_fn, msg, NULL);
Victor Stinner1231a462016-03-19 00:47:17 +0100432 Py_DECREF(show_fn);
433 Py_DECREF(msg);
434
435 if (res == NULL)
436 return -1;
437
438 Py_DECREF(res);
439 return 0;
440
441error:
442 Py_XDECREF(show_fn);
443 return -1;
444}
445
Christian Heimes33fe8092008-04-13 13:53:33 +0000446static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447warn_explicit(PyObject *category, PyObject *message,
Christian Heimes33fe8092008-04-13 13:53:33 +0000448 PyObject *filename, int lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100449 PyObject *module, PyObject *registry, PyObject *sourceline,
450 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000451{
452 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400453 PyObject *item = NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100454 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000455 int rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100457 /* module can be None if a warning is emitted late during Python shutdown.
458 In this case, the Python warnings module was probably unloaded, filters
459 are no more available to choose as action. It is safer to ignore the
460 warning and do nothing. */
461 if (module == Py_None)
462 Py_RETURN_NONE;
463
Brett Cannondb734912008-06-27 00:52:15 +0000464 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
Oren Milman252033d2017-09-11 09:28:39 +0300465 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
Brett Cannondb734912008-06-27 00:52:15 +0000466 return NULL;
467 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000468
469 /* Normalize module. */
470 if (module == NULL) {
471 module = normalize_module(filename);
472 if (module == NULL)
473 return NULL;
474 }
475 else
476 Py_INCREF(module);
477
478 /* Normalize message. */
479 Py_INCREF(message); /* DECREF'ed in cleanup. */
480 rc = PyObject_IsInstance(message, PyExc_Warning);
481 if (rc == -1) {
482 goto cleanup;
483 }
484 if (rc == 1) {
485 text = PyObject_Str(message);
Hirokazu Yamamoto1c0c0032009-07-17 06:55:42 +0000486 if (text == NULL)
487 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000488 category = (PyObject*)message->ob_type;
489 }
490 else {
491 text = message;
Victor Stinner7bfb42d2016-12-05 17:04:32 +0100492 message = PyObject_CallFunctionObjArgs(category, message, NULL);
Brett Cannondb734912008-06-27 00:52:15 +0000493 if (message == NULL)
494 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000495 }
496
497 lineno_obj = PyLong_FromLong(lineno);
498 if (lineno_obj == NULL)
499 goto cleanup;
500
Victor Stinner22f18752016-12-09 18:08:18 +0100501 if (source == Py_None) {
502 source = NULL;
503 }
504
Christian Heimes33fe8092008-04-13 13:53:33 +0000505 /* Create key. */
506 key = PyTuple_Pack(3, text, category, lineno_obj);
507 if (key == NULL)
508 goto cleanup;
509
Brett Cannondb734912008-06-27 00:52:15 +0000510 if ((registry != NULL) && (registry != Py_None)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000511 rc = already_warned(registry, key, 0);
512 if (rc == -1)
513 goto cleanup;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 else if (rc == 1)
Christian Heimes33fe8092008-04-13 13:53:33 +0000515 goto return_none;
516 /* Else this warning hasn't been generated before. */
517 }
518
519 action = get_filter(category, text, lineno, module, &item);
520 if (action == NULL)
521 goto cleanup;
522
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200523 if (_PyUnicode_EqualToASCIIString(action, "error")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000524 PyErr_SetObject(category, message);
525 goto cleanup;
526 }
527
528 /* Store in the registry that we've been here, *except* when the action
529 is "always". */
530 rc = 0;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200531 if (!_PyUnicode_EqualToASCIIString(action, "always")) {
Brett Cannondb734912008-06-27 00:52:15 +0000532 if (registry != NULL && registry != Py_None &&
533 PyDict_SetItem(registry, key, Py_True) < 0)
Christian Heimes33fe8092008-04-13 13:53:33 +0000534 goto cleanup;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200535 else if (_PyUnicode_EqualToASCIIString(action, "ignore"))
Christian Heimes33fe8092008-04-13 13:53:33 +0000536 goto return_none;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200537 else if (_PyUnicode_EqualToASCIIString(action, "once")) {
Brett Cannondb734912008-06-27 00:52:15 +0000538 if (registry == NULL || registry == Py_None) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000539 registry = get_once_registry();
540 if (registry == NULL)
541 goto cleanup;
542 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600543 /* _PyRuntime.warnings.once_registry[(text, category)] = 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000545 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200546 else if (_PyUnicode_EqualToASCIIString(action, "module")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000547 /* registry[(text, category, 0)] = 1 */
Brett Cannondb734912008-06-27 00:52:15 +0000548 if (registry != NULL && registry != Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000550 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200551 else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000552 PyErr_Format(PyExc_RuntimeError,
Victor Stinnera4c704b2013-10-29 23:43:41 +0100553 "Unrecognized action (%R) in warnings.filters:\n %R",
554 action, item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000555 goto cleanup;
556 }
557 }
558
Christian Heimes1a8501c2008-10-02 19:56:01 +0000559 if (rc == 1) /* Already warned for this module. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000560 goto return_none;
561 if (rc == 0) {
Victor Stinner1231a462016-03-19 00:47:17 +0100562 if (call_show_warning(category, text, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100563 lineno_obj, sourceline, source) < 0)
Victor Stinner1231a462016-03-19 00:47:17 +0100564 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000565 }
566 else /* if (rc == -1) */
567 goto cleanup;
568
569 return_none:
570 result = Py_None;
571 Py_INCREF(result);
572
573 cleanup:
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400574 Py_XDECREF(item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000575 Py_XDECREF(key);
576 Py_XDECREF(text);
577 Py_XDECREF(lineno_obj);
578 Py_DECREF(module);
Brett Cannondb734912008-06-27 00:52:15 +0000579 Py_XDECREF(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000580 return result; /* Py_None or NULL. */
581}
582
Larry Hastings714e4932015-09-06 00:39:37 -0700583static int
584is_internal_frame(PyFrameObject *frame)
585{
586 static PyObject *importlib_string = NULL;
587 static PyObject *bootstrap_string = NULL;
588 PyObject *filename;
589 int contains;
590
591 if (importlib_string == NULL) {
592 importlib_string = PyUnicode_FromString("importlib");
593 if (importlib_string == NULL) {
594 return 0;
595 }
596
597 bootstrap_string = PyUnicode_FromString("_bootstrap");
598 if (bootstrap_string == NULL) {
599 Py_DECREF(importlib_string);
600 return 0;
601 }
602 Py_INCREF(importlib_string);
603 Py_INCREF(bootstrap_string);
604 }
605
606 if (frame == NULL || frame->f_code == NULL ||
607 frame->f_code->co_filename == NULL) {
608 return 0;
609 }
610 filename = frame->f_code->co_filename;
611 if (!PyUnicode_Check(filename)) {
612 return 0;
613 }
614 contains = PyUnicode_Contains(filename, importlib_string);
615 if (contains < 0) {
616 return 0;
617 }
618 else if (contains > 0) {
619 contains = PyUnicode_Contains(filename, bootstrap_string);
620 if (contains < 0) {
621 return 0;
622 }
623 else if (contains > 0) {
624 return 1;
625 }
626 }
627
628 return 0;
629}
630
631static PyFrameObject *
632next_external_frame(PyFrameObject *frame)
633{
634 do {
635 frame = frame->f_back;
636 } while (frame != NULL && is_internal_frame(frame));
637
638 return frame;
639}
640
Christian Heimes33fe8092008-04-13 13:53:33 +0000641/* filename, module, and registry are new refs, globals is borrowed */
642/* Returns 0 on error (no new refs), 1 on success */
643static int
644setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
645 PyObject **module, PyObject **registry)
646{
647 PyObject *globals;
648
649 /* Setup globals and lineno. */
650 PyFrameObject *f = PyThreadState_GET()->frame;
Larry Hastings714e4932015-09-06 00:39:37 -0700651 // Stack level comparisons to Python code is off by one as there is no
652 // warnings-related stack level to avoid.
653 if (stack_level <= 0 || is_internal_frame(f)) {
654 while (--stack_level > 0 && f != NULL) {
655 f = f->f_back;
656 }
657 }
658 else {
659 while (--stack_level > 0 && f != NULL) {
660 f = next_external_frame(f);
661 }
662 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000663
664 if (f == NULL) {
665 globals = PyThreadState_Get()->interp->sysdict;
666 *lineno = 1;
667 }
668 else {
669 globals = f->f_globals;
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000670 *lineno = PyFrame_GetLineNumber(f);
Christian Heimes33fe8092008-04-13 13:53:33 +0000671 }
672
673 *module = NULL;
674
675 /* Setup registry. */
676 assert(globals != NULL);
677 assert(PyDict_Check(globals));
678 *registry = PyDict_GetItemString(globals, "__warningregistry__");
679 if (*registry == NULL) {
680 int rc;
681
682 *registry = PyDict_New();
683 if (*registry == NULL)
684 return 0;
685
686 rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
687 if (rc < 0)
688 goto handle_error;
689 }
690 else
691 Py_INCREF(*registry);
692
693 /* Setup module. */
694 *module = PyDict_GetItemString(globals, "__name__");
Oren Milman5d3e8002017-09-24 21:28:42 +0300695 if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) {
696 Py_INCREF(*module);
697 }
698 else {
Christian Heimes33fe8092008-04-13 13:53:33 +0000699 *module = PyUnicode_FromString("<string>");
700 if (*module == NULL)
701 goto handle_error;
702 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000703
704 /* Setup filename. */
705 *filename = PyDict_GetItemString(globals, "__file__");
Victor Stinner8b0508e2011-07-04 02:43:09 +0200706 if (*filename != NULL && PyUnicode_Check(*filename)) {
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200707 Py_ssize_t len;
708 int kind;
709 void *data;
710
711 if (PyUnicode_READY(*filename))
712 goto handle_error;
713
Victor Stinner9e30aa52011-11-21 02:49:52 +0100714 len = PyUnicode_GetLength(*filename);
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200715 kind = PyUnicode_KIND(*filename);
716 data = PyUnicode_DATA(*filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000717
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500718#define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0)
Brett Cannonf299abd2015-04-13 14:21:02 -0400719 /* if filename.lower().endswith(".pyc"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000720 if (len >= 4 &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200721 PyUnicode_READ(kind, data, len-4) == '.' &&
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500722 ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' &&
723 ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' &&
Brett Cannonf299abd2015-04-13 14:21:02 -0400724 ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c')
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000725 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200726 *filename = PyUnicode_Substring(*filename, 0,
727 PyUnicode_GET_LENGTH(*filename)-1);
Victor Stinner2e5f1172010-08-08 22:12:45 +0000728 if (*filename == NULL)
729 goto handle_error;
730 }
731 else
Christian Heimes33fe8092008-04-13 13:53:33 +0000732 Py_INCREF(*filename);
733 }
734 else {
Benjamin Petersonbb4a7472011-07-04 22:27:16 -0500735 *filename = NULL;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200736 if (*module != Py_None && _PyUnicode_EqualToASCIIString(*module, "__main__")) {
Victor Stinnerbd303c12013-11-07 23:07:29 +0100737 PyObject *argv = _PySys_GetObjectId(&PyId_argv);
Victor Stinnerce5f4fb2013-10-28 18:47:22 +0100738 /* PyList_Check() is needed because sys.argv is set to None during
739 Python finalization */
740 if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) {
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000741 int is_true;
Christian Heimes33fe8092008-04-13 13:53:33 +0000742 *filename = PyList_GetItem(argv, 0);
743 Py_INCREF(*filename);
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000744 /* If sys.argv[0] is false, then use '__main__'. */
745 is_true = PyObject_IsTrue(*filename);
746 if (is_true < 0) {
747 Py_DECREF(*filename);
748 goto handle_error;
749 }
750 else if (!is_true) {
Serhiy Storchaka57a01d32016-04-10 18:05:40 +0300751 Py_SETREF(*filename, PyUnicode_FromString("__main__"));
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000752 if (*filename == NULL)
753 goto handle_error;
754 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000755 }
756 else {
757 /* embedded interpreters don't have sys.argv, see bug #839151 */
758 *filename = PyUnicode_FromString("__main__");
Victor Stinner856f45f2013-10-30 00:04:59 +0100759 if (*filename == NULL)
760 goto handle_error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000761 }
762 }
763 if (*filename == NULL) {
764 *filename = *module;
765 Py_INCREF(*filename);
766 }
767 }
768
769 return 1;
770
771 handle_error:
772 /* filename not XDECREF'ed here as there is no way to jump here with a
773 dangling reference. */
774 Py_XDECREF(*registry);
775 Py_XDECREF(*module);
776 return 0;
777}
778
779static PyObject *
780get_category(PyObject *message, PyObject *category)
781{
782 int rc;
783
784 /* Get category. */
785 rc = PyObject_IsInstance(message, PyExc_Warning);
786 if (rc == -1)
787 return NULL;
788
789 if (rc == 1)
790 category = (PyObject*)message->ob_type;
Berker Peksagd8089e02014-07-11 19:50:25 +0300791 else if (category == NULL || category == Py_None)
Christian Heimes33fe8092008-04-13 13:53:33 +0000792 category = PyExc_UserWarning;
793
794 /* Validate category. */
795 rc = PyObject_IsSubclass(category, PyExc_Warning);
Berker Peksagd8089e02014-07-11 19:50:25 +0300796 /* category is not a subclass of PyExc_Warning or
797 PyObject_IsSubclass raised an error */
798 if (rc == -1 || rc == 0) {
799 PyErr_Format(PyExc_TypeError,
800 "category must be a Warning subclass, not '%s'",
801 Py_TYPE(category)->tp_name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000802 return NULL;
803 }
804
805 return category;
806}
807
808static PyObject *
Victor Stinner914cde82016-03-19 01:03:51 +0100809do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
810 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000811{
812 PyObject *filename, *module, *registry, *res;
813 int lineno;
814
815 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
816 return NULL;
817
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100818 res = warn_explicit(category, message, filename, lineno, module, registry,
Victor Stinner914cde82016-03-19 01:03:51 +0100819 NULL, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000820 Py_DECREF(filename);
821 Py_DECREF(registry);
822 Py_DECREF(module);
823 return res;
824}
825
Victor Stinner22f18752016-12-09 18:08:18 +0100826/*[clinic input]
827warn as warnings_warn
828
829 message: object
830 category: object = None
831 stacklevel: Py_ssize_t = 1
832 source: object = None
833
834Issue a warning, or maybe ignore it or raise an exception.
835[clinic start generated code]*/
836
Christian Heimes33fe8092008-04-13 13:53:33 +0000837static PyObject *
Victor Stinner22f18752016-12-09 18:08:18 +0100838warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
839 Py_ssize_t stacklevel, PyObject *source)
840/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
Christian Heimes33fe8092008-04-13 13:53:33 +0000841{
Christian Heimes33fe8092008-04-13 13:53:33 +0000842 category = get_category(message, category);
843 if (category == NULL)
844 return NULL;
Victor Stinner22f18752016-12-09 18:08:18 +0100845 return do_warn(message, category, stacklevel, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000846}
847
848static PyObject *
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200849get_source_line(PyObject *module_globals, int lineno)
850{
851 _Py_IDENTIFIER(get_source);
852 _Py_IDENTIFIER(__loader__);
853 _Py_IDENTIFIER(__name__);
854 PyObject *loader;
855 PyObject *module_name;
856 PyObject *get_source;
857 PyObject *source;
858 PyObject *source_list;
859 PyObject *source_line;
860
861 /* Check/get the requisite pieces needed for the loader. */
862 loader = _PyDict_GetItemIdWithError(module_globals, &PyId___loader__);
863 if (loader == NULL) {
864 return NULL;
865 }
866 Py_INCREF(loader);
867 module_name = _PyDict_GetItemIdWithError(module_globals, &PyId___name__);
868 if (!module_name) {
869 Py_DECREF(loader);
870 return NULL;
871 }
872 Py_INCREF(module_name);
873
874 /* Make sure the loader implements the optional get_source() method. */
875 get_source = _PyObject_GetAttrId(loader, &PyId_get_source);
876 Py_DECREF(loader);
877 if (!get_source) {
878 Py_DECREF(module_name);
879 if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
880 PyErr_Clear();
881 }
882 return NULL;
883 }
884 /* Call get_source() to get the source code. */
885 source = PyObject_CallFunctionObjArgs(get_source, module_name, NULL);
886 Py_DECREF(get_source);
887 Py_DECREF(module_name);
888 if (!source) {
889 return NULL;
890 }
891 if (source == Py_None) {
892 Py_DECREF(source);
893 return NULL;
894 }
895
896 /* Split the source into lines. */
897 source_list = PyUnicode_Splitlines(source, 0);
898 Py_DECREF(source);
899 if (!source_list) {
900 return NULL;
901 }
902
903 /* Get the source line. */
904 source_line = PyList_GetItem(source_list, lineno-1);
905 Py_XINCREF(source_line);
906 Py_DECREF(source_list);
907 return source_line;
908}
909
910static PyObject *
Christian Heimes33fe8092008-04-13 13:53:33 +0000911warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
912{
913 static char *kwd_list[] = {"message", "category", "filename", "lineno",
Victor Stinner914cde82016-03-19 01:03:51 +0100914 "module", "registry", "module_globals",
915 "source", 0};
Christian Heimes33fe8092008-04-13 13:53:33 +0000916 PyObject *message;
917 PyObject *category;
918 PyObject *filename;
919 int lineno;
920 PyObject *module = NULL;
921 PyObject *registry = NULL;
922 PyObject *module_globals = NULL;
Victor Stinner914cde82016-03-19 01:03:51 +0100923 PyObject *sourceobj = NULL;
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200924 PyObject *source_line = NULL;
925 PyObject *returned;
Christian Heimes33fe8092008-04-13 13:53:33 +0000926
Victor Stinner914cde82016-03-19 01:03:51 +0100927 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
Christian Heimes33fe8092008-04-13 13:53:33 +0000928 kwd_list, &message, &category, &filename, &lineno, &module,
Victor Stinner914cde82016-03-19 01:03:51 +0100929 &registry, &module_globals, &sourceobj))
Christian Heimes33fe8092008-04-13 13:53:33 +0000930 return NULL;
931
932 if (module_globals) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200933 source_line = get_source_line(module_globals, lineno);
934 if (source_line == NULL && PyErr_Occurred()) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000935 return NULL;
936 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000937 }
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200938 returned = warn_explicit(category, message, filename, lineno, module,
939 registry, source_line, sourceobj);
940 Py_XDECREF(source_line);
941 return returned;
Christian Heimes33fe8092008-04-13 13:53:33 +0000942}
943
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200944static PyObject *
945warnings_filters_mutated(PyObject *self, PyObject *args)
946{
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600947 _PyRuntime.warnings.filters_version++;
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200948 Py_RETURN_NONE;
949}
950
Christian Heimes33fe8092008-04-13 13:53:33 +0000951
952/* Function to issue a warning message; may raise an exception. */
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000953
954static int
955warn_unicode(PyObject *category, PyObject *message,
Victor Stinner914cde82016-03-19 01:03:51 +0100956 Py_ssize_t stack_level, PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000957{
958 PyObject *res;
Christian Heimes33fe8092008-04-13 13:53:33 +0000959
960 if (category == NULL)
961 category = PyExc_RuntimeWarning;
962
Victor Stinner914cde82016-03-19 01:03:51 +0100963 res = do_warn(message, category, stack_level, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000964 if (res == NULL)
965 return -1;
966 Py_DECREF(res);
967
968 return 0;
969}
970
Victor Stinner914cde82016-03-19 01:03:51 +0100971static int
972_PyErr_WarnFormatV(PyObject *source,
973 PyObject *category, Py_ssize_t stack_level,
974 const char *format, va_list vargs)
975{
976 PyObject *message;
977 int res;
978
979 message = PyUnicode_FromFormatV(format, vargs);
980 if (message == NULL)
981 return -1;
982
983 res = warn_unicode(category, message, stack_level, source);
984 Py_DECREF(message);
985 return res;
986}
987
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000988int
989PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
990 const char *format, ...)
991{
Victor Stinner914cde82016-03-19 01:03:51 +0100992 int res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000993 va_list vargs;
994
995#ifdef HAVE_STDARG_PROTOTYPES
996 va_start(vargs, format);
997#else
998 va_start(vargs);
999#endif
Victor Stinner914cde82016-03-19 01:03:51 +01001000 res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001001 va_end(vargs);
Victor Stinner914cde82016-03-19 01:03:51 +01001002 return res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001003}
1004
1005int
Victor Stinner914cde82016-03-19 01:03:51 +01001006PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
1007 const char *format, ...)
1008{
1009 int res;
1010 va_list vargs;
1011
1012#ifdef HAVE_STDARG_PROTOTYPES
1013 va_start(vargs, format);
1014#else
1015 va_start(vargs);
1016#endif
1017 res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
1018 stack_level, format, vargs);
1019 va_end(vargs);
1020 return res;
1021}
1022
1023
1024int
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001025PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
1026{
1027 int ret;
1028 PyObject *message = PyUnicode_FromString(text);
1029 if (message == NULL)
1030 return -1;
Victor Stinner914cde82016-03-19 01:03:51 +01001031 ret = warn_unicode(category, message, stack_level, NULL);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001032 Py_DECREF(message);
1033 return ret;
1034}
1035
Ezio Melotti42da6632011-03-15 05:18:48 +02001036/* PyErr_Warn is only for backwards compatibility and will be removed.
Christian Heimes33fe8092008-04-13 13:53:33 +00001037 Use PyErr_WarnEx instead. */
1038
1039#undef PyErr_Warn
1040
1041PyAPI_FUNC(int)
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001042PyErr_Warn(PyObject *category, const char *text)
Christian Heimes33fe8092008-04-13 13:53:33 +00001043{
1044 return PyErr_WarnEx(category, text, 1);
1045}
1046
1047/* Warning with explicit origin */
1048int
Victor Stinner14e461d2013-08-26 22:28:21 +02001049PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1050 PyObject *filename, int lineno,
1051 PyObject *module, PyObject *registry)
1052{
1053 PyObject *res;
1054 if (category == NULL)
1055 category = PyExc_RuntimeWarning;
1056 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001057 module, registry, NULL, NULL);
Victor Stinner14e461d2013-08-26 22:28:21 +02001058 if (res == NULL)
1059 return -1;
1060 Py_DECREF(res);
1061 return 0;
1062}
1063
1064int
Christian Heimes33fe8092008-04-13 13:53:33 +00001065PyErr_WarnExplicit(PyObject *category, const char *text,
1066 const char *filename_str, int lineno,
1067 const char *module_str, PyObject *registry)
1068{
Christian Heimes33fe8092008-04-13 13:53:33 +00001069 PyObject *message = PyUnicode_FromString(text);
Victor Stinnercb428f02010-12-27 20:10:36 +00001070 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
Christian Heimes33fe8092008-04-13 13:53:33 +00001071 PyObject *module = NULL;
1072 int ret = -1;
1073
1074 if (message == NULL || filename == NULL)
1075 goto exit;
1076 if (module_str != NULL) {
1077 module = PyUnicode_FromString(module_str);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001078 if (module == NULL)
1079 goto exit;
Christian Heimes33fe8092008-04-13 13:53:33 +00001080 }
1081
Victor Stinner14e461d2013-08-26 22:28:21 +02001082 ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1083 module, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +00001084
1085 exit:
1086 Py_XDECREF(message);
1087 Py_XDECREF(module);
1088 Py_XDECREF(filename);
1089 return ret;
1090}
1091
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001092int
1093PyErr_WarnExplicitFormat(PyObject *category,
1094 const char *filename_str, int lineno,
1095 const char *module_str, PyObject *registry,
1096 const char *format, ...)
1097{
1098 PyObject *message;
1099 PyObject *module = NULL;
1100 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1101 int ret = -1;
1102 va_list vargs;
1103
1104 if (filename == NULL)
1105 goto exit;
1106 if (module_str != NULL) {
1107 module = PyUnicode_FromString(module_str);
1108 if (module == NULL)
1109 goto exit;
1110 }
1111
1112#ifdef HAVE_STDARG_PROTOTYPES
1113 va_start(vargs, format);
1114#else
1115 va_start(vargs);
1116#endif
1117 message = PyUnicode_FromFormatV(format, vargs);
1118 if (message != NULL) {
1119 PyObject *res;
1120 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001121 module, registry, NULL, NULL);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001122 Py_DECREF(message);
1123 if (res != NULL) {
1124 Py_DECREF(res);
1125 ret = 0;
1126 }
1127 }
1128 va_end(vargs);
1129exit:
1130 Py_XDECREF(module);
1131 Py_XDECREF(filename);
1132 return ret;
1133}
1134
Christian Heimes33fe8092008-04-13 13:53:33 +00001135
Christian Heimes33fe8092008-04-13 13:53:33 +00001136PyDoc_STRVAR(warn_explicit_doc,
1137"Low-level inferface to warnings functionality.");
1138
1139static PyMethodDef warnings_functions[] = {
Victor Stinner22f18752016-12-09 18:08:18 +01001140 WARNINGS_WARN_METHODDEF
Christian Heimes33fe8092008-04-13 13:53:33 +00001141 {"warn_explicit", (PyCFunction)warnings_warn_explicit,
1142 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001143 {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
1144 NULL},
Christian Heimes1a8501c2008-10-02 19:56:01 +00001145 /* XXX(brett.cannon): add showwarning? */
1146 /* XXX(brett.cannon): Reasonable to add formatwarning? */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 {NULL, NULL} /* sentinel */
Christian Heimes33fe8092008-04-13 13:53:33 +00001148};
1149
1150
1151static PyObject *
1152create_filter(PyObject *category, const char *action)
1153{
Victor Stinner82656272017-11-22 23:51:42 +01001154 _Py_IDENTIFIER(ignore);
1155 _Py_IDENTIFIER(error);
1156 _Py_IDENTIFIER(always);
1157 _Py_static_string(PyId_default, "default");
1158 _Py_Identifier *id;
Christian Heimes33fe8092008-04-13 13:53:33 +00001159
1160 if (!strcmp(action, "ignore")) {
Victor Stinner82656272017-11-22 23:51:42 +01001161 id = &PyId_ignore;
Christian Heimes33fe8092008-04-13 13:53:33 +00001162 }
1163 else if (!strcmp(action, "error")) {
Victor Stinner82656272017-11-22 23:51:42 +01001164 id = &PyId_error;
Christian Heimes33fe8092008-04-13 13:53:33 +00001165 }
1166 else if (!strcmp(action, "default")) {
Victor Stinner82656272017-11-22 23:51:42 +01001167 id = &PyId_default;
Christian Heimes33fe8092008-04-13 13:53:33 +00001168 }
Georg Brandl08be72d2010-10-24 15:11:22 +00001169 else if (!strcmp(action, "always")) {
Victor Stinner82656272017-11-22 23:51:42 +01001170 id = &PyId_always;
Georg Brandl08be72d2010-10-24 15:11:22 +00001171 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001172 else {
Victor Stinner82656272017-11-22 23:51:42 +01001173 PyErr_SetString(PyExc_ValueError, "unknown action");
1174 return NULL;
1175 }
1176
1177 PyObject *action_str = _PyUnicode_FromId(id);
1178 if (action_str == NULL) {
1179 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001180 }
1181
1182 /* This assumes the line number is zero for now. */
Victor Stinner82656272017-11-22 23:51:42 +01001183 return PyTuple_Pack(5, action_str, Py_None,
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001184 category, Py_None, _PyLong_Zero);
Christian Heimes33fe8092008-04-13 13:53:33 +00001185}
1186
1187static PyObject *
Victor Stinner1f151112017-11-23 10:43:14 +01001188init_filters(const _PyCoreConfig *config)
Christian Heimes33fe8092008-04-13 13:53:33 +00001189{
Victor Stinner1f151112017-11-23 10:43:14 +01001190 int dev_mode = config->dev_mode;
Victor Stinner09f3a8a2017-11-20 17:32:40 -08001191
1192 Py_ssize_t count = 2;
1193 if (dev_mode) {
1194 count++;
1195 }
Victor Stinner895862a2017-11-20 09:47:03 -08001196#ifndef Py_DEBUG
Victor Stinner09f3a8a2017-11-20 17:32:40 -08001197 if (!dev_mode) {
1198 count += 3;
1199 }
Victor Stinner895862a2017-11-20 09:47:03 -08001200#endif
Victor Stinner09f3a8a2017-11-20 17:32:40 -08001201 PyObject *filters = PyList_New(count);
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001202 unsigned int pos = 0; /* Post-incremented in each use. */
1203 unsigned int x;
Georg Brandl08be72d2010-10-24 15:11:22 +00001204 const char *bytes_action, *resource_action;
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001205
Christian Heimes33fe8092008-04-13 13:53:33 +00001206 if (filters == NULL)
1207 return NULL;
1208
Victor Stinner895862a2017-11-20 09:47:03 -08001209#ifndef Py_DEBUG
Victor Stinner09f3a8a2017-11-20 17:32:40 -08001210 if (!dev_mode) {
1211 PyList_SET_ITEM(filters, pos++,
1212 create_filter(PyExc_DeprecationWarning, "ignore"));
1213 PyList_SET_ITEM(filters, pos++,
1214 create_filter(PyExc_PendingDeprecationWarning, "ignore"));
1215 PyList_SET_ITEM(filters, pos++,
1216 create_filter(PyExc_ImportWarning, "ignore"));
1217 }
Victor Stinner895862a2017-11-20 09:47:03 -08001218#endif
1219
Christian Heimes33fe8092008-04-13 13:53:33 +00001220 if (Py_BytesWarningFlag > 1)
1221 bytes_action = "error";
1222 else if (Py_BytesWarningFlag)
1223 bytes_action = "default";
1224 else
1225 bytes_action = "ignore";
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001226 PyList_SET_ITEM(filters, pos++, create_filter(PyExc_BytesWarning,
Christian Heimes33fe8092008-04-13 13:53:33 +00001227 bytes_action));
Victor Stinner09f3a8a2017-11-20 17:32:40 -08001228
Georg Brandl08be72d2010-10-24 15:11:22 +00001229 /* resource usage warnings are enabled by default in pydebug mode */
1230#ifdef Py_DEBUG
1231 resource_action = "always";
1232#else
Victor Stinner09f3a8a2017-11-20 17:32:40 -08001233 resource_action = (dev_mode ? "always" : "ignore");
Georg Brandl08be72d2010-10-24 15:11:22 +00001234#endif
1235 PyList_SET_ITEM(filters, pos++, create_filter(PyExc_ResourceWarning,
1236 resource_action));
Victor Stinner09f3a8a2017-11-20 17:32:40 -08001237
1238 if (dev_mode) {
1239 PyList_SET_ITEM(filters, pos++,
1240 create_filter(PyExc_Warning, "default"));
1241 }
1242
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001243 for (x = 0; x < pos; x += 1) {
1244 if (PyList_GET_ITEM(filters, x) == NULL) {
1245 Py_DECREF(filters);
1246 return NULL;
1247 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001248 }
1249
1250 return filters;
1251}
1252
Martin v. Löwis1a214512008-06-11 05:26:20 +00001253static struct PyModuleDef warningsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 PyModuleDef_HEAD_INIT,
1255 MODULE_NAME,
1256 warnings__doc__,
1257 0,
1258 warnings_functions,
1259 NULL,
1260 NULL,
1261 NULL,
1262 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001263};
1264
Christian Heimes33fe8092008-04-13 13:53:33 +00001265
Victor Stinner1f151112017-11-23 10:43:14 +01001266PyObject*
1267_PyWarnings_InitWithConfig(const _PyCoreConfig *config)
Christian Heimes33fe8092008-04-13 13:53:33 +00001268{
Brett Cannon0759dd62009-04-01 18:13:07 +00001269 PyObject *m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001270
Martin v. Löwis1a214512008-06-11 05:26:20 +00001271 m = PyModule_Create(&warningsmodule);
Christian Heimes33fe8092008-04-13 13:53:33 +00001272 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001273 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001274
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001275 if (_PyRuntime.warnings.filters == NULL) {
Victor Stinner1f151112017-11-23 10:43:14 +01001276 _PyRuntime.warnings.filters = init_filters(config);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001277 if (_PyRuntime.warnings.filters == NULL)
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001278 return NULL;
1279 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001280 Py_INCREF(_PyRuntime.warnings.filters);
1281 if (PyModule_AddObject(m, "filters", _PyRuntime.warnings.filters) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001282 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001283
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001284 if (_PyRuntime.warnings.once_registry == NULL) {
1285 _PyRuntime.warnings.once_registry = PyDict_New();
1286 if (_PyRuntime.warnings.once_registry == NULL)
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001287 return NULL;
1288 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001289 Py_INCREF(_PyRuntime.warnings.once_registry);
1290 if (PyModule_AddObject(m, "_onceregistry",
1291 _PyRuntime.warnings.once_registry) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001292 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001293
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001294 if (_PyRuntime.warnings.default_action == NULL) {
1295 _PyRuntime.warnings.default_action = PyUnicode_FromString("default");
1296 if (_PyRuntime.warnings.default_action == NULL)
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001297 return NULL;
1298 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001299 Py_INCREF(_PyRuntime.warnings.default_action);
1300 if (PyModule_AddObject(m, "_defaultaction",
1301 _PyRuntime.warnings.default_action) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001302 return NULL;
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001303
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001304 _PyRuntime.warnings.filters_version = 0;
Martin v. Löwis1a214512008-06-11 05:26:20 +00001305 return m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001306}
Victor Stinner1f151112017-11-23 10:43:14 +01001307
1308
1309PyMODINIT_FUNC
1310_PyWarnings_Init(void)
1311{
1312 PyInterpreterState *interp = PyThreadState_GET()->interp;
1313 const _PyCoreConfig *config = &interp->core_config;
1314 return _PyWarnings_InitWithConfig(config);
1315}