1 #include "Python.h" 2 #include "frameobject.h" 3 4 #define MODULE_NAME "_warnings" 5 6 PyDoc_STRVAR(warnings__doc__, 7 MODULE_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. */ 12 static PyObject *_filters; /* List */ 13 static PyObject *_once_registry; /* Dict */ 14 static PyObject *_default_action; /* String */ 15 16 17 static int 18 check_matched(PyObject *obj, PyObject *arg) 19 { 20 PyObject *result; 21 int rc; 22 23 if (obj == Py_None) 24 return 1; 25 result = PyObject_CallMethod(obj, "match", "O", arg); 26 if (result == NULL) 27 return -1; 28 29 rc = PyObject_IsTrue(result); 30 Py_DECREF(result); 31 return rc; 32 } 33 34 /* 35 Returns a new reference. 36 A NULL return value can mean false or an error. 37 */ 38 static PyObject * 39 get_warnings_attr(const char *attr) 40 { 41 static PyObject *warnings_str = NULL; 42 PyObject *all_modules; 43 PyObject *warnings_module; 44 int result; 45 46 if (warnings_str == NULL) { 47 warnings_str = PyString_InternFromString("warnings"); 48 if (warnings_str == NULL) 49 return NULL; 50 } 51 52 all_modules = PyImport_GetModuleDict(); 53 result = PyDict_Contains(all_modules, warnings_str); 54 if (result == -1 || result == 0) 55 return NULL; 56 57 warnings_module = PyDict_GetItem(all_modules, warnings_str); 58 if (!PyObject_HasAttrString(warnings_module, attr)) 59 return NULL; 60 return PyObject_GetAttrString(warnings_module, attr); 61 } 62 63 64 static PyObject * 65 get_once_registry(void) 66 { 67 PyObject *registry; 68 69 registry = get_warnings_attr("onceregistry"); 70 if (registry == NULL) { 71 if (PyErr_Occurred()) 72 return NULL; 73 return _once_registry; 74 } 75 if (!PyDict_Check(registry)) { 76 PyErr_SetString(PyExc_TypeError, 77 "warnings.onceregistry must be a dict"); 78 Py_DECREF(registry); 79 return NULL; 80 } 81 Py_DECREF(_once_registry); 82 _once_registry = registry; 83 return registry; 84 } 85 86 87 static PyObject * 88 get_default_action(void) 89 { 90 PyObject *default_action; 91 92 default_action = get_warnings_attr("defaultaction"); 93 if (default_action == NULL) { 94 if (PyErr_Occurred()) { 95 return NULL; 96 } 97 return _default_action; 98 } 99 100 Py_DECREF(_default_action); 101 _default_action = default_action; 102 return default_action; 103 } 104 105 106 /* The item is a borrowed reference. */ 107 static const char * 108 get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, 109 PyObject *module, PyObject **item) 110 { 111 PyObject *action; 112 Py_ssize_t i; 113 PyObject *warnings_filters; 114 115 warnings_filters = get_warnings_attr("filters"); 116 if (warnings_filters == NULL) { 117 if (PyErr_Occurred()) 118 return NULL; 119 } 120 else { 121 Py_DECREF(_filters); 122 _filters = warnings_filters; 123 } 124 125 if (!PyList_Check(_filters)) { 126 PyErr_SetString(PyExc_ValueError, 127 MODULE_NAME ".filters must be a list"); 128 return NULL; 129 } 130 131 /* _filters could change while we are iterating over it. */ 132 for (i = 0; i < PyList_GET_SIZE(_filters); i++) { 133 PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj; 134 Py_ssize_t ln; 135 int is_subclass, good_msg, good_mod; 136 137 tmp_item = *item = PyList_GET_ITEM(_filters, i); 138 if (PyTuple_Size(tmp_item) != 5) { 139 PyErr_Format(PyExc_ValueError, 140 MODULE_NAME ".filters item %zd isn't a 5-tuple", i); 141 return NULL; 142 } 143 144 /* Python code: action, msg, cat, mod, ln = item */ 145 action = PyTuple_GET_ITEM(tmp_item, 0); 146 msg = PyTuple_GET_ITEM(tmp_item, 1); 147 cat = PyTuple_GET_ITEM(tmp_item, 2); 148 mod = PyTuple_GET_ITEM(tmp_item, 3); 149 ln_obj = PyTuple_GET_ITEM(tmp_item, 4); 150 151 good_msg = check_matched(msg, text); 152 good_mod = check_matched(mod, module); 153 is_subclass = PyObject_IsSubclass(category, cat); 154 ln = PyInt_AsSsize_t(ln_obj); 155 if (good_msg == -1 || good_mod == -1 || is_subclass == -1 || 156 (ln == -1 && PyErr_Occurred())) 157 return NULL; 158 159 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) 160 return PyString_AsString(action); 161 } 162 163 action = get_default_action(); 164 if (action != NULL) { 165 return PyString_AsString(action); 166 } 167 168 PyErr_SetString(PyExc_ValueError, 169 MODULE_NAME ".defaultaction not found"); 170 return NULL; 171 } 172 173 174 static int 175 already_warned(PyObject *registry, PyObject *key, int should_set) 176 { 177 PyObject *already_warned; 178 179 if (key == NULL) 180 return -1; 181 182 already_warned = PyDict_GetItem(registry, key); 183 if (already_warned != NULL) { 184 int rc = PyObject_IsTrue(already_warned); 185 if (rc != 0) 186 return rc; 187 } 188 189 /* This warning wasn't found in the registry, set it. */ 190 if (should_set) 191 return PyDict_SetItem(registry, key, Py_True); 192 return 0; 193 } 194 195 /* New reference. */ 196 static PyObject * 197 normalize_module(PyObject *filename) 198 { 199 PyObject *module; 200 const char *mod_str; 201 Py_ssize_t len; 202 203 int rc = PyObject_IsTrue(filename); 204 if (rc == -1) 205 return NULL; 206 else if (rc == 0) 207 return PyString_FromString("<unknown>"); 208 209 mod_str = PyString_AsString(filename); 210 if (mod_str == NULL) 211 return NULL; 212 len = PyString_Size(filename); 213 if (len < 0) 214 return NULL; 215 if (len >= 3 && 216 strncmp(mod_str + (len - 3), ".py", 3) == 0) { 217 module = PyString_FromStringAndSize(mod_str, len-3); 218 } 219 else { 220 module = filename; 221 Py_INCREF(module); 222 } 223 return module; 224 } 225 226 static int 227 update_registry(PyObject *registry, PyObject *text, PyObject *category, 228 int add_zero) 229 { 230 PyObject *altkey, *zero = NULL; 231 int rc; 232 233 if (add_zero) { 234 zero = PyInt_FromLong(0); 235 if (zero == NULL) 236 return -1; 237 altkey = PyTuple_Pack(3, text, category, zero); 238 } 239 else 240 altkey = PyTuple_Pack(2, text, category); 241 242 rc = already_warned(registry, altkey, 1); 243 Py_XDECREF(zero); 244 Py_XDECREF(altkey); 245 return rc; 246 } 247 248 static void 249 show_warning(PyObject *filename, int lineno, PyObject *text, PyObject 250 *category, PyObject *sourceline) 251 { 252 PyObject *f_stderr; 253 PyObject *name; 254 char lineno_str[128]; 255 256 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno); 257 258 name = PyObject_GetAttrString(category, "__name__"); 259 if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */ 260 return; 261 262 f_stderr = PySys_GetObject("stderr"); 263 if (f_stderr == NULL) { 264 fprintf(stderr, "lost sys.stderr\n"); 265 Py_DECREF(name); 266 return; 267 } 268 269 /* Print "filename:lineno: category: text\n" */ 270 PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW); 271 PyFile_WriteString(lineno_str, f_stderr); 272 PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW); 273 PyFile_WriteString(": ", f_stderr); 274 PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW); 275 PyFile_WriteString("\n", f_stderr); 276 Py_XDECREF(name); 277 278 /* Print " source_line\n" */ 279 if (sourceline) { 280 char *source_line_str = PyString_AS_STRING(sourceline); 281 while (*source_line_str == ' ' || *source_line_str == '\t' || 282 *source_line_str == '\014') 283 source_line_str++; 284 285 PyFile_WriteString(source_line_str, f_stderr); 286 PyFile_WriteString("\n", f_stderr); 287 } 288 else 289 _Py_DisplaySourceLine(f_stderr, PyString_AS_STRING(filename), 290 lineno, 2); 291 PyErr_Clear(); 292 } 293 294 static PyObject * 295 warn_explicit(PyObject *category, PyObject *message, 296 PyObject *filename, int lineno, 297 PyObject *module, PyObject *registry, PyObject *sourceline) 298 { 299 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL; 300 PyObject *item = Py_None; 301 const char *action; 302 int rc; 303 304 if (registry && !PyDict_Check(registry) && (registry != Py_None)) { 305 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None"); 306 return NULL; 307 } 308 309 /* Normalize module. */ 310 if (module == NULL) { 311 module = normalize_module(filename); 312 if (module == NULL) 313 return NULL; 314 } 315 else 316 Py_INCREF(module); 317 318 /* Normalize message. */ 319 Py_INCREF(message); /* DECREF'ed in cleanup. */ 320 rc = PyObject_IsInstance(message, PyExc_Warning); 321 if (rc == -1) { 322 goto cleanup; 323 } 324 if (rc == 1) { 325 text = PyObject_Str(message); 326 if (text == NULL) 327 goto cleanup; 328 category = (PyObject*)message->ob_type; 329 } 330 else { 331 text = message; 332 message = PyObject_CallFunction(category, "O", message); 333 if (message == NULL) 334 goto cleanup; 335 } 336 337 lineno_obj = PyInt_FromLong(lineno); 338 if (lineno_obj == NULL) 339 goto cleanup; 340 341 /* Create key. */ 342 key = PyTuple_Pack(3, text, category, lineno_obj); 343 if (key == NULL) 344 goto cleanup; 345 346 if ((registry != NULL) && (registry != Py_None)) { 347 rc = already_warned(registry, key, 0); 348 if (rc == -1) 349 goto cleanup; 350 else if (rc == 1) 351 goto return_none; 352 /* Else this warning hasn't been generated before. */ 353 } 354 355 action = get_filter(category, text, lineno, module, &item); 356 if (action == NULL) 357 goto cleanup; 358 359 if (strcmp(action, "error") == 0) { 360 PyErr_SetObject(category, message); 361 goto cleanup; 362 } 363 364 /* Store in the registry that we've been here, *except* when the action 365 is "always". */ 366 rc = 0; 367 if (strcmp(action, "always") != 0) { 368 if (registry != NULL && registry != Py_None && 369 PyDict_SetItem(registry, key, Py_True) < 0) 370 goto cleanup; 371 else if (strcmp(action, "ignore") == 0) 372 goto return_none; 373 else if (strcmp(action, "once") == 0) { 374 if (registry == NULL || registry == Py_None) { 375 registry = get_once_registry(); 376 if (registry == NULL) 377 goto cleanup; 378 } 379 /* _once_registry[(text, category)] = 1 */ 380 rc = update_registry(registry, text, category, 0); 381 } 382 else if (strcmp(action, "module") == 0) { 383 /* registry[(text, category, 0)] = 1 */ 384 if (registry != NULL && registry != Py_None) 385 rc = update_registry(registry, text, category, 0); 386 } 387 else if (strcmp(action, "default") != 0) { 388 PyObject *to_str = PyObject_Str(item); 389 const char *err_str = "???"; 390 391 if (to_str != NULL) 392 err_str = PyString_AS_STRING(to_str); 393 PyErr_Format(PyExc_RuntimeError, 394 "Unrecognized action (%s) in warnings.filters:\n %s", 395 action, err_str); 396 Py_XDECREF(to_str); 397 goto cleanup; 398 } 399 } 400 401 if (rc == 1) /* Already warned for this module. */ 402 goto return_none; 403 if (rc == 0) { 404 PyObject *show_fxn = get_warnings_attr("showwarning"); 405 if (show_fxn == NULL) { 406 if (PyErr_Occurred()) 407 goto cleanup; 408 show_warning(filename, lineno, text, category, sourceline); 409 } 410 else { 411 PyObject *res; 412 413 if (!PyMethod_Check(show_fxn) && !PyFunction_Check(show_fxn)) { 414 PyErr_SetString(PyExc_TypeError, 415 "warnings.showwarning() must be set to a " 416 "function or method"); 417 Py_DECREF(show_fxn); 418 goto cleanup; 419 } 420 421 res = PyObject_CallFunctionObjArgs(show_fxn, message, category, 422 filename, lineno_obj, 423 NULL); 424 Py_DECREF(show_fxn); 425 Py_XDECREF(res); 426 if (res == NULL) 427 goto cleanup; 428 } 429 } 430 else /* if (rc == -1) */ 431 goto cleanup; 432 433 return_none: 434 result = Py_None; 435 Py_INCREF(result); 436 437 cleanup: 438 Py_XDECREF(key); 439 Py_XDECREF(text); 440 Py_XDECREF(lineno_obj); 441 Py_DECREF(module); 442 Py_XDECREF(message); 443 return result; /* Py_None or NULL. */ 444 } 445 446 /* filename, module, and registry are new refs, globals is borrowed */ 447 /* Returns 0 on error (no new refs), 1 on success */ 448 static int 449 setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, 450 PyObject **module, PyObject **registry) 451 { 452 PyObject *globals; 453 454 /* Setup globals and lineno. */ 455 PyFrameObject *f = PyThreadState_GET()->frame; 456 while (--stack_level > 0 && f != NULL) 457 f = f->f_back; 458 459 if (f == NULL) { 460 globals = PyThreadState_Get()->interp->sysdict; 461 *lineno = 1; 462 } 463 else { 464 globals = f->f_globals; 465 *lineno = PyFrame_GetLineNumber(f); 466 } 467 468 *module = NULL; 469 470 /* Setup registry. */ 471 assert(globals != NULL); 472 assert(PyDict_Check(globals)); 473 *registry = PyDict_GetItemString(globals, "__warningregistry__"); 474 if (*registry == NULL) { 475 int rc; 476 477 *registry = PyDict_New(); 478 if (*registry == NULL) 479 return 0; 480 481 rc = PyDict_SetItemString(globals, "__warningregistry__", *registry); 482 if (rc < 0) 483 goto handle_error; 484 } 485 else 486 Py_INCREF(*registry); 487 488 /* Setup module. */ 489 *module = PyDict_GetItemString(globals, "__name__"); 490 if (*module == NULL) { 491 *module = PyString_FromString("<string>"); 492 if (*module == NULL) 493 goto handle_error; 494 } 495 else 496 Py_INCREF(*module); 497 498 /* Setup filename. */ 499 *filename = PyDict_GetItemString(globals, "__file__"); 500 if (*filename != NULL && PyString_Check(*filename)) { 501 Py_ssize_t len = PyString_Size(*filename); 502 const char *file_str = PyString_AsString(*filename); 503 if (file_str == NULL || (len < 0 && PyErr_Occurred())) 504 goto handle_error; 505 506 /* if filename.lower().endswith((".pyc", ".pyo")): */ 507 if (len >= 4 && 508 file_str[len-4] == '.' && 509 tolower(file_str[len-3]) == 'p' && 510 tolower(file_str[len-2]) == 'y' && 511 (tolower(file_str[len-1]) == 'c' || 512 tolower(file_str[len-1]) == 'o')) 513 { 514 *filename = PyString_FromStringAndSize(file_str, len-1); 515 if (*filename == NULL) 516 goto handle_error; 517 } 518 else 519 Py_INCREF(*filename); 520 } 521 else { 522 const char *module_str = PyString_AsString(*module); 523 *filename = NULL; 524 if (module_str && strcmp(module_str, "__main__") == 0) { 525 PyObject *argv = PySys_GetObject("argv"); 526 if (argv != NULL && PyList_Size(argv) > 0) { 527 int is_true; 528 *filename = PyList_GetItem(argv, 0); 529 Py_INCREF(*filename); 530 /* If sys.argv[0] is false, then use '__main__'. */ 531 is_true = PyObject_IsTrue(*filename); 532 if (is_true < 0) { 533 Py_DECREF(*filename); 534 goto handle_error; 535 } 536 else if (!is_true) { 537 Py_SETREF(*filename, PyString_FromString("__main__")); 538 if (*filename == NULL) 539 goto handle_error; 540 } 541 } 542 else { 543 /* embedded interpreters don't have sys.argv, see bug #839151 */ 544 *filename = PyString_FromString("__main__"); 545 if (*filename == NULL) 546 goto handle_error; 547 } 548 } 549 if (*filename == NULL) { 550 *filename = *module; 551 Py_INCREF(*filename); 552 } 553 } 554 555 return 1; 556 557 handle_error: 558 /* filename not XDECREF'ed here as there is no way to jump here with a 559 dangling reference. */ 560 Py_XDECREF(*registry); 561 Py_XDECREF(*module); 562 return 0; 563 } 564 565 static PyObject * 566 get_category(PyObject *message, PyObject *category) 567 { 568 int rc; 569 570 /* Get category. */ 571 rc = PyObject_IsInstance(message, PyExc_Warning); 572 if (rc == -1) 573 return NULL; 574 575 if (rc == 1) 576 category = (PyObject*)message->ob_type; 577 else if (category == NULL) 578 category = PyExc_UserWarning; 579 580 /* Validate category. */ 581 rc = PyObject_IsSubclass(category, PyExc_Warning); 582 if (rc == -1) 583 return NULL; 584 if (rc == 0) { 585 PyErr_SetString(PyExc_ValueError, 586 "category is not a subclass of Warning"); 587 return NULL; 588 } 589 590 return category; 591 } 592 593 static PyObject * 594 do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level) 595 { 596 PyObject *filename, *module, *registry, *res; 597 int lineno; 598 599 if (!setup_context(stack_level, &filename, &lineno, &module, ®istry)) 600 return NULL; 601 602 res = warn_explicit(category, message, filename, lineno, module, registry, 603 NULL); 604 Py_DECREF(filename); 605 Py_DECREF(registry); 606 Py_DECREF(module); 607 return res; 608 } 609 610 static PyObject * 611 warnings_warn(PyObject *self, PyObject *args, PyObject *kwds) 612 { 613 static char *kw_list[] = { "message", "category", "stacklevel", 0 }; 614 PyObject *message, *category = NULL; 615 Py_ssize_t stack_level = 1; 616 617 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|On:warn", kw_list, 618 &message, &category, &stack_level)) 619 return NULL; 620 621 category = get_category(message, category); 622 if (category == NULL) 623 return NULL; 624 return do_warn(message, category, stack_level); 625 } 626 627 static PyObject * 628 warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) 629 { 630 static char *kwd_list[] = {"message", "category", "filename", "lineno", 631 "module", "registry", "module_globals", 0}; 632 PyObject *message; 633 PyObject *category; 634 PyObject *filename; 635 int lineno; 636 PyObject *module = NULL; 637 PyObject *registry = NULL; 638 PyObject *module_globals = NULL; 639 640 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOi|OOO:warn_explicit", 641 kwd_list, &message, &category, &filename, &lineno, &module, 642 ®istry, &module_globals)) 643 return NULL; 644 645 if (module_globals) { 646 static PyObject *get_source_name = NULL; 647 static PyObject *splitlines_name = NULL; 648 PyObject *loader; 649 PyObject *module_name; 650 PyObject *source; 651 PyObject *source_list; 652 PyObject *source_line; 653 PyObject *returned; 654 655 if (get_source_name == NULL) { 656 get_source_name = PyString_InternFromString("get_source"); 657 if (!get_source_name) 658 return NULL; 659 } 660 if (splitlines_name == NULL) { 661 splitlines_name = PyString_InternFromString("splitlines"); 662 if (!splitlines_name) 663 return NULL; 664 } 665 666 /* Check/get the requisite pieces needed for the loader. */ 667 loader = PyDict_GetItemString(module_globals, "__loader__"); 668 module_name = PyDict_GetItemString(module_globals, "__name__"); 669 670 if (loader == NULL || module_name == NULL) 671 goto standard_call; 672 673 /* Make sure the loader implements the optional get_source() method. */ 674 if (!PyObject_HasAttrString(loader, "get_source")) 675 goto standard_call; 676 /* Call get_source() to get the source code. */ 677 source = PyObject_CallMethodObjArgs(loader, get_source_name, 678 module_name, NULL); 679 if (!source) 680 return NULL; 681 else if (source == Py_None) { 682 Py_DECREF(Py_None); 683 goto standard_call; 684 } 685 686 /* Split the source into lines. */ 687 source_list = PyObject_CallMethodObjArgs((PyObject *)&PyString_Type, 688 splitlines_name, source, 689 NULL); 690 Py_DECREF(source); 691 if (!source_list) 692 return NULL; 693 694 /* Get the source line. */ 695 source_line = PyList_GetItem(source_list, lineno-1); 696 if (!source_line) { 697 Py_DECREF(source_list); 698 return NULL; 699 } 700 701 /* Handle the warning. */ 702 returned = warn_explicit(category, message, filename, lineno, module, 703 registry, source_line); 704 Py_DECREF(source_list); 705 return returned; 706 } 707 708 standard_call: 709 return warn_explicit(category, message, filename, lineno, module, 710 registry, NULL); 711 } 712 713 714 /* Function to issue a warning message; may raise an exception. */ 715 int 716 PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level) 717 { 718 PyObject *res; 719 PyObject *message = PyString_FromString(text); 720 if (message == NULL) 721 return -1; 722 723 if (category == NULL) 724 category = PyExc_RuntimeWarning; 725 726 res = do_warn(message, category, stack_level); 727 Py_DECREF(message); 728 if (res == NULL) 729 return -1; 730 Py_DECREF(res); 731 732 return 0; 733 } 734 735 /* PyErr_Warn is only for backwards compatibility and will be removed. 736 Use PyErr_WarnEx instead. */ 737 738 #undef PyErr_Warn 739 740 PyAPI_FUNC(int) 741 PyErr_Warn(PyObject *category, char *text) 742 { 743 return PyErr_WarnEx(category, text, 1); 744 } 745 746 /* Warning with explicit origin */ 747 int 748 PyErr_WarnExplicit(PyObject *category, const char *text, 749 const char *filename_str, int lineno, 750 const char *module_str, PyObject *registry) 751 { 752 PyObject *res; 753 PyObject *message = PyString_FromString(text); 754 PyObject *filename = PyString_FromString(filename_str); 755 PyObject *module = NULL; 756 int ret = -1; 757 758 if (message == NULL || filename == NULL) 759 goto exit; 760 if (module_str != NULL) { 761 module = PyString_FromString(module_str); 762 if (module == NULL) 763 goto exit; 764 } 765 766 if (category == NULL) 767 category = PyExc_RuntimeWarning; 768 res = warn_explicit(category, message, filename, lineno, module, registry, 769 NULL); 770 if (res == NULL) 771 goto exit; 772 Py_DECREF(res); 773 ret = 0; 774 775 exit: 776 Py_XDECREF(message); 777 Py_XDECREF(module); 778 Py_XDECREF(filename); 779 return ret; 780 } 781 782 783 PyDoc_STRVAR(warn_doc, 784 "Issue a warning, or maybe ignore it or raise an exception."); 785 786 PyDoc_STRVAR(warn_explicit_doc, 787 "Low-level inferface to warnings functionality."); 788 789 static PyMethodDef warnings_functions[] = { 790 {"warn", (PyCFunction)warnings_warn, METH_VARARGS | METH_KEYWORDS, 791 warn_doc}, 792 {"warn_explicit", (PyCFunction)warnings_warn_explicit, 793 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc}, 794 /* XXX(brett.cannon): add showwarning? */ 795 /* XXX(brett.cannon): Reasonable to add formatwarning? */ 796 {NULL, NULL} /* sentinel */ 797 }; 798 799 800 static PyObject * 801 create_filter(PyObject *category, const char *action) 802 { 803 static PyObject *ignore_str = NULL; 804 static PyObject *error_str = NULL; 805 static PyObject *default_str = NULL; 806 PyObject *action_obj = NULL; 807 PyObject *lineno, *result; 808 809 if (!strcmp(action, "ignore")) { 810 if (ignore_str == NULL) { 811 ignore_str = PyString_InternFromString("ignore"); 812 if (ignore_str == NULL) 813 return NULL; 814 } 815 action_obj = ignore_str; 816 } 817 else if (!strcmp(action, "error")) { 818 if (error_str == NULL) { 819 error_str = PyString_InternFromString("error"); 820 if (error_str == NULL) 821 return NULL; 822 } 823 action_obj = error_str; 824 } 825 else if (!strcmp(action, "default")) { 826 if (default_str == NULL) { 827 default_str = PyString_InternFromString("default"); 828 if (default_str == NULL) 829 return NULL; 830 } 831 action_obj = default_str; 832 } 833 else { 834 Py_FatalError("unknown action"); 835 } 836 837 /* This assumes the line number is zero for now. */ 838 lineno = PyInt_FromLong(0); 839 if (lineno == NULL) 840 return NULL; 841 result = PyTuple_Pack(5, action_obj, Py_None, category, Py_None, lineno); 842 Py_DECREF(lineno); 843 return result; 844 } 845 846 static PyObject * 847 init_filters(void) 848 { 849 /* Don't silence DeprecationWarning if -3 or -Q were used. */ 850 PyObject *filters = PyList_New(Py_Py3kWarningFlag || 851 Py_DivisionWarningFlag ? 3 : 4); 852 unsigned int pos = 0; /* Post-incremented in each use. */ 853 unsigned int x; 854 const char *bytes_action; 855 856 if (filters == NULL) 857 return NULL; 858 859 /* If guard changes, make sure to update 'filters' initialization above. */ 860 if (!Py_Py3kWarningFlag && !Py_DivisionWarningFlag) { 861 PyList_SET_ITEM(filters, pos++, 862 create_filter(PyExc_DeprecationWarning, "ignore")); 863 } 864 PyList_SET_ITEM(filters, pos++, 865 create_filter(PyExc_PendingDeprecationWarning, "ignore")); 866 PyList_SET_ITEM(filters, pos++, 867 create_filter(PyExc_ImportWarning, "ignore")); 868 if (Py_BytesWarningFlag > 1) 869 bytes_action = "error"; 870 else if (Py_BytesWarningFlag) 871 bytes_action = "default"; 872 else 873 bytes_action = "ignore"; 874 PyList_SET_ITEM(filters, pos++, create_filter(PyExc_BytesWarning, 875 bytes_action)); 876 877 for (x = 0; x < pos; x += 1) { 878 if (PyList_GET_ITEM(filters, x) == NULL) { 879 Py_DECREF(filters); 880 return NULL; 881 } 882 } 883 884 return filters; 885 } 886 887 888 PyMODINIT_FUNC 889 _PyWarnings_Init(void) 890 { 891 PyObject *m; 892 893 m = Py_InitModule3(MODULE_NAME, warnings_functions, warnings__doc__); 894 if (m == NULL) 895 return; 896 897 _filters = init_filters(); 898 if (_filters == NULL) 899 return; 900 Py_INCREF(_filters); 901 if (PyModule_AddObject(m, "filters", _filters) < 0) 902 return; 903 904 _once_registry = PyDict_New(); 905 if (_once_registry == NULL) 906 return; 907 Py_INCREF(_once_registry); 908 if (PyModule_AddObject(m, "once_registry", _once_registry) < 0) 909 return; 910 911 _default_action = PyString_FromString("default"); 912 if (_default_action == NULL) 913 return; 914 Py_INCREF(_default_action); 915 if (PyModule_AddObject(m, "default_action", _default_action) < 0) 916 return; 917 } 918