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 static long _filters_version;
     16 
     17 _Py_IDENTIFIER(argv);
     18 _Py_IDENTIFIER(stderr);
     19 
     20 static int
     21 check_matched(PyObject *obj, PyObject *arg)
     22 {
     23     PyObject *result;
     24     _Py_IDENTIFIER(match);
     25     int rc;
     26 
     27     if (obj == Py_None)
     28         return 1;
     29     result = _PyObject_CallMethodId(obj, &PyId_match, "O", arg);
     30     if (result == NULL)
     31         return -1;
     32 
     33     rc = PyObject_IsTrue(result);
     34     Py_DECREF(result);
     35     return rc;
     36 }
     37 
     38 /*
     39    Returns a new reference.
     40    A NULL return value can mean false or an error.
     41 */
     42 static PyObject *
     43 get_warnings_attr(const char *attr, int try_import)
     44 {
     45     static PyObject *warnings_str = NULL;
     46     PyObject *all_modules;
     47     PyObject *warnings_module, *obj;
     48 
     49     if (warnings_str == NULL) {
     50         warnings_str = PyUnicode_InternFromString("warnings");
     51         if (warnings_str == NULL)
     52             return NULL;
     53     }
     54 
     55     /* don't try to import after the start of the Python finallization */
     56     if (try_import && _Py_Finalizing == NULL) {
     57         warnings_module = PyImport_Import(warnings_str);
     58         if (warnings_module == NULL) {
     59             /* Fallback to the C implementation if we cannot get
     60                the Python implementation */
     61             PyErr_Clear();
     62             return NULL;
     63         }
     64     }
     65     else {
     66         all_modules = PyImport_GetModuleDict();
     67 
     68         warnings_module = PyDict_GetItem(all_modules, warnings_str);
     69         if (warnings_module == NULL)
     70             return NULL;
     71 
     72         Py_INCREF(warnings_module);
     73     }
     74 
     75     if (!PyObject_HasAttrString(warnings_module, attr)) {
     76         Py_DECREF(warnings_module);
     77         return NULL;
     78     }
     79 
     80     obj = PyObject_GetAttrString(warnings_module, attr);
     81     Py_DECREF(warnings_module);
     82     return obj;
     83 }
     84 
     85 
     86 static PyObject *
     87 get_once_registry(void)
     88 {
     89     PyObject *registry;
     90 
     91     registry = get_warnings_attr("onceregistry", 0);
     92     if (registry == NULL) {
     93         if (PyErr_Occurred())
     94             return NULL;
     95         return _once_registry;
     96     }
     97     Py_DECREF(_once_registry);
     98     _once_registry = registry;
     99     return registry;
    100 }
    101 
    102 
    103 static PyObject *
    104 get_default_action(void)
    105 {
    106     PyObject *default_action;
    107 
    108     default_action = get_warnings_attr("defaultaction", 0);
    109     if (default_action == NULL) {
    110         if (PyErr_Occurred()) {
    111             return NULL;
    112         }
    113         return _default_action;
    114     }
    115 
    116     Py_DECREF(_default_action);
    117     _default_action = default_action;
    118     return default_action;
    119 }
    120 
    121 
    122 /* The item is a new reference. */
    123 static PyObject*
    124 get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
    125            PyObject *module, PyObject **item)
    126 {
    127     PyObject *action;
    128     Py_ssize_t i;
    129     PyObject *warnings_filters;
    130 
    131     warnings_filters = get_warnings_attr("filters", 0);
    132     if (warnings_filters == NULL) {
    133         if (PyErr_Occurred())
    134             return NULL;
    135     }
    136     else {
    137         Py_DECREF(_filters);
    138         _filters = warnings_filters;
    139     }
    140 
    141     if (_filters == NULL || !PyList_Check(_filters)) {
    142         PyErr_SetString(PyExc_ValueError,
    143                         MODULE_NAME ".filters must be a list");
    144         return NULL;
    145     }
    146 
    147     /* _filters could change while we are iterating over it. */
    148     for (i = 0; i < PyList_GET_SIZE(_filters); i++) {
    149         PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
    150         Py_ssize_t ln;
    151         int is_subclass, good_msg, good_mod;
    152 
    153         tmp_item = PyList_GET_ITEM(_filters, i);
    154         if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
    155             PyErr_Format(PyExc_ValueError,
    156                          MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
    157             return NULL;
    158         }
    159 
    160         /* Python code: action, msg, cat, mod, ln = item */
    161         Py_INCREF(tmp_item);
    162         action = PyTuple_GET_ITEM(tmp_item, 0);
    163         msg = PyTuple_GET_ITEM(tmp_item, 1);
    164         cat = PyTuple_GET_ITEM(tmp_item, 2);
    165         mod = PyTuple_GET_ITEM(tmp_item, 3);
    166         ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
    167 
    168         good_msg = check_matched(msg, text);
    169         if (good_msg == -1) {
    170             Py_DECREF(tmp_item);
    171             return NULL;
    172         }
    173 
    174         good_mod = check_matched(mod, module);
    175         if (good_mod == -1) {
    176             Py_DECREF(tmp_item);
    177             return NULL;
    178         }
    179 
    180         is_subclass = PyObject_IsSubclass(category, cat);
    181         if (is_subclass == -1) {
    182             Py_DECREF(tmp_item);
    183             return NULL;
    184         }
    185 
    186         ln = PyLong_AsSsize_t(ln_obj);
    187         if (ln == -1 && PyErr_Occurred()) {
    188             Py_DECREF(tmp_item);
    189             return NULL;
    190         }
    191 
    192         if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
    193             *item = tmp_item;
    194             return action;
    195         }
    196 
    197         Py_DECREF(tmp_item);
    198     }
    199 
    200     action = get_default_action();
    201     if (action != NULL) {
    202         Py_INCREF(Py_None);
    203         *item = Py_None;
    204         return action;
    205     }
    206 
    207     PyErr_SetString(PyExc_ValueError,
    208                     MODULE_NAME ".defaultaction not found");
    209     return NULL;
    210 }
    211 
    212 
    213 static int
    214 already_warned(PyObject *registry, PyObject *key, int should_set)
    215 {
    216     PyObject *version_obj, *already_warned;
    217     _Py_IDENTIFIER(version);
    218 
    219     if (key == NULL)
    220         return -1;
    221 
    222     version_obj = _PyDict_GetItemId(registry, &PyId_version);
    223     if (version_obj == NULL
    224         || !PyLong_CheckExact(version_obj)
    225         || PyLong_AsLong(version_obj) != _filters_version) {
    226         PyDict_Clear(registry);
    227         version_obj = PyLong_FromLong(_filters_version);
    228         if (version_obj == NULL)
    229             return -1;
    230         if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
    231             Py_DECREF(version_obj);
    232             return -1;
    233         }
    234         Py_DECREF(version_obj);
    235     }
    236     else {
    237         already_warned = PyDict_GetItem(registry, key);
    238         if (already_warned != NULL) {
    239             int rc = PyObject_IsTrue(already_warned);
    240             if (rc != 0)
    241                 return rc;
    242         }
    243     }
    244 
    245     /* This warning wasn't found in the registry, set it. */
    246     if (should_set)
    247         return PyDict_SetItem(registry, key, Py_True);
    248     return 0;
    249 }
    250 
    251 /* New reference. */
    252 static PyObject *
    253 normalize_module(PyObject *filename)
    254 {
    255     PyObject *module;
    256     int kind;
    257     void *data;
    258     Py_ssize_t len;
    259 
    260     len = PyUnicode_GetLength(filename);
    261     if (len < 0)
    262         return NULL;
    263 
    264     if (len == 0)
    265         return PyUnicode_FromString("<unknown>");
    266 
    267     kind = PyUnicode_KIND(filename);
    268     data = PyUnicode_DATA(filename);
    269 
    270     /* if filename.endswith(".py"): */
    271     if (len >= 3 &&
    272         PyUnicode_READ(kind, data, len-3) == '.' &&
    273         PyUnicode_READ(kind, data, len-2) == 'p' &&
    274         PyUnicode_READ(kind, data, len-1) == 'y')
    275     {
    276         module = PyUnicode_Substring(filename, 0, len-3);
    277     }
    278     else {
    279         module = filename;
    280         Py_INCREF(module);
    281     }
    282     return module;
    283 }
    284 
    285 static int
    286 update_registry(PyObject *registry, PyObject *text, PyObject *category,
    287                 int add_zero)
    288 {
    289     PyObject *altkey, *zero = NULL;
    290     int rc;
    291 
    292     if (add_zero) {
    293         zero = PyLong_FromLong(0);
    294         if (zero == NULL)
    295             return -1;
    296         altkey = PyTuple_Pack(3, text, category, zero);
    297     }
    298     else
    299         altkey = PyTuple_Pack(2, text, category);
    300 
    301     rc = already_warned(registry, altkey, 1);
    302     Py_XDECREF(zero);
    303     Py_XDECREF(altkey);
    304     return rc;
    305 }
    306 
    307 static void
    308 show_warning(PyObject *filename, int lineno, PyObject *text,
    309              PyObject *category, PyObject *sourceline)
    310 {
    311     PyObject *f_stderr;
    312     PyObject *name;
    313     char lineno_str[128];
    314     _Py_IDENTIFIER(__name__);
    315 
    316     PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
    317 
    318     name = _PyObject_GetAttrId(category, &PyId___name__);
    319     if (name == NULL)  /* XXX Can an object lack a '__name__' attribute? */
    320         goto error;
    321 
    322     f_stderr = _PySys_GetObjectId(&PyId_stderr);
    323     if (f_stderr == NULL) {
    324         fprintf(stderr, "lost sys.stderr\n");
    325         goto error;
    326     }
    327 
    328     /* Print "filename:lineno: category: text\n" */
    329     if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
    330         goto error;
    331     if (PyFile_WriteString(lineno_str, f_stderr) < 0)
    332         goto error;
    333     if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
    334         goto error;
    335     if (PyFile_WriteString(": ", f_stderr) < 0)
    336         goto error;
    337     if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
    338         goto error;
    339     if (PyFile_WriteString("\n", f_stderr) < 0)
    340         goto error;
    341     Py_CLEAR(name);
    342 
    343     /* Print "  source_line\n" */
    344     if (sourceline) {
    345         int kind;
    346         void *data;
    347         Py_ssize_t i, len;
    348         Py_UCS4 ch;
    349         PyObject *truncated;
    350 
    351         if (PyUnicode_READY(sourceline) < 1)
    352             goto error;
    353 
    354         kind = PyUnicode_KIND(sourceline);
    355         data = PyUnicode_DATA(sourceline);
    356         len = PyUnicode_GET_LENGTH(sourceline);
    357         for (i=0; i<len; i++) {
    358             ch = PyUnicode_READ(kind, data, i);
    359             if (ch != ' ' && ch != '\t' && ch != '\014')
    360                 break;
    361         }
    362 
    363         truncated = PyUnicode_Substring(sourceline, i, len);
    364         if (truncated == NULL)
    365             goto error;
    366 
    367         PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
    368         Py_DECREF(truncated);
    369         PyFile_WriteString("\n", f_stderr);
    370     }
    371     else {
    372         _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
    373     }
    374 
    375 error:
    376     Py_XDECREF(name);
    377     PyErr_Clear();
    378 }
    379 
    380 static int
    381 call_show_warning(PyObject *category, PyObject *text, PyObject *message,
    382                   PyObject *filename, int lineno, PyObject *lineno_obj,
    383                   PyObject *sourceline, PyObject *source)
    384 {
    385     PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
    386 
    387     /* If the source parameter is set, try to get the Python implementation.
    388        The Python implementation is able to log the traceback where the source
    389        was allocated, whereas the C implementation doesnt. */
    390     show_fn = get_warnings_attr("_showwarnmsg", source != NULL);
    391     if (show_fn == NULL) {
    392         if (PyErr_Occurred())
    393             return -1;
    394         show_warning(filename, lineno, text, category, sourceline);
    395         return 0;
    396     }
    397 
    398     if (!PyCallable_Check(show_fn)) {
    399         PyErr_SetString(PyExc_TypeError,
    400                 "warnings._showwarnmsg() must be set to a callable");
    401         goto error;
    402     }
    403 
    404     warnmsg_cls = get_warnings_attr("WarningMessage", 0);
    405     if (warnmsg_cls == NULL) {
    406         PyErr_SetString(PyExc_RuntimeError,
    407                 "unable to get warnings.WarningMessage");
    408         goto error;
    409     }
    410 
    411     msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
    412             filename, lineno_obj, Py_None, Py_None, source,
    413             NULL);
    414     Py_DECREF(warnmsg_cls);
    415     if (msg == NULL)
    416         goto error;
    417 
    418     res = PyObject_CallFunctionObjArgs(show_fn, msg, NULL);
    419     Py_DECREF(show_fn);
    420     Py_DECREF(msg);
    421 
    422     if (res == NULL)
    423         return -1;
    424 
    425     Py_DECREF(res);
    426     return 0;
    427 
    428 error:
    429     Py_XDECREF(show_fn);
    430     return -1;
    431 }
    432 
    433 static PyObject *
    434 warn_explicit(PyObject *category, PyObject *message,
    435               PyObject *filename, int lineno,
    436               PyObject *module, PyObject *registry, PyObject *sourceline,
    437               PyObject *source)
    438 {
    439     PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
    440     PyObject *item = NULL;
    441     PyObject *action;
    442     int rc;
    443 
    444     /* module can be None if a warning is emitted late during Python shutdown.
    445        In this case, the Python warnings module was probably unloaded, filters
    446        are no more available to choose as action. It is safer to ignore the
    447        warning and do nothing. */
    448     if (module == Py_None)
    449         Py_RETURN_NONE;
    450 
    451     if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
    452         PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");
    453         return NULL;
    454     }
    455 
    456     /* Normalize module. */
    457     if (module == NULL) {
    458         module = normalize_module(filename);
    459         if (module == NULL)
    460             return NULL;
    461     }
    462     else
    463         Py_INCREF(module);
    464 
    465     /* Normalize message. */
    466     Py_INCREF(message);  /* DECREF'ed in cleanup. */
    467     rc = PyObject_IsInstance(message, PyExc_Warning);
    468     if (rc == -1) {
    469         goto cleanup;
    470     }
    471     if (rc == 1) {
    472         text = PyObject_Str(message);
    473         if (text == NULL)
    474             goto cleanup;
    475         category = (PyObject*)message->ob_type;
    476     }
    477     else {
    478         text = message;
    479         message = PyObject_CallFunction(category, "O", message);
    480         if (message == NULL)
    481             goto cleanup;
    482     }
    483 
    484     lineno_obj = PyLong_FromLong(lineno);
    485     if (lineno_obj == NULL)
    486         goto cleanup;
    487 
    488     /* Create key. */
    489     key = PyTuple_Pack(3, text, category, lineno_obj);
    490     if (key == NULL)
    491         goto cleanup;
    492 
    493     if ((registry != NULL) && (registry != Py_None)) {
    494         rc = already_warned(registry, key, 0);
    495         if (rc == -1)
    496             goto cleanup;
    497         else if (rc == 1)
    498             goto return_none;
    499         /* Else this warning hasn't been generated before. */
    500     }
    501 
    502     action = get_filter(category, text, lineno, module, &item);
    503     if (action == NULL)
    504         goto cleanup;
    505 
    506     if (_PyUnicode_EqualToASCIIString(action, "error")) {
    507         PyErr_SetObject(category, message);
    508         goto cleanup;
    509     }
    510 
    511     /* Store in the registry that we've been here, *except* when the action
    512        is "always". */
    513     rc = 0;
    514     if (!_PyUnicode_EqualToASCIIString(action, "always")) {
    515         if (registry != NULL && registry != Py_None &&
    516                 PyDict_SetItem(registry, key, Py_True) < 0)
    517             goto cleanup;
    518         else if (_PyUnicode_EqualToASCIIString(action, "ignore"))
    519             goto return_none;
    520         else if (_PyUnicode_EqualToASCIIString(action, "once")) {
    521             if (registry == NULL || registry == Py_None) {
    522                 registry = get_once_registry();
    523                 if (registry == NULL)
    524                     goto cleanup;
    525             }
    526             /* _once_registry[(text, category)] = 1 */
    527             rc = update_registry(registry, text, category, 0);
    528         }
    529         else if (_PyUnicode_EqualToASCIIString(action, "module")) {
    530             /* registry[(text, category, 0)] = 1 */
    531             if (registry != NULL && registry != Py_None)
    532                 rc = update_registry(registry, text, category, 0);
    533         }
    534         else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
    535             PyErr_Format(PyExc_RuntimeError,
    536                         "Unrecognized action (%R) in warnings.filters:\n %R",
    537                         action, item);
    538             goto cleanup;
    539         }
    540     }
    541 
    542     if (rc == 1)  /* Already warned for this module. */
    543         goto return_none;
    544     if (rc == 0) {
    545         if (call_show_warning(category, text, message, filename, lineno,
    546                               lineno_obj, sourceline, source) < 0)
    547             goto cleanup;
    548     }
    549     else /* if (rc == -1) */
    550         goto cleanup;
    551 
    552  return_none:
    553     result = Py_None;
    554     Py_INCREF(result);
    555 
    556  cleanup:
    557     Py_XDECREF(item);
    558     Py_XDECREF(key);
    559     Py_XDECREF(text);
    560     Py_XDECREF(lineno_obj);
    561     Py_DECREF(module);
    562     Py_XDECREF(message);
    563     return result;  /* Py_None or NULL. */
    564 }
    565 
    566 static int
    567 is_internal_frame(PyFrameObject *frame)
    568 {
    569     static PyObject *importlib_string = NULL;
    570     static PyObject *bootstrap_string = NULL;
    571     PyObject *filename;
    572     int contains;
    573 
    574     if (importlib_string == NULL) {
    575         importlib_string = PyUnicode_FromString("importlib");
    576         if (importlib_string == NULL) {
    577             return 0;
    578         }
    579 
    580         bootstrap_string = PyUnicode_FromString("_bootstrap");
    581         if (bootstrap_string == NULL) {
    582             Py_DECREF(importlib_string);
    583             return 0;
    584         }
    585         Py_INCREF(importlib_string);
    586         Py_INCREF(bootstrap_string);
    587     }
    588 
    589     if (frame == NULL || frame->f_code == NULL ||
    590             frame->f_code->co_filename == NULL) {
    591         return 0;
    592     }
    593     filename = frame->f_code->co_filename;
    594     if (!PyUnicode_Check(filename)) {
    595         return 0;
    596     }
    597     contains = PyUnicode_Contains(filename, importlib_string);
    598     if (contains < 0) {
    599         return 0;
    600     }
    601     else if (contains > 0) {
    602         contains = PyUnicode_Contains(filename, bootstrap_string);
    603         if (contains < 0) {
    604             return 0;
    605         }
    606         else if (contains > 0) {
    607             return 1;
    608         }
    609     }
    610 
    611     return 0;
    612 }
    613 
    614 static PyFrameObject *
    615 next_external_frame(PyFrameObject *frame)
    616 {
    617     do {
    618         frame = frame->f_back;
    619     } while (frame != NULL && is_internal_frame(frame));
    620 
    621     return frame;
    622 }
    623 
    624 /* filename, module, and registry are new refs, globals is borrowed */
    625 /* Returns 0 on error (no new refs), 1 on success */
    626 static int
    627 setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
    628               PyObject **module, PyObject **registry)
    629 {
    630     PyObject *globals;
    631 
    632     /* Setup globals and lineno. */
    633     PyFrameObject *f = PyThreadState_GET()->frame;
    634     // Stack level comparisons to Python code is off by one as there is no
    635     // warnings-related stack level to avoid.
    636     if (stack_level <= 0 || is_internal_frame(f)) {
    637         while (--stack_level > 0 && f != NULL) {
    638             f = f->f_back;
    639         }
    640     }
    641     else {
    642         while (--stack_level > 0 && f != NULL) {
    643             f = next_external_frame(f);
    644         }
    645     }
    646 
    647     if (f == NULL) {
    648         globals = PyThreadState_Get()->interp->sysdict;
    649         *lineno = 1;
    650     }
    651     else {
    652         globals = f->f_globals;
    653         *lineno = PyFrame_GetLineNumber(f);
    654     }
    655 
    656     *module = NULL;
    657 
    658     /* Setup registry. */
    659     assert(globals != NULL);
    660     assert(PyDict_Check(globals));
    661     *registry = PyDict_GetItemString(globals, "__warningregistry__");
    662     if (*registry == NULL) {
    663         int rc;
    664 
    665         *registry = PyDict_New();
    666         if (*registry == NULL)
    667             return 0;
    668 
    669          rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
    670          if (rc < 0)
    671             goto handle_error;
    672     }
    673     else
    674         Py_INCREF(*registry);
    675 
    676     /* Setup module. */
    677     *module = PyDict_GetItemString(globals, "__name__");
    678     if (*module == NULL) {
    679         *module = PyUnicode_FromString("<string>");
    680         if (*module == NULL)
    681             goto handle_error;
    682     }
    683     else
    684         Py_INCREF(*module);
    685 
    686     /* Setup filename. */
    687     *filename = PyDict_GetItemString(globals, "__file__");
    688     if (*filename != NULL && PyUnicode_Check(*filename)) {
    689         Py_ssize_t len;
    690         int kind;
    691         void *data;
    692 
    693         if (PyUnicode_READY(*filename))
    694             goto handle_error;
    695 
    696         len = PyUnicode_GetLength(*filename);
    697         kind = PyUnicode_KIND(*filename);
    698         data = PyUnicode_DATA(*filename);
    699 
    700 #define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0)
    701         /* if filename.lower().endswith(".pyc"): */
    702         if (len >= 4 &&
    703             PyUnicode_READ(kind, data, len-4) == '.' &&
    704             ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' &&
    705             ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' &&
    706             ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c')
    707         {
    708             *filename = PyUnicode_Substring(*filename, 0,
    709                                             PyUnicode_GET_LENGTH(*filename)-1);
    710             if (*filename == NULL)
    711                 goto handle_error;
    712         }
    713         else
    714             Py_INCREF(*filename);
    715     }
    716     else {
    717         *filename = NULL;
    718         if (*module != Py_None && _PyUnicode_EqualToASCIIString(*module, "__main__")) {
    719             PyObject *argv = _PySys_GetObjectId(&PyId_argv);
    720             /* PyList_Check() is needed because sys.argv is set to None during
    721                Python finalization */
    722             if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) {
    723                 int is_true;
    724                 *filename = PyList_GetItem(argv, 0);
    725                 Py_INCREF(*filename);
    726                 /* If sys.argv[0] is false, then use '__main__'. */
    727                 is_true = PyObject_IsTrue(*filename);
    728                 if (is_true < 0) {
    729                     Py_DECREF(*filename);
    730                     goto handle_error;
    731                 }
    732                 else if (!is_true) {
    733                     Py_SETREF(*filename, PyUnicode_FromString("__main__"));
    734                     if (*filename == NULL)
    735                         goto handle_error;
    736                 }
    737             }
    738             else {
    739                 /* embedded interpreters don't have sys.argv, see bug #839151 */
    740                 *filename = PyUnicode_FromString("__main__");
    741                 if (*filename == NULL)
    742                     goto handle_error;
    743             }
    744         }
    745         if (*filename == NULL) {
    746             *filename = *module;
    747             Py_INCREF(*filename);
    748         }
    749     }
    750 
    751     return 1;
    752 
    753  handle_error:
    754     /* filename not XDECREF'ed here as there is no way to jump here with a
    755        dangling reference. */
    756     Py_XDECREF(*registry);
    757     Py_XDECREF(*module);
    758     return 0;
    759 }
    760 
    761 static PyObject *
    762 get_category(PyObject *message, PyObject *category)
    763 {
    764     int rc;
    765 
    766     /* Get category. */
    767     rc = PyObject_IsInstance(message, PyExc_Warning);
    768     if (rc == -1)
    769         return NULL;
    770 
    771     if (rc == 1)
    772         category = (PyObject*)message->ob_type;
    773     else if (category == NULL || category == Py_None)
    774         category = PyExc_UserWarning;
    775 
    776     /* Validate category. */
    777     rc = PyObject_IsSubclass(category, PyExc_Warning);
    778     /* category is not a subclass of PyExc_Warning or
    779        PyObject_IsSubclass raised an error */
    780     if (rc == -1 || rc == 0) {
    781         PyErr_Format(PyExc_TypeError,
    782                      "category must be a Warning subclass, not '%s'",
    783                      Py_TYPE(category)->tp_name);
    784         return NULL;
    785     }
    786 
    787     return category;
    788 }
    789 
    790 static PyObject *
    791 do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
    792         PyObject *source)
    793 {
    794     PyObject *filename, *module, *registry, *res;
    795     int lineno;
    796 
    797     if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
    798         return NULL;
    799 
    800     res = warn_explicit(category, message, filename, lineno, module, registry,
    801                         NULL, source);
    802     Py_DECREF(filename);
    803     Py_DECREF(registry);
    804     Py_DECREF(module);
    805     return res;
    806 }
    807 
    808 static PyObject *
    809 warnings_warn(PyObject *self, PyObject *args, PyObject *kwds)
    810 {
    811     static char *kw_list[] = {"message", "category", "stacklevel",
    812                               "source", NULL};
    813     PyObject *message, *category = NULL, *source = NULL;
    814     Py_ssize_t stack_level = 1;
    815 
    816     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OnO:warn", kw_list,
    817                                      &message, &category, &stack_level, &source))
    818         return NULL;
    819 
    820     category = get_category(message, category);
    821     if (category == NULL)
    822         return NULL;
    823     return do_warn(message, category, stack_level, source);
    824 }
    825 
    826 static PyObject *
    827 warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
    828 {
    829     static char *kwd_list[] = {"message", "category", "filename", "lineno",
    830                                 "module", "registry", "module_globals",
    831                                 "source", 0};
    832     PyObject *message;
    833     PyObject *category;
    834     PyObject *filename;
    835     int lineno;
    836     PyObject *module = NULL;
    837     PyObject *registry = NULL;
    838     PyObject *module_globals = NULL;
    839     PyObject *sourceobj = NULL;
    840 
    841     if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
    842                 kwd_list, &message, &category, &filename, &lineno, &module,
    843                 &registry, &module_globals, &sourceobj))
    844         return NULL;
    845 
    846     if (module_globals) {
    847         _Py_IDENTIFIER(get_source);
    848         _Py_IDENTIFIER(splitlines);
    849         PyObject *tmp;
    850         PyObject *loader;
    851         PyObject *module_name;
    852         PyObject *source;
    853         PyObject *source_list;
    854         PyObject *source_line;
    855         PyObject *returned;
    856 
    857         if ((tmp = _PyUnicode_FromId(&PyId_get_source)) == NULL)
    858             return NULL;
    859         if ((tmp = _PyUnicode_FromId(&PyId_splitlines)) == NULL)
    860             return NULL;
    861 
    862         /* Check/get the requisite pieces needed for the loader. */
    863         loader = PyDict_GetItemString(module_globals, "__loader__");
    864         module_name = PyDict_GetItemString(module_globals, "__name__");
    865 
    866         if (loader == NULL || module_name == NULL)
    867             goto standard_call;
    868 
    869         /* Make sure the loader implements the optional get_source() method. */
    870         if (!_PyObject_HasAttrId(loader, &PyId_get_source))
    871                 goto standard_call;
    872         /* Call get_source() to get the source code. */
    873         source = PyObject_CallMethodObjArgs(loader, PyId_get_source.object,
    874                                             module_name, NULL);
    875         if (!source)
    876             return NULL;
    877         else if (source == Py_None) {
    878             Py_DECREF(Py_None);
    879             goto standard_call;
    880         }
    881 
    882         /* Split the source into lines. */
    883         source_list = PyObject_CallMethodObjArgs(source,
    884                                                  PyId_splitlines.object,
    885                                                  NULL);
    886         Py_DECREF(source);
    887         if (!source_list)
    888             return NULL;
    889 
    890         /* Get the source line. */
    891         source_line = PyList_GetItem(source_list, lineno-1);
    892         if (!source_line) {
    893             Py_DECREF(source_list);
    894             return NULL;
    895         }
    896 
    897         /* Handle the warning. */
    898         returned = warn_explicit(category, message, filename, lineno, module,
    899                                  registry, source_line, sourceobj);
    900         Py_DECREF(source_list);
    901         return returned;
    902     }
    903 
    904  standard_call:
    905     return warn_explicit(category, message, filename, lineno, module,
    906                          registry, NULL, sourceobj);
    907 }
    908 
    909 static PyObject *
    910 warnings_filters_mutated(PyObject *self, PyObject *args)
    911 {
    912     _filters_version++;
    913     Py_RETURN_NONE;
    914 }
    915 
    916 
    917 /* Function to issue a warning message; may raise an exception. */
    918 
    919 static int
    920 warn_unicode(PyObject *category, PyObject *message,
    921              Py_ssize_t stack_level, PyObject *source)
    922 {
    923     PyObject *res;
    924 
    925     if (category == NULL)
    926         category = PyExc_RuntimeWarning;
    927 
    928     res = do_warn(message, category, stack_level, source);
    929     if (res == NULL)
    930         return -1;
    931     Py_DECREF(res);
    932 
    933     return 0;
    934 }
    935 
    936 static int
    937 _PyErr_WarnFormatV(PyObject *source,
    938                    PyObject *category, Py_ssize_t stack_level,
    939                    const char *format, va_list vargs)
    940 {
    941     PyObject *message;
    942     int res;
    943 
    944     message = PyUnicode_FromFormatV(format, vargs);
    945     if (message == NULL)
    946         return -1;
    947 
    948     res = warn_unicode(category, message, stack_level, source);
    949     Py_DECREF(message);
    950     return res;
    951 }
    952 
    953 int
    954 PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
    955                  const char *format, ...)
    956 {
    957     int res;
    958     va_list vargs;
    959 
    960 #ifdef HAVE_STDARG_PROTOTYPES
    961     va_start(vargs, format);
    962 #else
    963     va_start(vargs);
    964 #endif
    965     res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
    966     va_end(vargs);
    967     return res;
    968 }
    969 
    970 int
    971 PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
    972                       const char *format, ...)
    973 {
    974     int res;
    975     va_list vargs;
    976 
    977 #ifdef HAVE_STDARG_PROTOTYPES
    978     va_start(vargs, format);
    979 #else
    980     va_start(vargs);
    981 #endif
    982     res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
    983                              stack_level, format, vargs);
    984     va_end(vargs);
    985     return res;
    986 }
    987 
    988 
    989 int
    990 PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
    991 {
    992     int ret;
    993     PyObject *message = PyUnicode_FromString(text);
    994     if (message == NULL)
    995         return -1;
    996     ret = warn_unicode(category, message, stack_level, NULL);
    997     Py_DECREF(message);
    998     return ret;
    999 }
   1000 
   1001 /* PyErr_Warn is only for backwards compatibility and will be removed.
   1002    Use PyErr_WarnEx instead. */
   1003 
   1004 #undef PyErr_Warn
   1005 
   1006 PyAPI_FUNC(int)
   1007 PyErr_Warn(PyObject *category, const char *text)
   1008 {
   1009     return PyErr_WarnEx(category, text, 1);
   1010 }
   1011 
   1012 /* Warning with explicit origin */
   1013 int
   1014 PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
   1015                          PyObject *filename, int lineno,
   1016                          PyObject *module, PyObject *registry)
   1017 {
   1018     PyObject *res;
   1019     if (category == NULL)
   1020         category = PyExc_RuntimeWarning;
   1021     res = warn_explicit(category, message, filename, lineno,
   1022                         module, registry, NULL, NULL);
   1023     if (res == NULL)
   1024         return -1;
   1025     Py_DECREF(res);
   1026     return 0;
   1027 }
   1028 
   1029 int
   1030 PyErr_WarnExplicit(PyObject *category, const char *text,
   1031                    const char *filename_str, int lineno,
   1032                    const char *module_str, PyObject *registry)
   1033 {
   1034     PyObject *message = PyUnicode_FromString(text);
   1035     PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
   1036     PyObject *module = NULL;
   1037     int ret = -1;
   1038 
   1039     if (message == NULL || filename == NULL)
   1040         goto exit;
   1041     if (module_str != NULL) {
   1042         module = PyUnicode_FromString(module_str);
   1043         if (module == NULL)
   1044             goto exit;
   1045     }
   1046 
   1047     ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
   1048                                    module, registry);
   1049 
   1050  exit:
   1051     Py_XDECREF(message);
   1052     Py_XDECREF(module);
   1053     Py_XDECREF(filename);
   1054     return ret;
   1055 }
   1056 
   1057 int
   1058 PyErr_WarnExplicitFormat(PyObject *category,
   1059                          const char *filename_str, int lineno,
   1060                          const char *module_str, PyObject *registry,
   1061                          const char *format, ...)
   1062 {
   1063     PyObject *message;
   1064     PyObject *module = NULL;
   1065     PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
   1066     int ret = -1;
   1067     va_list vargs;
   1068 
   1069     if (filename == NULL)
   1070         goto exit;
   1071     if (module_str != NULL) {
   1072         module = PyUnicode_FromString(module_str);
   1073         if (module == NULL)
   1074             goto exit;
   1075     }
   1076 
   1077 #ifdef HAVE_STDARG_PROTOTYPES
   1078     va_start(vargs, format);
   1079 #else
   1080     va_start(vargs);
   1081 #endif
   1082     message = PyUnicode_FromFormatV(format, vargs);
   1083     if (message != NULL) {
   1084         PyObject *res;
   1085         res = warn_explicit(category, message, filename, lineno,
   1086                             module, registry, NULL, NULL);
   1087         Py_DECREF(message);
   1088         if (res != NULL) {
   1089             Py_DECREF(res);
   1090             ret = 0;
   1091         }
   1092     }
   1093     va_end(vargs);
   1094 exit:
   1095     Py_XDECREF(module);
   1096     Py_XDECREF(filename);
   1097     return ret;
   1098 }
   1099 
   1100 
   1101 PyDoc_STRVAR(warn_doc,
   1102 "Issue a warning, or maybe ignore it or raise an exception.");
   1103 
   1104 PyDoc_STRVAR(warn_explicit_doc,
   1105 "Low-level inferface to warnings functionality.");
   1106 
   1107 static PyMethodDef warnings_functions[] = {
   1108     {"warn", (PyCFunction)warnings_warn, METH_VARARGS | METH_KEYWORDS,
   1109         warn_doc},
   1110     {"warn_explicit", (PyCFunction)warnings_warn_explicit,
   1111         METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
   1112     {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
   1113         NULL},
   1114     /* XXX(brett.cannon): add showwarning? */
   1115     /* XXX(brett.cannon): Reasonable to add formatwarning? */
   1116     {NULL, NULL}                /* sentinel */
   1117 };
   1118 
   1119 
   1120 static PyObject *
   1121 create_filter(PyObject *category, const char *action)
   1122 {
   1123     static PyObject *ignore_str = NULL;
   1124     static PyObject *error_str = NULL;
   1125     static PyObject *default_str = NULL;
   1126     static PyObject *always_str = NULL;
   1127     PyObject *action_obj = NULL;
   1128     PyObject *lineno, *result;
   1129 
   1130     if (!strcmp(action, "ignore")) {
   1131         if (ignore_str == NULL) {
   1132             ignore_str = PyUnicode_InternFromString("ignore");
   1133             if (ignore_str == NULL)
   1134                 return NULL;
   1135         }
   1136         action_obj = ignore_str;
   1137     }
   1138     else if (!strcmp(action, "error")) {
   1139         if (error_str == NULL) {
   1140             error_str = PyUnicode_InternFromString("error");
   1141             if (error_str == NULL)
   1142                 return NULL;
   1143         }
   1144         action_obj = error_str;
   1145     }
   1146     else if (!strcmp(action, "default")) {
   1147         if (default_str == NULL) {
   1148             default_str = PyUnicode_InternFromString("default");
   1149             if (default_str == NULL)
   1150                 return NULL;
   1151         }
   1152         action_obj = default_str;
   1153     }
   1154     else if (!strcmp(action, "always")) {
   1155         if (always_str == NULL) {
   1156             always_str = PyUnicode_InternFromString("always");
   1157             if (always_str == NULL)
   1158                 return NULL;
   1159         }
   1160         action_obj = always_str;
   1161     }
   1162     else {
   1163         Py_FatalError("unknown action");
   1164     }
   1165 
   1166     /* This assumes the line number is zero for now. */
   1167     lineno = PyLong_FromLong(0);
   1168     if (lineno == NULL)
   1169         return NULL;
   1170     result = PyTuple_Pack(5, action_obj, Py_None, category, Py_None, lineno);
   1171     Py_DECREF(lineno);
   1172     return result;
   1173 }
   1174 
   1175 static PyObject *
   1176 init_filters(void)
   1177 {
   1178     PyObject *filters = PyList_New(5);
   1179     unsigned int pos = 0;  /* Post-incremented in each use. */
   1180     unsigned int x;
   1181     const char *bytes_action, *resource_action;
   1182 
   1183     if (filters == NULL)
   1184         return NULL;
   1185 
   1186     PyList_SET_ITEM(filters, pos++,
   1187                     create_filter(PyExc_DeprecationWarning, "ignore"));
   1188     PyList_SET_ITEM(filters, pos++,
   1189                     create_filter(PyExc_PendingDeprecationWarning, "ignore"));
   1190     PyList_SET_ITEM(filters, pos++,
   1191                     create_filter(PyExc_ImportWarning, "ignore"));
   1192     if (Py_BytesWarningFlag > 1)
   1193         bytes_action = "error";
   1194     else if (Py_BytesWarningFlag)
   1195         bytes_action = "default";
   1196     else
   1197         bytes_action = "ignore";
   1198     PyList_SET_ITEM(filters, pos++, create_filter(PyExc_BytesWarning,
   1199                     bytes_action));
   1200     /* resource usage warnings are enabled by default in pydebug mode */
   1201 #ifdef Py_DEBUG
   1202     resource_action = "always";
   1203 #else
   1204     resource_action = "ignore";
   1205 #endif
   1206     PyList_SET_ITEM(filters, pos++, create_filter(PyExc_ResourceWarning,
   1207                     resource_action));
   1208     for (x = 0; x < pos; x += 1) {
   1209         if (PyList_GET_ITEM(filters, x) == NULL) {
   1210             Py_DECREF(filters);
   1211             return NULL;
   1212         }
   1213     }
   1214 
   1215     return filters;
   1216 }
   1217 
   1218 static struct PyModuleDef warningsmodule = {
   1219         PyModuleDef_HEAD_INIT,
   1220         MODULE_NAME,
   1221         warnings__doc__,
   1222         0,
   1223         warnings_functions,
   1224         NULL,
   1225         NULL,
   1226         NULL,
   1227         NULL
   1228 };
   1229 
   1230 
   1231 PyMODINIT_FUNC
   1232 _PyWarnings_Init(void)
   1233 {
   1234     PyObject *m;
   1235 
   1236     m = PyModule_Create(&warningsmodule);
   1237     if (m == NULL)
   1238         return NULL;
   1239 
   1240     if (_filters == NULL) {
   1241         _filters = init_filters();
   1242         if (_filters == NULL)
   1243             return NULL;
   1244     }
   1245     Py_INCREF(_filters);
   1246     if (PyModule_AddObject(m, "filters", _filters) < 0)
   1247         return NULL;
   1248 
   1249     if (_once_registry == NULL) {
   1250         _once_registry = PyDict_New();
   1251         if (_once_registry == NULL)
   1252             return NULL;
   1253     }
   1254     Py_INCREF(_once_registry);
   1255     if (PyModule_AddObject(m, "_onceregistry", _once_registry) < 0)
   1256         return NULL;
   1257 
   1258     if (_default_action == NULL) {
   1259         _default_action = PyUnicode_FromString("default");
   1260         if (_default_action == NULL)
   1261             return NULL;
   1262     }
   1263     Py_INCREF(_default_action);
   1264     if (PyModule_AddObject(m, "_defaultaction", _default_action) < 0)
   1265         return NULL;
   1266 
   1267     _filters_version = 0;
   1268     return m;
   1269 }
   1270