From 63d05b117ac621279bea27b1a7903d3085d18240 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 8 May 2013 13:23:25 +0200 Subject: Issue #1545463: At shutdown, defer finalization of codec modules so that stderr remains usable. (should fix Windows buildbot failures on test_gc) --- Python/_warnings.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index f33e477ad7..03e0c4545a 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -800,8 +800,8 @@ PyErr_WarnExplicit(PyObject *category, const char *text, goto exit; if (module_str != NULL) { module = PyUnicode_FromString(module_str); - if (module == NULL) - goto exit; + if (module == NULL) + goto exit; } if (category == NULL) @@ -820,6 +820,49 @@ PyErr_WarnExplicit(PyObject *category, const char *text, return ret; } +int +PyErr_WarnExplicitFormat(PyObject *category, + const char *filename_str, int lineno, + const char *module_str, PyObject *registry, + const char *format, ...) +{ + PyObject *message; + PyObject *module = NULL; + PyObject *filename = PyUnicode_DecodeFSDefault(filename_str); + int ret = -1; + va_list vargs; + + if (filename == NULL) + goto exit; + if (module_str != NULL) { + module = PyUnicode_FromString(module_str); + if (module == NULL) + 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; + res = warn_explicit(category, message, filename, lineno, + module, registry, NULL); + Py_DECREF(message); + if (res != NULL) { + Py_DECREF(res); + ret = 0; + } + } + va_end(vargs); +exit: + Py_XDECREF(module); + Py_XDECREF(filename); + return ret; +} + PyDoc_STRVAR(warn_doc, "Issue a warning, or maybe ignore it or raise an exception."); -- cgit v1.2.1 From abae51304280e0a8d15d65f8b440b20f3589de0e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 16 Jul 2013 01:54:37 +0200 Subject: Issue #18408: Fix show_warning(), clear also the exception raised by _Py_DisplaySourceLine() For example, _PyGC_DumpShutdownStats() calls PyErr_WarnExplicitFormat() while the import machinery does not work anymore, _Py_DisplaySourceLine() fails when trying to import the io module. --- Python/_warnings.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index 03e0c4545a..f93ede2e2f 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -283,9 +283,9 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject PyFile_WriteString(source_line_str, f_stderr); PyFile_WriteString("\n", f_stderr); } - else - if (_Py_DisplaySourceLine(f_stderr, filename, lineno, 2) < 0) - return; + else { + _Py_DisplaySourceLine(f_stderr, filename, lineno, 2); + } PyErr_Clear(); } -- cgit v1.2.1 From c36bfc1c99c6dffff8cb89c723001902d721ff97 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 26 Aug 2013 22:28:21 +0200 Subject: Close #11619: The parser and the import machinery do not encode Unicode filenames anymore on Windows. --- Python/_warnings.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index f93ede2e2f..b8d4bb61de 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -707,14 +707,14 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) /* Handle the warning. */ returned = warn_explicit(category, message, filename, lineno, module, - registry, source_line); + registry, source_line); Py_DECREF(source_list); return returned; } standard_call: return warn_explicit(category, message, filename, lineno, module, - registry, NULL); + registry, NULL); } @@ -785,12 +785,27 @@ PyErr_Warn(PyObject *category, char *text) } /* Warning with explicit origin */ +int +PyErr_WarnExplicitObject(PyObject *category, PyObject *message, + PyObject *filename, int lineno, + PyObject *module, PyObject *registry) +{ + PyObject *res; + if (category == NULL) + category = PyExc_RuntimeWarning; + res = warn_explicit(category, message, filename, lineno, + module, registry, NULL); + if (res == NULL) + return -1; + Py_DECREF(res); + return 0; +} + int PyErr_WarnExplicit(PyObject *category, const char *text, const char *filename_str, int lineno, const char *module_str, PyObject *registry) { - PyObject *res; PyObject *message = PyUnicode_FromString(text); PyObject *filename = PyUnicode_DecodeFSDefault(filename_str); PyObject *module = NULL; @@ -804,14 +819,8 @@ PyErr_WarnExplicit(PyObject *category, const char *text, goto exit; } - if (category == NULL) - category = PyExc_RuntimeWarning; - res = warn_explicit(category, message, filename, lineno, module, registry, - NULL); - if (res == NULL) - goto exit; - Py_DECREF(res); - ret = 0; + ret = PyErr_WarnExplicitObject(category, message, filename, lineno, + module, registry); exit: Py_XDECREF(message); -- cgit v1.2.1 From fe2feb2def06b6ee8e2818f1818a2b2743d917b1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 28 Oct 2013 18:47:22 +0100 Subject: Issue #19421: fix a check in warnings.warn() to be able to use it during Python finalization. sys.argv is set to None during Python finalization: add PyList_Check() to avoid a crash in PyList_Size(). --- Python/_warnings.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index b8d4bb61de..23b3f5c02d 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -534,7 +534,9 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, goto handle_error; if (strcmp(module_str, "__main__") == 0) { PyObject *argv = PySys_GetObject("argv"); - if (argv != NULL && PyList_Size(argv) > 0) { + /* PyList_Check() is needed because sys.argv is set to None during + Python finalization */ + if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) { int is_true; *filename = PyList_GetItem(argv, 0); Py_INCREF(*filename); -- cgit v1.2.1 From ac6fac028987ae6ada3efdfe8bf3fb3a3fefd63b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 29 Oct 2013 23:43:41 +0100 Subject: Issue #19424: Fix the warnings module to accept filename containing surrogate characters. --- Python/_warnings.c | 102 +++++++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 47 deletions(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index 23b3f5c02d..cbc64e3b94 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -99,7 +99,7 @@ get_default_action(void) /* The item is a borrowed reference. */ -static const char * +static PyObject* get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, PyObject *module, PyObject **item) { @@ -152,13 +152,12 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, return NULL; if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) - return _PyUnicode_AsString(action); + return action; } action = get_default_action(); - if (action != NULL) { - return _PyUnicode_AsString(action); - } + if (action != NULL) + return action; PyErr_SetString(PyExc_ValueError, MODULE_NAME ".defaultaction not found"); @@ -192,23 +191,26 @@ static PyObject * normalize_module(PyObject *filename) { PyObject *module; - const char *mod_str; + int kind; + void *data; Py_ssize_t len; - int rc = PyObject_IsTrue(filename); - if (rc == -1) - return NULL; - else if (rc == 0) - return PyUnicode_FromString(""); - - mod_str = _PyUnicode_AsString(filename); - if (mod_str == NULL) - return NULL; len = PyUnicode_GetLength(filename); if (len < 0) return NULL; + + if (len == 0) + return PyUnicode_FromString(""); + + kind = PyUnicode_KIND(filename); + data = PyUnicode_DATA(filename); + + /* if filename.endswith(".py"): */ if (len >= 3 && - strncmp(mod_str + (len - 3), ".py", 3) == 0) { + PyUnicode_READ(kind, data, len-3) == '.' && + PyUnicode_READ(kind, data, len-2) == 'p' && + PyUnicode_READ(kind, data, len-1) == 'y') + { module = PyUnicode_Substring(filename, 0, len-3); } else { @@ -273,19 +275,37 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject /* Print " source_line\n" */ if (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++; - - PyFile_WriteString(source_line_str, f_stderr); + int kind; + void *data; + Py_ssize_t i, len; + 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); + for (i=0; i Date: Wed, 30 Oct 2013 00:04:59 +0100 Subject: Issue #19442: Fix warnings emitted during Python shutdown Warnings may be emitted during Python shutdown, like "unclosed file XXX". During shutdown, globals()['__main__'] may be None. --- Python/_warnings.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index cbc64e3b94..8d9666afcc 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -540,7 +540,7 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, } else { *filename = NULL; - if (PyUnicode_CompareWithASCIIString(*module, "__main__") == 0) { + if (*module != Py_None && PyUnicode_CompareWithASCIIString(*module, "__main__") == 0) { PyObject *argv = PySys_GetObject("argv"); /* PyList_Check() is needed because sys.argv is set to None during Python finalization */ @@ -564,8 +564,8 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, else { /* embedded interpreters don't have sys.argv, see bug #839151 */ *filename = PyUnicode_FromString("__main__"); - if (*filename == NULL) - goto handle_error; + if (*filename == NULL) + goto handle_error; } } if (*filename == NULL) { @@ -621,8 +621,15 @@ do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level) if (!setup_context(stack_level, &filename, &lineno, &module, ®istry)) return NULL; - res = warn_explicit(category, message, filename, lineno, module, registry, - NULL); + if (module != Py_None) { + res = warn_explicit(category, message, filename, lineno, module, registry, + NULL); + } + else { + /* FIXME: emitting warnings at exit does crash Python */ + res = Py_None; + Py_INCREF(res); + } Py_DECREF(filename); Py_DECREF(registry); Py_DECREF(module); -- cgit v1.2.1 From f68daf9b935f9aa8fd6b590271844b00dbcf1f12 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 31 Oct 2013 14:46:00 +0100 Subject: Issue #19437: Fix get_filter() from _warnings, don't call PyObject_IsSubclass() with an exception set --- Python/_warnings.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index 8d9666afcc..74ac8c65bf 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -144,11 +144,19 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, ln_obj = PyTuple_GET_ITEM(tmp_item, 4); good_msg = check_matched(msg, text); + if (good_msg == -1) + return NULL; + good_mod = check_matched(mod, module); + if (good_mod == -1) + return NULL; + is_subclass = PyObject_IsSubclass(category, cat); + if (is_subclass == -1) + return NULL; + ln = PyLong_AsSsize_t(ln_obj); - if (good_msg == -1 || good_mod == -1 || is_subclass == -1 || - (ln == -1 && PyErr_Occurred())) + if (ln == -1 && PyErr_Occurred()) return NULL; if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) -- cgit v1.2.1 From 48ff28c76cbc4c7aaaf91e035554f79914a7b8d4 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 31 Oct 2013 14:51:38 +0100 Subject: Issue #19437: Fix show_warning() of _warnings, stop at the first error to not call a Python function with an exception set --- Python/_warnings.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index 74ac8c65bf..d9f3297dd3 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -263,23 +263,28 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject name = _PyObject_GetAttrId(category, &PyId___name__); if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */ - return; + goto error; f_stderr = PySys_GetObject("stderr"); if (f_stderr == NULL) { fprintf(stderr, "lost sys.stderr\n"); - Py_DECREF(name); - return; + goto error; } /* Print "filename:lineno: category: text\n" */ - PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW); - PyFile_WriteString(lineno_str, f_stderr); - PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW); - PyFile_WriteString(": ", f_stderr); - PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW); - PyFile_WriteString("\n", f_stderr); - Py_XDECREF(name); + if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0) + goto error; + if (PyFile_WriteString(lineno_str, f_stderr) < 0) + goto error; + if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0) + goto error; + if (PyFile_WriteString(": ", f_stderr) < 0) + goto error; + if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0) + goto error; + if (PyFile_WriteString("\n", f_stderr) < 0) + goto error; + Py_CLEAR(name); /* Print " source_line\n" */ if (sourceline) { @@ -314,6 +319,7 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject } error: + Py_XDECREF(name); PyErr_Clear(); } -- cgit v1.2.1 From c52af1265e0b79bc1787abccf29ea0ff471440ba Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 1 Nov 2013 00:55:30 +0100 Subject: Close #19442: warn_explicit() does nothing when called late during Python shutdown After more tests, I now think that it is the safest option. --- Python/_warnings.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index d9f3297dd3..e88f646089 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -333,6 +333,13 @@ warn_explicit(PyObject *category, PyObject *message, PyObject *action; int rc; + /* module can be None if a warning is emitted late during Python shutdown. + In this case, the Python warnings module was probably unloaded, filters + are no more available to choose as action. It is safer to ignore the + warning and do nothing. */ + if (module == Py_None) + Py_RETURN_NONE; + if (registry && !PyDict_Check(registry) && (registry != Py_None)) { PyErr_SetString(PyExc_TypeError, "'registry' must be a dict"); return NULL; @@ -635,15 +642,8 @@ do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level) if (!setup_context(stack_level, &filename, &lineno, &module, ®istry)) return NULL; - if (module != Py_None) { - res = warn_explicit(category, message, filename, lineno, module, registry, - NULL); - } - else { - /* FIXME: emitting warnings at exit does crash Python */ - res = Py_None; - Py_INCREF(res); - } + res = warn_explicit(category, message, filename, lineno, module, registry, + NULL); Py_DECREF(filename); Py_DECREF(registry); Py_DECREF(module); -- cgit v1.2.1 From abe98ac333cb6792ed82b144822738e50e38d443 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 6 Nov 2013 22:41:44 +0100 Subject: Issue #19512: add some common identifiers to only create common strings once, instead of creating temporary Unicode string objects Add also more identifiers in pythonrun.c to avoid temporary Unicode string objets for the interactive interpreter. --- Python/_warnings.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index e88f646089..de601281be 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -265,7 +265,7 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */ goto error; - f_stderr = PySys_GetObject("stderr"); + f_stderr = _PySys_GetObjectId(&_PyId_stderr); if (f_stderr == NULL) { fprintf(stderr, "lost sys.stderr\n"); goto error; @@ -562,7 +562,7 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, else { *filename = NULL; if (*module != Py_None && PyUnicode_CompareWithASCIIString(*module, "__main__") == 0) { - PyObject *argv = PySys_GetObject("argv"); + PyObject *argv = _PySys_GetObjectId(&_PyId_argv); /* PyList_Check() is needed because sys.argv is set to None during Python finalization */ if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) { -- cgit v1.2.1 From 359ed22ea49d63923b451351ebf80decaaa7b79e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 7 Nov 2013 23:07:29 +0100 Subject: Issue #19512, #19515: remove shared identifiers, move identifiers where they are used. Move also _Py_IDENTIFIER() defintions to the top in modified files to remove identifiers duplicated in the same file. --- Python/_warnings.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index de601281be..6013d7d7d4 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -13,6 +13,8 @@ static PyObject *_filters; /* List */ static PyObject *_once_registry; /* Dict */ static PyObject *_default_action; /* String */ +_Py_IDENTIFIER(argv); +_Py_IDENTIFIER(stderr); static int check_matched(PyObject *obj, PyObject *arg) @@ -265,7 +267,7 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */ goto error; - f_stderr = _PySys_GetObjectId(&_PyId_stderr); + f_stderr = _PySys_GetObjectId(&PyId_stderr); if (f_stderr == NULL) { fprintf(stderr, "lost sys.stderr\n"); goto error; @@ -562,7 +564,7 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, else { *filename = NULL; if (*module != Py_None && PyUnicode_CompareWithASCIIString(*module, "__main__") == 0) { - PyObject *argv = _PySys_GetObjectId(&_PyId_argv); + PyObject *argv = _PySys_GetObjectId(&PyId_argv); /* PyList_Check() is needed because sys.argv is set to None during Python finalization */ if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) { -- cgit v1.2.1