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