diff options
Diffstat (limited to 'Python/_warnings.c')
-rw-r--r-- | Python/_warnings.c | 298 |
1 files changed, 188 insertions, 110 deletions
diff --git a/Python/_warnings.c b/Python/_warnings.c index 445ff6b..f33e477 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -18,11 +18,12 @@ static int check_matched(PyObject *obj, PyObject *arg) { PyObject *result; + _Py_IDENTIFIER(match); int rc; if (obj == Py_None) return 1; - result = PyObject_CallMethod(obj, "match", "O", arg); + result = _PyObject_CallMethodId(obj, &PyId_match, "O", arg); if (result == NULL) return -1; @@ -44,7 +45,7 @@ get_warnings_attr(const char *attr) int result; if (warnings_str == NULL) { - warnings_str = PyString_InternFromString("warnings"); + warnings_str = PyUnicode_InternFromString("warnings"); if (warnings_str == NULL) return NULL; } @@ -116,7 +117,7 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, _filters = warnings_filters; } - if (!PyList_Check(_filters)) { + if (_filters == NULL || !PyList_Check(_filters)) { PyErr_SetString(PyExc_ValueError, MODULE_NAME ".filters must be a list"); return NULL; @@ -145,18 +146,18 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, good_msg = check_matched(msg, text); good_mod = check_matched(mod, module); is_subclass = PyObject_IsSubclass(category, cat); - ln = PyInt_AsSsize_t(ln_obj); + ln = PyLong_AsSsize_t(ln_obj); if (good_msg == -1 || good_mod == -1 || is_subclass == -1 || (ln == -1 && PyErr_Occurred())) return NULL; if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) - return PyString_AsString(action); + return _PyUnicode_AsString(action); } action = get_default_action(); if (action != NULL) { - return PyString_AsString(action); + return _PyUnicode_AsString(action); } PyErr_SetString(PyExc_ValueError, @@ -198,17 +199,17 @@ normalize_module(PyObject *filename) if (rc == -1) return NULL; else if (rc == 0) - return PyString_FromString("<unknown>"); + return PyUnicode_FromString("<unknown>"); - mod_str = PyString_AsString(filename); + mod_str = _PyUnicode_AsString(filename); if (mod_str == NULL) return NULL; - len = PyString_Size(filename); + len = PyUnicode_GetLength(filename); if (len < 0) return NULL; if (len >= 3 && - strncmp(mod_str + (len - 3), ".py", 3) == 0) { - module = PyString_FromStringAndSize(mod_str, len-3); + strncmp(mod_str + (len - 3), ".py", 3) == 0) { + module = PyUnicode_Substring(filename, 0, len-3); } else { module = filename; @@ -225,7 +226,7 @@ update_registry(PyObject *registry, PyObject *text, PyObject *category, int rc; if (add_zero) { - zero = PyInt_FromLong(0); + zero = PyLong_FromLong(0); if (zero == NULL) return -1; altkey = PyTuple_Pack(3, text, category, zero); @@ -246,10 +247,11 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject PyObject *f_stderr; PyObject *name; char lineno_str[128]; + _Py_IDENTIFIER(__name__); PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno); - name = PyObject_GetAttrString(category, "__name__"); + name = _PyObject_GetAttrId(category, &PyId___name__); if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */ return; @@ -271,7 +273,9 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject /* Print " source_line\n" */ if (sourceline) { - char *source_line_str = PyString_AS_STRING(sourceline); + char *source_line_str = _PyUnicode_AsString(sourceline); + if (source_line_str == NULL) + return; while (*source_line_str == ' ' || *source_line_str == '\t' || *source_line_str == '\014') source_line_str++; @@ -280,8 +284,8 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject PyFile_WriteString("\n", f_stderr); } else - _Py_DisplaySourceLine(f_stderr, PyString_AS_STRING(filename), - lineno, 2); + if (_Py_DisplaySourceLine(f_stderr, filename, lineno, 2) < 0) + return; PyErr_Clear(); } @@ -328,7 +332,7 @@ warn_explicit(PyObject *category, PyObject *message, goto cleanup; } - lineno_obj = PyInt_FromLong(lineno); + lineno_obj = PyLong_FromLong(lineno); if (lineno_obj == NULL) goto cleanup; @@ -382,8 +386,11 @@ warn_explicit(PyObject *category, PyObject *message, PyObject *to_str = PyObject_Str(item); const char *err_str = "???"; - if (to_str != NULL) - err_str = PyString_AS_STRING(to_str); + if (to_str != NULL) { + err_str = _PyUnicode_AsString(to_str); + if (err_str == NULL) + goto cleanup; + } PyErr_Format(PyExc_RuntimeError, "Unrecognized action (%s) in warnings.filters:\n %s", action, err_str); @@ -402,23 +409,23 @@ warn_explicit(PyObject *category, PyObject *message, show_warning(filename, lineno, text, category, sourceline); } else { - PyObject *res; - - if (!PyMethod_Check(show_fxn) && !PyFunction_Check(show_fxn)) { - PyErr_SetString(PyExc_TypeError, - "warnings.showwarning() must be set to a " - "function or method"); - Py_DECREF(show_fxn); - goto cleanup; - } - - res = PyObject_CallFunctionObjArgs(show_fxn, message, category, - filename, lineno_obj, - NULL); - Py_DECREF(show_fxn); - Py_XDECREF(res); - if (res == NULL) - goto cleanup; + PyObject *res; + + if (!PyCallable_Check(show_fxn)) { + PyErr_SetString(PyExc_TypeError, + "warnings.showwarning() must be set to a " + "callable"); + Py_DECREF(show_fxn); + goto cleanup; + } + + res = PyObject_CallFunctionObjArgs(show_fxn, message, category, + filename, lineno_obj, + NULL); + Py_DECREF(show_fxn); + Py_XDECREF(res); + if (res == NULL) + goto cleanup; } } else /* if (rc == -1) */ @@ -482,7 +489,7 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, /* Setup module. */ *module = PyDict_GetItemString(globals, "__name__"); if (*module == NULL) { - *module = PyString_FromString("<string>"); + *module = PyUnicode_FromString("<string>"); if (*module == NULL) goto handle_error; } @@ -491,21 +498,29 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, /* Setup filename. */ *filename = PyDict_GetItemString(globals, "__file__"); - if (*filename != NULL && PyString_Check(*filename)) { - Py_ssize_t len = PyString_Size(*filename); - const char *file_str = PyString_AsString(*filename); - if (file_str == NULL || (len < 0 && PyErr_Occurred())) + if (*filename != NULL && PyUnicode_Check(*filename)) { + Py_ssize_t len; + int kind; + void *data; + + if (PyUnicode_READY(*filename)) goto handle_error; + len = PyUnicode_GetLength(*filename); + kind = PyUnicode_KIND(*filename); + data = PyUnicode_DATA(*filename); + +#define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0) /* if filename.lower().endswith((".pyc", ".pyo")): */ if (len >= 4 && - file_str[len-4] == '.' && - tolower(file_str[len-3]) == 'p' && - tolower(file_str[len-2]) == 'y' && - (tolower(file_str[len-1]) == 'c' || - tolower(file_str[len-1]) == 'o')) + PyUnicode_READ(kind, data, len-4) == '.' && + ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' && + ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' && + (ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c' || + ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'o')) { - *filename = PyString_FromStringAndSize(file_str, len-1); + *filename = PyUnicode_Substring(*filename, 0, + PyUnicode_GET_LENGTH(*filename)-1); if (*filename == NULL) goto handle_error; } @@ -513,9 +528,11 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, Py_INCREF(*filename); } else { - const char *module_str = PyString_AsString(*module); + const char *module_str = _PyUnicode_AsString(*module); *filename = NULL; - if (module_str && strcmp(module_str, "__main__") == 0) { + if (module_str == NULL) + goto handle_error; + if (strcmp(module_str, "__main__") == 0) { PyObject *argv = PySys_GetObject("argv"); if (argv != NULL && PyList_Size(argv) > 0) { int is_true; @@ -529,16 +546,16 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, } else if (!is_true) { Py_DECREF(*filename); - *filename = PyString_FromString("__main__"); + *filename = PyUnicode_FromString("__main__"); if (*filename == NULL) goto handle_error; } } else { /* embedded interpreters don't have sys.argv, see bug #839151 */ - *filename = PyString_FromString("__main__"); - if (*filename == NULL) - goto handle_error; + *filename = PyUnicode_FromString("__main__"); + if (*filename == NULL) + goto handle_error; } } if (*filename == NULL) { @@ -638,8 +655,9 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) return NULL; if (module_globals) { - static PyObject *get_source_name = NULL; - static PyObject *splitlines_name = NULL; + _Py_IDENTIFIER(get_source); + _Py_IDENTIFIER(splitlines); + PyObject *tmp; PyObject *loader; PyObject *module_name; PyObject *source; @@ -647,16 +665,10 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) PyObject *source_line; PyObject *returned; - if (get_source_name == NULL) { - get_source_name = PyString_InternFromString("get_source"); - if (!get_source_name) - return NULL; - } - if (splitlines_name == NULL) { - splitlines_name = PyString_InternFromString("splitlines"); - if (!splitlines_name) - return NULL; - } + if ((tmp = _PyUnicode_FromId(&PyId_get_source)) == NULL) + return NULL; + if ((tmp = _PyUnicode_FromId(&PyId_splitlines)) == NULL) + return NULL; /* Check/get the requisite pieces needed for the loader. */ loader = PyDict_GetItemString(module_globals, "__loader__"); @@ -666,11 +678,11 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) goto standard_call; /* Make sure the loader implements the optional get_source() method. */ - if (!PyObject_HasAttrString(loader, "get_source")) + if (!_PyObject_HasAttrId(loader, &PyId_get_source)) goto standard_call; /* Call get_source() to get the source code. */ - source = PyObject_CallMethodObjArgs(loader, get_source_name, - module_name, NULL); + source = PyObject_CallMethodObjArgs(loader, PyId_get_source.object, + module_name, NULL); if (!source) return NULL; else if (source == Py_None) { @@ -679,8 +691,9 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) } /* Split the source into lines. */ - source_list = PyObject_CallMethodObjArgs(source, splitlines_name, - NULL); + source_list = PyObject_CallMethodObjArgs(source, + PyId_splitlines.object, + NULL); Py_DECREF(source); if (!source_list) return NULL; @@ -706,19 +719,17 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) /* Function to issue a warning message; may raise an exception. */ -int -PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level) + +static int +warn_unicode(PyObject *category, PyObject *message, + Py_ssize_t stack_level) { PyObject *res; - PyObject *message = PyString_FromString(text); - if (message == NULL) - return -1; if (category == NULL) category = PyExc_RuntimeWarning; res = do_warn(message, category, stack_level); - Py_DECREF(message); if (res == NULL) return -1; Py_DECREF(res); @@ -726,6 +737,42 @@ PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level) return 0; } +int +PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, + const char *format, ...) +{ + int ret; + PyObject *message; + va_list vargs; + +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + message = PyUnicode_FromFormatV(format, vargs); + if (message != NULL) { + ret = warn_unicode(category, message, stack_level); + Py_DECREF(message); + } + else + ret = -1; + va_end(vargs); + return ret; +} + +int +PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level) +{ + int ret; + PyObject *message = PyUnicode_FromString(text); + if (message == NULL) + return -1; + ret = warn_unicode(category, message, stack_level); + Py_DECREF(message); + return ret; +} + /* PyErr_Warn is only for backwards compatibility and will be removed. Use PyErr_WarnEx instead. */ @@ -744,15 +791,15 @@ PyErr_WarnExplicit(PyObject *category, const char *text, const char *module_str, PyObject *registry) { PyObject *res; - PyObject *message = PyString_FromString(text); - PyObject *filename = PyString_FromString(filename_str); + PyObject *message = PyUnicode_FromString(text); + PyObject *filename = PyUnicode_DecodeFSDefault(filename_str); PyObject *module = NULL; int ret = -1; if (message == NULL || filename == NULL) goto exit; if (module_str != NULL) { - module = PyString_FromString(module_str); + module = PyUnicode_FromString(module_str); if (module == NULL) goto exit; } @@ -787,7 +834,7 @@ static PyMethodDef warnings_functions[] = { METH_VARARGS | METH_KEYWORDS, warn_explicit_doc}, /* XXX(brett.cannon): add showwarning? */ /* XXX(brett.cannon): Reasonable to add formatwarning? */ - {NULL, NULL} /* sentinel */ + {NULL, NULL} /* sentinel */ }; @@ -797,12 +844,13 @@ create_filter(PyObject *category, const char *action) static PyObject *ignore_str = NULL; static PyObject *error_str = NULL; static PyObject *default_str = NULL; + static PyObject *always_str = NULL; PyObject *action_obj = NULL; PyObject *lineno, *result; if (!strcmp(action, "ignore")) { if (ignore_str == NULL) { - ignore_str = PyString_InternFromString("ignore"); + ignore_str = PyUnicode_InternFromString("ignore"); if (ignore_str == NULL) return NULL; } @@ -810,7 +858,7 @@ create_filter(PyObject *category, const char *action) } else if (!strcmp(action, "error")) { if (error_str == NULL) { - error_str = PyString_InternFromString("error"); + error_str = PyUnicode_InternFromString("error"); if (error_str == NULL) return NULL; } @@ -818,18 +866,26 @@ create_filter(PyObject *category, const char *action) } else if (!strcmp(action, "default")) { if (default_str == NULL) { - default_str = PyString_InternFromString("default"); + default_str = PyUnicode_InternFromString("default"); if (default_str == NULL) return NULL; } action_obj = default_str; } + else if (!strcmp(action, "always")) { + if (always_str == NULL) { + always_str = PyUnicode_InternFromString("always"); + if (always_str == NULL) + return NULL; + } + action_obj = always_str; + } else { Py_FatalError("unknown action"); } /* This assumes the line number is zero for now. */ - lineno = PyInt_FromLong(0); + lineno = PyLong_FromLong(0); if (lineno == NULL) return NULL; result = PyTuple_Pack(5, action_obj, Py_None, category, Py_None, lineno); @@ -840,21 +896,16 @@ create_filter(PyObject *category, const char *action) static PyObject * init_filters(void) { - /* Don't silence DeprecationWarning if -3 or -Q were used. */ - PyObject *filters = PyList_New(Py_Py3kWarningFlag || - Py_DivisionWarningFlag ? 3 : 4); + PyObject *filters = PyList_New(5); unsigned int pos = 0; /* Post-incremented in each use. */ unsigned int x; - const char *bytes_action; + const char *bytes_action, *resource_action; if (filters == NULL) return NULL; - /* If guard changes, make sure to update 'filters' initialization above. */ - if (!Py_Py3kWarningFlag && !Py_DivisionWarningFlag) { - PyList_SET_ITEM(filters, pos++, - create_filter(PyExc_DeprecationWarning, "ignore")); - } + PyList_SET_ITEM(filters, pos++, + create_filter(PyExc_DeprecationWarning, "ignore")); PyList_SET_ITEM(filters, pos++, create_filter(PyExc_PendingDeprecationWarning, "ignore")); PyList_SET_ITEM(filters, pos++, @@ -867,7 +918,14 @@ init_filters(void) bytes_action = "ignore"; PyList_SET_ITEM(filters, pos++, create_filter(PyExc_BytesWarning, bytes_action)); - + /* resource usage warnings are enabled by default in pydebug mode */ +#ifdef Py_DEBUG + resource_action = "always"; +#else + resource_action = "ignore"; +#endif + PyList_SET_ITEM(filters, pos++, create_filter(PyExc_ResourceWarning, + resource_action)); for (x = 0; x < pos; x += 1) { if (PyList_GET_ITEM(filters, x) == NULL) { Py_DECREF(filters); @@ -878,33 +936,53 @@ init_filters(void) return filters; } +static struct PyModuleDef warningsmodule = { + PyModuleDef_HEAD_INIT, + MODULE_NAME, + warnings__doc__, + 0, + warnings_functions, + NULL, + NULL, + NULL, + NULL +}; + PyMODINIT_FUNC _PyWarnings_Init(void) { PyObject *m; - m = Py_InitModule3(MODULE_NAME, warnings_functions, warnings__doc__); + m = PyModule_Create(&warningsmodule); if (m == NULL) - return; + return NULL; - _filters = init_filters(); - if (_filters == NULL) - return; + if (_filters == NULL) { + _filters = init_filters(); + if (_filters == NULL) + return NULL; + } Py_INCREF(_filters); if (PyModule_AddObject(m, "filters", _filters) < 0) - return; + return NULL; - _once_registry = PyDict_New(); - if (_once_registry == NULL) - return; + if (_once_registry == NULL) { + _once_registry = PyDict_New(); + if (_once_registry == NULL) + return NULL; + } Py_INCREF(_once_registry); - if (PyModule_AddObject(m, "once_registry", _once_registry) < 0) - return; + if (PyModule_AddObject(m, "_onceregistry", _once_registry) < 0) + return NULL; - _default_action = PyString_FromString("default"); - if (_default_action == NULL) - return; - if (PyModule_AddObject(m, "default_action", _default_action) < 0) - return; + if (_default_action == NULL) { + _default_action = PyUnicode_FromString("default"); + if (_default_action == NULL) + return NULL; + } + Py_INCREF(_default_action); + if (PyModule_AddObject(m, "_defaultaction", _default_action) < 0) + return NULL; + return m; } |