[Python-checkins] r82059 - in python/branches/py3k: Include/traceback.h Misc/NEWS Python/_warnings.c Python/compile.c Python/pythonrun.c Python/traceback.c

victor.stinner python-checkins at python.org
Fri Jun 18 01:08:51 CEST 2010


Author: victor.stinner
Date: Fri Jun 18 01:08:50 2010
New Revision: 82059

Log:
Issue #6543: Write the traceback in the terminal encoding instead of utf-8.
Fix the encoding of the modules filename.

Reindent also traceback.h, just because I hate tabs :-)


Modified:
   python/branches/py3k/Include/traceback.h
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Python/_warnings.c
   python/branches/py3k/Python/compile.c
   python/branches/py3k/Python/pythonrun.c
   python/branches/py3k/Python/traceback.c

Modified: python/branches/py3k/Include/traceback.h
==============================================================================
--- python/branches/py3k/Include/traceback.h	(original)
+++ python/branches/py3k/Include/traceback.h	Fri Jun 18 01:08:50 2010
@@ -10,16 +10,16 @@
 /* Traceback interface */
 
 typedef struct _traceback {
-	PyObject_HEAD
-	struct _traceback *tb_next;
-	struct _frame *tb_frame;
-	int tb_lasti;
-	int tb_lineno;
+    PyObject_HEAD
+    struct _traceback *tb_next;
+    struct _frame *tb_frame;
+    int tb_lasti;
+    int tb_lineno;
 } PyTracebackObject;
 
 PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *);
 PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *);
-PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, const char *, int, int);
+PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int);
 
 /* Reveal traceback type so we can typecheck traceback objects */
 PyAPI_DATA(PyTypeObject) PyTraceBack_Type;

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Fri Jun 18 01:08:50 2010
@@ -12,6 +12,9 @@
 Core and Builtins
 -----------------
 
+- Issue #6543: Write the traceback in the terminal encoding instead of utf-8.
+  Fix the encoding of the modules filename.
+
 - Issue #9011: Remove buggy and unnecessary (in 3.x) ST->AST
   compilation code dealing with unary minus applied to a constant.
   The removed code was mutating the ST, causing a second compilation

Modified: python/branches/py3k/Python/_warnings.c
==============================================================================
--- python/branches/py3k/Python/_warnings.c	(original)
+++ python/branches/py3k/Python/_warnings.c	Fri Jun 18 01:08:50 2010
@@ -282,8 +282,7 @@
         PyFile_WriteString("\n", f_stderr);
     }
     else
-        if (_Py_DisplaySourceLine(f_stderr, _PyUnicode_AsString(filename),
-                              lineno, 2) < 0)
+        if (_Py_DisplaySourceLine(f_stderr, filename, lineno, 2) < 0)
                 return;
     PyErr_Clear();
 }

Modified: python/branches/py3k/Python/compile.c
==============================================================================
--- python/branches/py3k/Python/compile.c	(original)
+++ python/branches/py3k/Python/compile.c	Fri Jun 18 01:08:50 2010
@@ -3942,7 +3942,7 @@
     freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars));
     if (!freevars)
         goto error;
-    filename = PyUnicode_DecodeFSDefault(c->c_filename);
+    filename = PyUnicode_FromString(c->c_filename);
     if (!filename)
         goto error;
 

Modified: python/branches/py3k/Python/pythonrun.c
==============================================================================
--- python/branches/py3k/Python/pythonrun.c	(original)
+++ python/branches/py3k/Python/pythonrun.c	Fri Jun 18 01:08:50 2010
@@ -1190,7 +1190,7 @@
     d = PyModule_GetDict(m);
     if (PyDict_GetItemString(d, "__file__") == NULL) {
         PyObject *f;
-        f = PyUnicode_DecodeFSDefault(filename);
+        f = PyUnicode_FromString(filename);
         if (f == NULL)
             return -1;
         if (PyDict_SetItemString(d, "__file__", f) < 0) {

Modified: python/branches/py3k/Python/traceback.c
==============================================================================
--- python/branches/py3k/Python/traceback.c	(original)
+++ python/branches/py3k/Python/traceback.c	Fri Jun 18 01:08:50 2010
@@ -133,33 +133,38 @@
     return 0;
 }
 
-static int
-_Py_FindSourceFile(const char* filename, char* namebuf, size_t namelen, int open_flags)
+static PyObject *
+_Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io)
 {
-    int i;
-    int fd = -1;
+    Py_ssize_t i;
+    PyObject *binary;
     PyObject *v;
-    Py_ssize_t _npath;
-    int npath;
+    Py_ssize_t npath;
     size_t taillen;
     PyObject *syspath;
     const char* path;
     const char* tail;
+    const char* filepath;
     Py_ssize_t len;
 
+    filepath = _PyUnicode_AsString(filename);
+    if (filepath == NULL) {
+        PyErr_Clear();
+        return NULL;
+    }
+
     /* Search tail of filename in sys.path before giving up */
-    tail = strrchr(filename, SEP);
+    tail = strrchr(filepath, SEP);
     if (tail == NULL)
-        tail = filename;
+        tail = filepath;
     else
         tail++;
     taillen = strlen(tail);
 
     syspath = PySys_GetObject("path");
     if (syspath == NULL || !PyList_Check(syspath))
-        return -1;
-    _npath = PyList_Size(syspath);
-    npath = Py_SAFE_DOWNCAST(_npath, Py_ssize_t, int);
+        return NULL;
+    npath = PyList_Size(syspath);
 
     for (i = 0; i < npath; i++) {
         v = PyList_GetItem(syspath, i);
@@ -170,6 +175,10 @@
         if (!PyUnicode_Check(v))
             continue;
         path = _PyUnicode_AsStringAndSize(v, &len);
+        if (path == NULL) {
+            PyErr_Clear();
+            continue;
+        }
         if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1)
             continue; /* Too long */
         strcpy(namebuf, path);
@@ -178,31 +187,27 @@
         if (len > 0 && namebuf[len-1] != SEP)
             namebuf[len++] = SEP;
         strcpy(namebuf+len, tail);
-        Py_BEGIN_ALLOW_THREADS
-        fd = open(namebuf, open_flags);
-        Py_END_ALLOW_THREADS
-        if (0 <= fd) {
-            return fd;
-        }
+
+        binary = PyObject_CallMethod(io, "open", "ss", namebuf, "rb");
+        if (binary != NULL)
+            return binary;
+        PyErr_Clear();
     }
-    return -1;
+    return NULL;
 }
 
 int
-_Py_DisplaySourceLine(PyObject *f, const char *filename, int lineno, int indent)
+_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent)
 {
     int err = 0;
     int fd;
     int i;
     char *found_encoding;
     char *encoding;
+    PyObject *io;
+    PyObject *binary;
     PyObject *fob = NULL;
     PyObject *lineobj = NULL;
-#ifdef O_BINARY
-    const int open_flags = O_RDONLY | O_BINARY;   /* necessary for Windows */
-#else
-    const int open_flags = O_RDONLY;
-#endif
     char buf[MAXPATHLEN+1];
     Py_UNICODE *u, *p;
     Py_ssize_t len;
@@ -210,27 +215,32 @@
     /* open the file */
     if (filename == NULL)
         return 0;
-    Py_BEGIN_ALLOW_THREADS
-    fd = open(filename, open_flags);
-    Py_END_ALLOW_THREADS
-    if (fd < 0) {
-        fd = _Py_FindSourceFile(filename, buf, sizeof(buf), open_flags);
-        if (fd < 0)
+
+    io = PyImport_ImportModuleNoBlock("io");
+    if (io == NULL)
+        return -1;
+    binary = PyObject_CallMethod(io, "open", "Os", filename, "rb");
+
+    if (binary == NULL) {
+        binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io);
+        if (binary == NULL) {
+            Py_DECREF(io);
             return 0;
-        filename = buf;
+        }
     }
 
     /* use the right encoding to decode the file as unicode */
+    fd = PyObject_AsFileDescriptor(binary);
     found_encoding = PyTokenizer_FindEncoding(fd);
-    encoding = (found_encoding != NULL) ? found_encoding :
-        (char*)PyUnicode_GetDefaultEncoding();
+    encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
     lseek(fd, 0, 0); /* Reset position */
-    fob = PyFile_FromFd(fd, (char*)filename, "r", -1, (char*)encoding,
-        NULL, NULL, 1);
+    fob = PyObject_CallMethod(io, "TextIOWrapper", "Os", binary, encoding);
+    Py_DECREF(io);
+    Py_DECREF(binary);
     PyMem_FREE(found_encoding);
+
     if (fob == NULL) {
         PyErr_Clear();
-        close(fd);
         return 0;
     }
 
@@ -287,17 +297,19 @@
 }
 
 static int
-tb_displayline(PyObject *f, const char *filename, int lineno, const char *name)
+tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name)
 {
-    int err = 0;
-    char linebuf[2000];
+    int err;
+    PyObject *line;
 
     if (filename == NULL || name == NULL)
         return -1;
-    /* This is needed by Emacs' compile command */
-#define FMT "  File \"%.500s\", line %d, in %.500s\n"
-    PyOS_snprintf(linebuf, sizeof(linebuf), FMT, filename, lineno, name);
-    err = PyFile_WriteString(linebuf, f);
+    line = PyUnicode_FromFormat("  File \"%U\", line %d, in %U\n",
+                                filename, lineno, name);
+    if (line == NULL)
+        return -1;
+    err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
+    Py_DECREF(line);
     if (err != 0)
         return err;
     return _Py_DisplaySourceLine(f, filename, lineno, 4);
@@ -316,10 +328,9 @@
     while (tb != NULL && err == 0) {
         if (depth <= limit) {
             err = tb_displayline(f,
-                _PyUnicode_AsString(
-                    tb->tb_frame->f_code->co_filename),
-                tb->tb_lineno,
-                _PyUnicode_AsString(tb->tb_frame->f_code->co_name));
+                                 tb->tb_frame->f_code->co_filename,
+                                 tb->tb_lineno,
+                                 tb->tb_frame->f_code->co_name);
         }
         depth--;
         tb = tb->tb_next;


More information about the Python-checkins mailing list