blob: 7270d2c2ecb15c1f14421bd5aa2aaedf9f7debb4 [file] [log] [blame]
Christian Heimes33fe8092008-04-13 13:53:33 +00001#include "Python.h"
2#include "frameobject.h"
3
4#define MODULE_NAME "_warnings"
Christian Heimes33fe8092008-04-13 13:53:33 +00005
6PyDoc_STRVAR(warnings__doc__,
7MODULE_NAME " provides basic warning filtering support.\n"
8"It is a helper module to speed up interpreter start-up.");
9
10/* Both 'filters' and 'onceregistry' can be set in warnings.py;
11 get_warnings_attr() will reset these variables accordingly. */
12static PyObject *_filters; /* List */
13static PyObject *_once_registry; /* Dict */
Brett Cannon0759dd62009-04-01 18:13:07 +000014static PyObject *_default_action; /* String */
Antoine Pitroucb0a0062014-09-18 02:40:46 +020015static long _filters_version;
Christian Heimes33fe8092008-04-13 13:53:33 +000016
Victor Stinnerbd303c12013-11-07 23:07:29 +010017_Py_IDENTIFIER(argv);
18_Py_IDENTIFIER(stderr);
Christian Heimes33fe8092008-04-13 13:53:33 +000019
20static int
21check_matched(PyObject *obj, PyObject *arg)
22{
23 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020024 _Py_IDENTIFIER(match);
Christian Heimes33fe8092008-04-13 13:53:33 +000025 int rc;
26
27 if (obj == Py_None)
28 return 1;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020029 result = _PyObject_CallMethodId(obj, &PyId_match, "O", arg);
Christian Heimes33fe8092008-04-13 13:53:33 +000030 if (result == NULL)
31 return -1;
32
33 rc = PyObject_IsTrue(result);
34 Py_DECREF(result);
35 return rc;
36}
37
38/*
39 Returns a new reference.
40 A NULL return value can mean false or an error.
41*/
42static PyObject *
Victor Stinnere98445a2016-03-23 00:54:48 +010043get_warnings_attr(const char *attr, int try_import)
Christian Heimes33fe8092008-04-13 13:53:33 +000044{
45 static PyObject *warnings_str = NULL;
46 PyObject *all_modules;
Victor Stinnere98445a2016-03-23 00:54:48 +010047 PyObject *warnings_module, *obj;
Christian Heimes33fe8092008-04-13 13:53:33 +000048
49 if (warnings_str == NULL) {
50 warnings_str = PyUnicode_InternFromString("warnings");
51 if (warnings_str == NULL)
52 return NULL;
53 }
54
Victor Stinnere98445a2016-03-23 00:54:48 +010055 /* don't try to import after the start of the Python finallization */
56 if (try_import && _Py_Finalizing == NULL) {
57 warnings_module = PyImport_Import(warnings_str);
58 if (warnings_module == NULL) {
59 /* Fallback to the C implementation if we cannot get
60 the Python implementation */
61 PyErr_Clear();
Christian Heimes33fe8092008-04-13 13:53:33 +000062 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +010063 }
64 }
65 else {
66 all_modules = PyImport_GetModuleDict();
Victor Stinnere98445a2016-03-23 00:54:48 +010067
68 warnings_module = PyDict_GetItem(all_modules, warnings_str);
Victor Stinner023654f2016-03-23 17:48:22 +010069 if (warnings_module == NULL)
70 return NULL;
71
Victor Stinnere98445a2016-03-23 00:54:48 +010072 Py_INCREF(warnings_module);
73 }
74
75 if (!PyObject_HasAttrString(warnings_module, attr)) {
76 Py_DECREF(warnings_module);
77 return NULL;
78 }
79
80 obj = PyObject_GetAttrString(warnings_module, attr);
81 Py_DECREF(warnings_module);
82 return obj;
Christian Heimes33fe8092008-04-13 13:53:33 +000083}
84
85
Neal Norwitz32dde222008-04-15 06:43:13 +000086static PyObject *
Christian Heimes33fe8092008-04-13 13:53:33 +000087get_once_registry(void)
88{
89 PyObject *registry;
90
Victor Stinnere98445a2016-03-23 00:54:48 +010091 registry = get_warnings_attr("onceregistry", 0);
Christian Heimes33fe8092008-04-13 13:53:33 +000092 if (registry == NULL) {
93 if (PyErr_Occurred())
94 return NULL;
95 return _once_registry;
96 }
Serhiy Storchaka7972ed22017-09-11 10:01:47 +030097 if (!PyDict_Check(registry)) {
98 PyErr_SetString(PyExc_TypeError,
99 "warnings.onceregistry must be a dict");
100 Py_DECREF(registry);
101 return NULL;
102 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000103 Py_DECREF(_once_registry);
104 _once_registry = registry;
105 return registry;
106}
107
108
Brett Cannon0759dd62009-04-01 18:13:07 +0000109static PyObject *
110get_default_action(void)
111{
112 PyObject *default_action;
113
Victor Stinnere98445a2016-03-23 00:54:48 +0100114 default_action = get_warnings_attr("defaultaction", 0);
Brett Cannon0759dd62009-04-01 18:13:07 +0000115 if (default_action == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 if (PyErr_Occurred()) {
117 return NULL;
118 }
119 return _default_action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000120 }
Serhiy Storchaka9adc87b2017-09-12 09:48:27 +0300121 if (!PyUnicode_Check(default_action)) {
122 PyErr_Format(PyExc_TypeError,
123 MODULE_NAME ".defaultaction must be a string, "
124 "not '%.200s'",
125 Py_TYPE(default_action)->tp_name);
126 Py_DECREF(default_action);
127 return NULL;
128 }
Brett Cannon0759dd62009-04-01 18:13:07 +0000129 Py_DECREF(_default_action);
130 _default_action = default_action;
131 return default_action;
132}
133
134
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400135/* The item is a new reference. */
Victor Stinnera4c704b2013-10-29 23:43:41 +0100136static PyObject*
Christian Heimes33fe8092008-04-13 13:53:33 +0000137get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
138 PyObject *module, PyObject **item)
139{
Brett Cannon0759dd62009-04-01 18:13:07 +0000140 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000141 Py_ssize_t i;
142 PyObject *warnings_filters;
143
Victor Stinnere98445a2016-03-23 00:54:48 +0100144 warnings_filters = get_warnings_attr("filters", 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000145 if (warnings_filters == NULL) {
146 if (PyErr_Occurred())
147 return NULL;
148 }
149 else {
150 Py_DECREF(_filters);
151 _filters = warnings_filters;
152 }
153
Victor Stinner7d79b8b2010-05-19 20:40:50 +0000154 if (_filters == NULL || !PyList_Check(_filters)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000155 PyErr_SetString(PyExc_ValueError,
156 MODULE_NAME ".filters must be a list");
157 return NULL;
158 }
159
160 /* _filters could change while we are iterating over it. */
161 for (i = 0; i < PyList_GET_SIZE(_filters); i++) {
162 PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
163 Py_ssize_t ln;
164 int is_subclass, good_msg, good_mod;
165
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400166 tmp_item = PyList_GET_ITEM(_filters, i);
167 if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000168 PyErr_Format(PyExc_ValueError,
169 MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
170 return NULL;
171 }
172
173 /* Python code: action, msg, cat, mod, ln = item */
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400174 Py_INCREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000175 action = PyTuple_GET_ITEM(tmp_item, 0);
176 msg = PyTuple_GET_ITEM(tmp_item, 1);
177 cat = PyTuple_GET_ITEM(tmp_item, 2);
178 mod = PyTuple_GET_ITEM(tmp_item, 3);
179 ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
180
Serhiy Storchaka9adc87b2017-09-12 09:48:27 +0300181 if (!PyUnicode_Check(action)) {
182 PyErr_Format(PyExc_TypeError,
183 "action must be a string, not '%.200s'",
184 Py_TYPE(action)->tp_name);
185 Py_DECREF(tmp_item);
186 return NULL;
187 }
188
Christian Heimes33fe8092008-04-13 13:53:33 +0000189 good_msg = check_matched(msg, text);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400190 if (good_msg == -1) {
191 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100192 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400193 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100194
Christian Heimes33fe8092008-04-13 13:53:33 +0000195 good_mod = check_matched(mod, module);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400196 if (good_mod == -1) {
197 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100198 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400199 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100200
Christian Heimes33fe8092008-04-13 13:53:33 +0000201 is_subclass = PyObject_IsSubclass(category, cat);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400202 if (is_subclass == -1) {
203 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100204 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400205 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100206
Christian Heimes33fe8092008-04-13 13:53:33 +0000207 ln = PyLong_AsSsize_t(ln_obj);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400208 if (ln == -1 && PyErr_Occurred()) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400209 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000210 return NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400211 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000212
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400213 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
214 *item = tmp_item;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100215 return action;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400216 }
217
218 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000219 }
220
Brett Cannon0759dd62009-04-01 18:13:07 +0000221 action = get_default_action();
222 if (action != NULL) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400223 Py_INCREF(Py_None);
224 *item = Py_None;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100225 return action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000226 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000227
Christian Heimes33fe8092008-04-13 13:53:33 +0000228 return NULL;
229}
230
Brett Cannon0759dd62009-04-01 18:13:07 +0000231
Christian Heimes33fe8092008-04-13 13:53:33 +0000232static int
233already_warned(PyObject *registry, PyObject *key, int should_set)
234{
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200235 PyObject *version_obj, *already_warned;
236 _Py_IDENTIFIER(version);
Christian Heimes33fe8092008-04-13 13:53:33 +0000237
238 if (key == NULL)
239 return -1;
240
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200241 version_obj = _PyDict_GetItemId(registry, &PyId_version);
242 if (version_obj == NULL
243 || !PyLong_CheckExact(version_obj)
244 || PyLong_AsLong(version_obj) != _filters_version) {
245 PyDict_Clear(registry);
246 version_obj = PyLong_FromLong(_filters_version);
247 if (version_obj == NULL)
248 return -1;
249 if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
250 Py_DECREF(version_obj);
251 return -1;
252 }
253 Py_DECREF(version_obj);
254 }
255 else {
256 already_warned = PyDict_GetItem(registry, key);
257 if (already_warned != NULL) {
258 int rc = PyObject_IsTrue(already_warned);
259 if (rc != 0)
260 return rc;
261 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000262 }
263
264 /* This warning wasn't found in the registry, set it. */
265 if (should_set)
266 return PyDict_SetItem(registry, key, Py_True);
267 return 0;
268}
269
270/* New reference. */
271static PyObject *
272normalize_module(PyObject *filename)
273{
274 PyObject *module;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100275 int kind;
276 void *data;
Christian Heimes33fe8092008-04-13 13:53:33 +0000277 Py_ssize_t len;
278
Victor Stinner9e30aa52011-11-21 02:49:52 +0100279 len = PyUnicode_GetLength(filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000280 if (len < 0)
281 return NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100282
283 if (len == 0)
284 return PyUnicode_FromString("<unknown>");
285
286 kind = PyUnicode_KIND(filename);
287 data = PyUnicode_DATA(filename);
288
289 /* if filename.endswith(".py"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000290 if (len >= 3 &&
Victor Stinnera4c704b2013-10-29 23:43:41 +0100291 PyUnicode_READ(kind, data, len-3) == '.' &&
292 PyUnicode_READ(kind, data, len-2) == 'p' &&
293 PyUnicode_READ(kind, data, len-1) == 'y')
294 {
Victor Stinner9e30aa52011-11-21 02:49:52 +0100295 module = PyUnicode_Substring(filename, 0, len-3);
Christian Heimes33fe8092008-04-13 13:53:33 +0000296 }
297 else {
298 module = filename;
299 Py_INCREF(module);
300 }
301 return module;
302}
303
304static int
305update_registry(PyObject *registry, PyObject *text, PyObject *category,
306 int add_zero)
307{
308 PyObject *altkey, *zero = NULL;
309 int rc;
310
311 if (add_zero) {
312 zero = PyLong_FromLong(0);
313 if (zero == NULL)
314 return -1;
315 altkey = PyTuple_Pack(3, text, category, zero);
316 }
317 else
318 altkey = PyTuple_Pack(2, text, category);
319
320 rc = already_warned(registry, altkey, 1);
321 Py_XDECREF(zero);
322 Py_XDECREF(altkey);
323 return rc;
324}
325
326static void
Victor Stinner914cde82016-03-19 01:03:51 +0100327show_warning(PyObject *filename, int lineno, PyObject *text,
328 PyObject *category, PyObject *sourceline)
Christian Heimes33fe8092008-04-13 13:53:33 +0000329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330 PyObject *f_stderr;
331 PyObject *name;
Christian Heimes33fe8092008-04-13 13:53:33 +0000332 char lineno_str[128];
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200333 _Py_IDENTIFIER(__name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000334
335 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
336
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200337 name = _PyObject_GetAttrId(category, &PyId___name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000338 if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100339 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000340
Victor Stinnerbd303c12013-11-07 23:07:29 +0100341 f_stderr = _PySys_GetObjectId(&PyId_stderr);
Christian Heimes33fe8092008-04-13 13:53:33 +0000342 if (f_stderr == NULL) {
343 fprintf(stderr, "lost sys.stderr\n");
Victor Stinnerae233ea2013-10-31 14:51:38 +0100344 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000345 }
346
347 /* Print "filename:lineno: category: text\n" */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100348 if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
349 goto error;
350 if (PyFile_WriteString(lineno_str, f_stderr) < 0)
351 goto error;
352 if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
353 goto error;
354 if (PyFile_WriteString(": ", f_stderr) < 0)
355 goto error;
356 if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
357 goto error;
358 if (PyFile_WriteString("\n", f_stderr) < 0)
359 goto error;
360 Py_CLEAR(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000361
362 /* Print " source_line\n" */
Christian Heimes33fe8092008-04-13 13:53:33 +0000363 if (sourceline) {
Victor Stinnera4c704b2013-10-29 23:43:41 +0100364 int kind;
365 void *data;
366 Py_ssize_t i, len;
367 Py_UCS4 ch;
368 PyObject *truncated;
Christian Heimes33fe8092008-04-13 13:53:33 +0000369
Victor Stinnera4c704b2013-10-29 23:43:41 +0100370 if (PyUnicode_READY(sourceline) < 1)
371 goto error;
372
373 kind = PyUnicode_KIND(sourceline);
374 data = PyUnicode_DATA(sourceline);
375 len = PyUnicode_GET_LENGTH(sourceline);
376 for (i=0; i<len; i++) {
377 ch = PyUnicode_READ(kind, data, i);
378 if (ch != ' ' && ch != '\t' && ch != '\014')
379 break;
380 }
381
382 truncated = PyUnicode_Substring(sourceline, i, len);
383 if (truncated == NULL)
384 goto error;
385
386 PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
387 Py_DECREF(truncated);
Christian Heimes33fe8092008-04-13 13:53:33 +0000388 PyFile_WriteString("\n", f_stderr);
389 }
Victor Stinner78e2c982013-07-16 01:54:37 +0200390 else {
391 _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
392 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100393
394error:
Victor Stinnerae233ea2013-10-31 14:51:38 +0100395 Py_XDECREF(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000396 PyErr_Clear();
397}
398
Victor Stinner1231a462016-03-19 00:47:17 +0100399static int
400call_show_warning(PyObject *category, PyObject *text, PyObject *message,
401 PyObject *filename, int lineno, PyObject *lineno_obj,
Victor Stinner914cde82016-03-19 01:03:51 +0100402 PyObject *sourceline, PyObject *source)
Victor Stinner1231a462016-03-19 00:47:17 +0100403{
404 PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
405
Victor Stinnere98445a2016-03-23 00:54:48 +0100406 /* If the source parameter is set, try to get the Python implementation.
407 The Python implementation is able to log the traceback where the source
408 was allocated, whereas the C implementation doesnt. */
409 show_fn = get_warnings_attr("_showwarnmsg", source != NULL);
Victor Stinner1231a462016-03-19 00:47:17 +0100410 if (show_fn == NULL) {
411 if (PyErr_Occurred())
412 return -1;
413 show_warning(filename, lineno, text, category, sourceline);
414 return 0;
415 }
416
417 if (!PyCallable_Check(show_fn)) {
418 PyErr_SetString(PyExc_TypeError,
419 "warnings._showwarnmsg() must be set to a callable");
420 goto error;
421 }
422
Victor Stinnere98445a2016-03-23 00:54:48 +0100423 warnmsg_cls = get_warnings_attr("WarningMessage", 0);
Victor Stinner1231a462016-03-19 00:47:17 +0100424 if (warnmsg_cls == NULL) {
425 PyErr_SetString(PyExc_RuntimeError,
426 "unable to get warnings.WarningMessage");
427 goto error;
428 }
429
430 msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
Victor Stinner914cde82016-03-19 01:03:51 +0100431 filename, lineno_obj, Py_None, Py_None, source,
Victor Stinner1231a462016-03-19 00:47:17 +0100432 NULL);
433 Py_DECREF(warnmsg_cls);
434 if (msg == NULL)
435 goto error;
436
437 res = PyObject_CallFunctionObjArgs(show_fn, msg, NULL);
438 Py_DECREF(show_fn);
439 Py_DECREF(msg);
440
441 if (res == NULL)
442 return -1;
443
444 Py_DECREF(res);
445 return 0;
446
447error:
448 Py_XDECREF(show_fn);
449 return -1;
450}
451
Christian Heimes33fe8092008-04-13 13:53:33 +0000452static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453warn_explicit(PyObject *category, PyObject *message,
Christian Heimes33fe8092008-04-13 13:53:33 +0000454 PyObject *filename, int lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100455 PyObject *module, PyObject *registry, PyObject *sourceline,
456 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000457{
458 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400459 PyObject *item = NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100460 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000461 int rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100463 /* module can be None if a warning is emitted late during Python shutdown.
464 In this case, the Python warnings module was probably unloaded, filters
465 are no more available to choose as action. It is safer to ignore the
466 warning and do nothing. */
467 if (module == Py_None)
468 Py_RETURN_NONE;
469
Brett Cannondb734912008-06-27 00:52:15 +0000470 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
Serhiy Storchaka7972ed22017-09-11 10:01:47 +0300471 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
Brett Cannondb734912008-06-27 00:52:15 +0000472 return NULL;
473 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000474
475 /* Normalize module. */
476 if (module == NULL) {
477 module = normalize_module(filename);
478 if (module == NULL)
479 return NULL;
480 }
481 else
482 Py_INCREF(module);
483
484 /* Normalize message. */
485 Py_INCREF(message); /* DECREF'ed in cleanup. */
486 rc = PyObject_IsInstance(message, PyExc_Warning);
487 if (rc == -1) {
488 goto cleanup;
489 }
490 if (rc == 1) {
491 text = PyObject_Str(message);
Hirokazu Yamamoto1c0c0032009-07-17 06:55:42 +0000492 if (text == NULL)
493 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000494 category = (PyObject*)message->ob_type;
495 }
496 else {
497 text = message;
498 message = PyObject_CallFunction(category, "O", message);
Brett Cannondb734912008-06-27 00:52:15 +0000499 if (message == NULL)
500 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000501 }
502
503 lineno_obj = PyLong_FromLong(lineno);
504 if (lineno_obj == NULL)
505 goto cleanup;
506
507 /* Create key. */
508 key = PyTuple_Pack(3, text, category, lineno_obj);
509 if (key == NULL)
510 goto cleanup;
511
Brett Cannondb734912008-06-27 00:52:15 +0000512 if ((registry != NULL) && (registry != Py_None)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000513 rc = already_warned(registry, key, 0);
514 if (rc == -1)
515 goto cleanup;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000516 else if (rc == 1)
Christian Heimes33fe8092008-04-13 13:53:33 +0000517 goto return_none;
518 /* Else this warning hasn't been generated before. */
519 }
520
521 action = get_filter(category, text, lineno, module, &item);
522 if (action == NULL)
523 goto cleanup;
524
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200525 if (_PyUnicode_EqualToASCIIString(action, "error")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000526 PyErr_SetObject(category, message);
527 goto cleanup;
528 }
529
530 /* Store in the registry that we've been here, *except* when the action
531 is "always". */
532 rc = 0;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200533 if (!_PyUnicode_EqualToASCIIString(action, "always")) {
Brett Cannondb734912008-06-27 00:52:15 +0000534 if (registry != NULL && registry != Py_None &&
535 PyDict_SetItem(registry, key, Py_True) < 0)
Christian Heimes33fe8092008-04-13 13:53:33 +0000536 goto cleanup;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200537 else if (_PyUnicode_EqualToASCIIString(action, "ignore"))
Christian Heimes33fe8092008-04-13 13:53:33 +0000538 goto return_none;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200539 else if (_PyUnicode_EqualToASCIIString(action, "once")) {
Brett Cannondb734912008-06-27 00:52:15 +0000540 if (registry == NULL || registry == Py_None) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000541 registry = get_once_registry();
542 if (registry == NULL)
543 goto cleanup;
544 }
545 /* _once_registry[(text, category)] = 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000547 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200548 else if (_PyUnicode_EqualToASCIIString(action, "module")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000549 /* registry[(text, category, 0)] = 1 */
Brett Cannondb734912008-06-27 00:52:15 +0000550 if (registry != NULL && registry != Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000552 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200553 else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000554 PyErr_Format(PyExc_RuntimeError,
Victor Stinnera4c704b2013-10-29 23:43:41 +0100555 "Unrecognized action (%R) in warnings.filters:\n %R",
556 action, item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000557 goto cleanup;
558 }
559 }
560
Christian Heimes1a8501c2008-10-02 19:56:01 +0000561 if (rc == 1) /* Already warned for this module. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000562 goto return_none;
563 if (rc == 0) {
Victor Stinner1231a462016-03-19 00:47:17 +0100564 if (call_show_warning(category, text, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100565 lineno_obj, sourceline, source) < 0)
Victor Stinner1231a462016-03-19 00:47:17 +0100566 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000567 }
568 else /* if (rc == -1) */
569 goto cleanup;
570
571 return_none:
572 result = Py_None;
573 Py_INCREF(result);
574
575 cleanup:
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400576 Py_XDECREF(item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000577 Py_XDECREF(key);
578 Py_XDECREF(text);
579 Py_XDECREF(lineno_obj);
580 Py_DECREF(module);
Brett Cannondb734912008-06-27 00:52:15 +0000581 Py_XDECREF(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000582 return result; /* Py_None or NULL. */
583}
584
Larry Hastings714e4932015-09-06 00:39:37 -0700585static int
586is_internal_frame(PyFrameObject *frame)
587{
588 static PyObject *importlib_string = NULL;
589 static PyObject *bootstrap_string = NULL;
590 PyObject *filename;
591 int contains;
592
593 if (importlib_string == NULL) {
594 importlib_string = PyUnicode_FromString("importlib");
595 if (importlib_string == NULL) {
596 return 0;
597 }
598
599 bootstrap_string = PyUnicode_FromString("_bootstrap");
600 if (bootstrap_string == NULL) {
601 Py_DECREF(importlib_string);
602 return 0;
603 }
604 Py_INCREF(importlib_string);
605 Py_INCREF(bootstrap_string);
606 }
607
608 if (frame == NULL || frame->f_code == NULL ||
609 frame->f_code->co_filename == NULL) {
610 return 0;
611 }
612 filename = frame->f_code->co_filename;
613 if (!PyUnicode_Check(filename)) {
614 return 0;
615 }
616 contains = PyUnicode_Contains(filename, importlib_string);
617 if (contains < 0) {
618 return 0;
619 }
620 else if (contains > 0) {
621 contains = PyUnicode_Contains(filename, bootstrap_string);
622 if (contains < 0) {
623 return 0;
624 }
625 else if (contains > 0) {
626 return 1;
627 }
628 }
629
630 return 0;
631}
632
633static PyFrameObject *
634next_external_frame(PyFrameObject *frame)
635{
636 do {
637 frame = frame->f_back;
638 } while (frame != NULL && is_internal_frame(frame));
639
640 return frame;
641}
642
Christian Heimes33fe8092008-04-13 13:53:33 +0000643/* filename, module, and registry are new refs, globals is borrowed */
644/* Returns 0 on error (no new refs), 1 on success */
645static int
646setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
647 PyObject **module, PyObject **registry)
648{
649 PyObject *globals;
650
651 /* Setup globals and lineno. */
652 PyFrameObject *f = PyThreadState_GET()->frame;
Larry Hastings714e4932015-09-06 00:39:37 -0700653 // Stack level comparisons to Python code is off by one as there is no
654 // warnings-related stack level to avoid.
655 if (stack_level <= 0 || is_internal_frame(f)) {
656 while (--stack_level > 0 && f != NULL) {
657 f = f->f_back;
658 }
659 }
660 else {
661 while (--stack_level > 0 && f != NULL) {
662 f = next_external_frame(f);
663 }
664 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000665
666 if (f == NULL) {
667 globals = PyThreadState_Get()->interp->sysdict;
668 *lineno = 1;
669 }
670 else {
671 globals = f->f_globals;
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000672 *lineno = PyFrame_GetLineNumber(f);
Christian Heimes33fe8092008-04-13 13:53:33 +0000673 }
674
675 *module = NULL;
676
677 /* Setup registry. */
678 assert(globals != NULL);
679 assert(PyDict_Check(globals));
680 *registry = PyDict_GetItemString(globals, "__warningregistry__");
681 if (*registry == NULL) {
682 int rc;
683
684 *registry = PyDict_New();
685 if (*registry == NULL)
686 return 0;
687
688 rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
689 if (rc < 0)
690 goto handle_error;
691 }
692 else
693 Py_INCREF(*registry);
694
695 /* Setup module. */
696 *module = PyDict_GetItemString(globals, "__name__");
697 if (*module == NULL) {
698 *module = PyUnicode_FromString("<string>");
699 if (*module == NULL)
700 goto handle_error;
701 }
702 else
703 Py_INCREF(*module);
704
705 /* Setup filename. */
706 *filename = PyDict_GetItemString(globals, "__file__");
Victor Stinner8b0508e2011-07-04 02:43:09 +0200707 if (*filename != NULL && PyUnicode_Check(*filename)) {
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200708 Py_ssize_t len;
709 int kind;
710 void *data;
711
712 if (PyUnicode_READY(*filename))
713 goto handle_error;
714
Victor Stinner9e30aa52011-11-21 02:49:52 +0100715 len = PyUnicode_GetLength(*filename);
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200716 kind = PyUnicode_KIND(*filename);
717 data = PyUnicode_DATA(*filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000718
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500719#define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0)
Brett Cannonf299abd2015-04-13 14:21:02 -0400720 /* if filename.lower().endswith(".pyc"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000721 if (len >= 4 &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200722 PyUnicode_READ(kind, data, len-4) == '.' &&
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500723 ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' &&
724 ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' &&
Brett Cannonf299abd2015-04-13 14:21:02 -0400725 ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c')
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000726 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200727 *filename = PyUnicode_Substring(*filename, 0,
728 PyUnicode_GET_LENGTH(*filename)-1);
Victor Stinner2e5f1172010-08-08 22:12:45 +0000729 if (*filename == NULL)
730 goto handle_error;
731 }
732 else
Christian Heimes33fe8092008-04-13 13:53:33 +0000733 Py_INCREF(*filename);
734 }
735 else {
Benjamin Petersonbb4a7472011-07-04 22:27:16 -0500736 *filename = NULL;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200737 if (*module != Py_None && _PyUnicode_EqualToASCIIString(*module, "__main__")) {
Victor Stinnerbd303c12013-11-07 23:07:29 +0100738 PyObject *argv = _PySys_GetObjectId(&PyId_argv);
Victor Stinnerce5f4fb2013-10-28 18:47:22 +0100739 /* PyList_Check() is needed because sys.argv is set to None during
740 Python finalization */
741 if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) {
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000742 int is_true;
Christian Heimes33fe8092008-04-13 13:53:33 +0000743 *filename = PyList_GetItem(argv, 0);
744 Py_INCREF(*filename);
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000745 /* If sys.argv[0] is false, then use '__main__'. */
746 is_true = PyObject_IsTrue(*filename);
747 if (is_true < 0) {
748 Py_DECREF(*filename);
749 goto handle_error;
750 }
751 else if (!is_true) {
Serhiy Storchaka57a01d32016-04-10 18:05:40 +0300752 Py_SETREF(*filename, PyUnicode_FromString("__main__"));
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000753 if (*filename == NULL)
754 goto handle_error;
755 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000756 }
757 else {
758 /* embedded interpreters don't have sys.argv, see bug #839151 */
759 *filename = PyUnicode_FromString("__main__");
Victor Stinner856f45f2013-10-30 00:04:59 +0100760 if (*filename == NULL)
761 goto handle_error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000762 }
763 }
764 if (*filename == NULL) {
765 *filename = *module;
766 Py_INCREF(*filename);
767 }
768 }
769
770 return 1;
771
772 handle_error:
773 /* filename not XDECREF'ed here as there is no way to jump here with a
774 dangling reference. */
775 Py_XDECREF(*registry);
776 Py_XDECREF(*module);
777 return 0;
778}
779
780static PyObject *
781get_category(PyObject *message, PyObject *category)
782{
783 int rc;
784
785 /* Get category. */
786 rc = PyObject_IsInstance(message, PyExc_Warning);
787 if (rc == -1)
788 return NULL;
789
790 if (rc == 1)
791 category = (PyObject*)message->ob_type;
Berker Peksagd8089e02014-07-11 19:50:25 +0300792 else if (category == NULL || category == Py_None)
Christian Heimes33fe8092008-04-13 13:53:33 +0000793 category = PyExc_UserWarning;
794
795 /* Validate category. */
796 rc = PyObject_IsSubclass(category, PyExc_Warning);
Berker Peksagd8089e02014-07-11 19:50:25 +0300797 /* category is not a subclass of PyExc_Warning or
798 PyObject_IsSubclass raised an error */
799 if (rc == -1 || rc == 0) {
800 PyErr_Format(PyExc_TypeError,
801 "category must be a Warning subclass, not '%s'",
802 Py_TYPE(category)->tp_name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000803 return NULL;
804 }
805
806 return category;
807}
808
809static PyObject *
Victor Stinner914cde82016-03-19 01:03:51 +0100810do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
811 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000812{
813 PyObject *filename, *module, *registry, *res;
814 int lineno;
815
816 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
817 return NULL;
818
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100819 res = warn_explicit(category, message, filename, lineno, module, registry,
Victor Stinner914cde82016-03-19 01:03:51 +0100820 NULL, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000821 Py_DECREF(filename);
822 Py_DECREF(registry);
823 Py_DECREF(module);
824 return res;
825}
826
827static PyObject *
828warnings_warn(PyObject *self, PyObject *args, PyObject *kwds)
829{
Victor Stinnere19558a2016-03-23 00:28:08 +0100830 static char *kw_list[] = {"message", "category", "stacklevel",
831 "source", NULL};
832 PyObject *message, *category = NULL, *source = NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000833 Py_ssize_t stack_level = 1;
834
Victor Stinnere19558a2016-03-23 00:28:08 +0100835 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OnO:warn", kw_list,
836 &message, &category, &stack_level, &source))
Christian Heimes33fe8092008-04-13 13:53:33 +0000837 return NULL;
838
839 category = get_category(message, category);
840 if (category == NULL)
841 return NULL;
Victor Stinnere19558a2016-03-23 00:28:08 +0100842 return do_warn(message, category, stack_level, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000843}
844
845static PyObject *
846warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
847{
848 static char *kwd_list[] = {"message", "category", "filename", "lineno",
Victor Stinner914cde82016-03-19 01:03:51 +0100849 "module", "registry", "module_globals",
850 "source", 0};
Christian Heimes33fe8092008-04-13 13:53:33 +0000851 PyObject *message;
852 PyObject *category;
853 PyObject *filename;
854 int lineno;
855 PyObject *module = NULL;
856 PyObject *registry = NULL;
857 PyObject *module_globals = NULL;
Victor Stinner914cde82016-03-19 01:03:51 +0100858 PyObject *sourceobj = NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000859
Victor Stinner914cde82016-03-19 01:03:51 +0100860 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
Christian Heimes33fe8092008-04-13 13:53:33 +0000861 kwd_list, &message, &category, &filename, &lineno, &module,
Victor Stinner914cde82016-03-19 01:03:51 +0100862 &registry, &module_globals, &sourceobj))
Christian Heimes33fe8092008-04-13 13:53:33 +0000863 return NULL;
864
865 if (module_globals) {
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200866 _Py_IDENTIFIER(get_source);
867 _Py_IDENTIFIER(splitlines);
868 PyObject *tmp;
Christian Heimes33fe8092008-04-13 13:53:33 +0000869 PyObject *loader;
870 PyObject *module_name;
871 PyObject *source;
872 PyObject *source_list;
873 PyObject *source_line;
874 PyObject *returned;
875
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200876 if ((tmp = _PyUnicode_FromId(&PyId_get_source)) == NULL)
877 return NULL;
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200878 if ((tmp = _PyUnicode_FromId(&PyId_splitlines)) == NULL)
879 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000880
881 /* Check/get the requisite pieces needed for the loader. */
882 loader = PyDict_GetItemString(module_globals, "__loader__");
883 module_name = PyDict_GetItemString(module_globals, "__name__");
884
885 if (loader == NULL || module_name == NULL)
886 goto standard_call;
887
888 /* Make sure the loader implements the optional get_source() method. */
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200889 if (!_PyObject_HasAttrId(loader, &PyId_get_source))
Christian Heimes33fe8092008-04-13 13:53:33 +0000890 goto standard_call;
891 /* Call get_source() to get the source code. */
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200892 source = PyObject_CallMethodObjArgs(loader, PyId_get_source.object,
893 module_name, NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000894 if (!source)
895 return NULL;
896 else if (source == Py_None) {
897 Py_DECREF(Py_None);
898 goto standard_call;
899 }
900
901 /* Split the source into lines. */
Victor Stinner9e30aa52011-11-21 02:49:52 +0100902 source_list = PyObject_CallMethodObjArgs(source,
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200903 PyId_splitlines.object,
904 NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000905 Py_DECREF(source);
906 if (!source_list)
907 return NULL;
908
909 /* Get the source line. */
910 source_line = PyList_GetItem(source_list, lineno-1);
911 if (!source_line) {
912 Py_DECREF(source_list);
913 return NULL;
914 }
915
916 /* Handle the warning. */
917 returned = warn_explicit(category, message, filename, lineno, module,
Victor Stinner914cde82016-03-19 01:03:51 +0100918 registry, source_line, sourceobj);
Christian Heimes33fe8092008-04-13 13:53:33 +0000919 Py_DECREF(source_list);
920 return returned;
921 }
922
923 standard_call:
924 return warn_explicit(category, message, filename, lineno, module,
Victor Stinner914cde82016-03-19 01:03:51 +0100925 registry, NULL, sourceobj);
Christian Heimes33fe8092008-04-13 13:53:33 +0000926}
927
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200928static PyObject *
929warnings_filters_mutated(PyObject *self, PyObject *args)
930{
931 _filters_version++;
932 Py_RETURN_NONE;
933}
934
Christian Heimes33fe8092008-04-13 13:53:33 +0000935
936/* Function to issue a warning message; may raise an exception. */
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000937
938static int
939warn_unicode(PyObject *category, PyObject *message,
Victor Stinner914cde82016-03-19 01:03:51 +0100940 Py_ssize_t stack_level, PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000941{
942 PyObject *res;
Christian Heimes33fe8092008-04-13 13:53:33 +0000943
944 if (category == NULL)
945 category = PyExc_RuntimeWarning;
946
Victor Stinner914cde82016-03-19 01:03:51 +0100947 res = do_warn(message, category, stack_level, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000948 if (res == NULL)
949 return -1;
950 Py_DECREF(res);
951
952 return 0;
953}
954
Victor Stinner914cde82016-03-19 01:03:51 +0100955static int
956_PyErr_WarnFormatV(PyObject *source,
957 PyObject *category, Py_ssize_t stack_level,
958 const char *format, va_list vargs)
959{
960 PyObject *message;
961 int res;
962
963 message = PyUnicode_FromFormatV(format, vargs);
964 if (message == NULL)
965 return -1;
966
967 res = warn_unicode(category, message, stack_level, source);
968 Py_DECREF(message);
969 return res;
970}
971
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000972int
973PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
974 const char *format, ...)
975{
Victor Stinner914cde82016-03-19 01:03:51 +0100976 int res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000977 va_list vargs;
978
979#ifdef HAVE_STDARG_PROTOTYPES
980 va_start(vargs, format);
981#else
982 va_start(vargs);
983#endif
Victor Stinner914cde82016-03-19 01:03:51 +0100984 res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000985 va_end(vargs);
Victor Stinner914cde82016-03-19 01:03:51 +0100986 return res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000987}
988
989int
Victor Stinner914cde82016-03-19 01:03:51 +0100990PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
991 const char *format, ...)
992{
993 int res;
994 va_list vargs;
995
996#ifdef HAVE_STDARG_PROTOTYPES
997 va_start(vargs, format);
998#else
999 va_start(vargs);
1000#endif
1001 res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
1002 stack_level, format, vargs);
1003 va_end(vargs);
1004 return res;
1005}
1006
1007
1008int
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001009PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
1010{
1011 int ret;
1012 PyObject *message = PyUnicode_FromString(text);
1013 if (message == NULL)
1014 return -1;
Victor Stinner914cde82016-03-19 01:03:51 +01001015 ret = warn_unicode(category, message, stack_level, NULL);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001016 Py_DECREF(message);
1017 return ret;
1018}
1019
Ezio Melotti42da6632011-03-15 05:18:48 +02001020/* PyErr_Warn is only for backwards compatibility and will be removed.
Christian Heimes33fe8092008-04-13 13:53:33 +00001021 Use PyErr_WarnEx instead. */
1022
1023#undef PyErr_Warn
1024
1025PyAPI_FUNC(int)
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001026PyErr_Warn(PyObject *category, const char *text)
Christian Heimes33fe8092008-04-13 13:53:33 +00001027{
1028 return PyErr_WarnEx(category, text, 1);
1029}
1030
1031/* Warning with explicit origin */
1032int
Victor Stinner14e461d2013-08-26 22:28:21 +02001033PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1034 PyObject *filename, int lineno,
1035 PyObject *module, PyObject *registry)
1036{
1037 PyObject *res;
1038 if (category == NULL)
1039 category = PyExc_RuntimeWarning;
1040 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001041 module, registry, NULL, NULL);
Victor Stinner14e461d2013-08-26 22:28:21 +02001042 if (res == NULL)
1043 return -1;
1044 Py_DECREF(res);
1045 return 0;
1046}
1047
1048int
Christian Heimes33fe8092008-04-13 13:53:33 +00001049PyErr_WarnExplicit(PyObject *category, const char *text,
1050 const char *filename_str, int lineno,
1051 const char *module_str, PyObject *registry)
1052{
Christian Heimes33fe8092008-04-13 13:53:33 +00001053 PyObject *message = PyUnicode_FromString(text);
Victor Stinnercb428f02010-12-27 20:10:36 +00001054 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
Christian Heimes33fe8092008-04-13 13:53:33 +00001055 PyObject *module = NULL;
1056 int ret = -1;
1057
1058 if (message == NULL || filename == NULL)
1059 goto exit;
1060 if (module_str != NULL) {
1061 module = PyUnicode_FromString(module_str);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001062 if (module == NULL)
1063 goto exit;
Christian Heimes33fe8092008-04-13 13:53:33 +00001064 }
1065
Victor Stinner14e461d2013-08-26 22:28:21 +02001066 ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1067 module, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +00001068
1069 exit:
1070 Py_XDECREF(message);
1071 Py_XDECREF(module);
1072 Py_XDECREF(filename);
1073 return ret;
1074}
1075
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001076int
1077PyErr_WarnExplicitFormat(PyObject *category,
1078 const char *filename_str, int lineno,
1079 const char *module_str, PyObject *registry,
1080 const char *format, ...)
1081{
1082 PyObject *message;
1083 PyObject *module = NULL;
1084 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1085 int ret = -1;
1086 va_list vargs;
1087
1088 if (filename == NULL)
1089 goto exit;
1090 if (module_str != NULL) {
1091 module = PyUnicode_FromString(module_str);
1092 if (module == NULL)
1093 goto exit;
1094 }
1095
1096#ifdef HAVE_STDARG_PROTOTYPES
1097 va_start(vargs, format);
1098#else
1099 va_start(vargs);
1100#endif
1101 message = PyUnicode_FromFormatV(format, vargs);
1102 if (message != NULL) {
1103 PyObject *res;
1104 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001105 module, registry, NULL, NULL);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001106 Py_DECREF(message);
1107 if (res != NULL) {
1108 Py_DECREF(res);
1109 ret = 0;
1110 }
1111 }
1112 va_end(vargs);
1113exit:
1114 Py_XDECREF(module);
1115 Py_XDECREF(filename);
1116 return ret;
1117}
1118
Christian Heimes33fe8092008-04-13 13:53:33 +00001119
1120PyDoc_STRVAR(warn_doc,
1121"Issue a warning, or maybe ignore it or raise an exception.");
1122
1123PyDoc_STRVAR(warn_explicit_doc,
1124"Low-level inferface to warnings functionality.");
1125
1126static PyMethodDef warnings_functions[] = {
1127 {"warn", (PyCFunction)warnings_warn, METH_VARARGS | METH_KEYWORDS,
1128 warn_doc},
1129 {"warn_explicit", (PyCFunction)warnings_warn_explicit,
1130 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001131 {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
1132 NULL},
Christian Heimes1a8501c2008-10-02 19:56:01 +00001133 /* XXX(brett.cannon): add showwarning? */
1134 /* XXX(brett.cannon): Reasonable to add formatwarning? */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 {NULL, NULL} /* sentinel */
Christian Heimes33fe8092008-04-13 13:53:33 +00001136};
1137
1138
1139static PyObject *
1140create_filter(PyObject *category, const char *action)
1141{
1142 static PyObject *ignore_str = NULL;
1143 static PyObject *error_str = NULL;
1144 static PyObject *default_str = NULL;
Georg Brandl08be72d2010-10-24 15:11:22 +00001145 static PyObject *always_str = NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001146 PyObject *action_obj = NULL;
1147 PyObject *lineno, *result;
1148
1149 if (!strcmp(action, "ignore")) {
1150 if (ignore_str == NULL) {
1151 ignore_str = PyUnicode_InternFromString("ignore");
1152 if (ignore_str == NULL)
1153 return NULL;
1154 }
1155 action_obj = ignore_str;
1156 }
1157 else if (!strcmp(action, "error")) {
1158 if (error_str == NULL) {
1159 error_str = PyUnicode_InternFromString("error");
1160 if (error_str == NULL)
1161 return NULL;
1162 }
1163 action_obj = error_str;
1164 }
1165 else if (!strcmp(action, "default")) {
1166 if (default_str == NULL) {
1167 default_str = PyUnicode_InternFromString("default");
1168 if (default_str == NULL)
1169 return NULL;
1170 }
1171 action_obj = default_str;
1172 }
Georg Brandl08be72d2010-10-24 15:11:22 +00001173 else if (!strcmp(action, "always")) {
1174 if (always_str == NULL) {
1175 always_str = PyUnicode_InternFromString("always");
1176 if (always_str == NULL)
1177 return NULL;
1178 }
1179 action_obj = always_str;
1180 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001181 else {
1182 Py_FatalError("unknown action");
1183 }
1184
1185 /* This assumes the line number is zero for now. */
1186 lineno = PyLong_FromLong(0);
1187 if (lineno == NULL)
1188 return NULL;
1189 result = PyTuple_Pack(5, action_obj, Py_None, category, Py_None, lineno);
1190 Py_DECREF(lineno);
1191 return result;
1192}
1193
1194static PyObject *
1195init_filters(void)
1196{
Georg Brandl08be72d2010-10-24 15:11:22 +00001197 PyObject *filters = PyList_New(5);
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001198 unsigned int pos = 0; /* Post-incremented in each use. */
1199 unsigned int x;
Georg Brandl08be72d2010-10-24 15:11:22 +00001200 const char *bytes_action, *resource_action;
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001201
Christian Heimes33fe8092008-04-13 13:53:33 +00001202 if (filters == NULL)
1203 return NULL;
1204
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001205 PyList_SET_ITEM(filters, pos++,
1206 create_filter(PyExc_DeprecationWarning, "ignore"));
1207 PyList_SET_ITEM(filters, pos++,
Christian Heimes33fe8092008-04-13 13:53:33 +00001208 create_filter(PyExc_PendingDeprecationWarning, "ignore"));
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001209 PyList_SET_ITEM(filters, pos++,
1210 create_filter(PyExc_ImportWarning, "ignore"));
Christian Heimes33fe8092008-04-13 13:53:33 +00001211 if (Py_BytesWarningFlag > 1)
1212 bytes_action = "error";
1213 else if (Py_BytesWarningFlag)
1214 bytes_action = "default";
1215 else
1216 bytes_action = "ignore";
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001217 PyList_SET_ITEM(filters, pos++, create_filter(PyExc_BytesWarning,
Christian Heimes33fe8092008-04-13 13:53:33 +00001218 bytes_action));
Georg Brandl08be72d2010-10-24 15:11:22 +00001219 /* resource usage warnings are enabled by default in pydebug mode */
1220#ifdef Py_DEBUG
1221 resource_action = "always";
1222#else
1223 resource_action = "ignore";
1224#endif
1225 PyList_SET_ITEM(filters, pos++, create_filter(PyExc_ResourceWarning,
1226 resource_action));
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001227 for (x = 0; x < pos; x += 1) {
1228 if (PyList_GET_ITEM(filters, x) == NULL) {
1229 Py_DECREF(filters);
1230 return NULL;
1231 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001232 }
1233
1234 return filters;
1235}
1236
Martin v. Löwis1a214512008-06-11 05:26:20 +00001237static struct PyModuleDef warningsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 PyModuleDef_HEAD_INIT,
1239 MODULE_NAME,
1240 warnings__doc__,
1241 0,
1242 warnings_functions,
1243 NULL,
1244 NULL,
1245 NULL,
1246 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001247};
1248
Christian Heimes33fe8092008-04-13 13:53:33 +00001249
1250PyMODINIT_FUNC
1251_PyWarnings_Init(void)
1252{
Brett Cannon0759dd62009-04-01 18:13:07 +00001253 PyObject *m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001254
Martin v. Löwis1a214512008-06-11 05:26:20 +00001255 m = PyModule_Create(&warningsmodule);
Christian Heimes33fe8092008-04-13 13:53:33 +00001256 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001257 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001258
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001259 if (_filters == NULL) {
1260 _filters = init_filters();
1261 if (_filters == NULL)
1262 return NULL;
1263 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001264 Py_INCREF(_filters);
1265 if (PyModule_AddObject(m, "filters", _filters) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001266 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001267
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001268 if (_once_registry == NULL) {
1269 _once_registry = PyDict_New();
1270 if (_once_registry == NULL)
1271 return NULL;
1272 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001273 Py_INCREF(_once_registry);
Brett Cannonef0e6c32010-09-04 18:24:04 +00001274 if (PyModule_AddObject(m, "_onceregistry", _once_registry) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001275 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001276
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001277 if (_default_action == NULL) {
1278 _default_action = PyUnicode_FromString("default");
1279 if (_default_action == NULL)
1280 return NULL;
1281 }
1282 Py_INCREF(_default_action);
Brett Cannonef0e6c32010-09-04 18:24:04 +00001283 if (PyModule_AddObject(m, "_defaultaction", _default_action) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001284 return NULL;
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001285
1286 _filters_version = 0;
Martin v. Löwis1a214512008-06-11 05:26:20 +00001287 return m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001288}