Added more cross-reference targets and tidied up list of useful handlers.
[python.git] / Python / _warnings.c
blob6a970bbb2bb706e79f4e878b00c587baf4353ee6
1 #include "Python.h"
2 #include "code.h" /* For DeprecationWarning about adding 'line'. */
3 #include "frameobject.h"
5 #define MODULE_NAME "_warnings"
6 #define DEFAULT_ACTION_NAME "default_action"
8 PyDoc_STRVAR(warnings__doc__,
9 MODULE_NAME " provides basic warning filtering support.\n"
10 "It is a helper module to speed up interpreter start-up.");
12 /* Both 'filters' and 'onceregistry' can be set in warnings.py;
13 get_warnings_attr() will reset these variables accordingly. */
14 static PyObject *_filters; /* List */
15 static PyObject *_once_registry; /* Dict */
18 static int
19 check_matched(PyObject *obj, PyObject *arg)
21 PyObject *result;
22 int rc;
24 if (obj == Py_None)
25 return 1;
26 result = PyObject_CallMethod(obj, "match", "O", arg);
27 if (result == NULL)
28 return -1;
30 rc = PyObject_IsTrue(result);
31 Py_DECREF(result);
32 return rc;
36 Returns a new reference.
37 A NULL return value can mean false or an error.
39 static PyObject *
40 get_warnings_attr(const char *attr)
42 static PyObject *warnings_str = NULL;
43 PyObject *all_modules;
44 PyObject *warnings_module;
45 int result;
47 if (warnings_str == NULL) {
48 warnings_str = PyString_InternFromString("warnings");
49 if (warnings_str == NULL)
50 return NULL;
53 all_modules = PyImport_GetModuleDict();
54 result = PyDict_Contains(all_modules, warnings_str);
55 if (result == -1 || result == 0)
56 return NULL;
58 warnings_module = PyDict_GetItem(all_modules, warnings_str);
59 if (!PyObject_HasAttrString(warnings_module, attr))
60 return NULL;
61 return PyObject_GetAttrString(warnings_module, attr);
65 static PyObject *
66 get_once_registry(void)
68 PyObject *registry;
70 registry = get_warnings_attr("onceregistry");
71 if (registry == NULL) {
72 if (PyErr_Occurred())
73 return NULL;
74 return _once_registry;
76 Py_DECREF(_once_registry);
77 _once_registry = registry;
78 return registry;
82 /* The item is a borrowed reference. */
83 static const char *
84 get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
85 PyObject *module, PyObject **item)
87 PyObject *action, *m, *d;
88 Py_ssize_t i;
89 PyObject *warnings_filters;
91 warnings_filters = get_warnings_attr("filters");
92 if (warnings_filters == NULL) {
93 if (PyErr_Occurred())
94 return NULL;
96 else {
97 Py_DECREF(_filters);
98 _filters = warnings_filters;
101 if (!PyList_Check(_filters)) {
102 PyErr_SetString(PyExc_ValueError,
103 MODULE_NAME ".filters must be a list");
104 return NULL;
107 /* _filters could change while we are iterating over it. */
108 for (i = 0; i < PyList_GET_SIZE(_filters); i++) {
109 PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
110 Py_ssize_t ln;
111 int is_subclass, good_msg, good_mod;
113 tmp_item = *item = PyList_GET_ITEM(_filters, i);
114 if (PyTuple_Size(tmp_item) != 5) {
115 PyErr_Format(PyExc_ValueError,
116 MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
117 return NULL;
120 /* Python code: action, msg, cat, mod, ln = item */
121 action = PyTuple_GET_ITEM(tmp_item, 0);
122 msg = PyTuple_GET_ITEM(tmp_item, 1);
123 cat = PyTuple_GET_ITEM(tmp_item, 2);
124 mod = PyTuple_GET_ITEM(tmp_item, 3);
125 ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
127 good_msg = check_matched(msg, text);
128 good_mod = check_matched(mod, module);
129 is_subclass = PyObject_IsSubclass(category, cat);
130 ln = PyInt_AsSsize_t(ln_obj);
131 if (good_msg == -1 || good_mod == -1 || is_subclass == -1 ||
132 (ln == -1 && PyErr_Occurred()))
133 return NULL;
135 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln))
136 return PyString_AsString(action);
139 m = PyImport_ImportModule(MODULE_NAME);
140 if (m == NULL)
141 return NULL;
142 d = PyModule_GetDict(m);
143 Py_DECREF(m);
144 if (d == NULL)
145 return NULL;
146 action = PyDict_GetItemString(d, DEFAULT_ACTION_NAME);
147 if (action != NULL)
148 return PyString_AsString(action);
150 PyErr_SetString(PyExc_ValueError,
151 MODULE_NAME "." DEFAULT_ACTION_NAME " not found");
152 return NULL;
155 static int
156 already_warned(PyObject *registry, PyObject *key, int should_set)
158 PyObject *already_warned;
160 if (key == NULL)
161 return -1;
163 already_warned = PyDict_GetItem(registry, key);
164 if (already_warned != NULL) {
165 int rc = PyObject_IsTrue(already_warned);
166 if (rc != 0)
167 return rc;
170 /* This warning wasn't found in the registry, set it. */
171 if (should_set)
172 return PyDict_SetItem(registry, key, Py_True);
173 return 0;
176 /* New reference. */
177 static PyObject *
178 normalize_module(PyObject *filename)
180 PyObject *module;
181 const char *mod_str;
182 Py_ssize_t len;
184 int rc = PyObject_IsTrue(filename);
185 if (rc == -1)
186 return NULL;
187 else if (rc == 0)
188 return PyString_FromString("<unknown>");
190 mod_str = PyString_AsString(filename);
191 if (mod_str == NULL)
192 return NULL;
193 len = PyString_Size(filename);
194 if (len < 0)
195 return NULL;
196 if (len >= 3 &&
197 strncmp(mod_str + (len - 3), ".py", 3) == 0) {
198 module = PyString_FromStringAndSize(mod_str, len-3);
200 else {
201 module = filename;
202 Py_INCREF(module);
204 return module;
207 static int
208 update_registry(PyObject *registry, PyObject *text, PyObject *category,
209 int add_zero)
211 PyObject *altkey, *zero = NULL;
212 int rc;
214 if (add_zero) {
215 zero = PyInt_FromLong(0);
216 if (zero == NULL)
217 return -1;
218 altkey = PyTuple_Pack(3, text, category, zero);
220 else
221 altkey = PyTuple_Pack(2, text, category);
223 rc = already_warned(registry, altkey, 1);
224 Py_XDECREF(zero);
225 Py_XDECREF(altkey);
226 return rc;
229 static void
230 show_warning(PyObject *filename, int lineno, PyObject *text, PyObject
231 *category, PyObject *sourceline)
233 PyObject *f_stderr;
234 PyObject *name;
235 char lineno_str[128];
237 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
239 name = PyObject_GetAttrString(category, "__name__");
240 if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
241 return;
243 f_stderr = PySys_GetObject("stderr");
244 if (f_stderr == NULL) {
245 fprintf(stderr, "lost sys.stderr\n");
246 Py_DECREF(name);
247 return;
250 /* Print "filename:lineno: category: text\n" */
251 PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW);
252 PyFile_WriteString(lineno_str, f_stderr);
253 PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW);
254 PyFile_WriteString(": ", f_stderr);
255 PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW);
256 PyFile_WriteString("\n", f_stderr);
257 Py_XDECREF(name);
259 /* Print " source_line\n" */
260 if (sourceline) {
261 char *source_line_str = PyString_AS_STRING(sourceline);
262 while (*source_line_str == ' ' || *source_line_str == '\t' ||
263 *source_line_str == '\014')
264 source_line_str++;
266 PyFile_WriteString(source_line_str, f_stderr);
267 PyFile_WriteString("\n", f_stderr);
269 else
270 _Py_DisplaySourceLine(f_stderr, PyString_AS_STRING(filename),
271 lineno, 2);
272 PyErr_Clear();
275 static PyObject *
276 warn_explicit(PyObject *category, PyObject *message,
277 PyObject *filename, int lineno,
278 PyObject *module, PyObject *registry, PyObject *sourceline)
280 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
281 PyObject *item = Py_None;
282 const char *action;
283 int rc;
285 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
286 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");
287 return NULL;
290 /* Normalize module. */
291 if (module == NULL) {
292 module = normalize_module(filename);
293 if (module == NULL)
294 return NULL;
296 else
297 Py_INCREF(module);
299 /* Normalize message. */
300 Py_INCREF(message); /* DECREF'ed in cleanup. */
301 rc = PyObject_IsInstance(message, PyExc_Warning);
302 if (rc == -1) {
303 goto cleanup;
305 if (rc == 1) {
306 text = PyObject_Str(message);
307 category = (PyObject*)message->ob_type;
309 else {
310 text = message;
311 message = PyObject_CallFunction(category, "O", message);
312 if (message == NULL)
313 goto cleanup;
316 lineno_obj = PyInt_FromLong(lineno);
317 if (lineno_obj == NULL)
318 goto cleanup;
320 /* Create key. */
321 key = PyTuple_Pack(3, text, category, lineno_obj);
322 if (key == NULL)
323 goto cleanup;
325 if ((registry != NULL) && (registry != Py_None)) {
326 rc = already_warned(registry, key, 0);
327 if (rc == -1)
328 goto cleanup;
329 else if (rc == 1)
330 goto return_none;
331 /* Else this warning hasn't been generated before. */
334 action = get_filter(category, text, lineno, module, &item);
335 if (action == NULL)
336 goto cleanup;
338 if (strcmp(action, "error") == 0) {
339 PyErr_SetObject(category, message);
340 goto cleanup;
343 /* Store in the registry that we've been here, *except* when the action
344 is "always". */
345 rc = 0;
346 if (strcmp(action, "always") != 0) {
347 if (registry != NULL && registry != Py_None &&
348 PyDict_SetItem(registry, key, Py_True) < 0)
349 goto cleanup;
350 else if (strcmp(action, "ignore") == 0)
351 goto return_none;
352 else if (strcmp(action, "once") == 0) {
353 if (registry == NULL || registry == Py_None) {
354 registry = get_once_registry();
355 if (registry == NULL)
356 goto cleanup;
358 /* _once_registry[(text, category)] = 1 */
359 rc = update_registry(registry, text, category, 0);
361 else if (strcmp(action, "module") == 0) {
362 /* registry[(text, category, 0)] = 1 */
363 if (registry != NULL && registry != Py_None)
364 rc = update_registry(registry, text, category, 0);
366 else if (strcmp(action, "default") != 0) {
367 PyObject *to_str = PyObject_Str(item);
368 const char *err_str = "???";
370 if (to_str != NULL)
371 err_str = PyString_AS_STRING(to_str);
372 PyErr_Format(PyExc_RuntimeError,
373 "Unrecognized action (%s) in warnings.filters:\n %s",
374 action, err_str);
375 Py_XDECREF(to_str);
376 goto cleanup;
380 if (rc == 1) /* Already warned for this module. */
381 goto return_none;
382 if (rc == 0) {
383 PyObject *show_fxn = get_warnings_attr("showwarning");
384 if (show_fxn == NULL) {
385 if (PyErr_Occurred())
386 goto cleanup;
387 show_warning(filename, lineno, text, category, sourceline);
389 else {
390 const char *msg = "functions overriding warnings.showwarning() "
391 "must support the 'line' argument";
392 const char *text_char = PyString_AS_STRING(text);
394 if (strcmp(msg, text_char) == 0) {
395 /* Prevent infinite recursion by using built-in implementation
396 of showwarning(). */
397 show_warning(filename, lineno, text, category, sourceline);
399 else {
400 PyObject *check_fxn;
401 PyObject *defaults;
402 PyObject *res;
404 if (PyMethod_Check(show_fxn))
405 check_fxn = PyMethod_Function(show_fxn);
406 else if (PyFunction_Check(show_fxn))
407 check_fxn = show_fxn;
408 else {
409 PyErr_SetString(PyExc_TypeError,
410 "warnings.showwarning() must be set to a "
411 "function or method");
412 Py_DECREF(show_fxn);
413 goto cleanup;
416 defaults = PyFunction_GetDefaults(check_fxn);
417 /* A proper implementation of warnings.showwarning() should
418 have at least two default arguments. */
419 if ((defaults == NULL) || (PyTuple_Size(defaults) < 2)) {
420 PyCodeObject *code = (PyCodeObject *)
421 PyFunction_GetCode(check_fxn);
422 if (!(code->co_flags & CO_VARARGS)) {
423 if (PyErr_WarnEx(PyExc_DeprecationWarning, msg, 1) <
424 0) {
425 Py_DECREF(show_fxn);
426 goto cleanup;
430 res = PyObject_CallFunctionObjArgs(show_fxn, message, category,
431 filename, lineno_obj,
432 NULL);
433 Py_DECREF(show_fxn);
434 Py_XDECREF(res);
435 if (res == NULL)
436 goto cleanup;
440 else /* if (rc == -1) */
441 goto cleanup;
443 return_none:
444 result = Py_None;
445 Py_INCREF(result);
447 cleanup:
448 Py_XDECREF(key);
449 Py_XDECREF(text);
450 Py_XDECREF(lineno_obj);
451 Py_DECREF(module);
452 Py_XDECREF(message);
453 return result; /* Py_None or NULL. */
456 /* filename, module, and registry are new refs, globals is borrowed */
457 /* Returns 0 on error (no new refs), 1 on success */
458 static int
459 setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
460 PyObject **module, PyObject **registry)
462 PyObject *globals;
464 /* Setup globals and lineno. */
465 PyFrameObject *f = PyThreadState_GET()->frame;
466 while (--stack_level > 0 && f != NULL)
467 f = f->f_back;
469 if (f == NULL) {
470 globals = PyThreadState_Get()->interp->sysdict;
471 *lineno = 1;
473 else {
474 globals = f->f_globals;
475 *lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
478 *module = NULL;
480 /* Setup registry. */
481 assert(globals != NULL);
482 assert(PyDict_Check(globals));
483 *registry = PyDict_GetItemString(globals, "__warningregistry__");
484 if (*registry == NULL) {
485 int rc;
487 *registry = PyDict_New();
488 if (*registry == NULL)
489 return 0;
491 rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
492 if (rc < 0)
493 goto handle_error;
495 else
496 Py_INCREF(*registry);
498 /* Setup module. */
499 *module = PyDict_GetItemString(globals, "__name__");
500 if (*module == NULL) {
501 *module = PyString_FromString("<string>");
502 if (*module == NULL)
503 goto handle_error;
505 else
506 Py_INCREF(*module);
508 /* Setup filename. */
509 *filename = PyDict_GetItemString(globals, "__file__");
510 if (*filename != NULL) {
511 Py_ssize_t len = PyString_Size(*filename);
512 const char *file_str = PyString_AsString(*filename);
513 if (file_str == NULL || (len < 0 && PyErr_Occurred()))
514 goto handle_error;
516 /* if filename.lower().endswith((".pyc", ".pyo")): */
517 if (len >= 4 &&
518 file_str[len-4] == '.' &&
519 tolower(file_str[len-3]) == 'p' &&
520 tolower(file_str[len-2]) == 'y' &&
521 (tolower(file_str[len-1]) == 'c' ||
522 tolower(file_str[len-1]) == 'o'))
524 *filename = PyString_FromStringAndSize(file_str, len-1);
525 if (*filename == NULL)
526 goto handle_error;
528 else
529 Py_INCREF(*filename);
531 else {
532 const char *module_str = PyString_AsString(*module);
533 if (module_str && strcmp(module_str, "__main__") == 0) {
534 PyObject *argv = PySys_GetObject("argv");
535 if (argv != NULL && PyList_Size(argv) > 0) {
536 int is_true;
537 *filename = PyList_GetItem(argv, 0);
538 Py_INCREF(*filename);
539 /* If sys.argv[0] is false, then use '__main__'. */
540 is_true = PyObject_IsTrue(*filename);
541 if (is_true < 0) {
542 Py_DECREF(*filename);
543 goto handle_error;
545 else if (!is_true) {
546 Py_DECREF(*filename);
547 *filename = PyString_FromString("__main__");
548 if (*filename == NULL)
549 goto handle_error;
552 else {
553 /* embedded interpreters don't have sys.argv, see bug #839151 */
554 *filename = PyString_FromString("__main__");
555 if (*filename == NULL)
556 goto handle_error;
559 if (*filename == NULL) {
560 *filename = *module;
561 Py_INCREF(*filename);
565 return 1;
567 handle_error:
568 /* filename not XDECREF'ed here as there is no way to jump here with a
569 dangling reference. */
570 Py_XDECREF(*registry);
571 Py_XDECREF(*module);
572 return 0;
575 static PyObject *
576 get_category(PyObject *message, PyObject *category)
578 int rc;
580 /* Get category. */
581 rc = PyObject_IsInstance(message, PyExc_Warning);
582 if (rc == -1)
583 return NULL;
585 if (rc == 1)
586 category = (PyObject*)message->ob_type;
587 else if (category == NULL)
588 category = PyExc_UserWarning;
590 /* Validate category. */
591 rc = PyObject_IsSubclass(category, PyExc_Warning);
592 if (rc == -1)
593 return NULL;
594 if (rc == 0) {
595 PyErr_SetString(PyExc_ValueError,
596 "category is not a subclass of Warning");
597 return NULL;
600 return category;
603 static PyObject *
604 do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level)
606 PyObject *filename, *module, *registry, *res;
607 int lineno;
609 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
610 return NULL;
612 res = warn_explicit(category, message, filename, lineno, module, registry,
613 NULL);
614 Py_DECREF(filename);
615 Py_DECREF(registry);
616 Py_DECREF(module);
617 return res;
620 static PyObject *
621 warnings_warn(PyObject *self, PyObject *args, PyObject *kwds)
623 static char *kw_list[] = { "message", "category", "stacklevel", 0 };
624 PyObject *message, *category = NULL;
625 Py_ssize_t stack_level = 1;
627 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|On:warn", kw_list,
628 &message, &category, &stack_level))
629 return NULL;
631 category = get_category(message, category);
632 if (category == NULL)
633 return NULL;
634 return do_warn(message, category, stack_level);
637 static PyObject *
638 warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
640 static char *kwd_list[] = {"message", "category", "filename", "lineno",
641 "module", "registry", "module_globals", 0};
642 PyObject *message;
643 PyObject *category;
644 PyObject *filename;
645 int lineno;
646 PyObject *module = NULL;
647 PyObject *registry = NULL;
648 PyObject *module_globals = NULL;
650 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOi|OOO:warn_explicit",
651 kwd_list, &message, &category, &filename, &lineno, &module,
652 &registry, &module_globals))
653 return NULL;
655 if (module_globals) {
656 static PyObject *get_source_name = NULL;
657 static PyObject *splitlines_name = NULL;
658 PyObject *loader;
659 PyObject *module_name;
660 PyObject *source;
661 PyObject *source_list;
662 PyObject *source_line;
663 PyObject *returned;
665 if (get_source_name == NULL) {
666 get_source_name = PyString_InternFromString("get_source");
667 if (!get_source_name)
668 return NULL;
670 if (splitlines_name == NULL) {
671 splitlines_name = PyString_InternFromString("splitlines");
672 if (!splitlines_name)
673 return NULL;
676 /* Check/get the requisite pieces needed for the loader. */
677 loader = PyDict_GetItemString(module_globals, "__loader__");
678 module_name = PyDict_GetItemString(module_globals, "__name__");
680 if (loader == NULL || module_name == NULL)
681 goto standard_call;
683 /* Make sure the loader implements the optional get_source() method. */
684 if (!PyObject_HasAttrString(loader, "get_source"))
685 goto standard_call;
686 /* Call get_source() to get the source code. */
687 source = PyObject_CallMethodObjArgs(loader, get_source_name,
688 module_name, NULL);
689 if (!source)
690 return NULL;
691 else if (source == Py_None) {
692 Py_DECREF(Py_None);
693 goto standard_call;
696 /* Split the source into lines. */
697 source_list = PyObject_CallMethodObjArgs(source, splitlines_name,
698 NULL);
699 Py_DECREF(source);
700 if (!source_list)
701 return NULL;
703 /* Get the source line. */
704 source_line = PyList_GetItem(source_list, lineno-1);
705 if (!source_line) {
706 Py_DECREF(source_list);
707 return NULL;
710 /* Handle the warning. */
711 returned = warn_explicit(category, message, filename, lineno, module,
712 registry, source_line);
713 Py_DECREF(source_list);
714 return returned;
717 standard_call:
718 return warn_explicit(category, message, filename, lineno, module,
719 registry, NULL);
723 /* Function to issue a warning message; may raise an exception. */
725 PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
727 PyObject *res;
728 PyObject *message = PyString_FromString(text);
729 if (message == NULL)
730 return -1;
732 if (category == NULL)
733 category = PyExc_RuntimeWarning;
735 res = do_warn(message, category, stack_level);
736 Py_DECREF(message);
737 if (res == NULL)
738 return -1;
739 Py_DECREF(res);
741 return 0;
744 /* PyErr_Warn is only for backwards compatability and will be removed.
745 Use PyErr_WarnEx instead. */
747 #undef PyErr_Warn
749 PyAPI_FUNC(int)
750 PyErr_Warn(PyObject *category, char *text)
752 return PyErr_WarnEx(category, text, 1);
755 /* Warning with explicit origin */
757 PyErr_WarnExplicit(PyObject *category, const char *text,
758 const char *filename_str, int lineno,
759 const char *module_str, PyObject *registry)
761 PyObject *res;
762 PyObject *message = PyString_FromString(text);
763 PyObject *filename = PyString_FromString(filename_str);
764 PyObject *module = NULL;
765 int ret = -1;
767 if (message == NULL || filename == NULL)
768 goto exit;
769 if (module_str != NULL) {
770 module = PyString_FromString(module_str);
771 if (module == NULL)
772 goto exit;
775 if (category == NULL)
776 category = PyExc_RuntimeWarning;
777 res = warn_explicit(category, message, filename, lineno, module, registry,
778 NULL);
779 if (res == NULL)
780 goto exit;
781 Py_DECREF(res);
782 ret = 0;
784 exit:
785 Py_XDECREF(message);
786 Py_XDECREF(module);
787 Py_XDECREF(filename);
788 return ret;
792 PyDoc_STRVAR(warn_doc,
793 "Issue a warning, or maybe ignore it or raise an exception.");
795 PyDoc_STRVAR(warn_explicit_doc,
796 "Low-level inferface to warnings functionality.");
798 static PyMethodDef warnings_functions[] = {
799 {"warn", (PyCFunction)warnings_warn, METH_VARARGS | METH_KEYWORDS,
800 warn_doc},
801 {"warn_explicit", (PyCFunction)warnings_warn_explicit,
802 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
803 /* XXX(brett.cannon): add showwarning? */
804 /* XXX(brett.cannon): Reasonable to add formatwarning? */
805 {NULL, NULL} /* sentinel */
809 static PyObject *
810 create_filter(PyObject *category, const char *action)
812 static PyObject *ignore_str = NULL;
813 static PyObject *error_str = NULL;
814 static PyObject *default_str = NULL;
815 PyObject *action_obj = NULL;
816 PyObject *lineno, *result;
818 if (!strcmp(action, "ignore")) {
819 if (ignore_str == NULL) {
820 ignore_str = PyString_InternFromString("ignore");
821 if (ignore_str == NULL)
822 return NULL;
824 action_obj = ignore_str;
826 else if (!strcmp(action, "error")) {
827 if (error_str == NULL) {
828 error_str = PyString_InternFromString("error");
829 if (error_str == NULL)
830 return NULL;
832 action_obj = error_str;
834 else if (!strcmp(action, "default")) {
835 if (default_str == NULL) {
836 default_str = PyString_InternFromString("default");
837 if (default_str == NULL)
838 return NULL;
840 action_obj = default_str;
842 else {
843 Py_FatalError("unknown action");
846 /* This assumes the line number is zero for now. */
847 lineno = PyInt_FromLong(0);
848 if (lineno == NULL)
849 return NULL;
850 result = PyTuple_Pack(5, action_obj, Py_None, category, Py_None, lineno);
851 Py_DECREF(lineno);
852 return result;
855 static PyObject *
856 init_filters(void)
858 PyObject *filters = PyList_New(3);
859 const char *bytes_action;
860 if (filters == NULL)
861 return NULL;
863 PyList_SET_ITEM(filters, 0,
864 create_filter(PyExc_PendingDeprecationWarning, "ignore"));
865 PyList_SET_ITEM(filters, 1, create_filter(PyExc_ImportWarning, "ignore"));
866 if (Py_BytesWarningFlag > 1)
867 bytes_action = "error";
868 else if (Py_BytesWarningFlag)
869 bytes_action = "default";
870 else
871 bytes_action = "ignore";
872 PyList_SET_ITEM(filters, 2, create_filter(PyExc_BytesWarning,
873 bytes_action));
875 if (PyList_GET_ITEM(filters, 0) == NULL ||
876 PyList_GET_ITEM(filters, 1) == NULL ||
877 PyList_GET_ITEM(filters, 2) == NULL) {
878 Py_DECREF(filters);
879 return NULL;
882 return filters;
886 PyMODINIT_FUNC
887 _PyWarnings_Init(void)
889 PyObject *m, *default_action;
891 m = Py_InitModule3(MODULE_NAME, warnings_functions, warnings__doc__);
892 if (m == NULL)
893 return;
895 _filters = init_filters();
896 if (_filters == NULL)
897 return;
898 Py_INCREF(_filters);
899 if (PyModule_AddObject(m, "filters", _filters) < 0)
900 return;
902 _once_registry = PyDict_New();
903 if (_once_registry == NULL)
904 return;
905 Py_INCREF(_once_registry);
906 if (PyModule_AddObject(m, "once_registry", _once_registry) < 0)
907 return;
909 default_action = PyString_InternFromString("default");
910 if (default_action == NULL)
911 return;
912 if (PyModule_AddObject(m, DEFAULT_ACTION_NAME, default_action) < 0)
913 return;