blob: a8c3703926471875b7033080d1585c00614ba90a [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 *
43get_warnings_attr(const char *attr)
44{
45 static PyObject *warnings_str = NULL;
46 PyObject *all_modules;
47 PyObject *warnings_module;
48 int result;
49
50 if (warnings_str == NULL) {
51 warnings_str = PyUnicode_InternFromString("warnings");
52 if (warnings_str == NULL)
53 return NULL;
54 }
55
56 all_modules = PyImport_GetModuleDict();
57 result = PyDict_Contains(all_modules, warnings_str);
58 if (result == -1 || result == 0)
59 return NULL;
60
61 warnings_module = PyDict_GetItem(all_modules, warnings_str);
62 if (!PyObject_HasAttrString(warnings_module, attr))
63 return NULL;
64 return PyObject_GetAttrString(warnings_module, attr);
65}
66
67
Neal Norwitz32dde222008-04-15 06:43:13 +000068static PyObject *
Christian Heimes33fe8092008-04-13 13:53:33 +000069get_once_registry(void)
70{
71 PyObject *registry;
72
73 registry = get_warnings_attr("onceregistry");
74 if (registry == NULL) {
75 if (PyErr_Occurred())
76 return NULL;
77 return _once_registry;
78 }
79 Py_DECREF(_once_registry);
80 _once_registry = registry;
81 return registry;
82}
83
84
Brett Cannon0759dd62009-04-01 18:13:07 +000085static PyObject *
86get_default_action(void)
87{
88 PyObject *default_action;
89
90 default_action = get_warnings_attr("defaultaction");
91 if (default_action == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000092 if (PyErr_Occurred()) {
93 return NULL;
94 }
95 return _default_action;
Brett Cannon0759dd62009-04-01 18:13:07 +000096 }
97
98 Py_DECREF(_default_action);
99 _default_action = default_action;
100 return default_action;
101}
102
103
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400104/* The item is a new reference. */
Victor Stinnera4c704b2013-10-29 23:43:41 +0100105static PyObject*
Christian Heimes33fe8092008-04-13 13:53:33 +0000106get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
107 PyObject *module, PyObject **item)
108{
Brett Cannon0759dd62009-04-01 18:13:07 +0000109 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000110 Py_ssize_t i;
111 PyObject *warnings_filters;
112
113 warnings_filters = get_warnings_attr("filters");
114 if (warnings_filters == NULL) {
115 if (PyErr_Occurred())
116 return NULL;
117 }
118 else {
119 Py_DECREF(_filters);
120 _filters = warnings_filters;
121 }
122
Victor Stinner7d79b8b2010-05-19 20:40:50 +0000123 if (_filters == NULL || !PyList_Check(_filters)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000124 PyErr_SetString(PyExc_ValueError,
125 MODULE_NAME ".filters must be a list");
126 return NULL;
127 }
128
129 /* _filters could change while we are iterating over it. */
130 for (i = 0; i < PyList_GET_SIZE(_filters); i++) {
131 PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
132 Py_ssize_t ln;
133 int is_subclass, good_msg, good_mod;
134
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400135 tmp_item = PyList_GET_ITEM(_filters, i);
136 if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000137 PyErr_Format(PyExc_ValueError,
138 MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
139 return NULL;
140 }
141
142 /* Python code: action, msg, cat, mod, ln = item */
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400143 Py_INCREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000144 action = PyTuple_GET_ITEM(tmp_item, 0);
145 msg = PyTuple_GET_ITEM(tmp_item, 1);
146 cat = PyTuple_GET_ITEM(tmp_item, 2);
147 mod = PyTuple_GET_ITEM(tmp_item, 3);
148 ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
149
150 good_msg = check_matched(msg, text);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400151 if (good_msg == -1) {
152 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100153 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400154 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100155
Christian Heimes33fe8092008-04-13 13:53:33 +0000156 good_mod = check_matched(mod, module);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400157 if (good_mod == -1) {
158 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100159 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400160 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100161
Christian Heimes33fe8092008-04-13 13:53:33 +0000162 is_subclass = PyObject_IsSubclass(category, cat);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400163 if (is_subclass == -1) {
164 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100165 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400166 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100167
Christian Heimes33fe8092008-04-13 13:53:33 +0000168 ln = PyLong_AsSsize_t(ln_obj);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400169 if (ln == -1 && PyErr_Occurred()) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400170 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000171 return NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400172 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000173
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400174 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
175 *item = tmp_item;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100176 return action;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400177 }
178
179 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000180 }
181
Brett Cannon0759dd62009-04-01 18:13:07 +0000182 action = get_default_action();
183 if (action != NULL) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400184 Py_INCREF(Py_None);
185 *item = Py_None;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100186 return action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000187 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000188
189 PyErr_SetString(PyExc_ValueError,
Brett Cannon0759dd62009-04-01 18:13:07 +0000190 MODULE_NAME ".defaultaction not found");
Christian Heimes33fe8092008-04-13 13:53:33 +0000191 return NULL;
192}
193
Brett Cannon0759dd62009-04-01 18:13:07 +0000194
Christian Heimes33fe8092008-04-13 13:53:33 +0000195static int
196already_warned(PyObject *registry, PyObject *key, int should_set)
197{
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200198 PyObject *version_obj, *already_warned;
199 _Py_IDENTIFIER(version);
Christian Heimes33fe8092008-04-13 13:53:33 +0000200
201 if (key == NULL)
202 return -1;
203
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200204 version_obj = _PyDict_GetItemId(registry, &PyId_version);
205 if (version_obj == NULL
206 || !PyLong_CheckExact(version_obj)
207 || PyLong_AsLong(version_obj) != _filters_version) {
208 PyDict_Clear(registry);
209 version_obj = PyLong_FromLong(_filters_version);
210 if (version_obj == NULL)
211 return -1;
212 if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
213 Py_DECREF(version_obj);
214 return -1;
215 }
216 Py_DECREF(version_obj);
217 }
218 else {
219 already_warned = PyDict_GetItem(registry, key);
220 if (already_warned != NULL) {
221 int rc = PyObject_IsTrue(already_warned);
222 if (rc != 0)
223 return rc;
224 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000225 }
226
227 /* This warning wasn't found in the registry, set it. */
228 if (should_set)
229 return PyDict_SetItem(registry, key, Py_True);
230 return 0;
231}
232
233/* New reference. */
234static PyObject *
235normalize_module(PyObject *filename)
236{
237 PyObject *module;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100238 int kind;
239 void *data;
Christian Heimes33fe8092008-04-13 13:53:33 +0000240 Py_ssize_t len;
241
Victor Stinner9e30aa52011-11-21 02:49:52 +0100242 len = PyUnicode_GetLength(filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000243 if (len < 0)
244 return NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100245
246 if (len == 0)
247 return PyUnicode_FromString("<unknown>");
248
249 kind = PyUnicode_KIND(filename);
250 data = PyUnicode_DATA(filename);
251
252 /* if filename.endswith(".py"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000253 if (len >= 3 &&
Victor Stinnera4c704b2013-10-29 23:43:41 +0100254 PyUnicode_READ(kind, data, len-3) == '.' &&
255 PyUnicode_READ(kind, data, len-2) == 'p' &&
256 PyUnicode_READ(kind, data, len-1) == 'y')
257 {
Victor Stinner9e30aa52011-11-21 02:49:52 +0100258 module = PyUnicode_Substring(filename, 0, len-3);
Christian Heimes33fe8092008-04-13 13:53:33 +0000259 }
260 else {
261 module = filename;
262 Py_INCREF(module);
263 }
264 return module;
265}
266
267static int
268update_registry(PyObject *registry, PyObject *text, PyObject *category,
269 int add_zero)
270{
271 PyObject *altkey, *zero = NULL;
272 int rc;
273
274 if (add_zero) {
275 zero = PyLong_FromLong(0);
276 if (zero == NULL)
277 return -1;
278 altkey = PyTuple_Pack(3, text, category, zero);
279 }
280 else
281 altkey = PyTuple_Pack(2, text, category);
282
283 rc = already_warned(registry, altkey, 1);
284 Py_XDECREF(zero);
285 Py_XDECREF(altkey);
286 return rc;
287}
288
289static void
290show_warning(PyObject *filename, int lineno, PyObject *text, PyObject
291 *category, PyObject *sourceline)
292{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293 PyObject *f_stderr;
294 PyObject *name;
Christian Heimes33fe8092008-04-13 13:53:33 +0000295 char lineno_str[128];
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200296 _Py_IDENTIFIER(__name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000297
298 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
299
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200300 name = _PyObject_GetAttrId(category, &PyId___name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000301 if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100302 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000303
Victor Stinnerbd303c12013-11-07 23:07:29 +0100304 f_stderr = _PySys_GetObjectId(&PyId_stderr);
Christian Heimes33fe8092008-04-13 13:53:33 +0000305 if (f_stderr == NULL) {
306 fprintf(stderr, "lost sys.stderr\n");
Victor Stinnerae233ea2013-10-31 14:51:38 +0100307 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000308 }
309
310 /* Print "filename:lineno: category: text\n" */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100311 if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
312 goto error;
313 if (PyFile_WriteString(lineno_str, f_stderr) < 0)
314 goto error;
315 if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
316 goto error;
317 if (PyFile_WriteString(": ", f_stderr) < 0)
318 goto error;
319 if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
320 goto error;
321 if (PyFile_WriteString("\n", f_stderr) < 0)
322 goto error;
323 Py_CLEAR(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000324
325 /* Print " source_line\n" */
Christian Heimes33fe8092008-04-13 13:53:33 +0000326 if (sourceline) {
Victor Stinnera4c704b2013-10-29 23:43:41 +0100327 int kind;
328 void *data;
329 Py_ssize_t i, len;
330 Py_UCS4 ch;
331 PyObject *truncated;
Christian Heimes33fe8092008-04-13 13:53:33 +0000332
Victor Stinnera4c704b2013-10-29 23:43:41 +0100333 if (PyUnicode_READY(sourceline) < 1)
334 goto error;
335
336 kind = PyUnicode_KIND(sourceline);
337 data = PyUnicode_DATA(sourceline);
338 len = PyUnicode_GET_LENGTH(sourceline);
339 for (i=0; i<len; i++) {
340 ch = PyUnicode_READ(kind, data, i);
341 if (ch != ' ' && ch != '\t' && ch != '\014')
342 break;
343 }
344
345 truncated = PyUnicode_Substring(sourceline, i, len);
346 if (truncated == NULL)
347 goto error;
348
349 PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
350 Py_DECREF(truncated);
Christian Heimes33fe8092008-04-13 13:53:33 +0000351 PyFile_WriteString("\n", f_stderr);
352 }
Victor Stinner78e2c982013-07-16 01:54:37 +0200353 else {
354 _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
355 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100356
357error:
Victor Stinnerae233ea2013-10-31 14:51:38 +0100358 Py_XDECREF(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000359 PyErr_Clear();
360}
361
Victor Stinner1231a462016-03-19 00:47:17 +0100362static int
363call_show_warning(PyObject *category, PyObject *text, PyObject *message,
364 PyObject *filename, int lineno, PyObject *lineno_obj,
365 PyObject *sourceline)
366{
367 PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
368
369 show_fn = get_warnings_attr("_showwarnmsg");
370 if (show_fn == NULL) {
371 if (PyErr_Occurred())
372 return -1;
373 show_warning(filename, lineno, text, category, sourceline);
374 return 0;
375 }
376
377 if (!PyCallable_Check(show_fn)) {
378 PyErr_SetString(PyExc_TypeError,
379 "warnings._showwarnmsg() must be set to a callable");
380 goto error;
381 }
382
383 warnmsg_cls = get_warnings_attr("WarningMessage");
384 if (warnmsg_cls == NULL) {
385 PyErr_SetString(PyExc_RuntimeError,
386 "unable to get warnings.WarningMessage");
387 goto error;
388 }
389
390 msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
391 filename, lineno_obj,
392 NULL);
393 Py_DECREF(warnmsg_cls);
394 if (msg == NULL)
395 goto error;
396
397 res = PyObject_CallFunctionObjArgs(show_fn, msg, NULL);
398 Py_DECREF(show_fn);
399 Py_DECREF(msg);
400
401 if (res == NULL)
402 return -1;
403
404 Py_DECREF(res);
405 return 0;
406
407error:
408 Py_XDECREF(show_fn);
409 return -1;
410}
411
Christian Heimes33fe8092008-04-13 13:53:33 +0000412static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413warn_explicit(PyObject *category, PyObject *message,
Christian Heimes33fe8092008-04-13 13:53:33 +0000414 PyObject *filename, int lineno,
415 PyObject *module, PyObject *registry, PyObject *sourceline)
416{
417 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400418 PyObject *item = NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100419 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000420 int rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100422 /* module can be None if a warning is emitted late during Python shutdown.
423 In this case, the Python warnings module was probably unloaded, filters
424 are no more available to choose as action. It is safer to ignore the
425 warning and do nothing. */
426 if (module == Py_None)
427 Py_RETURN_NONE;
428
Brett Cannondb734912008-06-27 00:52:15 +0000429 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
430 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");
431 return NULL;
432 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000433
434 /* Normalize module. */
435 if (module == NULL) {
436 module = normalize_module(filename);
437 if (module == NULL)
438 return NULL;
439 }
440 else
441 Py_INCREF(module);
442
443 /* Normalize message. */
444 Py_INCREF(message); /* DECREF'ed in cleanup. */
445 rc = PyObject_IsInstance(message, PyExc_Warning);
446 if (rc == -1) {
447 goto cleanup;
448 }
449 if (rc == 1) {
450 text = PyObject_Str(message);
Hirokazu Yamamoto1c0c0032009-07-17 06:55:42 +0000451 if (text == NULL)
452 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000453 category = (PyObject*)message->ob_type;
454 }
455 else {
456 text = message;
457 message = PyObject_CallFunction(category, "O", message);
Brett Cannondb734912008-06-27 00:52:15 +0000458 if (message == NULL)
459 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000460 }
461
462 lineno_obj = PyLong_FromLong(lineno);
463 if (lineno_obj == NULL)
464 goto cleanup;
465
466 /* Create key. */
467 key = PyTuple_Pack(3, text, category, lineno_obj);
468 if (key == NULL)
469 goto cleanup;
470
Brett Cannondb734912008-06-27 00:52:15 +0000471 if ((registry != NULL) && (registry != Py_None)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000472 rc = already_warned(registry, key, 0);
473 if (rc == -1)
474 goto cleanup;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 else if (rc == 1)
Christian Heimes33fe8092008-04-13 13:53:33 +0000476 goto return_none;
477 /* Else this warning hasn't been generated before. */
478 }
479
480 action = get_filter(category, text, lineno, module, &item);
481 if (action == NULL)
482 goto cleanup;
483
Victor Stinnera4c704b2013-10-29 23:43:41 +0100484 if (PyUnicode_CompareWithASCIIString(action, "error") == 0) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000485 PyErr_SetObject(category, message);
486 goto cleanup;
487 }
488
489 /* Store in the registry that we've been here, *except* when the action
490 is "always". */
491 rc = 0;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100492 if (PyUnicode_CompareWithASCIIString(action, "always") != 0) {
Brett Cannondb734912008-06-27 00:52:15 +0000493 if (registry != NULL && registry != Py_None &&
494 PyDict_SetItem(registry, key, Py_True) < 0)
Christian Heimes33fe8092008-04-13 13:53:33 +0000495 goto cleanup;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100496 else if (PyUnicode_CompareWithASCIIString(action, "ignore") == 0)
Christian Heimes33fe8092008-04-13 13:53:33 +0000497 goto return_none;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100498 else if (PyUnicode_CompareWithASCIIString(action, "once") == 0) {
Brett Cannondb734912008-06-27 00:52:15 +0000499 if (registry == NULL || registry == Py_None) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000500 registry = get_once_registry();
501 if (registry == NULL)
502 goto cleanup;
503 }
504 /* _once_registry[(text, category)] = 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000506 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100507 else if (PyUnicode_CompareWithASCIIString(action, "module") == 0) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000508 /* registry[(text, category, 0)] = 1 */
Brett Cannondb734912008-06-27 00:52:15 +0000509 if (registry != NULL && registry != Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000511 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100512 else if (PyUnicode_CompareWithASCIIString(action, "default") != 0) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000513 PyErr_Format(PyExc_RuntimeError,
Victor Stinnera4c704b2013-10-29 23:43:41 +0100514 "Unrecognized action (%R) in warnings.filters:\n %R",
515 action, item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000516 goto cleanup;
517 }
518 }
519
Christian Heimes1a8501c2008-10-02 19:56:01 +0000520 if (rc == 1) /* Already warned for this module. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000521 goto return_none;
522 if (rc == 0) {
Victor Stinner1231a462016-03-19 00:47:17 +0100523 if (call_show_warning(category, text, message, filename, lineno,
524 lineno_obj, sourceline) < 0)
525 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000526 }
527 else /* if (rc == -1) */
528 goto cleanup;
529
530 return_none:
531 result = Py_None;
532 Py_INCREF(result);
533
534 cleanup:
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400535 Py_XDECREF(item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000536 Py_XDECREF(key);
537 Py_XDECREF(text);
538 Py_XDECREF(lineno_obj);
539 Py_DECREF(module);
Brett Cannondb734912008-06-27 00:52:15 +0000540 Py_XDECREF(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000541 return result; /* Py_None or NULL. */
542}
543
Larry Hastings714e4932015-09-06 00:39:37 -0700544static int
545is_internal_frame(PyFrameObject *frame)
546{
547 static PyObject *importlib_string = NULL;
548 static PyObject *bootstrap_string = NULL;
549 PyObject *filename;
550 int contains;
551
552 if (importlib_string == NULL) {
553 importlib_string = PyUnicode_FromString("importlib");
554 if (importlib_string == NULL) {
555 return 0;
556 }
557
558 bootstrap_string = PyUnicode_FromString("_bootstrap");
559 if (bootstrap_string == NULL) {
560 Py_DECREF(importlib_string);
561 return 0;
562 }
563 Py_INCREF(importlib_string);
564 Py_INCREF(bootstrap_string);
565 }
566
567 if (frame == NULL || frame->f_code == NULL ||
568 frame->f_code->co_filename == NULL) {
569 return 0;
570 }
571 filename = frame->f_code->co_filename;
572 if (!PyUnicode_Check(filename)) {
573 return 0;
574 }
575 contains = PyUnicode_Contains(filename, importlib_string);
576 if (contains < 0) {
577 return 0;
578 }
579 else if (contains > 0) {
580 contains = PyUnicode_Contains(filename, bootstrap_string);
581 if (contains < 0) {
582 return 0;
583 }
584 else if (contains > 0) {
585 return 1;
586 }
587 }
588
589 return 0;
590}
591
592static PyFrameObject *
593next_external_frame(PyFrameObject *frame)
594{
595 do {
596 frame = frame->f_back;
597 } while (frame != NULL && is_internal_frame(frame));
598
599 return frame;
600}
601
Christian Heimes33fe8092008-04-13 13:53:33 +0000602/* filename, module, and registry are new refs, globals is borrowed */
603/* Returns 0 on error (no new refs), 1 on success */
604static int
605setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
606 PyObject **module, PyObject **registry)
607{
608 PyObject *globals;
609
610 /* Setup globals and lineno. */
611 PyFrameObject *f = PyThreadState_GET()->frame;
Larry Hastings714e4932015-09-06 00:39:37 -0700612 // Stack level comparisons to Python code is off by one as there is no
613 // warnings-related stack level to avoid.
614 if (stack_level <= 0 || is_internal_frame(f)) {
615 while (--stack_level > 0 && f != NULL) {
616 f = f->f_back;
617 }
618 }
619 else {
620 while (--stack_level > 0 && f != NULL) {
621 f = next_external_frame(f);
622 }
623 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000624
625 if (f == NULL) {
626 globals = PyThreadState_Get()->interp->sysdict;
627 *lineno = 1;
628 }
629 else {
630 globals = f->f_globals;
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000631 *lineno = PyFrame_GetLineNumber(f);
Christian Heimes33fe8092008-04-13 13:53:33 +0000632 }
633
634 *module = NULL;
635
636 /* Setup registry. */
637 assert(globals != NULL);
638 assert(PyDict_Check(globals));
639 *registry = PyDict_GetItemString(globals, "__warningregistry__");
640 if (*registry == NULL) {
641 int rc;
642
643 *registry = PyDict_New();
644 if (*registry == NULL)
645 return 0;
646
647 rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
648 if (rc < 0)
649 goto handle_error;
650 }
651 else
652 Py_INCREF(*registry);
653
654 /* Setup module. */
655 *module = PyDict_GetItemString(globals, "__name__");
656 if (*module == NULL) {
657 *module = PyUnicode_FromString("<string>");
658 if (*module == NULL)
659 goto handle_error;
660 }
661 else
662 Py_INCREF(*module);
663
664 /* Setup filename. */
665 *filename = PyDict_GetItemString(globals, "__file__");
Victor Stinner8b0508e2011-07-04 02:43:09 +0200666 if (*filename != NULL && PyUnicode_Check(*filename)) {
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200667 Py_ssize_t len;
668 int kind;
669 void *data;
670
671 if (PyUnicode_READY(*filename))
672 goto handle_error;
673
Victor Stinner9e30aa52011-11-21 02:49:52 +0100674 len = PyUnicode_GetLength(*filename);
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200675 kind = PyUnicode_KIND(*filename);
676 data = PyUnicode_DATA(*filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000677
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500678#define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0)
Brett Cannonf299abd2015-04-13 14:21:02 -0400679 /* if filename.lower().endswith(".pyc"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000680 if (len >= 4 &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200681 PyUnicode_READ(kind, data, len-4) == '.' &&
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500682 ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' &&
683 ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' &&
Brett Cannonf299abd2015-04-13 14:21:02 -0400684 ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c')
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000685 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200686 *filename = PyUnicode_Substring(*filename, 0,
687 PyUnicode_GET_LENGTH(*filename)-1);
Victor Stinner2e5f1172010-08-08 22:12:45 +0000688 if (*filename == NULL)
689 goto handle_error;
690 }
691 else
Christian Heimes33fe8092008-04-13 13:53:33 +0000692 Py_INCREF(*filename);
693 }
694 else {
Benjamin Petersonbb4a7472011-07-04 22:27:16 -0500695 *filename = NULL;
Victor Stinner856f45f2013-10-30 00:04:59 +0100696 if (*module != Py_None && PyUnicode_CompareWithASCIIString(*module, "__main__") == 0) {
Victor Stinnerbd303c12013-11-07 23:07:29 +0100697 PyObject *argv = _PySys_GetObjectId(&PyId_argv);
Victor Stinnerce5f4fb2013-10-28 18:47:22 +0100698 /* PyList_Check() is needed because sys.argv is set to None during
699 Python finalization */
700 if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) {
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000701 int is_true;
Christian Heimes33fe8092008-04-13 13:53:33 +0000702 *filename = PyList_GetItem(argv, 0);
703 Py_INCREF(*filename);
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000704 /* If sys.argv[0] is false, then use '__main__'. */
705 is_true = PyObject_IsTrue(*filename);
706 if (is_true < 0) {
707 Py_DECREF(*filename);
708 goto handle_error;
709 }
710 else if (!is_true) {
Serhiy Storchaka5a57ade2015-12-24 10:35:59 +0200711 Py_SETREF(*filename, PyUnicode_FromString("__main__"));
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000712 if (*filename == NULL)
713 goto handle_error;
714 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000715 }
716 else {
717 /* embedded interpreters don't have sys.argv, see bug #839151 */
718 *filename = PyUnicode_FromString("__main__");
Victor Stinner856f45f2013-10-30 00:04:59 +0100719 if (*filename == NULL)
720 goto handle_error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000721 }
722 }
723 if (*filename == NULL) {
724 *filename = *module;
725 Py_INCREF(*filename);
726 }
727 }
728
729 return 1;
730
731 handle_error:
732 /* filename not XDECREF'ed here as there is no way to jump here with a
733 dangling reference. */
734 Py_XDECREF(*registry);
735 Py_XDECREF(*module);
736 return 0;
737}
738
739static PyObject *
740get_category(PyObject *message, PyObject *category)
741{
742 int rc;
743
744 /* Get category. */
745 rc = PyObject_IsInstance(message, PyExc_Warning);
746 if (rc == -1)
747 return NULL;
748
749 if (rc == 1)
750 category = (PyObject*)message->ob_type;
Berker Peksagd8089e02014-07-11 19:50:25 +0300751 else if (category == NULL || category == Py_None)
Christian Heimes33fe8092008-04-13 13:53:33 +0000752 category = PyExc_UserWarning;
753
754 /* Validate category. */
755 rc = PyObject_IsSubclass(category, PyExc_Warning);
Berker Peksagd8089e02014-07-11 19:50:25 +0300756 /* category is not a subclass of PyExc_Warning or
757 PyObject_IsSubclass raised an error */
758 if (rc == -1 || rc == 0) {
759 PyErr_Format(PyExc_TypeError,
760 "category must be a Warning subclass, not '%s'",
761 Py_TYPE(category)->tp_name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000762 return NULL;
763 }
764
765 return category;
766}
767
768static PyObject *
769do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level)
770{
771 PyObject *filename, *module, *registry, *res;
772 int lineno;
773
774 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
775 return NULL;
776
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100777 res = warn_explicit(category, message, filename, lineno, module, registry,
778 NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000779 Py_DECREF(filename);
780 Py_DECREF(registry);
781 Py_DECREF(module);
782 return res;
783}
784
785static PyObject *
786warnings_warn(PyObject *self, PyObject *args, PyObject *kwds)
787{
788 static char *kw_list[] = { "message", "category", "stacklevel", 0 };
789 PyObject *message, *category = NULL;
790 Py_ssize_t stack_level = 1;
791
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000792 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|On:warn", kw_list,
Christian Heimes33fe8092008-04-13 13:53:33 +0000793 &message, &category, &stack_level))
794 return NULL;
795
796 category = get_category(message, category);
797 if (category == NULL)
798 return NULL;
799 return do_warn(message, category, stack_level);
800}
801
802static PyObject *
803warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
804{
805 static char *kwd_list[] = {"message", "category", "filename", "lineno",
806 "module", "registry", "module_globals", 0};
807 PyObject *message;
808 PyObject *category;
809 PyObject *filename;
810 int lineno;
811 PyObject *module = NULL;
812 PyObject *registry = NULL;
813 PyObject *module_globals = NULL;
814
Victor Stinnera4c704b2013-10-29 23:43:41 +0100815 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOO:warn_explicit",
Christian Heimes33fe8092008-04-13 13:53:33 +0000816 kwd_list, &message, &category, &filename, &lineno, &module,
817 &registry, &module_globals))
818 return NULL;
819
820 if (module_globals) {
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200821 _Py_IDENTIFIER(get_source);
822 _Py_IDENTIFIER(splitlines);
823 PyObject *tmp;
Christian Heimes33fe8092008-04-13 13:53:33 +0000824 PyObject *loader;
825 PyObject *module_name;
826 PyObject *source;
827 PyObject *source_list;
828 PyObject *source_line;
829 PyObject *returned;
830
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200831 if ((tmp = _PyUnicode_FromId(&PyId_get_source)) == NULL)
832 return NULL;
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200833 if ((tmp = _PyUnicode_FromId(&PyId_splitlines)) == NULL)
834 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000835
836 /* Check/get the requisite pieces needed for the loader. */
837 loader = PyDict_GetItemString(module_globals, "__loader__");
838 module_name = PyDict_GetItemString(module_globals, "__name__");
839
840 if (loader == NULL || module_name == NULL)
841 goto standard_call;
842
843 /* Make sure the loader implements the optional get_source() method. */
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200844 if (!_PyObject_HasAttrId(loader, &PyId_get_source))
Christian Heimes33fe8092008-04-13 13:53:33 +0000845 goto standard_call;
846 /* Call get_source() to get the source code. */
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200847 source = PyObject_CallMethodObjArgs(loader, PyId_get_source.object,
848 module_name, NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000849 if (!source)
850 return NULL;
851 else if (source == Py_None) {
852 Py_DECREF(Py_None);
853 goto standard_call;
854 }
855
856 /* Split the source into lines. */
Victor Stinner9e30aa52011-11-21 02:49:52 +0100857 source_list = PyObject_CallMethodObjArgs(source,
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200858 PyId_splitlines.object,
859 NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000860 Py_DECREF(source);
861 if (!source_list)
862 return NULL;
863
864 /* Get the source line. */
865 source_line = PyList_GetItem(source_list, lineno-1);
866 if (!source_line) {
867 Py_DECREF(source_list);
868 return NULL;
869 }
870
871 /* Handle the warning. */
872 returned = warn_explicit(category, message, filename, lineno, module,
Victor Stinner14e461d2013-08-26 22:28:21 +0200873 registry, source_line);
Christian Heimes33fe8092008-04-13 13:53:33 +0000874 Py_DECREF(source_list);
875 return returned;
876 }
877
878 standard_call:
879 return warn_explicit(category, message, filename, lineno, module,
Victor Stinner14e461d2013-08-26 22:28:21 +0200880 registry, NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000881}
882
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200883static PyObject *
884warnings_filters_mutated(PyObject *self, PyObject *args)
885{
886 _filters_version++;
887 Py_RETURN_NONE;
888}
889
Christian Heimes33fe8092008-04-13 13:53:33 +0000890
891/* Function to issue a warning message; may raise an exception. */
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000892
893static int
894warn_unicode(PyObject *category, PyObject *message,
895 Py_ssize_t stack_level)
Christian Heimes33fe8092008-04-13 13:53:33 +0000896{
897 PyObject *res;
Christian Heimes33fe8092008-04-13 13:53:33 +0000898
899 if (category == NULL)
900 category = PyExc_RuntimeWarning;
901
902 res = do_warn(message, category, stack_level);
Christian Heimes33fe8092008-04-13 13:53:33 +0000903 if (res == NULL)
904 return -1;
905 Py_DECREF(res);
906
907 return 0;
908}
909
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000910int
911PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
912 const char *format, ...)
913{
914 int ret;
915 PyObject *message;
916 va_list vargs;
917
918#ifdef HAVE_STDARG_PROTOTYPES
919 va_start(vargs, format);
920#else
921 va_start(vargs);
922#endif
923 message = PyUnicode_FromFormatV(format, vargs);
924 if (message != NULL) {
925 ret = warn_unicode(category, message, stack_level);
926 Py_DECREF(message);
927 }
928 else
929 ret = -1;
930 va_end(vargs);
931 return ret;
932}
933
934int
935PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
936{
937 int ret;
938 PyObject *message = PyUnicode_FromString(text);
939 if (message == NULL)
940 return -1;
941 ret = warn_unicode(category, message, stack_level);
942 Py_DECREF(message);
943 return ret;
944}
945
Ezio Melotti42da6632011-03-15 05:18:48 +0200946/* PyErr_Warn is only for backwards compatibility and will be removed.
Christian Heimes33fe8092008-04-13 13:53:33 +0000947 Use PyErr_WarnEx instead. */
948
949#undef PyErr_Warn
950
951PyAPI_FUNC(int)
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200952PyErr_Warn(PyObject *category, const char *text)
Christian Heimes33fe8092008-04-13 13:53:33 +0000953{
954 return PyErr_WarnEx(category, text, 1);
955}
956
957/* Warning with explicit origin */
958int
Victor Stinner14e461d2013-08-26 22:28:21 +0200959PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
960 PyObject *filename, int lineno,
961 PyObject *module, PyObject *registry)
962{
963 PyObject *res;
964 if (category == NULL)
965 category = PyExc_RuntimeWarning;
966 res = warn_explicit(category, message, filename, lineno,
967 module, registry, NULL);
968 if (res == NULL)
969 return -1;
970 Py_DECREF(res);
971 return 0;
972}
973
974int
Christian Heimes33fe8092008-04-13 13:53:33 +0000975PyErr_WarnExplicit(PyObject *category, const char *text,
976 const char *filename_str, int lineno,
977 const char *module_str, PyObject *registry)
978{
Christian Heimes33fe8092008-04-13 13:53:33 +0000979 PyObject *message = PyUnicode_FromString(text);
Victor Stinnercb428f02010-12-27 20:10:36 +0000980 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
Christian Heimes33fe8092008-04-13 13:53:33 +0000981 PyObject *module = NULL;
982 int ret = -1;
983
984 if (message == NULL || filename == NULL)
985 goto exit;
986 if (module_str != NULL) {
987 module = PyUnicode_FromString(module_str);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +0200988 if (module == NULL)
989 goto exit;
Christian Heimes33fe8092008-04-13 13:53:33 +0000990 }
991
Victor Stinner14e461d2013-08-26 22:28:21 +0200992 ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
993 module, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000994
995 exit:
996 Py_XDECREF(message);
997 Py_XDECREF(module);
998 Py_XDECREF(filename);
999 return ret;
1000}
1001
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001002int
1003PyErr_WarnExplicitFormat(PyObject *category,
1004 const char *filename_str, int lineno,
1005 const char *module_str, PyObject *registry,
1006 const char *format, ...)
1007{
1008 PyObject *message;
1009 PyObject *module = NULL;
1010 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1011 int ret = -1;
1012 va_list vargs;
1013
1014 if (filename == NULL)
1015 goto exit;
1016 if (module_str != NULL) {
1017 module = PyUnicode_FromString(module_str);
1018 if (module == NULL)
1019 goto exit;
1020 }
1021
1022#ifdef HAVE_STDARG_PROTOTYPES
1023 va_start(vargs, format);
1024#else
1025 va_start(vargs);
1026#endif
1027 message = PyUnicode_FromFormatV(format, vargs);
1028 if (message != NULL) {
1029 PyObject *res;
1030 res = warn_explicit(category, message, filename, lineno,
1031 module, registry, NULL);
1032 Py_DECREF(message);
1033 if (res != NULL) {
1034 Py_DECREF(res);
1035 ret = 0;
1036 }
1037 }
1038 va_end(vargs);
1039exit:
1040 Py_XDECREF(module);
1041 Py_XDECREF(filename);
1042 return ret;
1043}
1044
Christian Heimes33fe8092008-04-13 13:53:33 +00001045
1046PyDoc_STRVAR(warn_doc,
1047"Issue a warning, or maybe ignore it or raise an exception.");
1048
1049PyDoc_STRVAR(warn_explicit_doc,
1050"Low-level inferface to warnings functionality.");
1051
1052static PyMethodDef warnings_functions[] = {
1053 {"warn", (PyCFunction)warnings_warn, METH_VARARGS | METH_KEYWORDS,
1054 warn_doc},
1055 {"warn_explicit", (PyCFunction)warnings_warn_explicit,
1056 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001057 {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
1058 NULL},
Christian Heimes1a8501c2008-10-02 19:56:01 +00001059 /* XXX(brett.cannon): add showwarning? */
1060 /* XXX(brett.cannon): Reasonable to add formatwarning? */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 {NULL, NULL} /* sentinel */
Christian Heimes33fe8092008-04-13 13:53:33 +00001062};
1063
1064
1065static PyObject *
1066create_filter(PyObject *category, const char *action)
1067{
1068 static PyObject *ignore_str = NULL;
1069 static PyObject *error_str = NULL;
1070 static PyObject *default_str = NULL;
Georg Brandl08be72d2010-10-24 15:11:22 +00001071 static PyObject *always_str = NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001072 PyObject *action_obj = NULL;
1073 PyObject *lineno, *result;
1074
1075 if (!strcmp(action, "ignore")) {
1076 if (ignore_str == NULL) {
1077 ignore_str = PyUnicode_InternFromString("ignore");
1078 if (ignore_str == NULL)
1079 return NULL;
1080 }
1081 action_obj = ignore_str;
1082 }
1083 else if (!strcmp(action, "error")) {
1084 if (error_str == NULL) {
1085 error_str = PyUnicode_InternFromString("error");
1086 if (error_str == NULL)
1087 return NULL;
1088 }
1089 action_obj = error_str;
1090 }
1091 else if (!strcmp(action, "default")) {
1092 if (default_str == NULL) {
1093 default_str = PyUnicode_InternFromString("default");
1094 if (default_str == NULL)
1095 return NULL;
1096 }
1097 action_obj = default_str;
1098 }
Georg Brandl08be72d2010-10-24 15:11:22 +00001099 else if (!strcmp(action, "always")) {
1100 if (always_str == NULL) {
1101 always_str = PyUnicode_InternFromString("always");
1102 if (always_str == NULL)
1103 return NULL;
1104 }
1105 action_obj = always_str;
1106 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001107 else {
1108 Py_FatalError("unknown action");
1109 }
1110
1111 /* This assumes the line number is zero for now. */
1112 lineno = PyLong_FromLong(0);
1113 if (lineno == NULL)
1114 return NULL;
1115 result = PyTuple_Pack(5, action_obj, Py_None, category, Py_None, lineno);
1116 Py_DECREF(lineno);
1117 return result;
1118}
1119
1120static PyObject *
1121init_filters(void)
1122{
Georg Brandl08be72d2010-10-24 15:11:22 +00001123 PyObject *filters = PyList_New(5);
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001124 unsigned int pos = 0; /* Post-incremented in each use. */
1125 unsigned int x;
Georg Brandl08be72d2010-10-24 15:11:22 +00001126 const char *bytes_action, *resource_action;
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001127
Christian Heimes33fe8092008-04-13 13:53:33 +00001128 if (filters == NULL)
1129 return NULL;
1130
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001131 PyList_SET_ITEM(filters, pos++,
1132 create_filter(PyExc_DeprecationWarning, "ignore"));
1133 PyList_SET_ITEM(filters, pos++,
Christian Heimes33fe8092008-04-13 13:53:33 +00001134 create_filter(PyExc_PendingDeprecationWarning, "ignore"));
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001135 PyList_SET_ITEM(filters, pos++,
1136 create_filter(PyExc_ImportWarning, "ignore"));
Christian Heimes33fe8092008-04-13 13:53:33 +00001137 if (Py_BytesWarningFlag > 1)
1138 bytes_action = "error";
1139 else if (Py_BytesWarningFlag)
1140 bytes_action = "default";
1141 else
1142 bytes_action = "ignore";
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001143 PyList_SET_ITEM(filters, pos++, create_filter(PyExc_BytesWarning,
Christian Heimes33fe8092008-04-13 13:53:33 +00001144 bytes_action));
Georg Brandl08be72d2010-10-24 15:11:22 +00001145 /* resource usage warnings are enabled by default in pydebug mode */
1146#ifdef Py_DEBUG
1147 resource_action = "always";
1148#else
1149 resource_action = "ignore";
1150#endif
1151 PyList_SET_ITEM(filters, pos++, create_filter(PyExc_ResourceWarning,
1152 resource_action));
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001153 for (x = 0; x < pos; x += 1) {
1154 if (PyList_GET_ITEM(filters, x) == NULL) {
1155 Py_DECREF(filters);
1156 return NULL;
1157 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001158 }
1159
1160 return filters;
1161}
1162
Martin v. Löwis1a214512008-06-11 05:26:20 +00001163static struct PyModuleDef warningsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 PyModuleDef_HEAD_INIT,
1165 MODULE_NAME,
1166 warnings__doc__,
1167 0,
1168 warnings_functions,
1169 NULL,
1170 NULL,
1171 NULL,
1172 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001173};
1174
Christian Heimes33fe8092008-04-13 13:53:33 +00001175
1176PyMODINIT_FUNC
1177_PyWarnings_Init(void)
1178{
Brett Cannon0759dd62009-04-01 18:13:07 +00001179 PyObject *m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001180
Martin v. Löwis1a214512008-06-11 05:26:20 +00001181 m = PyModule_Create(&warningsmodule);
Christian Heimes33fe8092008-04-13 13:53:33 +00001182 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001183 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001184
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001185 if (_filters == NULL) {
1186 _filters = init_filters();
1187 if (_filters == NULL)
1188 return NULL;
1189 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001190 Py_INCREF(_filters);
1191 if (PyModule_AddObject(m, "filters", _filters) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001192 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001193
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001194 if (_once_registry == NULL) {
1195 _once_registry = PyDict_New();
1196 if (_once_registry == NULL)
1197 return NULL;
1198 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001199 Py_INCREF(_once_registry);
Brett Cannonef0e6c32010-09-04 18:24:04 +00001200 if (PyModule_AddObject(m, "_onceregistry", _once_registry) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001201 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001202
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001203 if (_default_action == NULL) {
1204 _default_action = PyUnicode_FromString("default");
1205 if (_default_action == NULL)
1206 return NULL;
1207 }
1208 Py_INCREF(_default_action);
Brett Cannonef0e6c32010-09-04 18:24:04 +00001209 if (PyModule_AddObject(m, "_defaultaction", _default_action) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001210 return NULL;
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001211
1212 _filters_version = 0;
Martin v. Löwis1a214512008-06-11 05:26:20 +00001213 return m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001214}