aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Python/_warnings.c
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.com>2024-02-12 07:53:52 +0300
committershadchin <shadchin@yandex-team.com>2024-02-12 08:07:36 +0300
commitce1b7ca3171f9158180640c6a02a74b4afffedea (patch)
treee47c1e8391b1b0128262c1e9b1e6ed4c8fff2348 /contrib/tools/python3/src/Python/_warnings.c
parent57350d96f030db90f220ce50ee591d5c5d403df7 (diff)
downloadydb-ce1b7ca3171f9158180640c6a02a74b4afffedea.tar.gz
Update Python from 3.11.8 to 3.12.2
Diffstat (limited to 'contrib/tools/python3/src/Python/_warnings.c')
-rw-r--r--contrib/tools/python3/src/Python/_warnings.c230
1 files changed, 146 insertions, 84 deletions
diff --git a/contrib/tools/python3/src/Python/_warnings.c b/contrib/tools/python3/src/Python/_warnings.c
index 2815f7987a..1f91edbf5c 100644
--- a/contrib/tools/python3/src/Python/_warnings.c
+++ b/contrib/tools/python3/src/Python/_warnings.c
@@ -198,7 +198,7 @@ get_warnings_attr(PyInterpreterState *interp, PyObject *attr, int try_import)
PyObject *warnings_module, *obj;
/* don't try to import after the start of the Python finallization */
- if (try_import && !_Py_IsFinalizing()) {
+ if (try_import && !_Py_IsInterpreterFinalizing(interp)) {
warnings_module = PyImport_Import(&_Py_ID(warnings));
if (warnings_module == NULL) {
/* Fallback to the C implementation if we cannot get
@@ -214,7 +214,7 @@ get_warnings_attr(PyInterpreterState *interp, PyObject *attr, int try_import)
gone, then we can't even use PyImport_GetModule without triggering
an interpreter abort.
*/
- if (!interp->modules) {
+ if (!_PyImport_GetModules(interp)) {
return NULL;
}
warnings_module = PyImport_GetModule(&_Py_ID(warnings));
@@ -382,8 +382,7 @@ get_filter(PyInterpreterState *interp, PyObject *category,
action = get_default_action(interp);
if (action != NULL) {
- Py_INCREF(Py_None);
- *item = Py_None;
+ *item = Py_NewRef(Py_None);
return action;
}
@@ -468,8 +467,7 @@ normalize_module(PyObject *filename)
module = PyUnicode_Substring(filename, 0, len-3);
}
else {
- module = filename;
- Py_INCREF(module);
+ module = Py_NewRef(filename);
}
return module;
}
@@ -751,8 +749,7 @@ warn_explicit(PyThreadState *tstate, PyObject *category, PyObject *message,
goto cleanup;
return_none:
- result = Py_None;
- Py_INCREF(result);
+ result = Py_NewRef(Py_None);
cleanup:
Py_XDECREF(item);
@@ -764,57 +761,99 @@ warn_explicit(PyThreadState *tstate, PyObject *category, PyObject *message,
return result; /* Py_None or NULL. */
}
-static int
-is_internal_frame(PyFrameObject *frame)
+static PyObject *
+get_frame_filename(PyFrameObject *frame)
{
- if (frame == NULL) {
- return 0;
- }
-
PyCodeObject *code = PyFrame_GetCode(frame);
PyObject *filename = code->co_filename;
Py_DECREF(code);
+ return filename;
+}
- if (filename == NULL) {
- return 0;
- }
+static bool
+is_internal_filename(PyObject *filename)
+{
if (!PyUnicode_Check(filename)) {
- return 0;
+ return false;
}
int contains = PyUnicode_Contains(filename, &_Py_ID(importlib));
if (contains < 0) {
- return 0;
+ return false;
}
else if (contains > 0) {
contains = PyUnicode_Contains(filename, &_Py_ID(_bootstrap));
if (contains < 0) {
- return 0;
+ return false;
}
else if (contains > 0) {
- return 1;
+ return true;
}
}
- return 0;
+ return false;
+}
+
+static bool
+is_filename_to_skip(PyObject *filename, PyTupleObject *skip_file_prefixes)
+{
+ if (skip_file_prefixes) {
+ if (!PyUnicode_Check(filename)) {
+ return false;
+ }
+
+ Py_ssize_t prefixes = PyTuple_GET_SIZE(skip_file_prefixes);
+ for (Py_ssize_t idx = 0; idx < prefixes; ++idx)
+ {
+ PyObject *prefix = PyTuple_GET_ITEM(skip_file_prefixes, idx);
+ Py_ssize_t found = PyUnicode_Tailmatch(filename, prefix, 0, -1, -1);
+ if (found == 1) {
+ return true;
+ }
+ if (found < 0) {
+ return false;
+ }
+ }
+ }
+ return false;
+}
+
+static bool
+is_internal_frame(PyFrameObject *frame)
+{
+ if (frame == NULL) {
+ return false;
+ }
+
+ PyObject *filename = get_frame_filename(frame);
+ if (filename == NULL) {
+ return false;
+ }
+
+ return is_internal_filename(filename);
}
static PyFrameObject *
-next_external_frame(PyFrameObject *frame)
+next_external_frame(PyFrameObject *frame, PyTupleObject *skip_file_prefixes)
{
+ PyObject *frame_filename;
do {
PyFrameObject *back = PyFrame_GetBack(frame);
- Py_DECREF(frame);
- frame = back;
- } while (frame != NULL && is_internal_frame(frame));
+ Py_SETREF(frame, back);
+ } while (frame != NULL && (frame_filename = get_frame_filename(frame)) &&
+ (is_internal_filename(frame_filename) ||
+ is_filename_to_skip(frame_filename, skip_file_prefixes)));
return frame;
}
/* filename, module, and registry are new refs, globals is borrowed */
+/* skip_file_prefixes is either NULL or a tuple of strs. */
/* Returns 0 on error (no new refs), 1 on success */
static int
-setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
+setup_context(Py_ssize_t stack_level,
+ PyTupleObject *skip_file_prefixes,
+ PyObject **filename, int *lineno,
PyObject **module, PyObject **registry)
{
PyObject *globals;
@@ -824,6 +863,21 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
if (tstate == NULL) {
return 0;
}
+ if (skip_file_prefixes) {
+ /* Type check our data structure up front. Later code that uses it
+ * isn't structured to report errors. */
+ Py_ssize_t prefixes = PyTuple_GET_SIZE(skip_file_prefixes);
+ for (Py_ssize_t idx = 0; idx < prefixes; ++idx)
+ {
+ PyObject *prefix = PyTuple_GET_ITEM(skip_file_prefixes, idx);
+ if (!PyUnicode_Check(prefix)) {
+ PyErr_Format(PyExc_TypeError,
+ "Found non-str '%s' in skip_file_prefixes.",
+ Py_TYPE(prefix)->tp_name);
+ return 0;
+ }
+ }
+ }
PyInterpreterState *interp = tstate->interp;
PyFrameObject *f = PyThreadState_GetFrame(tstate);
// Stack level comparisons to Python code is off by one as there is no
@@ -831,13 +885,12 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
if (stack_level <= 0 || is_internal_frame(f)) {
while (--stack_level > 0 && f != NULL) {
PyFrameObject *back = PyFrame_GetBack(f);
- Py_DECREF(f);
- f = back;
+ Py_SETREF(f, back);
}
}
else {
while (--stack_level > 0 && f != NULL) {
- f = next_external_frame(f);
+ f = next_external_frame(f, skip_file_prefixes);
}
}
@@ -848,8 +901,7 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
}
else {
globals = f->f_frame->f_globals;
- *filename = f->f_frame->f_code->co_filename;
- Py_INCREF(*filename);
+ *filename = Py_NewRef(f->f_frame->f_code->co_filename);
*lineno = PyFrame_GetLineNumber(f);
Py_DECREF(f);
}
@@ -931,7 +983,7 @@ get_category(PyObject *message, PyObject *category)
static PyObject *
do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
- PyObject *source)
+ PyObject *source, PyTupleObject *skip_file_prefixes)
{
PyObject *filename, *module, *registry, *res;
int lineno;
@@ -941,7 +993,8 @@ do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
return NULL;
}
- if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
+ if (!setup_context(stack_level, skip_file_prefixes,
+ &filename, &lineno, &module, &registry))
return NULL;
res = warn_explicit(tstate, category, message, filename, lineno, module, registry,
@@ -956,22 +1009,42 @@ do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
warn as warnings_warn
message: object
+ Text of the warning message.
category: object = None
+ The Warning category subclass. Defaults to UserWarning.
stacklevel: Py_ssize_t = 1
+ How far up the call stack to make this warning appear. A value of 2 for
+ example attributes the warning to the caller of the code calling warn().
source: object = None
+ If supplied, the destroyed object which emitted a ResourceWarning
+ *
+ skip_file_prefixes: object(type='PyTupleObject *', subclass_of='&PyTuple_Type') = NULL
+ An optional tuple of module filename prefixes indicating frames to skip
+ during stacklevel computations for stack frame attribution.
Issue a warning, or maybe ignore it or raise an exception.
[clinic start generated code]*/
static PyObject *
warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
- Py_ssize_t stacklevel, PyObject *source)
-/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
+ Py_ssize_t stacklevel, PyObject *source,
+ PyTupleObject *skip_file_prefixes)
+/*[clinic end generated code: output=a68e0f6906c65f80 input=eb37c6a18bec4ea1]*/
{
category = get_category(message, category);
if (category == NULL)
return NULL;
- return do_warn(message, category, stacklevel, source);
+ if (skip_file_prefixes) {
+ if (PyTuple_GET_SIZE(skip_file_prefixes) > 0) {
+ if (stacklevel < 2) {
+ stacklevel = 2;
+ }
+ } else {
+ Py_DECREF((PyObject *)skip_file_prefixes);
+ skip_file_prefixes = NULL;
+ }
+ }
+ return do_warn(message, category, stacklevel, source, skip_file_prefixes);
}
static PyObject *
@@ -984,12 +1057,12 @@ get_source_line(PyInterpreterState *interp, PyObject *module_globals, int lineno
PyObject *source_list;
PyObject *source_line;
- /* Check/get the requisite pieces needed for the loader. */
- loader = _PyDict_GetItemWithError(module_globals, &_Py_ID(__loader__));
+ /* stolen from import.c */
+ loader = _PyImport_BlessMyLoader(interp, module_globals);
if (loader == NULL) {
return NULL;
}
- Py_INCREF(loader);
+
module_name = _PyDict_GetItemWithError(module_globals, &_Py_ID(__name__));
if (!module_name) {
Py_DECREF(loader);
@@ -1030,28 +1103,31 @@ get_source_line(PyInterpreterState *interp, PyObject *module_globals, int lineno
return source_line;
}
+/*[clinic input]
+warn_explicit as warnings_warn_explicit
+
+ message: object
+ category: object
+ filename: unicode
+ lineno: int
+ module as mod: object = NULL
+ registry: object = None
+ module_globals: object = None
+ source as sourceobj: object = None
+
+Issue a warning, or maybe ignore it or raise an exception.
+[clinic start generated code]*/
+
static PyObject *
-warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
+warnings_warn_explicit_impl(PyObject *module, PyObject *message,
+ PyObject *category, PyObject *filename,
+ int lineno, PyObject *mod, PyObject *registry,
+ PyObject *module_globals, PyObject *sourceobj)
+/*[clinic end generated code: output=c49c62b15a49a186 input=df6eeb8b45e712f1]*/
{
- static char *kwd_list[] = {"message", "category", "filename", "lineno",
- "module", "registry", "module_globals",
- "source", 0};
- PyObject *message;
- PyObject *category;
- PyObject *filename;
- int lineno;
- PyObject *module = NULL;
- PyObject *registry = NULL;
- PyObject *module_globals = NULL;
- PyObject *sourceobj = NULL;
PyObject *source_line = NULL;
PyObject *returned;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
- kwd_list, &message, &category, &filename, &lineno, &module,
- &registry, &module_globals, &sourceobj))
- return NULL;
-
PyThreadState *tstate = get_current_tstate();
if (tstate == NULL) {
return NULL;
@@ -1070,14 +1146,20 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
return NULL;
}
}
- returned = warn_explicit(tstate, category, message, filename, lineno, module,
- registry, source_line, sourceobj);
+ returned = warn_explicit(tstate, category, message, filename, lineno,
+ mod, registry, source_line, sourceobj);
Py_XDECREF(source_line);
return returned;
}
+/*[clinic input]
+_filters_mutated as warnings_filters_mutated
+
+[clinic start generated code]*/
+
static PyObject *
-warnings_filters_mutated(PyObject *self, PyObject *Py_UNUSED(args))
+warnings_filters_mutated_impl(PyObject *module)
+/*[clinic end generated code: output=8ce517abd12b88f4 input=35ecbf08ee2491b2]*/
{
PyInterpreterState *interp = get_current_interp();
if (interp == NULL) {
@@ -1103,7 +1185,7 @@ warn_unicode(PyObject *category, PyObject *message,
if (category == NULL)
category = PyExc_RuntimeWarning;
- res = do_warn(message, category, stack_level, source);
+ res = do_warn(message, category, stack_level, source, NULL);
if (res == NULL)
return -1;
Py_DECREF(res);
@@ -1135,11 +1217,7 @@ PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
int res;
va_list vargs;
-#ifdef HAVE_STDARG_PROTOTYPES
va_start(vargs, format);
-#else
- va_start(vargs);
-#endif
res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
va_end(vargs);
return res;
@@ -1152,11 +1230,7 @@ _PyErr_WarnFormat(PyObject *source, PyObject *category, Py_ssize_t stack_level,
int res;
va_list vargs;
-#ifdef HAVE_STDARG_PROTOTYPES
va_start(vargs, format);
-#else
- va_start(vargs);
-#endif
res = _PyErr_WarnFormatV(source, category, stack_level, format, vargs);
va_end(vargs);
return res;
@@ -1169,11 +1243,7 @@ PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
int res;
va_list vargs;
-#ifdef HAVE_STDARG_PROTOTYPES
va_start(vargs, format);
-#else
- va_start(vargs);
-#endif
res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
stack_level, format, vargs);
va_end(vargs);
@@ -1277,11 +1347,7 @@ PyErr_WarnExplicitFormat(PyObject *category,
goto exit;
}
-#ifdef HAVE_STDARG_PROTOTYPES
va_start(vargs, format);
-#else
- va_start(vargs);
-#endif
message = PyUnicode_FromFormatV(format, vargs);
if (message != NULL) {
PyObject *res;
@@ -1351,15 +1417,10 @@ _PyErr_WarnUnawaitedCoroutine(PyObject *coro)
}
}
-PyDoc_STRVAR(warn_explicit_doc,
-"Low-level interface to warnings functionality.");
-
static PyMethodDef warnings_functions[] = {
WARNINGS_WARN_METHODDEF
- {"warn_explicit", _PyCFunction_CAST(warnings_warn_explicit),
- METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
- {"_filters_mutated", _PyCFunction_CAST(warnings_filters_mutated), METH_NOARGS,
- NULL},
+ WARNINGS_WARN_EXPLICIT_METHODDEF
+ WARNINGS_FILTERS_MUTATED_METHODDEF
/* XXX(brett.cannon): add showwarning? */
/* XXX(brett.cannon): Reasonable to add formatwarning? */
{NULL, NULL} /* sentinel */
@@ -1392,6 +1453,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},
{0, NULL}
};