Home | History | Annotate | Download | only in Python
      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, &registry))
    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                 &registry, &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