]> granicus.if.org Git - python/commitdiff
Patch #50002: Display line information for bad \x escapes:
authorMartin v. Löwis <martin@v.loewis.de>
Sun, 3 Mar 2002 21:30:27 +0000 (21:30 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Sun, 3 Mar 2002 21:30:27 +0000 (21:30 +0000)
- recognize "SyntaxError"s by the print_file_and_line attribute.
- add the syntaxerror attributes to all exceptions in compile.c.
Fixes #221791

Misc/NEWS
Python/compile.c
Python/errors.c
Python/exceptions.c
Python/pythonrun.c

index 15644b8b58cdf29f4f10bf0feb8bea5d3bdade23..58d5a66e21d94b307a45d963362fe4cdadd647e4 100644 (file)
--- 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.
 
index dbae00d3140bca96142cb6ee0e04fe163cddca15..de0a8e235a635845efbd7a9ffb595fbf65963ec5 100644 (file)
@@ -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++ = '\\';
index 2799cffc93ba2fa42692f86cb6321a9409f05ef4..13b3d11ed6b1971f33a5af35ffc45d89f2fb03cb 100644 (file)
@@ -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);
 }
 
index 99002bf1add1f1abe8e6527d7e3bf0895a6254ba..adfd699320ec6def72c4d48fd73c42c758f673ea 100644 (file)
@@ -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;
     }
index 6b70739d0a2b67c2a69a64c3ac1faac366e4630f..ad92004f9a5f694623ed46e246c66da7fa0d5136 100644 (file)
@@ -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;