diff options
Diffstat (limited to 'contrib/tools/python3/Python/_warnings.c')
| -rw-r--r-- | contrib/tools/python3/Python/_warnings.c | 196 |
1 files changed, 122 insertions, 74 deletions
diff --git a/contrib/tools/python3/Python/_warnings.c b/contrib/tools/python3/Python/_warnings.c index 1f91edbf5cb..9ed15c948f4 100644 --- a/contrib/tools/python3/Python/_warnings.c +++ b/contrib/tools/python3/Python/_warnings.c @@ -1,10 +1,15 @@ #include "Python.h" -#include "pycore_initconfig.h" +#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION_MUT() #include "pycore_interp.h" // PyInterpreterState.warnings #include "pycore_long.h" // _PyLong_GetZero() -#include "pycore_pyerrors.h" +#include "pycore_pyerrors.h" // _PyErr_Occurred() +#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing() #include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_frame.h" +#include "pycore_sysmodule.h" // _PySys_GetOptionalAttr() +#include "pycore_traceback.h" // _Py_DisplaySourceLine() + +#include <stdbool.h> + #include "clinic/_warnings.c.h" #define MODULE_NAME "_warnings" @@ -222,7 +227,7 @@ get_warnings_attr(PyInterpreterState *interp, PyObject *attr, int try_import) return NULL; } - (void)_PyObject_LookupAttr(warnings_module, attr, &obj); + (void)PyObject_GetOptionalAttr(warnings_module, attr, &obj); Py_DECREF(warnings_module); return obj; } @@ -231,14 +236,12 @@ get_warnings_attr(PyInterpreterState *interp, PyObject *attr, int try_import) static PyObject * get_once_registry(PyInterpreterState *interp) { - PyObject *registry; - WarningsState *st = warnings_get_state(interp); - if (st == NULL) { - return NULL; - } + assert(st != NULL); + + _Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(&st->mutex); - registry = GET_WARNINGS_ATTR(interp, onceregistry, 0); + PyObject *registry = GET_WARNINGS_ATTR(interp, onceregistry, 0); if (registry == NULL) { if (PyErr_Occurred()) return NULL; @@ -261,14 +264,12 @@ get_once_registry(PyInterpreterState *interp) static PyObject * get_default_action(PyInterpreterState *interp) { - PyObject *default_action; - WarningsState *st = warnings_get_state(interp); - if (st == NULL) { - return NULL; - } + assert(st != NULL); - default_action = GET_WARNINGS_ATTR(interp, defaultaction, 0); + _Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(&st->mutex); + + PyObject *default_action = GET_WARNINGS_ATTR(interp, defaultaction, 0); if (default_action == NULL) { if (PyErr_Occurred()) { return NULL; @@ -295,15 +296,12 @@ get_filter(PyInterpreterState *interp, PyObject *category, PyObject *text, Py_ssize_t lineno, PyObject *module, PyObject **item) { - PyObject *action; - Py_ssize_t i; - PyObject *warnings_filters; WarningsState *st = warnings_get_state(interp); - if (st == NULL) { - return NULL; - } + assert(st != NULL); + + _Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(&st->mutex); - warnings_filters = GET_WARNINGS_ATTR(interp, filters, 0); + PyObject *warnings_filters = GET_WARNINGS_ATTR(interp, filters, 0); if (warnings_filters == NULL) { if (PyErr_Occurred()) return NULL; @@ -320,7 +318,7 @@ get_filter(PyInterpreterState *interp, PyObject *category, } /* WarningsState.filters could change while we are iterating over it. */ - for (i = 0; i < PyList_GET_SIZE(filters); i++) { + for (Py_ssize_t i = 0; i < PyList_GET_SIZE(filters); i++) { PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj; Py_ssize_t ln; int is_subclass, good_msg, good_mod; @@ -380,7 +378,7 @@ get_filter(PyInterpreterState *interp, PyObject *category, Py_DECREF(tmp_item); } - action = get_default_action(interp); + PyObject *action = get_default_action(interp); if (action != NULL) { *item = Py_NewRef(Py_None); return action; @@ -394,23 +392,26 @@ static int already_warned(PyInterpreterState *interp, PyObject *registry, PyObject *key, int should_set) { - PyObject *version_obj, *already_warned; + PyObject *already_warned; if (key == NULL) return -1; WarningsState *st = warnings_get_state(interp); - if (st == NULL) { + assert(st != NULL); + _Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(&st->mutex); + + PyObject *version_obj; + if (PyDict_GetItemRef(registry, &_Py_ID(version), &version_obj) < 0) { return -1; } - version_obj = _PyDict_GetItemWithError(registry, &_Py_ID(version)); - if (version_obj == NULL + bool should_update_version = ( + version_obj == NULL || !PyLong_CheckExact(version_obj) - || PyLong_AsLong(version_obj) != st->filters_version) - { - if (PyErr_Occurred()) { - return -1; - } + || PyLong_AsLong(version_obj) != st->filters_version + ); + Py_XDECREF(version_obj); + if (should_update_version) { PyDict_Clear(registry); version_obj = PyLong_FromLong(st->filters_version); if (version_obj == NULL) @@ -422,15 +423,15 @@ already_warned(PyInterpreterState *interp, PyObject *registry, PyObject *key, Py_DECREF(version_obj); } else { - already_warned = PyDict_GetItemWithError(registry, key); + if (PyDict_GetItemRef(registry, key, &already_warned) < 0) { + return -1; + } if (already_warned != NULL) { int rc = PyObject_IsTrue(already_warned); + Py_DECREF(already_warned); if (rc != 0) return rc; } - else if (PyErr_Occurred()) { - return -1; - } } /* This warning wasn't found in the registry, set it. */ @@ -493,7 +494,7 @@ static void show_warning(PyThreadState *tstate, PyObject *filename, int lineno, PyObject *text, PyObject *category, PyObject *sourceline) { - PyObject *f_stderr; + PyObject *f_stderr = NULL; PyObject *name; char lineno_str[128]; @@ -504,8 +505,7 @@ show_warning(PyThreadState *tstate, PyObject *filename, int lineno, goto error; } - f_stderr = _PySys_GetAttr(tstate, &_Py_ID(stderr)); - if (f_stderr == NULL) { + if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &f_stderr) <= 0) { fprintf(stderr, "lost sys.stderr\n"); goto error; } @@ -533,9 +533,6 @@ show_warning(PyThreadState *tstate, PyObject *filename, int lineno, Py_UCS4 ch; PyObject *truncated; - if (PyUnicode_READY(sourceline) < 1) - goto error; - kind = PyUnicode_KIND(sourceline); data = PyUnicode_DATA(sourceline); len = PyUnicode_GET_LENGTH(sourceline); @@ -558,6 +555,7 @@ show_warning(PyThreadState *tstate, PyObject *filename, int lineno, } error: + Py_XDECREF(f_stderr); Py_XDECREF(name); PyErr_Clear(); } @@ -571,10 +569,9 @@ call_show_warning(PyThreadState *tstate, PyObject *category, PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL; PyInterpreterState *interp = tstate->interp; - /* If the source parameter is set, try to get the Python implementation. - The Python implementation is able to log the traceback where the source + /* The Python implementation is able to log the traceback where the source was allocated, whereas the C implementation doesn't. */ - show_fn = GET_WARNINGS_ATTR(interp, _showwarnmsg, source != NULL); + show_fn = GET_WARNINGS_ATTR(interp, _showwarnmsg, 1); if (show_fn == NULL) { if (PyErr_Occurred()) return -1; @@ -791,6 +788,10 @@ is_internal_filename(PyObject *filename) } } + if (_PyUnicode_EqualToASCIIString(filename, "library/python/runtime_py3/__res.py")) { + return true; + } + return false; } @@ -896,12 +897,12 @@ setup_context(Py_ssize_t stack_level, if (f == NULL) { globals = interp->sysdict; - *filename = PyUnicode_FromString("sys"); - *lineno = 1; + *filename = PyUnicode_FromString("<sys>"); + *lineno = 0; } else { globals = f->f_frame->f_globals; - *filename = Py_NewRef(f->f_frame->f_code->co_filename); + *filename = Py_NewRef(_PyFrame_GetCode(f->f_frame)->co_filename); *lineno = PyFrame_GetLineNumber(f); Py_DECREF(f); } @@ -911,13 +912,12 @@ setup_context(Py_ssize_t stack_level, /* Setup registry. */ assert(globals != NULL); assert(PyDict_Check(globals)); - *registry = _PyDict_GetItemWithError(globals, &_Py_ID(__warningregistry__)); + int rc = PyDict_GetItemRef(globals, &_Py_ID(__warningregistry__), + registry); + if (rc < 0) { + goto handle_error; + } if (*registry == NULL) { - int rc; - - if (_PyErr_Occurred(tstate)) { - goto handle_error; - } *registry = PyDict_New(); if (*registry == NULL) goto handle_error; @@ -926,21 +926,21 @@ setup_context(Py_ssize_t stack_level, if (rc < 0) goto handle_error; } - else - Py_INCREF(*registry); /* Setup module. */ - *module = _PyDict_GetItemWithError(globals, &_Py_ID(__name__)); - if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) { - Py_INCREF(*module); - } - else if (_PyErr_Occurred(tstate)) { + rc = PyDict_GetItemRef(globals, &_Py_ID(__name__), module); + if (rc < 0) { goto handle_error; } - else { - *module = PyUnicode_FromString("<string>"); - if (*module == NULL) - goto handle_error; + if (rc > 0) { + if (Py_IsNone(*module) || PyUnicode_Check(*module)) { + return 1; + } + Py_DECREF(*module); + } + *module = PyUnicode_FromString("<string>"); + if (*module == NULL) { + goto handle_error; } return 1; @@ -997,8 +997,15 @@ do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level, &filename, &lineno, &module, ®istry)) return NULL; +#ifdef Py_GIL_DISABLED + WarningsState *st = warnings_get_state(tstate->interp); + assert(st != NULL); +#endif + + Py_BEGIN_CRITICAL_SECTION_MUT(&st->mutex); res = warn_explicit(tstate, category, message, filename, lineno, module, registry, NULL, source); + Py_END_CRITICAL_SECTION(); Py_DECREF(filename); Py_DECREF(registry); Py_DECREF(module); @@ -1063,15 +1070,15 @@ get_source_line(PyInterpreterState *interp, PyObject *module_globals, int lineno return NULL; } - module_name = _PyDict_GetItemWithError(module_globals, &_Py_ID(__name__)); - if (!module_name) { + int rc = PyDict_GetItemRef(module_globals, &_Py_ID(__name__), + &module_name); + if (rc < 0 || rc == 0) { Py_DECREF(loader); return NULL; } - Py_INCREF(module_name); /* Make sure the loader implements the optional get_source() method. */ - (void)_PyObject_LookupAttr(loader, &_Py_ID(get_source), &get_source); + (void)PyObject_GetOptionalAttr(loader, &_Py_ID(get_source), &get_source); Py_DECREF(loader); if (!get_source) { Py_DECREF(module_name); @@ -1146,8 +1153,16 @@ warnings_warn_explicit_impl(PyObject *module, PyObject *message, return NULL; } } + +#ifdef Py_GIL_DISABLED + WarningsState *st = warnings_get_state(tstate->interp); + assert(st != NULL); +#endif + + Py_BEGIN_CRITICAL_SECTION_MUT(&st->mutex); returned = warn_explicit(tstate, category, message, filename, lineno, mod, registry, source_line, sourceobj); + Py_END_CRITICAL_SECTION(); Py_XDECREF(source_line); return returned; } @@ -1165,11 +1180,14 @@ warnings_filters_mutated_impl(PyObject *module) if (interp == NULL) { return NULL; } + WarningsState *st = warnings_get_state(interp); - if (st == NULL) { - return NULL; - } + assert(st != NULL); + + Py_BEGIN_CRITICAL_SECTION_MUT(&st->mutex); st->filters_version++; + Py_END_CRITICAL_SECTION(); + Py_RETURN_NONE; } @@ -1287,8 +1305,16 @@ PyErr_WarnExplicitObject(PyObject *category, PyObject *message, if (tstate == NULL) { return -1; } + +#ifdef Py_GIL_DISABLED + WarningsState *st = warnings_get_state(tstate->interp); + assert(st != NULL); +#endif + + Py_BEGIN_CRITICAL_SECTION_MUT(&st->mutex); res = warn_explicit(tstate, category, message, filename, lineno, module, registry, NULL, NULL); + Py_END_CRITICAL_SECTION(); if (res == NULL) return -1; Py_DECREF(res); @@ -1353,8 +1379,15 @@ PyErr_WarnExplicitFormat(PyObject *category, PyObject *res; PyThreadState *tstate = get_current_tstate(); if (tstate != NULL) { +#ifdef Py_GIL_DISABLED + WarningsState *st = warnings_get_state(tstate->interp); + assert(st != NULL); +#endif + + Py_BEGIN_CRITICAL_SECTION_MUT(&st->mutex); res = warn_explicit(tstate, category, message, filename, lineno, module, registry, NULL, NULL); + Py_END_CRITICAL_SECTION(); Py_DECREF(message); if (res != NULL) { Py_DECREF(res); @@ -1370,6 +1403,20 @@ exit: } void +_PyErr_WarnUnawaitedAgenMethod(PyAsyncGenObject *agen, PyObject *method) +{ + PyObject *exc = PyErr_GetRaisedException(); + if (_PyErr_WarnFormat((PyObject *)agen, PyExc_RuntimeWarning, 1, + "coroutine method %R of %R was never awaited", + method, agen->ag_qualname) < 0) + { + PyErr_WriteUnraisable((PyObject *)agen); + } + PyErr_SetRaisedException(exc); +} + + +void _PyErr_WarnUnawaitedCoroutine(PyObject *coro) { /* First, we attempt to funnel the warning through @@ -1454,6 +1501,7 @@ warnings_module_exec(PyObject *module) static PyModuleDef_Slot warnings_slots[] = { {Py_mod_exec, warnings_module_exec}, {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {Py_mod_gil, Py_MOD_GIL_NOT_USED}, {0, NULL} }; |
