Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0fe25a4

Browse files
author
Victor Stinner
committed
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 :-)
1 parent 870f09a commit 0fe25a4

6 files changed

Lines changed: 70 additions & 57 deletions

File tree

Include/traceback.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ struct _frame;
1010
/* Traceback interface */
1111

1212
typedef struct _traceback {
13-
PyObject_HEAD
14-
struct _traceback *tb_next;
15-
struct _frame *tb_frame;
16-
int tb_lasti;
17-
int tb_lineno;
13+
PyObject_HEAD
14+
struct _traceback *tb_next;
15+
struct _frame *tb_frame;
16+
int tb_lasti;
17+
int tb_lineno;
1818
} PyTracebackObject;
1919

2020
PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *);
2121
PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *);
22-
PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, const char *, int, int);
22+
PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int);
2323

2424
/* Reveal traceback type so we can typecheck traceback objects */
2525
PyAPI_DATA(PyTypeObject) PyTraceBack_Type;

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 3.2 Alpha 1?
1212
Core and Builtins
1313
-----------------
1414

15+
- Issue #6543: Write the traceback in the terminal encoding instead of utf-8.
16+
Fix the encoding of the modules filename.
17+
1518
- Issue #9011: Remove buggy and unnecessary (in 3.x) ST->AST
1619
compilation code dealing with unary minus applied to a constant.
1720
The removed code was mutating the ST, causing a second compilation

Python/_warnings.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,7 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject
282282
PyFile_WriteString("\n", f_stderr);
283283
}
284284
else
285-
if (_Py_DisplaySourceLine(f_stderr, _PyUnicode_AsString(filename),
286-
lineno, 2) < 0)
285+
if (_Py_DisplaySourceLine(f_stderr, filename, lineno, 2) < 0)
287286
return;
288287
PyErr_Clear();
289288
}

Python/compile.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3942,7 +3942,7 @@ makecode(struct compiler *c, struct assembler *a)
39423942
freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars));
39433943
if (!freevars)
39443944
goto error;
3945-
filename = PyUnicode_DecodeFSDefault(c->c_filename);
3945+
filename = PyUnicode_FromString(c->c_filename);
39463946
if (!filename)
39473947
goto error;
39483948

Python/pythonrun.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1190,7 +1190,7 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
11901190
d = PyModule_GetDict(m);
11911191
if (PyDict_GetItemString(d, "__file__") == NULL) {
11921192
PyObject *f;
1193-
f = PyUnicode_DecodeFSDefault(filename);
1193+
f = PyUnicode_FromString(filename);
11941194
if (f == NULL)
11951195
return -1;
11961196
if (PyDict_SetItemString(d, "__file__", f) < 0) {

Python/traceback.c

Lines changed: 58 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -133,33 +133,38 @@ PyTraceBack_Here(PyFrameObject *frame)
133133
return 0;
134134
}
135135

136-
static int
137-
_Py_FindSourceFile(const char* filename, char* namebuf, size_t namelen, int open_flags)
136+
static PyObject *
137+
_Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io)
138138
{
139-
int i;
140-
int fd = -1;
139+
Py_ssize_t i;
140+
PyObject *binary;
141141
PyObject *v;
142-
Py_ssize_t _npath;
143-
int npath;
142+
Py_ssize_t npath;
144143
size_t taillen;
145144
PyObject *syspath;
146145
const char* path;
147146
const char* tail;
147+
const char* filepath;
148148
Py_ssize_t len;
149149

150+
filepath = _PyUnicode_AsString(filename);
151+
if (filepath == NULL) {
152+
PyErr_Clear();
153+
return NULL;
154+
}
155+
150156
/* Search tail of filename in sys.path before giving up */
151-
tail = strrchr(filename, SEP);
157+
tail = strrchr(filepath, SEP);
152158
if (tail == NULL)
153-
tail = filename;
159+
tail = filepath;
154160
else
155161
tail++;
156162
taillen = strlen(tail);
157163

158164
syspath = PySys_GetObject("path");
159165
if (syspath == NULL || !PyList_Check(syspath))
160-
return -1;
161-
_npath = PyList_Size(syspath);
162-
npath = Py_SAFE_DOWNCAST(_npath, Py_ssize_t, int);
166+
return NULL;
167+
npath = PyList_Size(syspath);
163168

164169
for (i = 0; i < npath; i++) {
165170
v = PyList_GetItem(syspath, i);
@@ -170,6 +175,10 @@ _Py_FindSourceFile(const char* filename, char* namebuf, size_t namelen, int open
170175
if (!PyUnicode_Check(v))
171176
continue;
172177
path = _PyUnicode_AsStringAndSize(v, &len);
178+
if (path == NULL) {
179+
PyErr_Clear();
180+
continue;
181+
}
173182
if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1)
174183
continue; /* Too long */
175184
strcpy(namebuf, path);
@@ -178,59 +187,60 @@ _Py_FindSourceFile(const char* filename, char* namebuf, size_t namelen, int open
178187
if (len > 0 && namebuf[len-1] != SEP)
179188
namebuf[len++] = SEP;
180189
strcpy(namebuf+len, tail);
181-
Py_BEGIN_ALLOW_THREADS
182-
fd = open(namebuf, open_flags);
183-
Py_END_ALLOW_THREADS
184-
if (0 <= fd) {
185-
return fd;
186-
}
190+
191+
binary = PyObject_CallMethod(io, "open", "ss", namebuf, "rb");
192+
if (binary != NULL)
193+
return binary;
194+
PyErr_Clear();
187195
}
188-
return -1;
196+
return NULL;
189197
}
190198

191199
int
192-
_Py_DisplaySourceLine(PyObject *f, const char *filename, int lineno, int indent)
200+
_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent)
193201
{
194202
int err = 0;
195203
int fd;
196204
int i;
197205
char *found_encoding;
198206
char *encoding;
207+
PyObject *io;
208+
PyObject *binary;
199209
PyObject *fob = NULL;
200210
PyObject *lineobj = NULL;
201-
#ifdef O_BINARY
202-
const int open_flags = O_RDONLY | O_BINARY; /* necessary for Windows */
203-
#else
204-
const int open_flags = O_RDONLY;
205-
#endif
206211
char buf[MAXPATHLEN+1];
207212
Py_UNICODE *u, *p;
208213
Py_ssize_t len;
209214

210215
/* open the file */
211216
if (filename == NULL)
212217
return 0;
213-
Py_BEGIN_ALLOW_THREADS
214-
fd = open(filename, open_flags);
215-
Py_END_ALLOW_THREADS
216-
if (fd < 0) {
217-
fd = _Py_FindSourceFile(filename, buf, sizeof(buf), open_flags);
218-
if (fd < 0)
218+
219+
io = PyImport_ImportModuleNoBlock("io");
220+
if (io == NULL)
221+
return -1;
222+
binary = PyObject_CallMethod(io, "open", "Os", filename, "rb");
223+
224+
if (binary == NULL) {
225+
binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io);
226+
if (binary == NULL) {
227+
Py_DECREF(io);
219228
return 0;
220-
filename = buf;
229+
}
221230
}
222231

223232
/* use the right encoding to decode the file as unicode */
233+
fd = PyObject_AsFileDescriptor(binary);
224234
found_encoding = PyTokenizer_FindEncoding(fd);
225-
encoding = (found_encoding != NULL) ? found_encoding :
226-
(char*)PyUnicode_GetDefaultEncoding();
235+
encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
227236
lseek(fd, 0, 0); /* Reset position */
228-
fob = PyFile_FromFd(fd, (char*)filename, "r", -1, (char*)encoding,
229-
NULL, NULL, 1);
237+
fob = PyObject_CallMethod(io, "TextIOWrapper", "Os", binary, encoding);
238+
Py_DECREF(io);
239+
Py_DECREF(binary);
230240
PyMem_FREE(found_encoding);
241+
231242
if (fob == NULL) {
232243
PyErr_Clear();
233-
close(fd);
234244
return 0;
235245
}
236246

@@ -287,17 +297,19 @@ _Py_DisplaySourceLine(PyObject *f, const char *filename, int lineno, int indent)
287297
}
288298

289299
static int
290-
tb_displayline(PyObject *f, const char *filename, int lineno, const char *name)
300+
tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name)
291301
{
292-
int err = 0;
293-
char linebuf[2000];
302+
int err;
303+
PyObject *line;
294304

295305
if (filename == NULL || name == NULL)
296306
return -1;
297-
/* This is needed by Emacs' compile command */
298-
#define FMT " File \"%.500s\", line %d, in %.500s\n"
299-
PyOS_snprintf(linebuf, sizeof(linebuf), FMT, filename, lineno, name);
300-
err = PyFile_WriteString(linebuf, f);
307+
line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n",
308+
filename, lineno, name);
309+
if (line == NULL)
310+
return -1;
311+
err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
312+
Py_DECREF(line);
301313
if (err != 0)
302314
return err;
303315
return _Py_DisplaySourceLine(f, filename, lineno, 4);
@@ -316,10 +328,9 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
316328
while (tb != NULL && err == 0) {
317329
if (depth <= limit) {
318330
err = tb_displayline(f,
319-
_PyUnicode_AsString(
320-
tb->tb_frame->f_code->co_filename),
321-
tb->tb_lineno,
322-
_PyUnicode_AsString(tb->tb_frame->f_code->co_name));
331+
tb->tb_frame->f_code->co_filename,
332+
tb->tb_lineno,
333+
tb->tb_frame->f_code->co_name);
323334
}
324335
depth--;
325336
tb = tb->tb_next;

0 commit comments

Comments
 (0)