17db96d56Sopenharmony_ci#include "Python.h"
27db96d56Sopenharmony_ci#include "pycore_initconfig.h"
37db96d56Sopenharmony_ci#include "pycore_interp.h"        // PyInterpreterState.warnings
47db96d56Sopenharmony_ci#include "pycore_long.h"          // _PyLong_GetZero()
57db96d56Sopenharmony_ci#include "pycore_pyerrors.h"
67db96d56Sopenharmony_ci#include "pycore_pystate.h"       // _PyThreadState_GET()
77db96d56Sopenharmony_ci#include "pycore_frame.h"
87db96d56Sopenharmony_ci#include "clinic/_warnings.c.h"
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ci#define MODULE_NAME "_warnings"
117db96d56Sopenharmony_ci
127db96d56Sopenharmony_ciPyDoc_STRVAR(warnings__doc__,
137db96d56Sopenharmony_ciMODULE_NAME " provides basic warning filtering support.\n"
147db96d56Sopenharmony_ci"It is a helper module to speed up interpreter start-up.");
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci/*************************************************************************/
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_citypedef struct _warnings_runtime_state WarningsState;
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_cistatic inline int
227db96d56Sopenharmony_cicheck_interp(PyInterpreterState *interp)
237db96d56Sopenharmony_ci{
247db96d56Sopenharmony_ci    if (interp == NULL) {
257db96d56Sopenharmony_ci        PyErr_SetString(PyExc_RuntimeError,
267db96d56Sopenharmony_ci                        "warnings_get_state: could not identify "
277db96d56Sopenharmony_ci                        "current interpreter");
287db96d56Sopenharmony_ci        return 0;
297db96d56Sopenharmony_ci    }
307db96d56Sopenharmony_ci    return 1;
317db96d56Sopenharmony_ci}
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_cistatic inline PyInterpreterState *
347db96d56Sopenharmony_ciget_current_interp(void)
357db96d56Sopenharmony_ci{
367db96d56Sopenharmony_ci    PyInterpreterState *interp = _PyInterpreterState_GET();
377db96d56Sopenharmony_ci    return check_interp(interp) ? interp : NULL;
387db96d56Sopenharmony_ci}
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_cistatic inline PyThreadState *
417db96d56Sopenharmony_ciget_current_tstate(void)
427db96d56Sopenharmony_ci{
437db96d56Sopenharmony_ci    PyThreadState *tstate = _PyThreadState_GET();
447db96d56Sopenharmony_ci    if (tstate == NULL) {
457db96d56Sopenharmony_ci        (void)check_interp(NULL);
467db96d56Sopenharmony_ci        return NULL;
477db96d56Sopenharmony_ci    }
487db96d56Sopenharmony_ci    return check_interp(tstate->interp) ? tstate : NULL;
497db96d56Sopenharmony_ci}
507db96d56Sopenharmony_ci
517db96d56Sopenharmony_ci/* Given a module object, get its per-module state. */
527db96d56Sopenharmony_cistatic WarningsState *
537db96d56Sopenharmony_ciwarnings_get_state(PyInterpreterState *interp)
547db96d56Sopenharmony_ci{
557db96d56Sopenharmony_ci    return &interp->warnings;
567db96d56Sopenharmony_ci}
577db96d56Sopenharmony_ci
587db96d56Sopenharmony_ci/* Clear the given warnings module state. */
597db96d56Sopenharmony_cistatic void
607db96d56Sopenharmony_ciwarnings_clear_state(WarningsState *st)
617db96d56Sopenharmony_ci{
627db96d56Sopenharmony_ci    Py_CLEAR(st->filters);
637db96d56Sopenharmony_ci    Py_CLEAR(st->once_registry);
647db96d56Sopenharmony_ci    Py_CLEAR(st->default_action);
657db96d56Sopenharmony_ci}
667db96d56Sopenharmony_ci
677db96d56Sopenharmony_ci#ifndef Py_DEBUG
687db96d56Sopenharmony_cistatic PyObject *
697db96d56Sopenharmony_cicreate_filter(PyObject *category, PyObject *action_str, const char *modname)
707db96d56Sopenharmony_ci{
717db96d56Sopenharmony_ci    PyObject *modname_obj = NULL;
727db96d56Sopenharmony_ci
737db96d56Sopenharmony_ci    /* Default to "no module name" for initial filter set */
747db96d56Sopenharmony_ci    if (modname != NULL) {
757db96d56Sopenharmony_ci        modname_obj = PyUnicode_InternFromString(modname);
767db96d56Sopenharmony_ci        if (modname_obj == NULL) {
777db96d56Sopenharmony_ci            return NULL;
787db96d56Sopenharmony_ci        }
797db96d56Sopenharmony_ci    } else {
807db96d56Sopenharmony_ci        modname_obj = Py_NewRef(Py_None);
817db96d56Sopenharmony_ci    }
827db96d56Sopenharmony_ci
837db96d56Sopenharmony_ci    /* This assumes the line number is zero for now. */
847db96d56Sopenharmony_ci    PyObject *filter = PyTuple_Pack(5, action_str, Py_None,
857db96d56Sopenharmony_ci                                    category, modname_obj, _PyLong_GetZero());
867db96d56Sopenharmony_ci    Py_DECREF(modname_obj);
877db96d56Sopenharmony_ci    return filter;
887db96d56Sopenharmony_ci}
897db96d56Sopenharmony_ci#endif
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_cistatic PyObject *
927db96d56Sopenharmony_ciinit_filters(PyInterpreterState *interp)
937db96d56Sopenharmony_ci{
947db96d56Sopenharmony_ci#ifdef Py_DEBUG
957db96d56Sopenharmony_ci    /* Py_DEBUG builds show all warnings by default */
967db96d56Sopenharmony_ci    return PyList_New(0);
977db96d56Sopenharmony_ci#else
987db96d56Sopenharmony_ci    /* Other builds ignore a number of warning categories by default */
997db96d56Sopenharmony_ci    PyObject *filters = PyList_New(5);
1007db96d56Sopenharmony_ci    if (filters == NULL) {
1017db96d56Sopenharmony_ci        return NULL;
1027db96d56Sopenharmony_ci    }
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_ci    size_t pos = 0;  /* Post-incremented in each use. */
1057db96d56Sopenharmony_ci#define ADD(TYPE, ACTION, MODNAME) \
1067db96d56Sopenharmony_ci    PyList_SET_ITEM(filters, pos++, \
1077db96d56Sopenharmony_ci                    create_filter(TYPE, &_Py_ID(ACTION), MODNAME));
1087db96d56Sopenharmony_ci    ADD(PyExc_DeprecationWarning, default, "__main__");
1097db96d56Sopenharmony_ci    ADD(PyExc_DeprecationWarning, ignore, NULL);
1107db96d56Sopenharmony_ci    ADD(PyExc_PendingDeprecationWarning, ignore, NULL);
1117db96d56Sopenharmony_ci    ADD(PyExc_ImportWarning, ignore, NULL);
1127db96d56Sopenharmony_ci    ADD(PyExc_ResourceWarning, ignore, NULL);
1137db96d56Sopenharmony_ci#undef ADD
1147db96d56Sopenharmony_ci
1157db96d56Sopenharmony_ci    for (size_t x = 0; x < pos; x++) {
1167db96d56Sopenharmony_ci        if (PyList_GET_ITEM(filters, x) == NULL) {
1177db96d56Sopenharmony_ci            Py_DECREF(filters);
1187db96d56Sopenharmony_ci            return NULL;
1197db96d56Sopenharmony_ci        }
1207db96d56Sopenharmony_ci    }
1217db96d56Sopenharmony_ci    return filters;
1227db96d56Sopenharmony_ci#endif
1237db96d56Sopenharmony_ci}
1247db96d56Sopenharmony_ci
1257db96d56Sopenharmony_ci/* Initialize the given warnings module state. */
1267db96d56Sopenharmony_ciint
1277db96d56Sopenharmony_ci_PyWarnings_InitState(PyInterpreterState *interp)
1287db96d56Sopenharmony_ci{
1297db96d56Sopenharmony_ci    WarningsState *st = &interp->warnings;
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ci    if (st->filters == NULL) {
1327db96d56Sopenharmony_ci        st->filters = init_filters(interp);
1337db96d56Sopenharmony_ci        if (st->filters == NULL) {
1347db96d56Sopenharmony_ci            return -1;
1357db96d56Sopenharmony_ci        }
1367db96d56Sopenharmony_ci    }
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci    if (st->once_registry == NULL) {
1397db96d56Sopenharmony_ci        st->once_registry = PyDict_New();
1407db96d56Sopenharmony_ci        if (st->once_registry == NULL) {
1417db96d56Sopenharmony_ci            return -1;
1427db96d56Sopenharmony_ci        }
1437db96d56Sopenharmony_ci    }
1447db96d56Sopenharmony_ci
1457db96d56Sopenharmony_ci    if (st->default_action == NULL) {
1467db96d56Sopenharmony_ci        st->default_action = PyUnicode_FromString("default");
1477db96d56Sopenharmony_ci        if (st->default_action == NULL) {
1487db96d56Sopenharmony_ci            return -1;
1497db96d56Sopenharmony_ci        }
1507db96d56Sopenharmony_ci    }
1517db96d56Sopenharmony_ci
1527db96d56Sopenharmony_ci    st->filters_version = 0;
1537db96d56Sopenharmony_ci    return 0;
1547db96d56Sopenharmony_ci}
1557db96d56Sopenharmony_ci
1567db96d56Sopenharmony_ci
1577db96d56Sopenharmony_ci/*************************************************************************/
1587db96d56Sopenharmony_ci
1597db96d56Sopenharmony_cistatic int
1607db96d56Sopenharmony_cicheck_matched(PyInterpreterState *interp, PyObject *obj, PyObject *arg)
1617db96d56Sopenharmony_ci{
1627db96d56Sopenharmony_ci    PyObject *result;
1637db96d56Sopenharmony_ci    int rc;
1647db96d56Sopenharmony_ci
1657db96d56Sopenharmony_ci    /* A 'None' filter always matches */
1667db96d56Sopenharmony_ci    if (obj == Py_None)
1677db96d56Sopenharmony_ci        return 1;
1687db96d56Sopenharmony_ci
1697db96d56Sopenharmony_ci    /* An internal plain text default filter must match exactly */
1707db96d56Sopenharmony_ci    if (PyUnicode_CheckExact(obj)) {
1717db96d56Sopenharmony_ci        int cmp_result = PyUnicode_Compare(obj, arg);
1727db96d56Sopenharmony_ci        if (cmp_result == -1 && PyErr_Occurred()) {
1737db96d56Sopenharmony_ci            return -1;
1747db96d56Sopenharmony_ci        }
1757db96d56Sopenharmony_ci        return !cmp_result;
1767db96d56Sopenharmony_ci    }
1777db96d56Sopenharmony_ci
1787db96d56Sopenharmony_ci    /* Otherwise assume a regex filter and call its match() method */
1797db96d56Sopenharmony_ci    result = PyObject_CallMethodOneArg(obj, &_Py_ID(match), arg);
1807db96d56Sopenharmony_ci    if (result == NULL)
1817db96d56Sopenharmony_ci        return -1;
1827db96d56Sopenharmony_ci
1837db96d56Sopenharmony_ci    rc = PyObject_IsTrue(result);
1847db96d56Sopenharmony_ci    Py_DECREF(result);
1857db96d56Sopenharmony_ci    return rc;
1867db96d56Sopenharmony_ci}
1877db96d56Sopenharmony_ci
1887db96d56Sopenharmony_ci#define GET_WARNINGS_ATTR(interp, ATTR, try_import) \
1897db96d56Sopenharmony_ci    get_warnings_attr(interp, &_Py_ID(ATTR), try_import)
1907db96d56Sopenharmony_ci
1917db96d56Sopenharmony_ci/*
1927db96d56Sopenharmony_ci   Returns a new reference.
1937db96d56Sopenharmony_ci   A NULL return value can mean false or an error.
1947db96d56Sopenharmony_ci*/
1957db96d56Sopenharmony_cistatic PyObject *
1967db96d56Sopenharmony_ciget_warnings_attr(PyInterpreterState *interp, PyObject *attr, int try_import)
1977db96d56Sopenharmony_ci{
1987db96d56Sopenharmony_ci    PyObject *warnings_module, *obj;
1997db96d56Sopenharmony_ci
2007db96d56Sopenharmony_ci    /* don't try to import after the start of the Python finallization */
2017db96d56Sopenharmony_ci    if (try_import && !_Py_IsFinalizing()) {
2027db96d56Sopenharmony_ci        warnings_module = PyImport_Import(&_Py_ID(warnings));
2037db96d56Sopenharmony_ci        if (warnings_module == NULL) {
2047db96d56Sopenharmony_ci            /* Fallback to the C implementation if we cannot get
2057db96d56Sopenharmony_ci               the Python implementation */
2067db96d56Sopenharmony_ci            if (PyErr_ExceptionMatches(PyExc_ImportError)) {
2077db96d56Sopenharmony_ci                PyErr_Clear();
2087db96d56Sopenharmony_ci            }
2097db96d56Sopenharmony_ci            return NULL;
2107db96d56Sopenharmony_ci        }
2117db96d56Sopenharmony_ci    }
2127db96d56Sopenharmony_ci    else {
2137db96d56Sopenharmony_ci        /* if we're so late into Python finalization that the module dict is
2147db96d56Sopenharmony_ci           gone, then we can't even use PyImport_GetModule without triggering
2157db96d56Sopenharmony_ci           an interpreter abort.
2167db96d56Sopenharmony_ci        */
2177db96d56Sopenharmony_ci        if (!interp->modules) {
2187db96d56Sopenharmony_ci            return NULL;
2197db96d56Sopenharmony_ci        }
2207db96d56Sopenharmony_ci        warnings_module = PyImport_GetModule(&_Py_ID(warnings));
2217db96d56Sopenharmony_ci        if (warnings_module == NULL)
2227db96d56Sopenharmony_ci            return NULL;
2237db96d56Sopenharmony_ci    }
2247db96d56Sopenharmony_ci
2257db96d56Sopenharmony_ci    (void)_PyObject_LookupAttr(warnings_module, attr, &obj);
2267db96d56Sopenharmony_ci    Py_DECREF(warnings_module);
2277db96d56Sopenharmony_ci    return obj;
2287db96d56Sopenharmony_ci}
2297db96d56Sopenharmony_ci
2307db96d56Sopenharmony_ci
2317db96d56Sopenharmony_cistatic PyObject *
2327db96d56Sopenharmony_ciget_once_registry(PyInterpreterState *interp)
2337db96d56Sopenharmony_ci{
2347db96d56Sopenharmony_ci    PyObject *registry;
2357db96d56Sopenharmony_ci
2367db96d56Sopenharmony_ci    WarningsState *st = warnings_get_state(interp);
2377db96d56Sopenharmony_ci    if (st == NULL) {
2387db96d56Sopenharmony_ci        return NULL;
2397db96d56Sopenharmony_ci    }
2407db96d56Sopenharmony_ci
2417db96d56Sopenharmony_ci    registry = GET_WARNINGS_ATTR(interp, onceregistry, 0);
2427db96d56Sopenharmony_ci    if (registry == NULL) {
2437db96d56Sopenharmony_ci        if (PyErr_Occurred())
2447db96d56Sopenharmony_ci            return NULL;
2457db96d56Sopenharmony_ci        assert(st->once_registry);
2467db96d56Sopenharmony_ci        return st->once_registry;
2477db96d56Sopenharmony_ci    }
2487db96d56Sopenharmony_ci    if (!PyDict_Check(registry)) {
2497db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
2507db96d56Sopenharmony_ci                     MODULE_NAME ".onceregistry must be a dict, "
2517db96d56Sopenharmony_ci                     "not '%.200s'",
2527db96d56Sopenharmony_ci                     Py_TYPE(registry)->tp_name);
2537db96d56Sopenharmony_ci        Py_DECREF(registry);
2547db96d56Sopenharmony_ci        return NULL;
2557db96d56Sopenharmony_ci    }
2567db96d56Sopenharmony_ci    Py_SETREF(st->once_registry, registry);
2577db96d56Sopenharmony_ci    return registry;
2587db96d56Sopenharmony_ci}
2597db96d56Sopenharmony_ci
2607db96d56Sopenharmony_ci
2617db96d56Sopenharmony_cistatic PyObject *
2627db96d56Sopenharmony_ciget_default_action(PyInterpreterState *interp)
2637db96d56Sopenharmony_ci{
2647db96d56Sopenharmony_ci    PyObject *default_action;
2657db96d56Sopenharmony_ci
2667db96d56Sopenharmony_ci    WarningsState *st = warnings_get_state(interp);
2677db96d56Sopenharmony_ci    if (st == NULL) {
2687db96d56Sopenharmony_ci        return NULL;
2697db96d56Sopenharmony_ci    }
2707db96d56Sopenharmony_ci
2717db96d56Sopenharmony_ci    default_action = GET_WARNINGS_ATTR(interp, defaultaction, 0);
2727db96d56Sopenharmony_ci    if (default_action == NULL) {
2737db96d56Sopenharmony_ci        if (PyErr_Occurred()) {
2747db96d56Sopenharmony_ci            return NULL;
2757db96d56Sopenharmony_ci        }
2767db96d56Sopenharmony_ci        assert(st->default_action);
2777db96d56Sopenharmony_ci        return st->default_action;
2787db96d56Sopenharmony_ci    }
2797db96d56Sopenharmony_ci    if (!PyUnicode_Check(default_action)) {
2807db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
2817db96d56Sopenharmony_ci                     MODULE_NAME ".defaultaction must be a string, "
2827db96d56Sopenharmony_ci                     "not '%.200s'",
2837db96d56Sopenharmony_ci                     Py_TYPE(default_action)->tp_name);
2847db96d56Sopenharmony_ci        Py_DECREF(default_action);
2857db96d56Sopenharmony_ci        return NULL;
2867db96d56Sopenharmony_ci    }
2877db96d56Sopenharmony_ci    Py_SETREF(st->default_action, default_action);
2887db96d56Sopenharmony_ci    return default_action;
2897db96d56Sopenharmony_ci}
2907db96d56Sopenharmony_ci
2917db96d56Sopenharmony_ci
2927db96d56Sopenharmony_ci/* The item is a new reference. */
2937db96d56Sopenharmony_cistatic PyObject*
2947db96d56Sopenharmony_ciget_filter(PyInterpreterState *interp, PyObject *category,
2957db96d56Sopenharmony_ci           PyObject *text, Py_ssize_t lineno,
2967db96d56Sopenharmony_ci           PyObject *module, PyObject **item)
2977db96d56Sopenharmony_ci{
2987db96d56Sopenharmony_ci    PyObject *action;
2997db96d56Sopenharmony_ci    Py_ssize_t i;
3007db96d56Sopenharmony_ci    PyObject *warnings_filters;
3017db96d56Sopenharmony_ci    WarningsState *st = warnings_get_state(interp);
3027db96d56Sopenharmony_ci    if (st == NULL) {
3037db96d56Sopenharmony_ci        return NULL;
3047db96d56Sopenharmony_ci    }
3057db96d56Sopenharmony_ci
3067db96d56Sopenharmony_ci    warnings_filters = GET_WARNINGS_ATTR(interp, filters, 0);
3077db96d56Sopenharmony_ci    if (warnings_filters == NULL) {
3087db96d56Sopenharmony_ci        if (PyErr_Occurred())
3097db96d56Sopenharmony_ci            return NULL;
3107db96d56Sopenharmony_ci    }
3117db96d56Sopenharmony_ci    else {
3127db96d56Sopenharmony_ci        Py_SETREF(st->filters, warnings_filters);
3137db96d56Sopenharmony_ci    }
3147db96d56Sopenharmony_ci
3157db96d56Sopenharmony_ci    PyObject *filters = st->filters;
3167db96d56Sopenharmony_ci    if (filters == NULL || !PyList_Check(filters)) {
3177db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
3187db96d56Sopenharmony_ci                        MODULE_NAME ".filters must be a list");
3197db96d56Sopenharmony_ci        return NULL;
3207db96d56Sopenharmony_ci    }
3217db96d56Sopenharmony_ci
3227db96d56Sopenharmony_ci    /* WarningsState.filters could change while we are iterating over it. */
3237db96d56Sopenharmony_ci    for (i = 0; i < PyList_GET_SIZE(filters); i++) {
3247db96d56Sopenharmony_ci        PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
3257db96d56Sopenharmony_ci        Py_ssize_t ln;
3267db96d56Sopenharmony_ci        int is_subclass, good_msg, good_mod;
3277db96d56Sopenharmony_ci
3287db96d56Sopenharmony_ci        tmp_item = PyList_GET_ITEM(filters, i);
3297db96d56Sopenharmony_ci        if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
3307db96d56Sopenharmony_ci            PyErr_Format(PyExc_ValueError,
3317db96d56Sopenharmony_ci                         MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
3327db96d56Sopenharmony_ci            return NULL;
3337db96d56Sopenharmony_ci        }
3347db96d56Sopenharmony_ci
3357db96d56Sopenharmony_ci        /* Python code: action, msg, cat, mod, ln = item */
3367db96d56Sopenharmony_ci        Py_INCREF(tmp_item);
3377db96d56Sopenharmony_ci        action = PyTuple_GET_ITEM(tmp_item, 0);
3387db96d56Sopenharmony_ci        msg = PyTuple_GET_ITEM(tmp_item, 1);
3397db96d56Sopenharmony_ci        cat = PyTuple_GET_ITEM(tmp_item, 2);
3407db96d56Sopenharmony_ci        mod = PyTuple_GET_ITEM(tmp_item, 3);
3417db96d56Sopenharmony_ci        ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
3427db96d56Sopenharmony_ci
3437db96d56Sopenharmony_ci        if (!PyUnicode_Check(action)) {
3447db96d56Sopenharmony_ci            PyErr_Format(PyExc_TypeError,
3457db96d56Sopenharmony_ci                         "action must be a string, not '%.200s'",
3467db96d56Sopenharmony_ci                         Py_TYPE(action)->tp_name);
3477db96d56Sopenharmony_ci            Py_DECREF(tmp_item);
3487db96d56Sopenharmony_ci            return NULL;
3497db96d56Sopenharmony_ci        }
3507db96d56Sopenharmony_ci
3517db96d56Sopenharmony_ci        good_msg = check_matched(interp, msg, text);
3527db96d56Sopenharmony_ci        if (good_msg == -1) {
3537db96d56Sopenharmony_ci            Py_DECREF(tmp_item);
3547db96d56Sopenharmony_ci            return NULL;
3557db96d56Sopenharmony_ci        }
3567db96d56Sopenharmony_ci
3577db96d56Sopenharmony_ci        good_mod = check_matched(interp, mod, module);
3587db96d56Sopenharmony_ci        if (good_mod == -1) {
3597db96d56Sopenharmony_ci            Py_DECREF(tmp_item);
3607db96d56Sopenharmony_ci            return NULL;
3617db96d56Sopenharmony_ci        }
3627db96d56Sopenharmony_ci
3637db96d56Sopenharmony_ci        is_subclass = PyObject_IsSubclass(category, cat);
3647db96d56Sopenharmony_ci        if (is_subclass == -1) {
3657db96d56Sopenharmony_ci            Py_DECREF(tmp_item);
3667db96d56Sopenharmony_ci            return NULL;
3677db96d56Sopenharmony_ci        }
3687db96d56Sopenharmony_ci
3697db96d56Sopenharmony_ci        ln = PyLong_AsSsize_t(ln_obj);
3707db96d56Sopenharmony_ci        if (ln == -1 && PyErr_Occurred()) {
3717db96d56Sopenharmony_ci            Py_DECREF(tmp_item);
3727db96d56Sopenharmony_ci            return NULL;
3737db96d56Sopenharmony_ci        }
3747db96d56Sopenharmony_ci
3757db96d56Sopenharmony_ci        if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
3767db96d56Sopenharmony_ci            *item = tmp_item;
3777db96d56Sopenharmony_ci            return action;
3787db96d56Sopenharmony_ci        }
3797db96d56Sopenharmony_ci
3807db96d56Sopenharmony_ci        Py_DECREF(tmp_item);
3817db96d56Sopenharmony_ci    }
3827db96d56Sopenharmony_ci
3837db96d56Sopenharmony_ci    action = get_default_action(interp);
3847db96d56Sopenharmony_ci    if (action != NULL) {
3857db96d56Sopenharmony_ci        Py_INCREF(Py_None);
3867db96d56Sopenharmony_ci        *item = Py_None;
3877db96d56Sopenharmony_ci        return action;
3887db96d56Sopenharmony_ci    }
3897db96d56Sopenharmony_ci
3907db96d56Sopenharmony_ci    return NULL;
3917db96d56Sopenharmony_ci}
3927db96d56Sopenharmony_ci
3937db96d56Sopenharmony_ci
3947db96d56Sopenharmony_cistatic int
3957db96d56Sopenharmony_cialready_warned(PyInterpreterState *interp, PyObject *registry, PyObject *key,
3967db96d56Sopenharmony_ci               int should_set)
3977db96d56Sopenharmony_ci{
3987db96d56Sopenharmony_ci    PyObject *version_obj, *already_warned;
3997db96d56Sopenharmony_ci
4007db96d56Sopenharmony_ci    if (key == NULL)
4017db96d56Sopenharmony_ci        return -1;
4027db96d56Sopenharmony_ci
4037db96d56Sopenharmony_ci    WarningsState *st = warnings_get_state(interp);
4047db96d56Sopenharmony_ci    if (st == NULL) {
4057db96d56Sopenharmony_ci        return -1;
4067db96d56Sopenharmony_ci    }
4077db96d56Sopenharmony_ci    version_obj = _PyDict_GetItemWithError(registry, &_Py_ID(version));
4087db96d56Sopenharmony_ci    if (version_obj == NULL
4097db96d56Sopenharmony_ci        || !PyLong_CheckExact(version_obj)
4107db96d56Sopenharmony_ci        || PyLong_AsLong(version_obj) != st->filters_version)
4117db96d56Sopenharmony_ci    {
4127db96d56Sopenharmony_ci        if (PyErr_Occurred()) {
4137db96d56Sopenharmony_ci            return -1;
4147db96d56Sopenharmony_ci        }
4157db96d56Sopenharmony_ci        PyDict_Clear(registry);
4167db96d56Sopenharmony_ci        version_obj = PyLong_FromLong(st->filters_version);
4177db96d56Sopenharmony_ci        if (version_obj == NULL)
4187db96d56Sopenharmony_ci            return -1;
4197db96d56Sopenharmony_ci        if (PyDict_SetItem(registry, &_Py_ID(version), version_obj) < 0) {
4207db96d56Sopenharmony_ci            Py_DECREF(version_obj);
4217db96d56Sopenharmony_ci            return -1;
4227db96d56Sopenharmony_ci        }
4237db96d56Sopenharmony_ci        Py_DECREF(version_obj);
4247db96d56Sopenharmony_ci    }
4257db96d56Sopenharmony_ci    else {
4267db96d56Sopenharmony_ci        already_warned = PyDict_GetItemWithError(registry, key);
4277db96d56Sopenharmony_ci        if (already_warned != NULL) {
4287db96d56Sopenharmony_ci            int rc = PyObject_IsTrue(already_warned);
4297db96d56Sopenharmony_ci            if (rc != 0)
4307db96d56Sopenharmony_ci                return rc;
4317db96d56Sopenharmony_ci        }
4327db96d56Sopenharmony_ci        else if (PyErr_Occurred()) {
4337db96d56Sopenharmony_ci            return -1;
4347db96d56Sopenharmony_ci        }
4357db96d56Sopenharmony_ci    }
4367db96d56Sopenharmony_ci
4377db96d56Sopenharmony_ci    /* This warning wasn't found in the registry, set it. */
4387db96d56Sopenharmony_ci    if (should_set)
4397db96d56Sopenharmony_ci        return PyDict_SetItem(registry, key, Py_True);
4407db96d56Sopenharmony_ci    return 0;
4417db96d56Sopenharmony_ci}
4427db96d56Sopenharmony_ci
4437db96d56Sopenharmony_ci/* New reference. */
4447db96d56Sopenharmony_cistatic PyObject *
4457db96d56Sopenharmony_cinormalize_module(PyObject *filename)
4467db96d56Sopenharmony_ci{
4477db96d56Sopenharmony_ci    PyObject *module;
4487db96d56Sopenharmony_ci    int kind;
4497db96d56Sopenharmony_ci    const void *data;
4507db96d56Sopenharmony_ci    Py_ssize_t len;
4517db96d56Sopenharmony_ci
4527db96d56Sopenharmony_ci    len = PyUnicode_GetLength(filename);
4537db96d56Sopenharmony_ci    if (len < 0)
4547db96d56Sopenharmony_ci        return NULL;
4557db96d56Sopenharmony_ci
4567db96d56Sopenharmony_ci    if (len == 0)
4577db96d56Sopenharmony_ci        return PyUnicode_FromString("<unknown>");
4587db96d56Sopenharmony_ci
4597db96d56Sopenharmony_ci    kind = PyUnicode_KIND(filename);
4607db96d56Sopenharmony_ci    data = PyUnicode_DATA(filename);
4617db96d56Sopenharmony_ci
4627db96d56Sopenharmony_ci    /* if filename.endswith(".py"): */
4637db96d56Sopenharmony_ci    if (len >= 3 &&
4647db96d56Sopenharmony_ci        PyUnicode_READ(kind, data, len-3) == '.' &&
4657db96d56Sopenharmony_ci        PyUnicode_READ(kind, data, len-2) == 'p' &&
4667db96d56Sopenharmony_ci        PyUnicode_READ(kind, data, len-1) == 'y')
4677db96d56Sopenharmony_ci    {
4687db96d56Sopenharmony_ci        module = PyUnicode_Substring(filename, 0, len-3);
4697db96d56Sopenharmony_ci    }
4707db96d56Sopenharmony_ci    else {
4717db96d56Sopenharmony_ci        module = filename;
4727db96d56Sopenharmony_ci        Py_INCREF(module);
4737db96d56Sopenharmony_ci    }
4747db96d56Sopenharmony_ci    return module;
4757db96d56Sopenharmony_ci}
4767db96d56Sopenharmony_ci
4777db96d56Sopenharmony_cistatic int
4787db96d56Sopenharmony_ciupdate_registry(PyInterpreterState *interp, PyObject *registry, PyObject *text,
4797db96d56Sopenharmony_ci                PyObject *category, int add_zero)
4807db96d56Sopenharmony_ci{
4817db96d56Sopenharmony_ci    PyObject *altkey;
4827db96d56Sopenharmony_ci    int rc;
4837db96d56Sopenharmony_ci
4847db96d56Sopenharmony_ci    if (add_zero)
4857db96d56Sopenharmony_ci        altkey = PyTuple_Pack(3, text, category, _PyLong_GetZero());
4867db96d56Sopenharmony_ci    else
4877db96d56Sopenharmony_ci        altkey = PyTuple_Pack(2, text, category);
4887db96d56Sopenharmony_ci
4897db96d56Sopenharmony_ci    rc = already_warned(interp, registry, altkey, 1);
4907db96d56Sopenharmony_ci    Py_XDECREF(altkey);
4917db96d56Sopenharmony_ci    return rc;
4927db96d56Sopenharmony_ci}
4937db96d56Sopenharmony_ci
4947db96d56Sopenharmony_cistatic void
4957db96d56Sopenharmony_cishow_warning(PyThreadState *tstate, PyObject *filename, int lineno,
4967db96d56Sopenharmony_ci             PyObject *text, PyObject *category, PyObject *sourceline)
4977db96d56Sopenharmony_ci{
4987db96d56Sopenharmony_ci    PyObject *f_stderr;
4997db96d56Sopenharmony_ci    PyObject *name;
5007db96d56Sopenharmony_ci    char lineno_str[128];
5017db96d56Sopenharmony_ci
5027db96d56Sopenharmony_ci    PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
5037db96d56Sopenharmony_ci
5047db96d56Sopenharmony_ci    name = PyObject_GetAttr(category, &_Py_ID(__name__));
5057db96d56Sopenharmony_ci    if (name == NULL) {
5067db96d56Sopenharmony_ci        goto error;
5077db96d56Sopenharmony_ci    }
5087db96d56Sopenharmony_ci
5097db96d56Sopenharmony_ci    f_stderr = _PySys_GetAttr(tstate, &_Py_ID(stderr));
5107db96d56Sopenharmony_ci    if (f_stderr == NULL) {
5117db96d56Sopenharmony_ci        fprintf(stderr, "lost sys.stderr\n");
5127db96d56Sopenharmony_ci        goto error;
5137db96d56Sopenharmony_ci    }
5147db96d56Sopenharmony_ci
5157db96d56Sopenharmony_ci    /* Print "filename:lineno: category: text\n" */
5167db96d56Sopenharmony_ci    if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
5177db96d56Sopenharmony_ci        goto error;
5187db96d56Sopenharmony_ci    if (PyFile_WriteString(lineno_str, f_stderr) < 0)
5197db96d56Sopenharmony_ci        goto error;
5207db96d56Sopenharmony_ci    if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
5217db96d56Sopenharmony_ci        goto error;
5227db96d56Sopenharmony_ci    if (PyFile_WriteString(": ", f_stderr) < 0)
5237db96d56Sopenharmony_ci        goto error;
5247db96d56Sopenharmony_ci    if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
5257db96d56Sopenharmony_ci        goto error;
5267db96d56Sopenharmony_ci    if (PyFile_WriteString("\n", f_stderr) < 0)
5277db96d56Sopenharmony_ci        goto error;
5287db96d56Sopenharmony_ci    Py_CLEAR(name);
5297db96d56Sopenharmony_ci
5307db96d56Sopenharmony_ci    /* Print "  source_line\n" */
5317db96d56Sopenharmony_ci    if (sourceline) {
5327db96d56Sopenharmony_ci        int kind;
5337db96d56Sopenharmony_ci        const void *data;
5347db96d56Sopenharmony_ci        Py_ssize_t i, len;
5357db96d56Sopenharmony_ci        Py_UCS4 ch;
5367db96d56Sopenharmony_ci        PyObject *truncated;
5377db96d56Sopenharmony_ci
5387db96d56Sopenharmony_ci        if (PyUnicode_READY(sourceline) < 1)
5397db96d56Sopenharmony_ci            goto error;
5407db96d56Sopenharmony_ci
5417db96d56Sopenharmony_ci        kind = PyUnicode_KIND(sourceline);
5427db96d56Sopenharmony_ci        data = PyUnicode_DATA(sourceline);
5437db96d56Sopenharmony_ci        len = PyUnicode_GET_LENGTH(sourceline);
5447db96d56Sopenharmony_ci        for (i=0; i<len; i++) {
5457db96d56Sopenharmony_ci            ch = PyUnicode_READ(kind, data, i);
5467db96d56Sopenharmony_ci            if (ch != ' ' && ch != '\t' && ch != '\014')
5477db96d56Sopenharmony_ci                break;
5487db96d56Sopenharmony_ci        }
5497db96d56Sopenharmony_ci
5507db96d56Sopenharmony_ci        truncated = PyUnicode_Substring(sourceline, i, len);
5517db96d56Sopenharmony_ci        if (truncated == NULL)
5527db96d56Sopenharmony_ci            goto error;
5537db96d56Sopenharmony_ci
5547db96d56Sopenharmony_ci        PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
5557db96d56Sopenharmony_ci        Py_DECREF(truncated);
5567db96d56Sopenharmony_ci        PyFile_WriteString("\n", f_stderr);
5577db96d56Sopenharmony_ci    }
5587db96d56Sopenharmony_ci    else {
5597db96d56Sopenharmony_ci        _Py_DisplaySourceLine(f_stderr, filename, lineno, 2, NULL, NULL);
5607db96d56Sopenharmony_ci    }
5617db96d56Sopenharmony_ci
5627db96d56Sopenharmony_cierror:
5637db96d56Sopenharmony_ci    Py_XDECREF(name);
5647db96d56Sopenharmony_ci    PyErr_Clear();
5657db96d56Sopenharmony_ci}
5667db96d56Sopenharmony_ci
5677db96d56Sopenharmony_cistatic int
5687db96d56Sopenharmony_cicall_show_warning(PyThreadState *tstate, PyObject *category,
5697db96d56Sopenharmony_ci                  PyObject *text, PyObject *message,
5707db96d56Sopenharmony_ci                  PyObject *filename, int lineno, PyObject *lineno_obj,
5717db96d56Sopenharmony_ci                  PyObject *sourceline, PyObject *source)
5727db96d56Sopenharmony_ci{
5737db96d56Sopenharmony_ci    PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
5747db96d56Sopenharmony_ci    PyInterpreterState *interp = tstate->interp;
5757db96d56Sopenharmony_ci
5767db96d56Sopenharmony_ci    /* If the source parameter is set, try to get the Python implementation.
5777db96d56Sopenharmony_ci       The Python implementation is able to log the traceback where the source
5787db96d56Sopenharmony_ci       was allocated, whereas the C implementation doesn't. */
5797db96d56Sopenharmony_ci    show_fn = GET_WARNINGS_ATTR(interp, _showwarnmsg, source != NULL);
5807db96d56Sopenharmony_ci    if (show_fn == NULL) {
5817db96d56Sopenharmony_ci        if (PyErr_Occurred())
5827db96d56Sopenharmony_ci            return -1;
5837db96d56Sopenharmony_ci        show_warning(tstate, filename, lineno, text, category, sourceline);
5847db96d56Sopenharmony_ci        return 0;
5857db96d56Sopenharmony_ci    }
5867db96d56Sopenharmony_ci
5877db96d56Sopenharmony_ci    if (!PyCallable_Check(show_fn)) {
5887db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
5897db96d56Sopenharmony_ci                "warnings._showwarnmsg() must be set to a callable");
5907db96d56Sopenharmony_ci        goto error;
5917db96d56Sopenharmony_ci    }
5927db96d56Sopenharmony_ci
5937db96d56Sopenharmony_ci    warnmsg_cls = GET_WARNINGS_ATTR(interp, WarningMessage, 0);
5947db96d56Sopenharmony_ci    if (warnmsg_cls == NULL) {
5957db96d56Sopenharmony_ci        if (!PyErr_Occurred()) {
5967db96d56Sopenharmony_ci            PyErr_SetString(PyExc_RuntimeError,
5977db96d56Sopenharmony_ci                    "unable to get warnings.WarningMessage");
5987db96d56Sopenharmony_ci        }
5997db96d56Sopenharmony_ci        goto error;
6007db96d56Sopenharmony_ci    }
6017db96d56Sopenharmony_ci
6027db96d56Sopenharmony_ci    msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
6037db96d56Sopenharmony_ci            filename, lineno_obj, Py_None, Py_None, source,
6047db96d56Sopenharmony_ci            NULL);
6057db96d56Sopenharmony_ci    Py_DECREF(warnmsg_cls);
6067db96d56Sopenharmony_ci    if (msg == NULL)
6077db96d56Sopenharmony_ci        goto error;
6087db96d56Sopenharmony_ci
6097db96d56Sopenharmony_ci    res = PyObject_CallOneArg(show_fn, msg);
6107db96d56Sopenharmony_ci    Py_DECREF(show_fn);
6117db96d56Sopenharmony_ci    Py_DECREF(msg);
6127db96d56Sopenharmony_ci
6137db96d56Sopenharmony_ci    if (res == NULL)
6147db96d56Sopenharmony_ci        return -1;
6157db96d56Sopenharmony_ci
6167db96d56Sopenharmony_ci    Py_DECREF(res);
6177db96d56Sopenharmony_ci    return 0;
6187db96d56Sopenharmony_ci
6197db96d56Sopenharmony_cierror:
6207db96d56Sopenharmony_ci    Py_XDECREF(show_fn);
6217db96d56Sopenharmony_ci    return -1;
6227db96d56Sopenharmony_ci}
6237db96d56Sopenharmony_ci
6247db96d56Sopenharmony_cistatic PyObject *
6257db96d56Sopenharmony_ciwarn_explicit(PyThreadState *tstate, PyObject *category, PyObject *message,
6267db96d56Sopenharmony_ci              PyObject *filename, int lineno,
6277db96d56Sopenharmony_ci              PyObject *module, PyObject *registry, PyObject *sourceline,
6287db96d56Sopenharmony_ci              PyObject *source)
6297db96d56Sopenharmony_ci{
6307db96d56Sopenharmony_ci    PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
6317db96d56Sopenharmony_ci    PyObject *item = NULL;
6327db96d56Sopenharmony_ci    PyObject *action;
6337db96d56Sopenharmony_ci    int rc;
6347db96d56Sopenharmony_ci    PyInterpreterState *interp = tstate->interp;
6357db96d56Sopenharmony_ci
6367db96d56Sopenharmony_ci    /* module can be None if a warning is emitted late during Python shutdown.
6377db96d56Sopenharmony_ci       In this case, the Python warnings module was probably unloaded, filters
6387db96d56Sopenharmony_ci       are no more available to choose as action. It is safer to ignore the
6397db96d56Sopenharmony_ci       warning and do nothing. */
6407db96d56Sopenharmony_ci    if (module == Py_None)
6417db96d56Sopenharmony_ci        Py_RETURN_NONE;
6427db96d56Sopenharmony_ci
6437db96d56Sopenharmony_ci    if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
6447db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
6457db96d56Sopenharmony_ci        return NULL;
6467db96d56Sopenharmony_ci    }
6477db96d56Sopenharmony_ci
6487db96d56Sopenharmony_ci    /* Normalize module. */
6497db96d56Sopenharmony_ci    if (module == NULL) {
6507db96d56Sopenharmony_ci        module = normalize_module(filename);
6517db96d56Sopenharmony_ci        if (module == NULL)
6527db96d56Sopenharmony_ci            return NULL;
6537db96d56Sopenharmony_ci    }
6547db96d56Sopenharmony_ci    else
6557db96d56Sopenharmony_ci        Py_INCREF(module);
6567db96d56Sopenharmony_ci
6577db96d56Sopenharmony_ci    /* Normalize message. */
6587db96d56Sopenharmony_ci    Py_INCREF(message);  /* DECREF'ed in cleanup. */
6597db96d56Sopenharmony_ci    rc = PyObject_IsInstance(message, PyExc_Warning);
6607db96d56Sopenharmony_ci    if (rc == -1) {
6617db96d56Sopenharmony_ci        goto cleanup;
6627db96d56Sopenharmony_ci    }
6637db96d56Sopenharmony_ci    if (rc == 1) {
6647db96d56Sopenharmony_ci        text = PyObject_Str(message);
6657db96d56Sopenharmony_ci        if (text == NULL)
6667db96d56Sopenharmony_ci            goto cleanup;
6677db96d56Sopenharmony_ci        category = (PyObject*)Py_TYPE(message);
6687db96d56Sopenharmony_ci    }
6697db96d56Sopenharmony_ci    else {
6707db96d56Sopenharmony_ci        text = message;
6717db96d56Sopenharmony_ci        message = PyObject_CallOneArg(category, message);
6727db96d56Sopenharmony_ci        if (message == NULL)
6737db96d56Sopenharmony_ci            goto cleanup;
6747db96d56Sopenharmony_ci    }
6757db96d56Sopenharmony_ci
6767db96d56Sopenharmony_ci    lineno_obj = PyLong_FromLong(lineno);
6777db96d56Sopenharmony_ci    if (lineno_obj == NULL)
6787db96d56Sopenharmony_ci        goto cleanup;
6797db96d56Sopenharmony_ci
6807db96d56Sopenharmony_ci    if (source == Py_None) {
6817db96d56Sopenharmony_ci        source = NULL;
6827db96d56Sopenharmony_ci    }
6837db96d56Sopenharmony_ci
6847db96d56Sopenharmony_ci    /* Create key. */
6857db96d56Sopenharmony_ci    key = PyTuple_Pack(3, text, category, lineno_obj);
6867db96d56Sopenharmony_ci    if (key == NULL)
6877db96d56Sopenharmony_ci        goto cleanup;
6887db96d56Sopenharmony_ci
6897db96d56Sopenharmony_ci    if ((registry != NULL) && (registry != Py_None)) {
6907db96d56Sopenharmony_ci        rc = already_warned(interp, registry, key, 0);
6917db96d56Sopenharmony_ci        if (rc == -1)
6927db96d56Sopenharmony_ci            goto cleanup;
6937db96d56Sopenharmony_ci        else if (rc == 1)
6947db96d56Sopenharmony_ci            goto return_none;
6957db96d56Sopenharmony_ci        /* Else this warning hasn't been generated before. */
6967db96d56Sopenharmony_ci    }
6977db96d56Sopenharmony_ci
6987db96d56Sopenharmony_ci    action = get_filter(interp, category, text, lineno, module, &item);
6997db96d56Sopenharmony_ci    if (action == NULL)
7007db96d56Sopenharmony_ci        goto cleanup;
7017db96d56Sopenharmony_ci
7027db96d56Sopenharmony_ci    if (_PyUnicode_EqualToASCIIString(action, "error")) {
7037db96d56Sopenharmony_ci        PyErr_SetObject(category, message);
7047db96d56Sopenharmony_ci        goto cleanup;
7057db96d56Sopenharmony_ci    }
7067db96d56Sopenharmony_ci
7077db96d56Sopenharmony_ci    if (_PyUnicode_EqualToASCIIString(action, "ignore")) {
7087db96d56Sopenharmony_ci        goto return_none;
7097db96d56Sopenharmony_ci    }
7107db96d56Sopenharmony_ci
7117db96d56Sopenharmony_ci    /* Store in the registry that we've been here, *except* when the action
7127db96d56Sopenharmony_ci       is "always". */
7137db96d56Sopenharmony_ci    rc = 0;
7147db96d56Sopenharmony_ci    if (!_PyUnicode_EqualToASCIIString(action, "always")) {
7157db96d56Sopenharmony_ci        if (registry != NULL && registry != Py_None &&
7167db96d56Sopenharmony_ci            PyDict_SetItem(registry, key, Py_True) < 0)
7177db96d56Sopenharmony_ci        {
7187db96d56Sopenharmony_ci            goto cleanup;
7197db96d56Sopenharmony_ci        }
7207db96d56Sopenharmony_ci
7217db96d56Sopenharmony_ci        if (_PyUnicode_EqualToASCIIString(action, "once")) {
7227db96d56Sopenharmony_ci            if (registry == NULL || registry == Py_None) {
7237db96d56Sopenharmony_ci                registry = get_once_registry(interp);
7247db96d56Sopenharmony_ci                if (registry == NULL)
7257db96d56Sopenharmony_ci                    goto cleanup;
7267db96d56Sopenharmony_ci            }
7277db96d56Sopenharmony_ci            /* WarningsState.once_registry[(text, category)] = 1 */
7287db96d56Sopenharmony_ci            rc = update_registry(interp, registry, text, category, 0);
7297db96d56Sopenharmony_ci        }
7307db96d56Sopenharmony_ci        else if (_PyUnicode_EqualToASCIIString(action, "module")) {
7317db96d56Sopenharmony_ci            /* registry[(text, category, 0)] = 1 */
7327db96d56Sopenharmony_ci            if (registry != NULL && registry != Py_None)
7337db96d56Sopenharmony_ci                rc = update_registry(interp, registry, text, category, 0);
7347db96d56Sopenharmony_ci        }
7357db96d56Sopenharmony_ci        else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
7367db96d56Sopenharmony_ci            PyErr_Format(PyExc_RuntimeError,
7377db96d56Sopenharmony_ci                        "Unrecognized action (%R) in warnings.filters:\n %R",
7387db96d56Sopenharmony_ci                        action, item);
7397db96d56Sopenharmony_ci            goto cleanup;
7407db96d56Sopenharmony_ci        }
7417db96d56Sopenharmony_ci    }
7427db96d56Sopenharmony_ci
7437db96d56Sopenharmony_ci    if (rc == 1)  /* Already warned for this module. */
7447db96d56Sopenharmony_ci        goto return_none;
7457db96d56Sopenharmony_ci    if (rc == 0) {
7467db96d56Sopenharmony_ci        if (call_show_warning(tstate, category, text, message, filename,
7477db96d56Sopenharmony_ci                              lineno, lineno_obj, sourceline, source) < 0)
7487db96d56Sopenharmony_ci            goto cleanup;
7497db96d56Sopenharmony_ci    }
7507db96d56Sopenharmony_ci    else /* if (rc == -1) */
7517db96d56Sopenharmony_ci        goto cleanup;
7527db96d56Sopenharmony_ci
7537db96d56Sopenharmony_ci return_none:
7547db96d56Sopenharmony_ci    result = Py_None;
7557db96d56Sopenharmony_ci    Py_INCREF(result);
7567db96d56Sopenharmony_ci
7577db96d56Sopenharmony_ci cleanup:
7587db96d56Sopenharmony_ci    Py_XDECREF(item);
7597db96d56Sopenharmony_ci    Py_XDECREF(key);
7607db96d56Sopenharmony_ci    Py_XDECREF(text);
7617db96d56Sopenharmony_ci    Py_XDECREF(lineno_obj);
7627db96d56Sopenharmony_ci    Py_DECREF(module);
7637db96d56Sopenharmony_ci    Py_XDECREF(message);
7647db96d56Sopenharmony_ci    return result;  /* Py_None or NULL. */
7657db96d56Sopenharmony_ci}
7667db96d56Sopenharmony_ci
7677db96d56Sopenharmony_cistatic int
7687db96d56Sopenharmony_ciis_internal_frame(PyFrameObject *frame)
7697db96d56Sopenharmony_ci{
7707db96d56Sopenharmony_ci    if (frame == NULL) {
7717db96d56Sopenharmony_ci        return 0;
7727db96d56Sopenharmony_ci    }
7737db96d56Sopenharmony_ci
7747db96d56Sopenharmony_ci    PyCodeObject *code = PyFrame_GetCode(frame);
7757db96d56Sopenharmony_ci    PyObject *filename = code->co_filename;
7767db96d56Sopenharmony_ci    Py_DECREF(code);
7777db96d56Sopenharmony_ci
7787db96d56Sopenharmony_ci    if (filename == NULL) {
7797db96d56Sopenharmony_ci        return 0;
7807db96d56Sopenharmony_ci    }
7817db96d56Sopenharmony_ci    if (!PyUnicode_Check(filename)) {
7827db96d56Sopenharmony_ci        return 0;
7837db96d56Sopenharmony_ci    }
7847db96d56Sopenharmony_ci
7857db96d56Sopenharmony_ci    int contains = PyUnicode_Contains(filename, &_Py_ID(importlib));
7867db96d56Sopenharmony_ci    if (contains < 0) {
7877db96d56Sopenharmony_ci        return 0;
7887db96d56Sopenharmony_ci    }
7897db96d56Sopenharmony_ci    else if (contains > 0) {
7907db96d56Sopenharmony_ci        contains = PyUnicode_Contains(filename, &_Py_ID(_bootstrap));
7917db96d56Sopenharmony_ci        if (contains < 0) {
7927db96d56Sopenharmony_ci            return 0;
7937db96d56Sopenharmony_ci        }
7947db96d56Sopenharmony_ci        else if (contains > 0) {
7957db96d56Sopenharmony_ci            return 1;
7967db96d56Sopenharmony_ci        }
7977db96d56Sopenharmony_ci    }
7987db96d56Sopenharmony_ci
7997db96d56Sopenharmony_ci    return 0;
8007db96d56Sopenharmony_ci}
8017db96d56Sopenharmony_ci
8027db96d56Sopenharmony_cistatic PyFrameObject *
8037db96d56Sopenharmony_cinext_external_frame(PyFrameObject *frame)
8047db96d56Sopenharmony_ci{
8057db96d56Sopenharmony_ci    do {
8067db96d56Sopenharmony_ci        PyFrameObject *back = PyFrame_GetBack(frame);
8077db96d56Sopenharmony_ci        Py_DECREF(frame);
8087db96d56Sopenharmony_ci        frame = back;
8097db96d56Sopenharmony_ci    } while (frame != NULL && is_internal_frame(frame));
8107db96d56Sopenharmony_ci
8117db96d56Sopenharmony_ci    return frame;
8127db96d56Sopenharmony_ci}
8137db96d56Sopenharmony_ci
8147db96d56Sopenharmony_ci/* filename, module, and registry are new refs, globals is borrowed */
8157db96d56Sopenharmony_ci/* Returns 0 on error (no new refs), 1 on success */
8167db96d56Sopenharmony_cistatic int
8177db96d56Sopenharmony_cisetup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
8187db96d56Sopenharmony_ci              PyObject **module, PyObject **registry)
8197db96d56Sopenharmony_ci{
8207db96d56Sopenharmony_ci    PyObject *globals;
8217db96d56Sopenharmony_ci
8227db96d56Sopenharmony_ci    /* Setup globals, filename and lineno. */
8237db96d56Sopenharmony_ci    PyThreadState *tstate = get_current_tstate();
8247db96d56Sopenharmony_ci    if (tstate == NULL) {
8257db96d56Sopenharmony_ci        return 0;
8267db96d56Sopenharmony_ci    }
8277db96d56Sopenharmony_ci    PyInterpreterState *interp = tstate->interp;
8287db96d56Sopenharmony_ci    PyFrameObject *f = PyThreadState_GetFrame(tstate);
8297db96d56Sopenharmony_ci    // Stack level comparisons to Python code is off by one as there is no
8307db96d56Sopenharmony_ci    // warnings-related stack level to avoid.
8317db96d56Sopenharmony_ci    if (stack_level <= 0 || is_internal_frame(f)) {
8327db96d56Sopenharmony_ci        while (--stack_level > 0 && f != NULL) {
8337db96d56Sopenharmony_ci            PyFrameObject *back = PyFrame_GetBack(f);
8347db96d56Sopenharmony_ci            Py_DECREF(f);
8357db96d56Sopenharmony_ci            f = back;
8367db96d56Sopenharmony_ci        }
8377db96d56Sopenharmony_ci    }
8387db96d56Sopenharmony_ci    else {
8397db96d56Sopenharmony_ci        while (--stack_level > 0 && f != NULL) {
8407db96d56Sopenharmony_ci            f = next_external_frame(f);
8417db96d56Sopenharmony_ci        }
8427db96d56Sopenharmony_ci    }
8437db96d56Sopenharmony_ci
8447db96d56Sopenharmony_ci    if (f == NULL) {
8457db96d56Sopenharmony_ci        globals = interp->sysdict;
8467db96d56Sopenharmony_ci        *filename = PyUnicode_FromString("sys");
8477db96d56Sopenharmony_ci        *lineno = 1;
8487db96d56Sopenharmony_ci    }
8497db96d56Sopenharmony_ci    else {
8507db96d56Sopenharmony_ci        globals = f->f_frame->f_globals;
8517db96d56Sopenharmony_ci        *filename = f->f_frame->f_code->co_filename;
8527db96d56Sopenharmony_ci        Py_INCREF(*filename);
8537db96d56Sopenharmony_ci        *lineno = PyFrame_GetLineNumber(f);
8547db96d56Sopenharmony_ci        Py_DECREF(f);
8557db96d56Sopenharmony_ci    }
8567db96d56Sopenharmony_ci
8577db96d56Sopenharmony_ci    *module = NULL;
8587db96d56Sopenharmony_ci
8597db96d56Sopenharmony_ci    /* Setup registry. */
8607db96d56Sopenharmony_ci    assert(globals != NULL);
8617db96d56Sopenharmony_ci    assert(PyDict_Check(globals));
8627db96d56Sopenharmony_ci    *registry = _PyDict_GetItemWithError(globals, &_Py_ID(__warningregistry__));
8637db96d56Sopenharmony_ci    if (*registry == NULL) {
8647db96d56Sopenharmony_ci        int rc;
8657db96d56Sopenharmony_ci
8667db96d56Sopenharmony_ci        if (_PyErr_Occurred(tstate)) {
8677db96d56Sopenharmony_ci            goto handle_error;
8687db96d56Sopenharmony_ci        }
8697db96d56Sopenharmony_ci        *registry = PyDict_New();
8707db96d56Sopenharmony_ci        if (*registry == NULL)
8717db96d56Sopenharmony_ci            goto handle_error;
8727db96d56Sopenharmony_ci
8737db96d56Sopenharmony_ci         rc = PyDict_SetItem(globals, &_Py_ID(__warningregistry__), *registry);
8747db96d56Sopenharmony_ci         if (rc < 0)
8757db96d56Sopenharmony_ci            goto handle_error;
8767db96d56Sopenharmony_ci    }
8777db96d56Sopenharmony_ci    else
8787db96d56Sopenharmony_ci        Py_INCREF(*registry);
8797db96d56Sopenharmony_ci
8807db96d56Sopenharmony_ci    /* Setup module. */
8817db96d56Sopenharmony_ci    *module = _PyDict_GetItemWithError(globals, &_Py_ID(__name__));
8827db96d56Sopenharmony_ci    if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) {
8837db96d56Sopenharmony_ci        Py_INCREF(*module);
8847db96d56Sopenharmony_ci    }
8857db96d56Sopenharmony_ci    else if (_PyErr_Occurred(tstate)) {
8867db96d56Sopenharmony_ci        goto handle_error;
8877db96d56Sopenharmony_ci    }
8887db96d56Sopenharmony_ci    else {
8897db96d56Sopenharmony_ci        *module = PyUnicode_FromString("<string>");
8907db96d56Sopenharmony_ci        if (*module == NULL)
8917db96d56Sopenharmony_ci            goto handle_error;
8927db96d56Sopenharmony_ci    }
8937db96d56Sopenharmony_ci
8947db96d56Sopenharmony_ci    return 1;
8957db96d56Sopenharmony_ci
8967db96d56Sopenharmony_ci handle_error:
8977db96d56Sopenharmony_ci    Py_XDECREF(*registry);
8987db96d56Sopenharmony_ci    Py_XDECREF(*module);
8997db96d56Sopenharmony_ci    Py_DECREF(*filename);
9007db96d56Sopenharmony_ci    return 0;
9017db96d56Sopenharmony_ci}
9027db96d56Sopenharmony_ci
9037db96d56Sopenharmony_cistatic PyObject *
9047db96d56Sopenharmony_ciget_category(PyObject *message, PyObject *category)
9057db96d56Sopenharmony_ci{
9067db96d56Sopenharmony_ci    int rc;
9077db96d56Sopenharmony_ci
9087db96d56Sopenharmony_ci    /* Get category. */
9097db96d56Sopenharmony_ci    rc = PyObject_IsInstance(message, PyExc_Warning);
9107db96d56Sopenharmony_ci    if (rc == -1)
9117db96d56Sopenharmony_ci        return NULL;
9127db96d56Sopenharmony_ci
9137db96d56Sopenharmony_ci    if (rc == 1)
9147db96d56Sopenharmony_ci        category = (PyObject*)Py_TYPE(message);
9157db96d56Sopenharmony_ci    else if (category == NULL || category == Py_None)
9167db96d56Sopenharmony_ci        category = PyExc_UserWarning;
9177db96d56Sopenharmony_ci
9187db96d56Sopenharmony_ci    /* Validate category. */
9197db96d56Sopenharmony_ci    rc = PyObject_IsSubclass(category, PyExc_Warning);
9207db96d56Sopenharmony_ci    /* category is not a subclass of PyExc_Warning or
9217db96d56Sopenharmony_ci       PyObject_IsSubclass raised an error */
9227db96d56Sopenharmony_ci    if (rc == -1 || rc == 0) {
9237db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
9247db96d56Sopenharmony_ci                     "category must be a Warning subclass, not '%s'",
9257db96d56Sopenharmony_ci                     Py_TYPE(category)->tp_name);
9267db96d56Sopenharmony_ci        return NULL;
9277db96d56Sopenharmony_ci    }
9287db96d56Sopenharmony_ci
9297db96d56Sopenharmony_ci    return category;
9307db96d56Sopenharmony_ci}
9317db96d56Sopenharmony_ci
9327db96d56Sopenharmony_cistatic PyObject *
9337db96d56Sopenharmony_cido_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
9347db96d56Sopenharmony_ci        PyObject *source)
9357db96d56Sopenharmony_ci{
9367db96d56Sopenharmony_ci    PyObject *filename, *module, *registry, *res;
9377db96d56Sopenharmony_ci    int lineno;
9387db96d56Sopenharmony_ci
9397db96d56Sopenharmony_ci    PyThreadState *tstate = get_current_tstate();
9407db96d56Sopenharmony_ci    if (tstate == NULL) {
9417db96d56Sopenharmony_ci        return NULL;
9427db96d56Sopenharmony_ci    }
9437db96d56Sopenharmony_ci
9447db96d56Sopenharmony_ci    if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
9457db96d56Sopenharmony_ci        return NULL;
9467db96d56Sopenharmony_ci
9477db96d56Sopenharmony_ci    res = warn_explicit(tstate, category, message, filename, lineno, module, registry,
9487db96d56Sopenharmony_ci                        NULL, source);
9497db96d56Sopenharmony_ci    Py_DECREF(filename);
9507db96d56Sopenharmony_ci    Py_DECREF(registry);
9517db96d56Sopenharmony_ci    Py_DECREF(module);
9527db96d56Sopenharmony_ci    return res;
9537db96d56Sopenharmony_ci}
9547db96d56Sopenharmony_ci
9557db96d56Sopenharmony_ci/*[clinic input]
9567db96d56Sopenharmony_ciwarn as warnings_warn
9577db96d56Sopenharmony_ci
9587db96d56Sopenharmony_ci    message: object
9597db96d56Sopenharmony_ci    category: object = None
9607db96d56Sopenharmony_ci    stacklevel: Py_ssize_t = 1
9617db96d56Sopenharmony_ci    source: object = None
9627db96d56Sopenharmony_ci
9637db96d56Sopenharmony_ciIssue a warning, or maybe ignore it or raise an exception.
9647db96d56Sopenharmony_ci[clinic start generated code]*/
9657db96d56Sopenharmony_ci
9667db96d56Sopenharmony_cistatic PyObject *
9677db96d56Sopenharmony_ciwarnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
9687db96d56Sopenharmony_ci                   Py_ssize_t stacklevel, PyObject *source)
9697db96d56Sopenharmony_ci/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
9707db96d56Sopenharmony_ci{
9717db96d56Sopenharmony_ci    category = get_category(message, category);
9727db96d56Sopenharmony_ci    if (category == NULL)
9737db96d56Sopenharmony_ci        return NULL;
9747db96d56Sopenharmony_ci    return do_warn(message, category, stacklevel, source);
9757db96d56Sopenharmony_ci}
9767db96d56Sopenharmony_ci
9777db96d56Sopenharmony_cistatic PyObject *
9787db96d56Sopenharmony_ciget_source_line(PyInterpreterState *interp, PyObject *module_globals, int lineno)
9797db96d56Sopenharmony_ci{
9807db96d56Sopenharmony_ci    PyObject *loader;
9817db96d56Sopenharmony_ci    PyObject *module_name;
9827db96d56Sopenharmony_ci    PyObject *get_source;
9837db96d56Sopenharmony_ci    PyObject *source;
9847db96d56Sopenharmony_ci    PyObject *source_list;
9857db96d56Sopenharmony_ci    PyObject *source_line;
9867db96d56Sopenharmony_ci
9877db96d56Sopenharmony_ci    /* Check/get the requisite pieces needed for the loader. */
9887db96d56Sopenharmony_ci    loader = _PyDict_GetItemWithError(module_globals, &_Py_ID(__loader__));
9897db96d56Sopenharmony_ci    if (loader == NULL) {
9907db96d56Sopenharmony_ci        return NULL;
9917db96d56Sopenharmony_ci    }
9927db96d56Sopenharmony_ci    Py_INCREF(loader);
9937db96d56Sopenharmony_ci    module_name = _PyDict_GetItemWithError(module_globals, &_Py_ID(__name__));
9947db96d56Sopenharmony_ci    if (!module_name) {
9957db96d56Sopenharmony_ci        Py_DECREF(loader);
9967db96d56Sopenharmony_ci        return NULL;
9977db96d56Sopenharmony_ci    }
9987db96d56Sopenharmony_ci    Py_INCREF(module_name);
9997db96d56Sopenharmony_ci
10007db96d56Sopenharmony_ci    /* Make sure the loader implements the optional get_source() method. */
10017db96d56Sopenharmony_ci    (void)_PyObject_LookupAttr(loader, &_Py_ID(get_source), &get_source);
10027db96d56Sopenharmony_ci    Py_DECREF(loader);
10037db96d56Sopenharmony_ci    if (!get_source) {
10047db96d56Sopenharmony_ci        Py_DECREF(module_name);
10057db96d56Sopenharmony_ci        return NULL;
10067db96d56Sopenharmony_ci    }
10077db96d56Sopenharmony_ci    /* Call get_source() to get the source code. */
10087db96d56Sopenharmony_ci    source = PyObject_CallOneArg(get_source, module_name);
10097db96d56Sopenharmony_ci    Py_DECREF(get_source);
10107db96d56Sopenharmony_ci    Py_DECREF(module_name);
10117db96d56Sopenharmony_ci    if (!source) {
10127db96d56Sopenharmony_ci        return NULL;
10137db96d56Sopenharmony_ci    }
10147db96d56Sopenharmony_ci    if (source == Py_None) {
10157db96d56Sopenharmony_ci        Py_DECREF(source);
10167db96d56Sopenharmony_ci        return NULL;
10177db96d56Sopenharmony_ci    }
10187db96d56Sopenharmony_ci
10197db96d56Sopenharmony_ci    /* Split the source into lines. */
10207db96d56Sopenharmony_ci    source_list = PyUnicode_Splitlines(source, 0);
10217db96d56Sopenharmony_ci    Py_DECREF(source);
10227db96d56Sopenharmony_ci    if (!source_list) {
10237db96d56Sopenharmony_ci        return NULL;
10247db96d56Sopenharmony_ci    }
10257db96d56Sopenharmony_ci
10267db96d56Sopenharmony_ci    /* Get the source line. */
10277db96d56Sopenharmony_ci    source_line = PyList_GetItem(source_list, lineno-1);
10287db96d56Sopenharmony_ci    Py_XINCREF(source_line);
10297db96d56Sopenharmony_ci    Py_DECREF(source_list);
10307db96d56Sopenharmony_ci    return source_line;
10317db96d56Sopenharmony_ci}
10327db96d56Sopenharmony_ci
10337db96d56Sopenharmony_cistatic PyObject *
10347db96d56Sopenharmony_ciwarnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
10357db96d56Sopenharmony_ci{
10367db96d56Sopenharmony_ci    static char *kwd_list[] = {"message", "category", "filename", "lineno",
10377db96d56Sopenharmony_ci                                "module", "registry", "module_globals",
10387db96d56Sopenharmony_ci                                "source", 0};
10397db96d56Sopenharmony_ci    PyObject *message;
10407db96d56Sopenharmony_ci    PyObject *category;
10417db96d56Sopenharmony_ci    PyObject *filename;
10427db96d56Sopenharmony_ci    int lineno;
10437db96d56Sopenharmony_ci    PyObject *module = NULL;
10447db96d56Sopenharmony_ci    PyObject *registry = NULL;
10457db96d56Sopenharmony_ci    PyObject *module_globals = NULL;
10467db96d56Sopenharmony_ci    PyObject *sourceobj = NULL;
10477db96d56Sopenharmony_ci    PyObject *source_line = NULL;
10487db96d56Sopenharmony_ci    PyObject *returned;
10497db96d56Sopenharmony_ci
10507db96d56Sopenharmony_ci    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
10517db96d56Sopenharmony_ci                kwd_list, &message, &category, &filename, &lineno, &module,
10527db96d56Sopenharmony_ci                &registry, &module_globals, &sourceobj))
10537db96d56Sopenharmony_ci        return NULL;
10547db96d56Sopenharmony_ci
10557db96d56Sopenharmony_ci    PyThreadState *tstate = get_current_tstate();
10567db96d56Sopenharmony_ci    if (tstate == NULL) {
10577db96d56Sopenharmony_ci        return NULL;
10587db96d56Sopenharmony_ci    }
10597db96d56Sopenharmony_ci
10607db96d56Sopenharmony_ci    if (module_globals && module_globals != Py_None) {
10617db96d56Sopenharmony_ci        if (!PyDict_Check(module_globals)) {
10627db96d56Sopenharmony_ci            PyErr_Format(PyExc_TypeError,
10637db96d56Sopenharmony_ci                         "module_globals must be a dict, not '%.200s'",
10647db96d56Sopenharmony_ci                         Py_TYPE(module_globals)->tp_name);
10657db96d56Sopenharmony_ci            return NULL;
10667db96d56Sopenharmony_ci        }
10677db96d56Sopenharmony_ci
10687db96d56Sopenharmony_ci        source_line = get_source_line(tstate->interp, module_globals, lineno);
10697db96d56Sopenharmony_ci        if (source_line == NULL && PyErr_Occurred()) {
10707db96d56Sopenharmony_ci            return NULL;
10717db96d56Sopenharmony_ci        }
10727db96d56Sopenharmony_ci    }
10737db96d56Sopenharmony_ci    returned = warn_explicit(tstate, category, message, filename, lineno, module,
10747db96d56Sopenharmony_ci                             registry, source_line, sourceobj);
10757db96d56Sopenharmony_ci    Py_XDECREF(source_line);
10767db96d56Sopenharmony_ci    return returned;
10777db96d56Sopenharmony_ci}
10787db96d56Sopenharmony_ci
10797db96d56Sopenharmony_cistatic PyObject *
10807db96d56Sopenharmony_ciwarnings_filters_mutated(PyObject *self, PyObject *Py_UNUSED(args))
10817db96d56Sopenharmony_ci{
10827db96d56Sopenharmony_ci    PyInterpreterState *interp = get_current_interp();
10837db96d56Sopenharmony_ci    if (interp == NULL) {
10847db96d56Sopenharmony_ci        return NULL;
10857db96d56Sopenharmony_ci    }
10867db96d56Sopenharmony_ci    WarningsState *st = warnings_get_state(interp);
10877db96d56Sopenharmony_ci    if (st == NULL) {
10887db96d56Sopenharmony_ci        return NULL;
10897db96d56Sopenharmony_ci    }
10907db96d56Sopenharmony_ci    st->filters_version++;
10917db96d56Sopenharmony_ci    Py_RETURN_NONE;
10927db96d56Sopenharmony_ci}
10937db96d56Sopenharmony_ci
10947db96d56Sopenharmony_ci
10957db96d56Sopenharmony_ci/* Function to issue a warning message; may raise an exception. */
10967db96d56Sopenharmony_ci
10977db96d56Sopenharmony_cistatic int
10987db96d56Sopenharmony_ciwarn_unicode(PyObject *category, PyObject *message,
10997db96d56Sopenharmony_ci             Py_ssize_t stack_level, PyObject *source)
11007db96d56Sopenharmony_ci{
11017db96d56Sopenharmony_ci    PyObject *res;
11027db96d56Sopenharmony_ci
11037db96d56Sopenharmony_ci    if (category == NULL)
11047db96d56Sopenharmony_ci        category = PyExc_RuntimeWarning;
11057db96d56Sopenharmony_ci
11067db96d56Sopenharmony_ci    res = do_warn(message, category, stack_level, source);
11077db96d56Sopenharmony_ci    if (res == NULL)
11087db96d56Sopenharmony_ci        return -1;
11097db96d56Sopenharmony_ci    Py_DECREF(res);
11107db96d56Sopenharmony_ci
11117db96d56Sopenharmony_ci    return 0;
11127db96d56Sopenharmony_ci}
11137db96d56Sopenharmony_ci
11147db96d56Sopenharmony_cistatic int
11157db96d56Sopenharmony_ci_PyErr_WarnFormatV(PyObject *source,
11167db96d56Sopenharmony_ci                   PyObject *category, Py_ssize_t stack_level,
11177db96d56Sopenharmony_ci                   const char *format, va_list vargs)
11187db96d56Sopenharmony_ci{
11197db96d56Sopenharmony_ci    PyObject *message;
11207db96d56Sopenharmony_ci    int res;
11217db96d56Sopenharmony_ci
11227db96d56Sopenharmony_ci    message = PyUnicode_FromFormatV(format, vargs);
11237db96d56Sopenharmony_ci    if (message == NULL)
11247db96d56Sopenharmony_ci        return -1;
11257db96d56Sopenharmony_ci
11267db96d56Sopenharmony_ci    res = warn_unicode(category, message, stack_level, source);
11277db96d56Sopenharmony_ci    Py_DECREF(message);
11287db96d56Sopenharmony_ci    return res;
11297db96d56Sopenharmony_ci}
11307db96d56Sopenharmony_ci
11317db96d56Sopenharmony_ciint
11327db96d56Sopenharmony_ciPyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
11337db96d56Sopenharmony_ci                 const char *format, ...)
11347db96d56Sopenharmony_ci{
11357db96d56Sopenharmony_ci    int res;
11367db96d56Sopenharmony_ci    va_list vargs;
11377db96d56Sopenharmony_ci
11387db96d56Sopenharmony_ci#ifdef HAVE_STDARG_PROTOTYPES
11397db96d56Sopenharmony_ci    va_start(vargs, format);
11407db96d56Sopenharmony_ci#else
11417db96d56Sopenharmony_ci    va_start(vargs);
11427db96d56Sopenharmony_ci#endif
11437db96d56Sopenharmony_ci    res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
11447db96d56Sopenharmony_ci    va_end(vargs);
11457db96d56Sopenharmony_ci    return res;
11467db96d56Sopenharmony_ci}
11477db96d56Sopenharmony_ci
11487db96d56Sopenharmony_cistatic int
11497db96d56Sopenharmony_ci_PyErr_WarnFormat(PyObject *source, PyObject *category, Py_ssize_t stack_level,
11507db96d56Sopenharmony_ci                  const char *format, ...)
11517db96d56Sopenharmony_ci{
11527db96d56Sopenharmony_ci    int res;
11537db96d56Sopenharmony_ci    va_list vargs;
11547db96d56Sopenharmony_ci
11557db96d56Sopenharmony_ci#ifdef HAVE_STDARG_PROTOTYPES
11567db96d56Sopenharmony_ci    va_start(vargs, format);
11577db96d56Sopenharmony_ci#else
11587db96d56Sopenharmony_ci    va_start(vargs);
11597db96d56Sopenharmony_ci#endif
11607db96d56Sopenharmony_ci    res = _PyErr_WarnFormatV(source, category, stack_level, format, vargs);
11617db96d56Sopenharmony_ci    va_end(vargs);
11627db96d56Sopenharmony_ci    return res;
11637db96d56Sopenharmony_ci}
11647db96d56Sopenharmony_ci
11657db96d56Sopenharmony_ciint
11667db96d56Sopenharmony_ciPyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
11677db96d56Sopenharmony_ci                      const char *format, ...)
11687db96d56Sopenharmony_ci{
11697db96d56Sopenharmony_ci    int res;
11707db96d56Sopenharmony_ci    va_list vargs;
11717db96d56Sopenharmony_ci
11727db96d56Sopenharmony_ci#ifdef HAVE_STDARG_PROTOTYPES
11737db96d56Sopenharmony_ci    va_start(vargs, format);
11747db96d56Sopenharmony_ci#else
11757db96d56Sopenharmony_ci    va_start(vargs);
11767db96d56Sopenharmony_ci#endif
11777db96d56Sopenharmony_ci    res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
11787db96d56Sopenharmony_ci                             stack_level, format, vargs);
11797db96d56Sopenharmony_ci    va_end(vargs);
11807db96d56Sopenharmony_ci    return res;
11817db96d56Sopenharmony_ci}
11827db96d56Sopenharmony_ci
11837db96d56Sopenharmony_ci
11847db96d56Sopenharmony_ciint
11857db96d56Sopenharmony_ciPyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
11867db96d56Sopenharmony_ci{
11877db96d56Sopenharmony_ci    int ret;
11887db96d56Sopenharmony_ci    PyObject *message = PyUnicode_FromString(text);
11897db96d56Sopenharmony_ci    if (message == NULL)
11907db96d56Sopenharmony_ci        return -1;
11917db96d56Sopenharmony_ci    ret = warn_unicode(category, message, stack_level, NULL);
11927db96d56Sopenharmony_ci    Py_DECREF(message);
11937db96d56Sopenharmony_ci    return ret;
11947db96d56Sopenharmony_ci}
11957db96d56Sopenharmony_ci
11967db96d56Sopenharmony_ci/* PyErr_Warn is only for backwards compatibility and will be removed.
11977db96d56Sopenharmony_ci   Use PyErr_WarnEx instead. */
11987db96d56Sopenharmony_ci
11997db96d56Sopenharmony_ci#undef PyErr_Warn
12007db96d56Sopenharmony_ci
12017db96d56Sopenharmony_ciint
12027db96d56Sopenharmony_ciPyErr_Warn(PyObject *category, const char *text)
12037db96d56Sopenharmony_ci{
12047db96d56Sopenharmony_ci    return PyErr_WarnEx(category, text, 1);
12057db96d56Sopenharmony_ci}
12067db96d56Sopenharmony_ci
12077db96d56Sopenharmony_ci/* Warning with explicit origin */
12087db96d56Sopenharmony_ciint
12097db96d56Sopenharmony_ciPyErr_WarnExplicitObject(PyObject *category, PyObject *message,
12107db96d56Sopenharmony_ci                         PyObject *filename, int lineno,
12117db96d56Sopenharmony_ci                         PyObject *module, PyObject *registry)
12127db96d56Sopenharmony_ci{
12137db96d56Sopenharmony_ci    PyObject *res;
12147db96d56Sopenharmony_ci    if (category == NULL)
12157db96d56Sopenharmony_ci        category = PyExc_RuntimeWarning;
12167db96d56Sopenharmony_ci    PyThreadState *tstate = get_current_tstate();
12177db96d56Sopenharmony_ci    if (tstate == NULL) {
12187db96d56Sopenharmony_ci        return -1;
12197db96d56Sopenharmony_ci    }
12207db96d56Sopenharmony_ci    res = warn_explicit(tstate, category, message, filename, lineno,
12217db96d56Sopenharmony_ci                        module, registry, NULL, NULL);
12227db96d56Sopenharmony_ci    if (res == NULL)
12237db96d56Sopenharmony_ci        return -1;
12247db96d56Sopenharmony_ci    Py_DECREF(res);
12257db96d56Sopenharmony_ci    return 0;
12267db96d56Sopenharmony_ci}
12277db96d56Sopenharmony_ci
12287db96d56Sopenharmony_ciint
12297db96d56Sopenharmony_ciPyErr_WarnExplicit(PyObject *category, const char *text,
12307db96d56Sopenharmony_ci                   const char *filename_str, int lineno,
12317db96d56Sopenharmony_ci                   const char *module_str, PyObject *registry)
12327db96d56Sopenharmony_ci{
12337db96d56Sopenharmony_ci    PyObject *message = PyUnicode_FromString(text);
12347db96d56Sopenharmony_ci    PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
12357db96d56Sopenharmony_ci    PyObject *module = NULL;
12367db96d56Sopenharmony_ci    int ret = -1;
12377db96d56Sopenharmony_ci
12387db96d56Sopenharmony_ci    if (message == NULL || filename == NULL)
12397db96d56Sopenharmony_ci        goto exit;
12407db96d56Sopenharmony_ci    if (module_str != NULL) {
12417db96d56Sopenharmony_ci        module = PyUnicode_FromString(module_str);
12427db96d56Sopenharmony_ci        if (module == NULL)
12437db96d56Sopenharmony_ci            goto exit;
12447db96d56Sopenharmony_ci    }
12457db96d56Sopenharmony_ci
12467db96d56Sopenharmony_ci    ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
12477db96d56Sopenharmony_ci                                   module, registry);
12487db96d56Sopenharmony_ci
12497db96d56Sopenharmony_ci exit:
12507db96d56Sopenharmony_ci    Py_XDECREF(message);
12517db96d56Sopenharmony_ci    Py_XDECREF(module);
12527db96d56Sopenharmony_ci    Py_XDECREF(filename);
12537db96d56Sopenharmony_ci    return ret;
12547db96d56Sopenharmony_ci}
12557db96d56Sopenharmony_ci
12567db96d56Sopenharmony_ciint
12577db96d56Sopenharmony_ciPyErr_WarnExplicitFormat(PyObject *category,
12587db96d56Sopenharmony_ci                         const char *filename_str, int lineno,
12597db96d56Sopenharmony_ci                         const char *module_str, PyObject *registry,
12607db96d56Sopenharmony_ci                         const char *format, ...)
12617db96d56Sopenharmony_ci{
12627db96d56Sopenharmony_ci    PyObject *message;
12637db96d56Sopenharmony_ci    PyObject *module = NULL;
12647db96d56Sopenharmony_ci    PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
12657db96d56Sopenharmony_ci    int ret = -1;
12667db96d56Sopenharmony_ci    va_list vargs;
12677db96d56Sopenharmony_ci
12687db96d56Sopenharmony_ci    if (filename == NULL)
12697db96d56Sopenharmony_ci        goto exit;
12707db96d56Sopenharmony_ci    if (module_str != NULL) {
12717db96d56Sopenharmony_ci        module = PyUnicode_FromString(module_str);
12727db96d56Sopenharmony_ci        if (module == NULL)
12737db96d56Sopenharmony_ci            goto exit;
12747db96d56Sopenharmony_ci    }
12757db96d56Sopenharmony_ci
12767db96d56Sopenharmony_ci#ifdef HAVE_STDARG_PROTOTYPES
12777db96d56Sopenharmony_ci    va_start(vargs, format);
12787db96d56Sopenharmony_ci#else
12797db96d56Sopenharmony_ci    va_start(vargs);
12807db96d56Sopenharmony_ci#endif
12817db96d56Sopenharmony_ci    message = PyUnicode_FromFormatV(format, vargs);
12827db96d56Sopenharmony_ci    if (message != NULL) {
12837db96d56Sopenharmony_ci        PyObject *res;
12847db96d56Sopenharmony_ci        PyThreadState *tstate = get_current_tstate();
12857db96d56Sopenharmony_ci        if (tstate != NULL) {
12867db96d56Sopenharmony_ci            res = warn_explicit(tstate, category, message, filename, lineno,
12877db96d56Sopenharmony_ci                                module, registry, NULL, NULL);
12887db96d56Sopenharmony_ci            Py_DECREF(message);
12897db96d56Sopenharmony_ci            if (res != NULL) {
12907db96d56Sopenharmony_ci                Py_DECREF(res);
12917db96d56Sopenharmony_ci                ret = 0;
12927db96d56Sopenharmony_ci            }
12937db96d56Sopenharmony_ci        }
12947db96d56Sopenharmony_ci    }
12957db96d56Sopenharmony_ci    va_end(vargs);
12967db96d56Sopenharmony_ciexit:
12977db96d56Sopenharmony_ci    Py_XDECREF(module);
12987db96d56Sopenharmony_ci    Py_XDECREF(filename);
12997db96d56Sopenharmony_ci    return ret;
13007db96d56Sopenharmony_ci}
13017db96d56Sopenharmony_ci
13027db96d56Sopenharmony_civoid
13037db96d56Sopenharmony_ci_PyErr_WarnUnawaitedCoroutine(PyObject *coro)
13047db96d56Sopenharmony_ci{
13057db96d56Sopenharmony_ci    /* First, we attempt to funnel the warning through
13067db96d56Sopenharmony_ci       warnings._warn_unawaited_coroutine.
13077db96d56Sopenharmony_ci
13087db96d56Sopenharmony_ci       This could raise an exception, due to:
13097db96d56Sopenharmony_ci       - a bug
13107db96d56Sopenharmony_ci       - some kind of shutdown-related brokenness
13117db96d56Sopenharmony_ci       - succeeding, but with an "error" warning filter installed, so the
13127db96d56Sopenharmony_ci         warning is converted into a RuntimeWarning exception
13137db96d56Sopenharmony_ci
13147db96d56Sopenharmony_ci       In the first two cases, we want to print the error (so we know what it
13157db96d56Sopenharmony_ci       is!), and then print a warning directly as a fallback. In the last
13167db96d56Sopenharmony_ci       case, we want to print the error (since it's the warning!), but *not*
13177db96d56Sopenharmony_ci       do a fallback. And after we print the error we can't check for what
13187db96d56Sopenharmony_ci       type of error it was (because PyErr_WriteUnraisable clears it), so we
13197db96d56Sopenharmony_ci       need a flag to keep track.
13207db96d56Sopenharmony_ci
13217db96d56Sopenharmony_ci       Since this is called from __del__ context, it's careful to never raise
13227db96d56Sopenharmony_ci       an exception.
13237db96d56Sopenharmony_ci    */
13247db96d56Sopenharmony_ci    int warned = 0;
13257db96d56Sopenharmony_ci    PyInterpreterState *interp = _PyInterpreterState_GET();
13267db96d56Sopenharmony_ci    assert(interp != NULL);
13277db96d56Sopenharmony_ci    PyObject *fn = GET_WARNINGS_ATTR(interp, _warn_unawaited_coroutine, 1);
13287db96d56Sopenharmony_ci    if (fn) {
13297db96d56Sopenharmony_ci        PyObject *res = PyObject_CallOneArg(fn, coro);
13307db96d56Sopenharmony_ci        Py_DECREF(fn);
13317db96d56Sopenharmony_ci        if (res || PyErr_ExceptionMatches(PyExc_RuntimeWarning)) {
13327db96d56Sopenharmony_ci            warned = 1;
13337db96d56Sopenharmony_ci        }
13347db96d56Sopenharmony_ci        Py_XDECREF(res);
13357db96d56Sopenharmony_ci    }
13367db96d56Sopenharmony_ci
13377db96d56Sopenharmony_ci    if (PyErr_Occurred()) {
13387db96d56Sopenharmony_ci        PyErr_WriteUnraisable(coro);
13397db96d56Sopenharmony_ci    }
13407db96d56Sopenharmony_ci    if (!warned) {
13417db96d56Sopenharmony_ci        if (_PyErr_WarnFormat(coro, PyExc_RuntimeWarning, 1,
13427db96d56Sopenharmony_ci                              "coroutine '%S' was never awaited",
13437db96d56Sopenharmony_ci                              ((PyCoroObject *)coro)->cr_qualname) < 0)
13447db96d56Sopenharmony_ci        {
13457db96d56Sopenharmony_ci            PyErr_WriteUnraisable(coro);
13467db96d56Sopenharmony_ci        }
13477db96d56Sopenharmony_ci    }
13487db96d56Sopenharmony_ci}
13497db96d56Sopenharmony_ci
13507db96d56Sopenharmony_ciPyDoc_STRVAR(warn_explicit_doc,
13517db96d56Sopenharmony_ci"Low-level interface to warnings functionality.");
13527db96d56Sopenharmony_ci
13537db96d56Sopenharmony_cistatic PyMethodDef warnings_functions[] = {
13547db96d56Sopenharmony_ci    WARNINGS_WARN_METHODDEF
13557db96d56Sopenharmony_ci    {"warn_explicit", _PyCFunction_CAST(warnings_warn_explicit),
13567db96d56Sopenharmony_ci        METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
13577db96d56Sopenharmony_ci    {"_filters_mutated", _PyCFunction_CAST(warnings_filters_mutated), METH_NOARGS,
13587db96d56Sopenharmony_ci        NULL},
13597db96d56Sopenharmony_ci    /* XXX(brett.cannon): add showwarning? */
13607db96d56Sopenharmony_ci    /* XXX(brett.cannon): Reasonable to add formatwarning? */
13617db96d56Sopenharmony_ci    {NULL, NULL}                /* sentinel */
13627db96d56Sopenharmony_ci};
13637db96d56Sopenharmony_ci
13647db96d56Sopenharmony_ci
13657db96d56Sopenharmony_cistatic int
13667db96d56Sopenharmony_ciwarnings_module_exec(PyObject *module)
13677db96d56Sopenharmony_ci{
13687db96d56Sopenharmony_ci    PyInterpreterState *interp = get_current_interp();
13697db96d56Sopenharmony_ci    if (interp == NULL) {
13707db96d56Sopenharmony_ci        return -1;
13717db96d56Sopenharmony_ci    }
13727db96d56Sopenharmony_ci    WarningsState *st = warnings_get_state(interp);
13737db96d56Sopenharmony_ci    if (st == NULL) {
13747db96d56Sopenharmony_ci        return -1;
13757db96d56Sopenharmony_ci    }
13767db96d56Sopenharmony_ci    if (PyModule_AddObjectRef(module, "filters", st->filters) < 0) {
13777db96d56Sopenharmony_ci        return -1;
13787db96d56Sopenharmony_ci    }
13797db96d56Sopenharmony_ci    if (PyModule_AddObjectRef(module, "_onceregistry", st->once_registry) < 0) {
13807db96d56Sopenharmony_ci        return -1;
13817db96d56Sopenharmony_ci    }
13827db96d56Sopenharmony_ci    if (PyModule_AddObjectRef(module, "_defaultaction", st->default_action) < 0) {
13837db96d56Sopenharmony_ci        return -1;
13847db96d56Sopenharmony_ci    }
13857db96d56Sopenharmony_ci    return 0;
13867db96d56Sopenharmony_ci}
13877db96d56Sopenharmony_ci
13887db96d56Sopenharmony_ci
13897db96d56Sopenharmony_cistatic PyModuleDef_Slot warnings_slots[] = {
13907db96d56Sopenharmony_ci    {Py_mod_exec, warnings_module_exec},
13917db96d56Sopenharmony_ci    {0, NULL}
13927db96d56Sopenharmony_ci};
13937db96d56Sopenharmony_ci
13947db96d56Sopenharmony_cistatic struct PyModuleDef warnings_module = {
13957db96d56Sopenharmony_ci    PyModuleDef_HEAD_INIT,
13967db96d56Sopenharmony_ci    .m_name = MODULE_NAME,
13977db96d56Sopenharmony_ci    .m_doc = warnings__doc__,
13987db96d56Sopenharmony_ci    .m_size = 0,
13997db96d56Sopenharmony_ci    .m_methods = warnings_functions,
14007db96d56Sopenharmony_ci    .m_slots = warnings_slots,
14017db96d56Sopenharmony_ci};
14027db96d56Sopenharmony_ci
14037db96d56Sopenharmony_ci
14047db96d56Sopenharmony_ciPyMODINIT_FUNC
14057db96d56Sopenharmony_ci_PyWarnings_Init(void)
14067db96d56Sopenharmony_ci{
14077db96d56Sopenharmony_ci    return PyModuleDef_Init(&warnings_module);
14087db96d56Sopenharmony_ci}
14097db96d56Sopenharmony_ci
14107db96d56Sopenharmony_ci// We need this to ensure that warnings still work until late in finalization.
14117db96d56Sopenharmony_civoid
14127db96d56Sopenharmony_ci_PyWarnings_Fini(PyInterpreterState *interp)
14137db96d56Sopenharmony_ci{
14147db96d56Sopenharmony_ci    warnings_clear_state(&interp->warnings);
14157db96d56Sopenharmony_ci}
1416