Commit 15244f7b authored by Victor Stinner's avatar Victor Stinner

Recorded merge of revisions 85569-85570 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r85569 | victor.stinner | 2010-10-16 15:14:10 +0200 (sam., 16 oct. 2010) | 4 lines

  Issue #9713, #10114: Parser functions (eg. PyParser_ASTFromFile) expects
  filenames encoded to the filesystem encoding with surrogateescape error handler
  (to support undecodable bytes), instead of UTF-8 in strict mode.
........
  r85570 | victor.stinner | 2010-10-16 15:42:53 +0200 (sam., 16 oct. 2010) | 4 lines

  Fix ast_error_finish() and err_input(): filename can be NULL

  Fix my previous commit (r85569).
........
parent 089144e5
...@@ -10,6 +10,10 @@ What's New in Python 3.1.3? ...@@ -10,6 +10,10 @@ What's New in Python 3.1.3?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #9713, #10114: Parser functions (eg. PyParser_ASTFromFile) expects
filenames encoded to the filesystem encoding with surrogateescape error
handler (to support undecodable bytes), instead of UTF-8 in strict mode.
- Issue #10006: type.__abstractmethods__ now raises an AttributeError. As a - Issue #10006: type.__abstractmethods__ now raises an AttributeError. As a
result metaclasses can now be ABCs (see #9533). result metaclasses can now be ABCs (see #9533).
......
...@@ -40,7 +40,7 @@ struct tok_state { ...@@ -40,7 +40,7 @@ struct tok_state {
int level; /* () [] {} Parentheses nesting level */ int level; /* () [] {} Parentheses nesting level */
/* Used to allow free continuations inside them */ /* Used to allow free continuations inside them */
/* Stuff for checking on different tab sizes */ /* Stuff for checking on different tab sizes */
const char *filename; /* For error messages */ const char *filename; /* encoded to the filesystem encoding */
int altwarning; /* Issue warning if alternate tabs don't match */ int altwarning; /* Issue warning if alternate tabs don't match */
int alterror; /* Issue error if alternate tabs don't match */ int alterror; /* Issue error if alternate tabs don't match */
int alttabsize; /* Alternate tab spacing */ int alttabsize; /* Alternate tab spacing */
......
...@@ -102,6 +102,7 @@ static void ...@@ -102,6 +102,7 @@ static void
ast_error_finish(const char *filename) ast_error_finish(const char *filename)
{ {
PyObject *type, *value, *tback, *errstr, *loc, *tmp; PyObject *type, *value, *tback, *errstr, *loc, *tmp;
PyObject *filename_obj;
long lineno; long lineno;
assert(PyErr_Occurred()); assert(PyErr_Occurred());
...@@ -125,7 +126,16 @@ ast_error_finish(const char *filename) ...@@ -125,7 +126,16 @@ ast_error_finish(const char *filename)
Py_INCREF(Py_None); Py_INCREF(Py_None);
loc = Py_None; loc = Py_None;
} }
tmp = Py_BuildValue("(zlOO)", filename, lineno, Py_None, loc); if (filename != NULL)
filename_obj = PyUnicode_DecodeFSDefault(filename);
else {
Py_INCREF(Py_None);
filename_obj = Py_None;
}
if (filename_obj != NULL)
tmp = Py_BuildValue("(NlOO)", filename_obj, lineno, Py_None, loc);
else
tmp = NULL;
Py_DECREF(loc); Py_DECREF(loc);
if (!tmp) { if (!tmp) {
Py_DECREF(errstr); Py_DECREF(errstr);
......
...@@ -536,6 +536,7 @@ static PyObject * ...@@ -536,6 +536,7 @@ static PyObject *
builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
{ {
char *str; char *str;
PyObject *filename_obj;
char *filename; char *filename;
char *startstr; char *startstr;
int mode = -1; int mode = -1;
...@@ -547,12 +548,16 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) ...@@ -547,12 +548,16 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
static char *kwlist[] = {"source", "filename", "mode", "flags", static char *kwlist[] = {"source", "filename", "mode", "flags",
"dont_inherit", NULL}; "dont_inherit", NULL};
int start[] = {Py_file_input, Py_eval_input, Py_single_input}; int start[] = {Py_file_input, Py_eval_input, Py_single_input};
PyObject *result;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oss|ii:compile", if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&s|ii:compile", kwlist,
kwlist, &cmd, &filename, &startstr, &cmd,
&supplied_flags, &dont_inherit)) PyUnicode_FSConverter, &filename_obj,
&startstr, &supplied_flags,
&dont_inherit))
return NULL; return NULL;
filename = PyBytes_AS_STRING(filename_obj);
cf.cf_flags = supplied_flags | PyCF_SOURCE_IS_UTF8; cf.cf_flags = supplied_flags | PyCF_SOURCE_IS_UTF8;
if (supplied_flags & if (supplied_flags &
...@@ -560,7 +565,7 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) ...@@ -560,7 +565,7 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
{ {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"compile(): unrecognised flags"); "compile(): unrecognised flags");
return NULL; goto error;
} }
/* XXX Warn if (supplied_flags & PyCF_MASK_OBSOLETE) != 0? */ /* XXX Warn if (supplied_flags & PyCF_MASK_OBSOLETE) != 0? */
...@@ -577,14 +582,13 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) ...@@ -577,14 +582,13 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
else { else {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"compile() arg 3 must be 'exec', 'eval' or 'single'"); "compile() arg 3 must be 'exec', 'eval' or 'single'");
return NULL; goto error;
} }
is_ast = PyAST_Check(cmd); is_ast = PyAST_Check(cmd);
if (is_ast == -1) if (is_ast == -1)
return NULL; goto error;
if (is_ast) { if (is_ast) {
PyObject *result;
if (supplied_flags & PyCF_ONLY_AST) { if (supplied_flags & PyCF_ONLY_AST) {
Py_INCREF(cmd); Py_INCREF(cmd);
result = cmd; result = cmd;
...@@ -597,20 +601,27 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) ...@@ -597,20 +601,27 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
mod = PyAST_obj2mod(cmd, arena, mode); mod = PyAST_obj2mod(cmd, arena, mode);
if (mod == NULL) { if (mod == NULL) {
PyArena_Free(arena); PyArena_Free(arena);
return NULL; goto error;
} }
result = (PyObject*)PyAST_Compile(mod, filename, result = (PyObject*)PyAST_Compile(mod, filename,
&cf, arena); &cf, arena);
PyArena_Free(arena); PyArena_Free(arena);
} }
return result; goto finally;
} }
str = source_as_string(cmd, "compile", "string, bytes, AST or code", &cf); str = source_as_string(cmd, "compile", "string, bytes, AST or code", &cf);
if (str == NULL) if (str == NULL)
return NULL; goto error;
result = Py_CompileStringFlags(str, filename, start[mode], &cf);
goto finally;
return Py_CompileStringFlags(str, filename, start[mode], &cf); error:
result = NULL;
finally:
Py_DECREF(filename_obj);
return result;
} }
PyDoc_STRVAR(compile_doc, PyDoc_STRVAR(compile_doc,
......
...@@ -4046,7 +4046,7 @@ makecode(struct compiler *c, struct assembler *a) ...@@ -4046,7 +4046,7 @@ makecode(struct compiler *c, struct assembler *a)
freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars)); freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars));
if (!freevars) if (!freevars)
goto error; goto error;
filename = PyUnicode_FromString(c->c_filename); filename = PyUnicode_DecodeFSDefault(c->c_filename);
if (!filename) if (!filename)
goto error; goto error;
......
...@@ -1160,7 +1160,7 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, ...@@ -1160,7 +1160,7 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
d = PyModule_GetDict(m); d = PyModule_GetDict(m);
if (PyDict_GetItemString(d, "__file__") == NULL) { if (PyDict_GetItemString(d, "__file__") == NULL) {
PyObject *f; PyObject *f;
f = PyUnicode_FromString(filename); f = PyUnicode_DecodeFSDefault(filename);
if (f == NULL) if (f == NULL)
return -1; return -1;
if (PyDict_SetItemString(d, "__file__", f) < 0) { if (PyDict_SetItemString(d, "__file__", f) < 0) {
...@@ -1911,7 +1911,9 @@ err_input(perrdetail *err) ...@@ -1911,7 +1911,9 @@ err_input(perrdetail *err)
{ {
PyObject *v, *w, *errtype, *errtext; PyObject *v, *w, *errtype, *errtext;
PyObject* u = NULL; PyObject* u = NULL;
PyObject *filename;
char *msg = NULL; char *msg = NULL;
errtype = PyExc_SyntaxError; errtype = PyExc_SyntaxError;
switch (err->error) { switch (err->error) {
case E_ERROR: case E_ERROR:
...@@ -2000,8 +2002,17 @@ err_input(perrdetail *err) ...@@ -2000,8 +2002,17 @@ err_input(perrdetail *err)
errtext = PyUnicode_DecodeUTF8(err->text, strlen(err->text), errtext = PyUnicode_DecodeUTF8(err->text, strlen(err->text),
"replace"); "replace");
} }
v = Py_BuildValue("(ziiN)", err->filename, if (err->filename != NULL)
filename = PyUnicode_DecodeFSDefault(err->filename);
else {
Py_INCREF(Py_None);
filename = Py_None;
}
if (filename != NULL)
v = Py_BuildValue("(NiiN)", filename,
err->lineno, err->offset, errtext); err->lineno, err->offset, errtext);
else
v = NULL;
w = NULL; w = NULL;
if (v != NULL) if (v != NULL)
w = Py_BuildValue("(sO)", msg, v); w = Py_BuildValue("(sO)", msg, v);
......
...@@ -143,16 +143,20 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject * ...@@ -143,16 +143,20 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *
Py_ssize_t npath; Py_ssize_t npath;
size_t taillen; size_t taillen;
PyObject *syspath; PyObject *syspath;
const char* path; PyObject *path;
const char* tail; const char* tail;
PyObject *filebytes;
const char* filepath; const char* filepath;
Py_ssize_t len; Py_ssize_t len;
PyObject* result;
filepath = _PyUnicode_AsString(filename); filebytes = PyUnicode_AsEncodedObject(filename,
if (filepath == NULL) { Py_FileSystemDefaultEncoding, "surrogateescape");
if (filebytes == NULL) {
PyErr_Clear(); PyErr_Clear();
return NULL; return NULL;
} }
filepath = PyBytes_AS_STRING(filebytes);
/* Search tail of filename in sys.path before giving up */ /* Search tail of filename in sys.path before giving up */
tail = strrchr(filepath, SEP); tail = strrchr(filepath, SEP);
...@@ -164,7 +168,7 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject * ...@@ -164,7 +168,7 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *
syspath = PySys_GetObject("path"); syspath = PySys_GetObject("path");
if (syspath == NULL || !PyList_Check(syspath)) if (syspath == NULL || !PyList_Check(syspath))
return NULL; goto error;
npath = PyList_Size(syspath); npath = PyList_Size(syspath);
for (i = 0; i < npath; i++) { for (i = 0; i < npath; i++) {
...@@ -175,14 +179,20 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject * ...@@ -175,14 +179,20 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *
} }
if (!PyUnicode_Check(v)) if (!PyUnicode_Check(v))
continue; continue;
path = _PyUnicode_AsStringAndSize(v, &len);
path = PyUnicode_AsEncodedObject(v, Py_FileSystemDefaultEncoding,
"surrogateescape");
if (path == NULL) { if (path == NULL) {
PyErr_Clear(); PyErr_Clear();
continue; continue;
} }
if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) len = PyBytes_GET_SIZE(path);
if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) {
Py_DECREF(path);
continue; /* Too long */ continue; /* Too long */
strcpy(namebuf, path); }
strcpy(namebuf, PyBytes_AS_STRING(path));
Py_DECREF(path);
if (strlen(namebuf) != len) if (strlen(namebuf) != len)
continue; /* v contains '\0' */ continue; /* v contains '\0' */
if (len > 0 && namebuf[len-1] != SEP) if (len > 0 && namebuf[len-1] != SEP)
...@@ -190,11 +200,19 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject * ...@@ -190,11 +200,19 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *
strcpy(namebuf+len, tail); strcpy(namebuf+len, tail);
binary = PyObject_CallMethod(io, "open", "ss", namebuf, "rb"); binary = PyObject_CallMethod(io, "open", "ss", namebuf, "rb");
if (binary != NULL) if (binary != NULL) {
return binary; result = binary;
goto finally;
}
PyErr_Clear(); PyErr_Clear();
} }
return NULL; goto error;
error:
result = NULL;
finally:
Py_DECREF(filebytes);
return result;
} }
int int
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment