blob: 41eaf5310ae66d161c711f32207e4d5363cfbc75 [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 int result;
49
50 if (warnings_str == NULL) {
51 warnings_str = PyUnicode_InternFromString("warnings");
52 if (warnings_str == NULL)
53 return NULL;
54 }
55
Victor Stinnere98445a2016-03-23 00:54:48 +010056 /* don't try to import after the start of the Python finallization */
57 if (try_import && _Py_Finalizing == NULL) {
58 warnings_module = PyImport_Import(warnings_str);
59 if (warnings_module == NULL) {
60 /* Fallback to the C implementation if we cannot get
61 the Python implementation */
62 PyErr_Clear();
Christian Heimes33fe8092008-04-13 13:53:33 +000063 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +010064 }
65 }
66 else {
67 all_modules = PyImport_GetModuleDict();
68 result = PyDict_Contains(all_modules, warnings_str);
69 if (result == -1 || result == 0)
70 return NULL;
71
72 warnings_module = PyDict_GetItem(all_modules, warnings_str);
73 Py_INCREF(warnings_module);
74 }
75
76 if (!PyObject_HasAttrString(warnings_module, attr)) {
77 Py_DECREF(warnings_module);
78 return NULL;
79 }
80
81 obj = PyObject_GetAttrString(warnings_module, attr);
82 Py_DECREF(warnings_module);
83 return obj;
Christian Heimes33fe8092008-04-13 13:53:33 +000084}
85
86
Neal Norwitz32dde222008-04-15 06:43:13 +000087static PyObject *
Christian Heimes33fe8092008-04-13 13:53:33 +000088get_once_registry(void)
89{
90 PyObject *registry;
91
Victor Stinnere98445a2016-03-23 00:54:48 +010092 registry = get_warnings_attr("onceregistry", 0);
Christian Heimes33fe8092008-04-13 13:53:33 +000093 if (registry == NULL) {
94 if (PyErr_Occurred())
95 return NULL;
96 return _once_registry;
97 }
98 Py_DECREF(_once_registry);
99 _once_registry = registry;
100 return registry;
101}
102
103
Brett Cannon0759dd62009-04-01 18:13:07 +0000104static PyObject *
105get_default_action(void)
106{
107 PyObject *default_action;
108
Victor Stinnere98445a2016-03-23 00:54:48 +0100109 default_action = get_warnings_attr("defaultaction", 0);
Brett Cannon0759dd62009-04-01 18:13:07 +0000110 if (default_action == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 if (PyErr_Occurred()) {
112 return NULL;
113 }
114 return _default_action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000115 }
116
117 Py_DECREF(_default_action);
118 _default_action = default_action;
119 return default_action;
120}
121
122
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400123/* The item is a new reference. */
Victor Stinnera4c704b2013-10-29 23:43:41 +0100124static PyObject*
Christian Heimes33fe8092008-04-13 13:53:33 +0000125get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
126 PyObject *module, PyObject **item)
127{
Brett Cannon0759dd62009-04-01 18:13:07 +0000128 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000129 Py_ssize_t i;
130 PyObject *warnings_filters;
131
Victor Stinnere98445a2016-03-23 00:54:48 +0100132 warnings_filters = get_warnings_attr("filters", 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000133 if (warnings_filters == NULL) {
134 if (PyErr_Occurred())
135 return NULL;
136 }
137 else {
138 Py_DECREF(_filters);
139 _filters = warnings_filters;
140 }
141
Victor Stinner7d79b8b2010-05-19 20:40:50 +0000142 if (_filters == NULL || !PyList_Check(_filters)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000143 PyErr_SetString(PyExc_ValueError,
144 MODULE_NAME ".filters must be a list");
145 return NULL;
146 }
147
148 /* _filters could change while we are iterating over it. */
149 for (i = 0; i < PyList_GET_SIZE(_filters); i++) {
150 PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
151 Py_ssize_t ln;
152 int is_subclass, good_msg, good_mod;
153
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400154 tmp_item = PyList_GET_ITEM(_filters, i);
155 if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000156 PyErr_Format(PyExc_ValueError,
157 MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
158 return NULL;
159 }
160
161 /* Python code: action, msg, cat, mod, ln = item */
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400162 Py_INCREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000163 action = PyTuple_GET_ITEM(tmp_item, 0);
164 msg = PyTuple_GET_ITEM(tmp_item, 1);
165 cat = PyTuple_GET_ITEM(tmp_item, 2);
166 mod = PyTuple_GET_ITEM(tmp_item, 3);
167 ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
168
169 good_msg = check_matched(msg, text);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400170 if (good_msg == -1) {
171 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100172 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400173 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100174
Christian Heimes33fe8092008-04-13 13:53:33 +0000175 good_mod = check_matched(mod, module);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400176 if (good_mod == -1) {
177 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100178 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400179 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100180
Christian Heimes33fe8092008-04-13 13:53:33 +0000181 is_subclass = PyObject_IsSubclass(category, cat);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400182 if (is_subclass == -1) {
183 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100184 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400185 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100186
Christian Heimes33fe8092008-04-13 13:53:33 +0000187 ln = PyLong_AsSsize_t(ln_obj);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400188 if (ln == -1 && PyErr_Occurred()) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400189 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000190 return NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400191 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000192
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400193 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
194 *item = tmp_item;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100195 return action;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400196 }
197
198 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000199 }
200
Brett Cannon0759dd62009-04-01 18:13:07 +0000201 action = get_default_action();
202 if (action != NULL) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400203 Py_INCREF(Py_None);
204 *item = Py_None;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100205 return action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000206 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000207
208 PyErr_SetString(PyExc_ValueError,
Brett Cannon0759dd62009-04-01 18:13:07 +0000209 MODULE_NAME ".defaultaction not found");
Christian Heimes33fe8092008-04-13 13:53:33 +0000210 return NULL;
211}
212
Brett Cannon0759dd62009-04-01 18:13:07 +0000213
Christian Heimes33fe8092008-04-13 13:53:33 +0000214static int
215already_warned(PyObject *registry, PyObject *key, int should_set)
216{
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200217 PyObject *version_obj, *already_warned;
218 _Py_IDENTIFIER(version);
Christian Heimes33fe8092008-04-13 13:53:33 +0000219
220 if (key == NULL)
221 return -1;
222
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200223 version_obj = _PyDict_GetItemId(registry, &PyId_version);
224 if (version_obj == NULL
225 || !PyLong_CheckExact(version_obj)
226 || PyLong_AsLong(version_obj) != _filters_version) {
227 PyDict_Clear(registry);
228 version_obj = PyLong_FromLong(_filters_version);
229 if (version_obj == NULL)
230 return -1;
231 if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
232 Py_DECREF(version_obj);
233 return -1;
234 }
235 Py_DECREF(version_obj);
236 }
237 else {
238 already_warned = PyDict_GetItem(registry, key);
239 if (already_warned != NULL) {
240 int rc = PyObject_IsTrue(already_warned);
241 if (rc != 0)
242 return rc;
243 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000244 }
245
246 /* This warning wasn't found in the registry, set it. */
247 if (should_set)
248 return PyDict_SetItem(registry, key, Py_True);
249 return 0;
250}
251
252/* New reference. */
253static PyObject *
254normalize_module(PyObject *filename)
255{
256 PyObject *module;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100257 int kind;
258 void *data;
Christian Heimes33fe8092008-04-13 13:53:33 +0000259 Py_ssize_t len;
260
Victor Stinner9e30aa52011-11-21 02:49:52 +0100261 len = PyUnicode_GetLength(filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000262 if (len < 0)
263 return NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100264
265 if (len == 0)
266 return PyUnicode_FromString("<unknown>");
267
268 kind = PyUnicode_KIND(filename);
269 data = PyUnicode_DATA(filename);
270
271 /* if filename.endswith(".py"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000272 if (len >= 3 &&
Victor Stinnera4c704b2013-10-29 23:43:41 +0100273 PyUnicode_READ(kind, data, len-3) == '.' &&
274 PyUnicode_READ(kind, data, len-2) == 'p' &&
275 PyUnicode_READ(kind, data, len-1) == 'y')
276 {
Victor Stinner9e30aa52011-11-21 02:49:52 +0100277 module = PyUnicode_Substring(filename, 0, len-3);
Christian Heimes33fe8092008-04-13 13:53:33 +0000278 }
279 else {
280 module = filename;
281 Py_INCREF(module);
282 }
283 return module;
284}
285
286static int
287update_registry(PyObject *registry, PyObject *text, PyObject *category,
288 int add_zero)
289{
290 PyObject *altkey, *zero = NULL;
291 int rc;
292
293 if (add_zero) {
294 zero = PyLong_FromLong(0);
295 if (zero == NULL)
296 return -1;
297 altkey = PyTuple_Pack(3, text, category, zero);
298 }
299 else
300 altkey = PyTuple_Pack(2, text, category);
301
302 rc = already_warned(registry, altkey, 1);
303 Py_XDECREF(zero);
304 Py_XDECREF(altkey);
305 return rc;
306}
307
308static void
Victor Stinner914cde82016-03-19 01:03:51 +0100309show_warning(PyObject *filename, int lineno, PyObject *text,
310 PyObject *category, PyObject *sourceline)
Christian Heimes33fe8092008-04-13 13:53:33 +0000311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 PyObject *f_stderr;
313 PyObject *name;
Christian Heimes33fe8092008-04-13 13:53:33 +0000314 char lineno_str[128];
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200315 _Py_IDENTIFIER(__name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000316
317 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
318
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200319 name = _PyObject_GetAttrId(category, &PyId___name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000320 if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100321 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000322
Victor Stinnerbd303c12013-11-07 23:07:29 +0100323 f_stderr = _PySys_GetObjectId(&PyId_stderr);
Christian Heimes33fe8092008-04-13 13:53:33 +0000324 if (f_stderr == NULL) {
325 fprintf(stderr, "lost sys.stderr\n");
Victor Stinnerae233ea2013-10-31 14:51:38 +0100326 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000327 }
328
329 /* Print "filename:lineno: category: text\n" */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100330 if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
331 goto error;
332 if (PyFile_WriteString(lineno_str, f_stderr) < 0)
333 goto error;
334 if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
335 goto error;
336 if (PyFile_WriteString(": ", f_stderr) < 0)
337 goto error;
338 if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
339 goto error;
340 if (PyFile_WriteString("\n", f_stderr) < 0)
341 goto error;
342 Py_CLEAR(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000343
344 /* Print " source_line\n" */
Christian Heimes33fe8092008-04-13 13:53:33 +0000345 if (sourceline) {
Victor Stinnera4c704b2013-10-29 23:43:41 +0100346 int kind;
347 void *data;
348 Py_ssize_t i, len;
349 Py_UCS4 ch;
350 PyObject *truncated;
Christian Heimes33fe8092008-04-13 13:53:33 +0000351
Victor Stinnera4c704b2013-10-29 23:43:41 +0100352 if (PyUnicode_READY(sourceline) < 1)
353 goto error;
354
355 kind = PyUnicode_KIND(sourceline);
356 data = PyUnicode_DATA(sourceline);
357 len = PyUnicode_GET_LENGTH(sourceline);
358 for (i=0; i<len; i++) {
359 ch = PyUnicode_READ(kind, data, i);
360 if (ch != ' ' && ch != '\t' && ch != '\014')
361 break;
362 }
363
364 truncated = PyUnicode_Substring(sourceline, i, len);
365 if (truncated == NULL)
366 goto error;
367
368 PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
369 Py_DECREF(truncated);
Christian Heimes33fe8092008-04-13 13:53:33 +0000370 PyFile_WriteString("\n", f_stderr);
371 }
Victor Stinner78e2c982013-07-16 01:54:37 +0200372 else {
373 _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
374 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100375
376error:
Victor Stinnerae233ea2013-10-31 14:51:38 +0100377 Py_XDECREF(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000378 PyErr_Clear();
379}
380
Victor Stinner1231a462016-03-19 00:47:17 +0100381static int
382call_show_warning(PyObject *category, PyObject *text, PyObject *message,
383 PyObject *filename, int lineno, PyObject *lineno_obj,
Victor Stinner914cde82016-03-19 01:03:51 +0100384 PyObject *sourceline, PyObject *source)
Victor Stinner1231a462016-03-19 00:47:17 +0100385{
386 PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
387
Victor Stinnere98445a2016-03-23 00:54:48 +0100388 /* If the source parameter is set, try to get the Python implementation.
389 The Python implementation is able to log the traceback where the source
390 was allocated, whereas the C implementation doesnt. */
391 show_fn = get_warnings_attr("_showwarnmsg", source != NULL);
Victor Stinner1231a462016-03-19 00:47:17 +0100392 if (show_fn == NULL) {
393 if (PyErr_Occurred())
394 return -1;
395 show_warning(filename, lineno, text, category, sourceline);
396 return 0;
397 }
398
399 if (!PyCallable_Check(show_fn)) {
400 PyErr_SetString(PyExc_TypeError,
401 "warnings._showwarnmsg() must be set to a callable");
402 goto error;
403 }
404
Victor Stinnere98445a2016-03-23 00:54:48 +0100405 warnmsg_cls = get_warnings_attr("WarningMessage", 0);
Victor Stinner1231a462016-03-19 00:47:17 +0100406 if (warnmsg_cls == NULL) {
407 PyErr_SetString(PyExc_RuntimeError,
408 "unable to get warnings.WarningMessage");
409 goto error;
410 }
411
412 msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
Victor Stinner914cde82016-03-19 01:03:51 +0100413 filename, lineno_obj, Py_None, Py_None, source,
Victor Stinner1231a462016-03-19 00:47:17 +0100414 NULL);
415 Py_DECREF(warnmsg_cls);
416 if (msg == NULL)
417 goto error;
418
419 res = PyObject_CallFunctionObjArgs(show_fn, msg, NULL);
420 Py_DECREF(show_fn);
421 Py_DECREF(msg);
422
423 if (res == NULL)
424 return -1;
425
426 Py_DECREF(res);
427 return 0;
428
429error:
430 Py_XDECREF(show_fn);
431 return -1;
432}
433
Christian Heimes33fe8092008-04-13 13:53:33 +0000434static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435warn_explicit(PyObject *category, PyObject *message,
Christian Heimes33fe8092008-04-13 13:53:33 +0000436 PyObject *filename, int lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100437 PyObject *module, PyObject *registry, PyObject *sourceline,
438 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000439{
440 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400441 PyObject *item = NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100442 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000443 int rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100445 /* module can be None if a warning is emitted late during Python shutdown.
446 In this case, the Python warnings module was probably unloaded, filters
447 are no more available to choose as action. It is safer to ignore the
448 warning and do nothing. */
449 if (module == Py_None)
450 Py_RETURN_NONE;
451
Brett Cannondb734912008-06-27 00:52:15 +0000452 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
453 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");
454 return NULL;
455 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000456
457 /* Normalize module. */
458 if (module == NULL) {
459 module = normalize_module(filename);
460 if (module == NULL)
461 return NULL;
462 }
463 else
464 Py_INCREF(module);
465
466 /* Normalize message. */
467 Py_INCREF(message); /* DECREF'ed in cleanup. */
468 rc = PyObject_IsInstance(message, PyExc_Warning);
469 if (rc == -1) {
470 goto cleanup;
471 }
472 if (rc == 1) {
473 text = PyObject_Str(message);
Hirokazu Yamamoto1c0c0032009-07-17 06:55:42 +0000474 if (text == NULL)
475 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000476 category = (PyObject*)message->ob_type;
477 }
478 else {
479 text = message;
480 message = PyObject_CallFunction(category, "O", message);
Brett Cannondb734912008-06-27 00:52:15 +0000481 if (message == NULL)
482 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000483 }
484
485 lineno_obj = PyLong_FromLong(lineno);
486 if (lineno_obj == NULL)
487 goto cleanup;
488
489 /* Create key. */
490 key = PyTuple_Pack(3, text, category, lineno_obj);
491 if (key == NULL)
492 goto cleanup;
493
Brett Cannondb734912008-06-27 00:52:15 +0000494 if ((registry != NULL) && (registry != Py_None)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000495 rc = already_warned(registry, key, 0);
496 if (rc == -1)
497 goto cleanup;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 else if (rc == 1)
Christian Heimes33fe8092008-04-13 13:53:33 +0000499 goto return_none;
500 /* Else this warning hasn't been generated before. */
501 }
502
503 action = get_filter(category, text, lineno, module, &item);
504 if (action == NULL)
505 goto cleanup;
506
Victor Stinnera4c704b2013-10-29 23:43:41 +0100507 if (PyUnicode_CompareWithASCIIString(action, "error") == 0) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000508 PyErr_SetObject(category, message);
509 goto cleanup;
510 }
511
512 /* Store in the registry that we've been here, *except* when the action
513 is "always". */
514 rc = 0;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100515 if (PyUnicode_CompareWithASCIIString(action, "always") != 0) {
Brett Cannondb734912008-06-27 00:52:15 +0000516 if (registry != NULL && registry != Py_None &&
517 PyDict_SetItem(registry, key, Py_True) < 0)
Christian Heimes33fe8092008-04-13 13:53:33 +0000518 goto cleanup;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100519 else if (PyUnicode_CompareWithASCIIString(action, "ignore") == 0)
Christian Heimes33fe8092008-04-13 13:53:33 +0000520 goto return_none;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100521 else if (PyUnicode_CompareWithASCIIString(action, "once") == 0) {
Brett Cannondb734912008-06-27 00:52:15 +0000522 if (registry == NULL || registry == Py_None) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000523 registry = get_once_registry();
524 if (registry == NULL)
525 goto cleanup;
526 }
527 /* _once_registry[(text, category)] = 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000529 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100530 else if (PyUnicode_CompareWithASCIIString(action, "module") == 0) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000531 /* registry[(text, category, 0)] = 1 */
Brett Cannondb734912008-06-27 00:52:15 +0000532 if (registry != NULL && registry != Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000534 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100535 else if (PyUnicode_CompareWithASCIIString(action, "default") != 0) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000536 PyErr_Format(PyExc_RuntimeError,
Victor Stinnera4c704b2013-10-29 23:43:41 +0100537 "Unrecognized action (%R) in warnings.filters:\n %R",
538 action, item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000539 goto cleanup;
540 }
541 }
542
Christian Heimes1a8501c2008-10-02 19:56:01 +0000543 if (rc == 1) /* Already warned for this module. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000544 goto return_none;
545 if (rc == 0) {
Victor Stinner1231a462016-03-19 00:47:17 +0100546 if (call_show_warning(category, text, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100547 lineno_obj, sourceline, source) < 0)
Victor Stinner1231a462016-03-19 00:47:17 +0100548 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000549 }
550 else /* if (rc == -1) */
551 goto cleanup;
552
553 return_none:
554 result = Py_None;
555 Py_INCREF(result);
556
557 cleanup:
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400558 Py_XDECREF(item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000559 Py_XDECREF(key);
560 Py_XDECREF(text);
561 Py_XDECREF(lineno_obj);
562 Py_DECREF(module);
Brett Cannondb734912008-06-27 00:52:15 +0000563 Py_XDECREF(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000564 return result; /* Py_None or NULL. */
565}
566
Larry Hastings714e4932015-09-06 00:39:37 -0700567static int
568is_internal_frame(PyFrameObject *frame)
569{
570 static PyObject *importlib_string = NULL;
571 static PyObject *bootstrap_string = NULL;
572 PyObject *filename;
573 int contains;
574
575 if (importlib_string == NULL) {
576 importlib_string = PyUnicode_FromString("importlib");
577 if (importlib_string == NULL) {
578 return 0;
579 }
580
581 bootstrap_string = PyUnicode_FromString("_bootstrap");
582 if (bootstrap_string == NULL) {
583 Py_DECREF(importlib_string);
584 return 0;
585 }
586 Py_INCREF(importlib_string);
587 Py_INCREF(bootstrap_string);
588 }
589
590 if (frame == NULL || frame->f_code == NULL ||
591 frame->f_code->co_filename == NULL) {
592 return 0;
593 }
594 filename = frame->f_code->co_filename;
595 if (!PyUnicode_Check(filename)) {
596 return 0;
597 }
598 contains = PyUnicode_Contains(filename, importlib_string);
599 if (contains < 0) {
600 return 0;
601 }
602 else if (contains > 0) {
603 contains = PyUnicode_Contains(filename, bootstrap_string);
604 if (contains < 0) {
605 return 0;
606 }
607 else if (contains > 0) {
608 return 1;
609 }
610 }
611
612 return 0;
613}
614
615static PyFrameObject *
616next_external_frame(PyFrameObject *frame)
617{
618 do {
619 frame = frame->f_back;
620 } while (frame != NULL && is_internal_frame(frame));
621
622 return frame;
623}
624
Christian Heimes33fe8092008-04-13 13:53:33 +0000625/* filename, module, and registry are new refs, globals is borrowed */
626/* Returns 0 on error (no new refs), 1 on success */
627static int
628setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
629 PyObject **module, PyObject **registry)
630{
631 PyObject *globals;
632
633 /* Setup globals and lineno. */
634 PyFrameObject *f = PyThreadState_GET()->frame;
Larry Hastings714e4932015-09-06 00:39:37 -0700635 // Stack level comparisons to Python code is off by one as there is no
636 // warnings-related stack level to avoid.
637 if (stack_level <= 0 || is_internal_frame(f)) {
638 while (--stack_level > 0 && f != NULL) {
639 f = f->f_back;
640 }
641 }
642 else {
643 while (--stack_level > 0 && f != NULL) {
644 f = next_external_frame(f);
645 }
646 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000647
648 if (f == NULL) {
649 globals = PyThreadState_Get()->interp->sysdict;
650 *lineno = 1;
651 }
652 else {
653 globals = f->f_globals;
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000654 *lineno = PyFrame_GetLineNumber(f);
Christian Heimes33fe8092008-04-13 13:53:33 +0000655 }
656
657 *module = NULL;
658
659 /* Setup registry. */
660 assert(globals != NULL);
661 assert(PyDict_Check(globals));
662 *registry = PyDict_GetItemString(globals, "__warningregistry__");
663 if (*registry == NULL) {
664 int rc;
665
666 *registry = PyDict_New();
667 if (*registry == NULL)
668 return 0;
669
670 rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
671 if (rc < 0)
672 goto handle_error;
673 }
674 else
675 Py_INCREF(*registry);
676
677 /* Setup module. */
678 *module = PyDict_GetItemString(globals, "__name__");
679 if (*module == NULL) {
680 *module = PyUnicode_FromString("<string>");
681 if (*module == NULL)
682 goto handle_error;
683 }
684 else
685 Py_INCREF(*module);
686
687 /* Setup filename. */
688 *filename = PyDict_GetItemString(globals, "__file__");
Victor Stinner8b0508e2011-07-04 02:43:09 +0200689 if (*filename != NULL && PyUnicode_Check(*filename)) {
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200690 Py_ssize_t len;
691 int kind;
692 void *data;
693
694 if (PyUnicode_READY(*filename))
695 goto handle_error;
696
Victor Stinner9e30aa52011-11-21 02:49:52 +0100697 len = PyUnicode_GetLength(*filename);
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200698 kind = PyUnicode_KIND(*filename);
699 data = PyUnicode_DATA(*filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000700
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500701#define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0)
Brett Cannonf299abd2015-04-13 14:21:02 -0400702 /* if filename.lower().endswith(".pyc"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000703 if (len >= 4 &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200704 PyUnicode_READ(kind, data, len-4) == '.' &&
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500705 ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' &&
706 ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' &&
Brett Cannonf299abd2015-04-13 14:21:02 -0400707 ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c')
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000708 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200709 *filename = PyUnicode_Substring(*filename, 0,
710 PyUnicode_GET_LENGTH(*filename)-1);
Victor Stinner2e5f1172010-08-08 22:12:45 +0000711 if (*filename == NULL)
712 goto handle_error;
713 }
714 else
Christian Heimes33fe8092008-04-13 13:53:33 +0000715 Py_INCREF(*filename);
716 }
717 else {
Benjamin Petersonbb4a7472011-07-04 22:27:16 -0500718 *filename = NULL;
Victor Stinner856f45f2013-10-30 00:04:59 +0100719 if (*module != Py_None && PyUnicode_CompareWithASCIIString(*module, "__main__") == 0) {
Victor Stinnerbd303c12013-11-07 23:07:29 +0100720 PyObject *argv = _PySys_GetObjectId(&PyId_argv);
Victor Stinnerce5f4fb2013-10-28 18:47:22 +0100721 /* PyList_Check() is needed because sys.argv is set to None during
722 Python finalization */
723 if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) {
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000724 int is_true;
Christian Heimes33fe8092008-04-13 13:53:33 +0000725 *filename = PyList_GetItem(argv, 0);
726 Py_INCREF(*filename);
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000727 /* If sys.argv[0] is false, then use '__main__'. */
728 is_true = PyObject_IsTrue(*filename);
729 if (is_true < 0) {
730 Py_DECREF(*filename);
731 goto handle_error;
732 }
733 else if (!is_true) {
Serhiy Storchaka5a57ade2015-12-24 10:35:59 +0200734 Py_SETREF(*filename, PyUnicode_FromString("__main__"));
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000735 if (*filename == NULL)
736 goto handle_error;
737 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000738 }
739 else {
740 /* embedded interpreters don't have sys.argv, see bug #839151 */
741 *filename = PyUnicode_FromString("__main__");
Victor Stinner856f45f2013-10-30 00:04:59 +0100742 if (*filename == NULL)
743 goto handle_error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000744 }
745 }
746 if (*filename == NULL) {
747 *filename = *module;
748 Py_INCREF(*filename);
749 }
750 }
751
752 return 1;
753
754 handle_error:
755 /* filename not XDECREF'ed here as there is no way to jump here with a
756 dangling reference. */
757 Py_XDECREF(*registry);
758 Py_XDECREF(*module);
759 return 0;
760}
761
762static PyObject *
763get_category(PyObject *message, PyObject *category)
764{
765 int rc;
766
767 /* Get category. */
768 rc = PyObject_IsInstance(message, PyExc_Warning);
769 if (rc == -1)
770 return NULL;
771
772 if (rc == 1)
773 category = (PyObject*)message->ob_type;
Berker Peksagd8089e02014-07-11 19:50:25 +0300774 else if (category == NULL || category == Py_None)
Christian Heimes33fe8092008-04-13 13:53:33 +0000775 category = PyExc_UserWarning;
776
777 /* Validate category. */
778 rc = PyObject_IsSubclass(category, PyExc_Warning);
Berker Peksagd8089e02014-07-11 19:50:25 +0300779 /* category is not a subclass of PyExc_Warning or
780 PyObject_IsSubclass raised an error */
781 if (rc == -1 || rc == 0) {
782 PyErr_Format(PyExc_TypeError,
783 "category must be a Warning subclass, not '%s'",
784 Py_TYPE(category)->tp_name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000785 return NULL;
786 }
787
788 return category;
789}
790
791static PyObject *
Victor Stinner914cde82016-03-19 01:03:51 +0100792do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
793 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000794{
795 PyObject *filename, *module, *registry, *res;
796 int lineno;
797
798 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
799 return NULL;
800
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100801 res = warn_explicit(category, message, filename, lineno, module, registry,
Victor Stinner914cde82016-03-19 01:03:51 +0100802 NULL, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000803 Py_DECREF(filename);
804 Py_DECREF(registry);
805 Py_DECREF(module);
806 return res;
807}
808
809static PyObject *
810warnings_warn(PyObject *self, PyObject *args, PyObject *kwds)
811{
Victor Stinnere19558a2016-03-23 00:28:08 +0100812 static char *kw_list[] = {"message", "category", "stacklevel",
813 "source", NULL};
814 PyObject *message, *category = NULL, *source = NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000815 Py_ssize_t stack_level = 1;
816
Victor Stinnere19558a2016-03-23 00:28:08 +0100817 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OnO:warn", kw_list,
818 &message, &category, &stack_level, &source))
Christian Heimes33fe8092008-04-13 13:53:33 +0000819 return NULL;
820
821 category = get_category(message, category);
822 if (category == NULL)
823 return NULL;
Victor Stinnere19558a2016-03-23 00:28:08 +0100824 return do_warn(message, category, stack_level, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000825}
826
827static PyObject *
828warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
829{
830 static char *kwd_list[] = {"message", "category", "filename", "lineno",
Victor Stinner914cde82016-03-19 01:03:51 +0100831 "module", "registry", "module_globals",
832 "source", 0};
Christian Heimes33fe8092008-04-13 13:53:33 +0000833 PyObject *message;
834 PyObject *category;
835 PyObject *filename;
836 int lineno;
837 PyObject *module = NULL;
838 PyObject *registry = NULL;
839 PyObject *module_globals = NULL;
Victor Stinner914cde82016-03-19 01:03:51 +0100840 PyObject *sourceobj = NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000841
Victor Stinner914cde82016-03-19 01:03:51 +0100842 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
Christian Heimes33fe8092008-04-13 13:53:33 +0000843 kwd_list, &message, &category, &filename, &lineno, &module,
Victor Stinner914cde82016-03-19 01:03:51 +0100844 &registry, &module_globals, &sourceobj))
Christian Heimes33fe8092008-04-13 13:53:33 +0000845 return NULL;
846
847 if (module_globals) {
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200848 _Py_IDENTIFIER(get_source);
849 _Py_IDENTIFIER(splitlines);
850 PyObject *tmp;
Christian Heimes33fe8092008-04-13 13:53:33 +0000851 PyObject *loader;
852 PyObject *module_name;
853 PyObject *source;
854 PyObject *source_list;
855 PyObject *source_line;
856 PyObject *returned;
857
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200858 if ((tmp = _PyUnicode_FromId(&PyId_get_source)) == NULL)
859 return NULL;
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200860 if ((tmp = _PyUnicode_FromId(&PyId_splitlines)) == NULL)
861 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000862
863 /* Check/get the requisite pieces needed for the loader. */
864 loader = PyDict_GetItemString(module_globals, "__loader__");
865 module_name = PyDict_GetItemString(module_globals, "__name__");
866
867 if (loader == NULL || module_name == NULL)
868 goto standard_call;
869
870 /* Make sure the loader implements the optional get_source() method. */
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200871 if (!_PyObject_HasAttrId(loader, &PyId_get_source))
Christian Heimes33fe8092008-04-13 13:53:33 +0000872 goto standard_call;
873 /* Call get_source() to get the source code. */
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200874 source = PyObject_CallMethodObjArgs(loader, PyId_get_source.object,
875 module_name, NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000876 if (!source)
877 return NULL;
878 else if (source == Py_None) {
879 Py_DECREF(Py_None);
880 goto standard_call;
881 }
882
883 /* Split the source into lines. */
Victor Stinner9e30aa52011-11-21 02:49:52 +0100884 source_list = PyObject_CallMethodObjArgs(source,
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200885 PyId_splitlines.object,
886 NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000887 Py_DECREF(source);
888 if (!source_list)
889 return NULL;
890
891 /* Get the source line. */
892 source_line = PyList_GetItem(source_list, lineno-1);
893 if (!source_line) {
894 Py_DECREF(source_list);
895 return NULL;
896 }
897
898 /* Handle the warning. */
899 returned = warn_explicit(category, message, filename, lineno, module,
Victor Stinner914cde82016-03-19 01:03:51 +0100900 registry, source_line, sourceobj);
Christian Heimes33fe8092008-04-13 13:53:33 +0000901 Py_DECREF(source_list);
902 return returned;
903 }
904
905 standard_call:
906 return warn_explicit(category, message, filename, lineno, module,
Victor Stinner914cde82016-03-19 01:03:51 +0100907 registry, NULL, sourceobj);
Christian Heimes33fe8092008-04-13 13:53:33 +0000908}
909
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200910static PyObject *
911warnings_filters_mutated(PyObject *self, PyObject *args)
912{
913 _filters_version++;
914 Py_RETURN_NONE;
915}
916
Christian Heimes33fe8092008-04-13 13:53:33 +0000917
918/* Function to issue a warning message; may raise an exception. */
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000919
920static int
921warn_unicode(PyObject *category, PyObject *message,
Victor Stinner914cde82016-03-19 01:03:51 +0100922 Py_ssize_t stack_level, PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000923{
924 PyObject *res;
Christian Heimes33fe8092008-04-13 13:53:33 +0000925
926 if (category == NULL)
927 category = PyExc_RuntimeWarning;
928
Victor Stinner914cde82016-03-19 01:03:51 +0100929 res = do_warn(message, category, stack_level, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000930 if (res == NULL)
931 return -1;
932 Py_DECREF(res);
933
934 return 0;
935}
936
Victor Stinner914cde82016-03-19 01:03:51 +0100937static int
938_PyErr_WarnFormatV(PyObject *source,
939 PyObject *category, Py_ssize_t stack_level,
940 const char *format, va_list vargs)
941{
942 PyObject *message;
943 int res;
944
945 message = PyUnicode_FromFormatV(format, vargs);
946 if (message == NULL)
947 return -1;
948
949 res = warn_unicode(category, message, stack_level, source);
950 Py_DECREF(message);
951 return res;
952}
953
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000954int
955PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
956 const char *format, ...)
957{
Victor Stinner914cde82016-03-19 01:03:51 +0100958 int res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000959 va_list vargs;
960
961#ifdef HAVE_STDARG_PROTOTYPES
962 va_start(vargs, format);
963#else
964 va_start(vargs);
965#endif
Victor Stinner914cde82016-03-19 01:03:51 +0100966 res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000967 va_end(vargs);
Victor Stinner914cde82016-03-19 01:03:51 +0100968 return res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000969}
970
971int
Victor Stinner914cde82016-03-19 01:03:51 +0100972PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
973 const char *format, ...)
974{
975 int res;
976 va_list vargs;
977
978#ifdef HAVE_STDARG_PROTOTYPES
979 va_start(vargs, format);
980#else
981 va_start(vargs);
982#endif
983 res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
984 stack_level, format, vargs);
985 va_end(vargs);
986 return res;
987}
988
989
990int
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000991PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
992{
993 int ret;
994 PyObject *message = PyUnicode_FromString(text);
995 if (message == NULL)
996 return -1;
Victor Stinner914cde82016-03-19 01:03:51 +0100997 ret = warn_unicode(category, message, stack_level, NULL);
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000998 Py_DECREF(message);
999 return ret;
1000}
1001
Ezio Melotti42da6632011-03-15 05:18:48 +02001002/* PyErr_Warn is only for backwards compatibility and will be removed.
Christian Heimes33fe8092008-04-13 13:53:33 +00001003 Use PyErr_WarnEx instead. */
1004
1005#undef PyErr_Warn
1006
1007PyAPI_FUNC(int)
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001008PyErr_Warn(PyObject *category, const char *text)
Christian Heimes33fe8092008-04-13 13:53:33 +00001009{
1010 return PyErr_WarnEx(category, text, 1);
1011}
1012
1013/* Warning with explicit origin */
1014int
Victor Stinner14e461d2013-08-26 22:28:21 +02001015PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1016 PyObject *filename, int lineno,
1017 PyObject *module, PyObject *registry)
1018{
1019 PyObject *res;
1020 if (category == NULL)
1021 category = PyExc_RuntimeWarning;
1022 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001023 module, registry, NULL, NULL);
Victor Stinner14e461d2013-08-26 22:28:21 +02001024 if (res == NULL)
1025 return -1;
1026 Py_DECREF(res);
1027 return 0;
1028}
1029
1030int
Christian Heimes33fe8092008-04-13 13:53:33 +00001031PyErr_WarnExplicit(PyObject *category, const char *text,
1032 const char *filename_str, int lineno,
1033 const char *module_str, PyObject *registry)
1034{
Christian Heimes33fe8092008-04-13 13:53:33 +00001035 PyObject *message = PyUnicode_FromString(text);
Victor Stinnercb428f02010-12-27 20:10:36 +00001036 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
Christian Heimes33fe8092008-04-13 13:53:33 +00001037 PyObject *module = NULL;
1038 int ret = -1;
1039
1040 if (message == NULL || filename == NULL)
1041 goto exit;
1042 if (module_str != NULL) {
1043 module = PyUnicode_FromString(module_str);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001044 if (module == NULL)
1045 goto exit;
Christian Heimes33fe8092008-04-13 13:53:33 +00001046 }
1047
Victor Stinner14e461d2013-08-26 22:28:21 +02001048 ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1049 module, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +00001050
1051 exit:
1052 Py_XDECREF(message);
1053 Py_XDECREF(module);
1054 Py_XDECREF(filename);
1055 return ret;
1056}
1057
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001058int
1059PyErr_WarnExplicitFormat(PyObject *category,
1060 const char *filename_str, int lineno,
1061 const char *module_str, PyObject *registry,
1062 const char *format, ...)
1063{
1064 PyObject *message;
1065 PyObject *module = NULL;
1066 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1067 int ret = -1;
1068 va_list vargs;
1069
1070 if (filename == NULL)
1071 goto exit;
1072 if (module_str != NULL) {
1073 module = PyUnicode_FromString(module_str);
1074 if (module == NULL)
1075 goto exit;
1076 }
1077
1078#ifdef HAVE_STDARG_PROTOTYPES
1079 va_start(vargs, format);
1080#else
1081 va_start(vargs);
1082#endif
1083 message = PyUnicode_FromFormatV(format, vargs);
1084 if (message != NULL) {
1085 PyObject *res;
1086 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001087 module, registry, NULL, NULL);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001088 Py_DECREF(message);
1089 if (res != NULL) {
1090 Py_DECREF(res);
1091 ret = 0;
1092 }
1093 }
1094 va_end(vargs);
1095exit:
1096 Py_XDECREF(module);
1097 Py_XDECREF(filename);
1098 return ret;
1099}
1100
Christian Heimes33fe8092008-04-13 13:53:33 +00001101
1102PyDoc_STRVAR(warn_doc,
1103"Issue a warning, or maybe ignore it or raise an exception.");
1104
1105PyDoc_STRVAR(warn_explicit_doc,
1106"Low-level inferface to warnings functionality.");
1107
1108static PyMethodDef warnings_functions[] = {
1109 {"warn", (PyCFunction)warnings_warn, METH_VARARGS | METH_KEYWORDS,
1110 warn_doc},
1111 {"warn_explicit", (PyCFunction)warnings_warn_explicit,
1112 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001113 {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
1114 NULL},
Christian Heimes1a8501c2008-10-02 19:56:01 +00001115 /* XXX(brett.cannon): add showwarning? */
1116 /* XXX(brett.cannon): Reasonable to add formatwarning? */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 {NULL, NULL} /* sentinel */
Christian Heimes33fe8092008-04-13 13:53:33 +00001118};
1119
1120
1121static PyObject *
1122create_filter(PyObject *category, const char *action)
1123{
1124 static PyObject *ignore_str = NULL;
1125 static PyObject *error_str = NULL;
1126 static PyObject *default_str = NULL;
Georg Brandl08be72d2010-10-24 15:11:22 +00001127 static PyObject *always_str = NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001128 PyObject *action_obj = NULL;
1129 PyObject *lineno, *result;
1130
1131 if (!strcmp(action, "ignore")) {
1132 if (ignore_str == NULL) {
1133 ignore_str = PyUnicode_InternFromString("ignore");
1134 if (ignore_str == NULL)
1135 return NULL;
1136 }
1137 action_obj = ignore_str;
1138 }
1139 else if (!strcmp(action, "error")) {
1140 if (error_str == NULL) {
1141 error_str = PyUnicode_InternFromString("error");
1142 if (error_str == NULL)
1143 return NULL;
1144 }
1145 action_obj = error_str;
1146 }
1147 else if (!strcmp(action, "default")) {
1148 if (default_str == NULL) {
1149 default_str = PyUnicode_InternFromString("default");
1150 if (default_str == NULL)
1151 return NULL;
1152 }
1153 action_obj = default_str;
1154 }
Georg Brandl08be72d2010-10-24 15:11:22 +00001155 else if (!strcmp(action, "always")) {
1156 if (always_str == NULL) {
1157 always_str = PyUnicode_InternFromString("always");
1158 if (always_str == NULL)
1159 return NULL;
1160 }
1161 action_obj = always_str;
1162 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001163 else {
1164 Py_FatalError("unknown action");
1165 }
1166
1167 /* This assumes the line number is zero for now. */
1168 lineno = PyLong_FromLong(0);
1169 if (lineno == NULL)
1170 return NULL;
1171 result = PyTuple_Pack(5, action_obj, Py_None, category, Py_None, lineno);
1172 Py_DECREF(lineno);
1173 return result;
1174}
1175
1176static PyObject *
1177init_filters(void)
1178{
Georg Brandl08be72d2010-10-24 15:11:22 +00001179 PyObject *filters = PyList_New(5);
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001180 unsigned int pos = 0; /* Post-incremented in each use. */
1181 unsigned int x;
Georg Brandl08be72d2010-10-24 15:11:22 +00001182 const char *bytes_action, *resource_action;
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001183
Christian Heimes33fe8092008-04-13 13:53:33 +00001184 if (filters == NULL)
1185 return NULL;
1186
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001187 PyList_SET_ITEM(filters, pos++,
1188 create_filter(PyExc_DeprecationWarning, "ignore"));
1189 PyList_SET_ITEM(filters, pos++,
Christian Heimes33fe8092008-04-13 13:53:33 +00001190 create_filter(PyExc_PendingDeprecationWarning, "ignore"));
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001191 PyList_SET_ITEM(filters, pos++,
1192 create_filter(PyExc_ImportWarning, "ignore"));
Christian Heimes33fe8092008-04-13 13:53:33 +00001193 if (Py_BytesWarningFlag > 1)
1194 bytes_action = "error";
1195 else if (Py_BytesWarningFlag)
1196 bytes_action = "default";
1197 else
1198 bytes_action = "ignore";
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001199 PyList_SET_ITEM(filters, pos++, create_filter(PyExc_BytesWarning,
Christian Heimes33fe8092008-04-13 13:53:33 +00001200 bytes_action));
Georg Brandl08be72d2010-10-24 15:11:22 +00001201 /* resource usage warnings are enabled by default in pydebug mode */
1202#ifdef Py_DEBUG
1203 resource_action = "always";
1204#else
1205 resource_action = "ignore";
1206#endif
1207 PyList_SET_ITEM(filters, pos++, create_filter(PyExc_ResourceWarning,
1208 resource_action));
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001209 for (x = 0; x < pos; x += 1) {
1210 if (PyList_GET_ITEM(filters, x) == NULL) {
1211 Py_DECREF(filters);
1212 return NULL;
1213 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001214 }
1215
1216 return filters;
1217}
1218
Martin v. Löwis1a214512008-06-11 05:26:20 +00001219static struct PyModuleDef warningsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 PyModuleDef_HEAD_INIT,
1221 MODULE_NAME,
1222 warnings__doc__,
1223 0,
1224 warnings_functions,
1225 NULL,
1226 NULL,
1227 NULL,
1228 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001229};
1230
Christian Heimes33fe8092008-04-13 13:53:33 +00001231
1232PyMODINIT_FUNC
1233_PyWarnings_Init(void)
1234{
Brett Cannon0759dd62009-04-01 18:13:07 +00001235 PyObject *m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001236
Martin v. Löwis1a214512008-06-11 05:26:20 +00001237 m = PyModule_Create(&warningsmodule);
Christian Heimes33fe8092008-04-13 13:53:33 +00001238 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001239 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001240
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001241 if (_filters == NULL) {
1242 _filters = init_filters();
1243 if (_filters == NULL)
1244 return NULL;
1245 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001246 Py_INCREF(_filters);
1247 if (PyModule_AddObject(m, "filters", _filters) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001248 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001249
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001250 if (_once_registry == NULL) {
1251 _once_registry = PyDict_New();
1252 if (_once_registry == NULL)
1253 return NULL;
1254 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001255 Py_INCREF(_once_registry);
Brett Cannonef0e6c32010-09-04 18:24:04 +00001256 if (PyModule_AddObject(m, "_onceregistry", _once_registry) < 0)
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 (_default_action == NULL) {
1260 _default_action = PyUnicode_FromString("default");
1261 if (_default_action == NULL)
1262 return NULL;
1263 }
1264 Py_INCREF(_default_action);
Brett Cannonef0e6c32010-09-04 18:24:04 +00001265 if (PyModule_AddObject(m, "_defaultaction", _default_action) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001266 return NULL;
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001267
1268 _filters_version = 0;
Martin v. Löwis1a214512008-06-11 05:26:20 +00001269 return m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001270}