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, ®istry)) 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 ®istry, &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