From cfeb3b6ab8e213cb3551b101d0566d77f5b47409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Sun, 3 Mar 2002 21:30:27 +0000 Subject: Patch #50002: Display line information for bad \x escapes: - recognize "SyntaxError"s by the print_file_and_line attribute. - add the syntaxerror attributes to all exceptions in compile.c. Fixes #221791 --- Misc/NEWS | 3 +++ Python/compile.c | 40 ++++++++++++++++++++++++++-------------- Python/errors.c | 24 +++++++++++++++++++++++- Python/exceptions.c | 3 ++- Python/pythonrun.c | 2 +- 5 files changed, 55 insertions(+), 17 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 15644b8..58d5a66 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -6,6 +6,9 @@ Type/class unification and new-style classes Core and builtins +- PyErr_Display will provide file and line information for all exceptions + that have an attribute print_file_and_line, not just SyntaxErrors. + - The UTF-8 codec will now encode and decode Unicode surrogates correctly and without raising exceptions for unpaired ones. diff --git a/Python/compile.c b/Python/compile.c index dbae00d..de0a8e2 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -465,14 +465,21 @@ com_error(struct compiling *c, PyObject *exc, char *msg) Py_INCREF(Py_None); line = Py_None; } - t = Py_BuildValue("(ziOO)", c->c_filename, c->c_lineno, - Py_None, line); - if (t == NULL) - goto exit; - w = Py_BuildValue("(OO)", v, t); - if (w == NULL) - goto exit; - PyErr_SetObject(exc, w); + if (exc == PyExc_SyntaxError) { + t = Py_BuildValue("(ziOO)", c->c_filename, c->c_lineno, + Py_None, line); + if (t == NULL) + goto exit; + w = Py_BuildValue("(OO)", v, t); + if (w == NULL) + goto exit; + PyErr_SetObject(exc, w); + } else { + /* Make sure additional exceptions are printed with + file and line, also. */ + PyErr_SetObject(exc, v); + PyErr_SyntaxLocation(c->c_filename, c->c_lineno); + } exit: Py_XDECREF(t); Py_XDECREF(v); @@ -1153,7 +1160,8 @@ parsestr(struct compiling *com, char *s) s++; len = strlen(s); if (len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, "string to parse is too long"); + com_error(com, PyExc_OverflowError, + "string to parse is too long"); return NULL; } if (s[--len] != quote) { @@ -1171,11 +1179,15 @@ parsestr(struct compiling *com, char *s) #ifdef Py_USING_UNICODE if (unicode || Py_UnicodeFlag) { if (rawmode) - return PyUnicode_DecodeRawUnicodeEscape( - s, len, NULL); + v = PyUnicode_DecodeRawUnicodeEscape( + s, len, NULL); else - return PyUnicode_DecodeUnicodeEscape( + v = PyUnicode_DecodeUnicodeEscape( s, len, NULL); + if (v == NULL) + PyErr_SyntaxLocation(com->c_filename, com->c_lineno); + return v; + } #endif if (rawmode || strchr(s, '\\') == NULL) @@ -1238,9 +1250,9 @@ parsestr(struct compiling *com, char *s) *p++ = x; break; } - PyErr_SetString(PyExc_ValueError, - "invalid \\x escape"); Py_DECREF(v); + com_error(com, PyExc_ValueError, + "invalid \\x escape"); return NULL; default: *p++ = '\\'; diff --git a/Python/errors.c b/Python/errors.c index 2799cff..13b3d11 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -561,7 +561,9 @@ PyErr_WarnExplicit(PyObject *category, char *message, } -/* XXX There's a comment missing here */ +/* Set file and line information for the current exception. + If the exception is not a SyntaxError, also sets additional attributes + to make printing of exceptions believe it is a syntax error. */ void PyErr_SyntaxLocation(char *filename, int lineno) @@ -596,6 +598,26 @@ PyErr_SyntaxLocation(char *filename, int lineno) Py_DECREF(tmp); } } + if (PyObject_SetAttrString(v, "offset", Py_None)) { + PyErr_Clear(); + } + if (exc != PyExc_SyntaxError) { + if (!PyObject_HasAttrString(v, "msg")) { + tmp = PyObject_Str(v); + if (tmp) { + if (PyObject_SetAttrString(v, "msg", tmp)) + PyErr_Clear(); + Py_DECREF(tmp); + } else { + PyErr_Clear(); + } + } + if (!PyObject_HasAttrString(v, "print_file_and_line")) { + if (PyObject_SetAttrString(v, "print_file_and_line", + Py_None)) + PyErr_Clear(); + } + } PyErr_Restore(exc, v, tb); } diff --git a/Python/exceptions.c b/Python/exceptions.c index 99002bf..adfd699 100644 --- a/Python/exceptions.c +++ b/Python/exceptions.c @@ -670,7 +670,8 @@ SyntaxError__classinit__(PyObject *klass) PyObject_SetAttrString(klass, "filename", Py_None) || PyObject_SetAttrString(klass, "lineno", Py_None) || PyObject_SetAttrString(klass, "offset", Py_None) || - PyObject_SetAttrString(klass, "text", Py_None)) + PyObject_SetAttrString(klass, "text", Py_None) || + PyObject_SetAttrString(klass, "print_file_and_line", Py_None)) { retval = -1; } diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 6b70739..ad92004 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -920,7 +920,7 @@ void PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) if (tb && tb != Py_None) err = PyTraceBack_Print(tb, f); if (err == 0 && - PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) + PyObject_HasAttrString(v, "print_file_and_line")) { PyObject *message; char *filename, *text; -- cgit v0.12