diff -r 8fb3a6f9b0a4 Doc/c-api/exceptions.rst --- a/Doc/c-api/exceptions.rst Mon Aug 26 14:05:19 2013 +0200 +++ b/Doc/c-api/exceptions.rst Mon Aug 26 16:10:52 2013 +0200 @@ -293,20 +293,27 @@ in various ways. There is a separate er .. versionadded:: 3.3 -.. c:function:: void PyErr_SyntaxLocationEx(char *filename, int lineno, int col_offset) +.. c:function:: void PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) Set file, line, and offset information for the current exception. If the current exception is not a :exc:`SyntaxError`, then it sets additional attributes, which make the exception printing subsystem think the exception - is a :exc:`SyntaxError`. *filename* is decoded from the filesystem encoding - (:func:`sys.getfilesystemencoding`). + is a :exc:`SyntaxError`. - .. versionadded:: 3.2 +.. versionadded:: 3.3 + + +.. c:function:: void PyErr_SyntaxLocationEx(char *filename, int lineno, int col_offset) + + Like :c:func:`PyErr_SyntaxLocationObject`, but *filename* is a byte string + decoded from the filesystem encoding (:func:`sys.getfilesystemencoding`). + +.. versionadded:: 3.2 .. c:function:: void PyErr_SyntaxLocation(char *filename, int lineno) - Like :c:func:`PyErr_SyntaxLocationExc`, but the col_offset parameter is + Like :c:func:`PyErr_SyntaxLocationEx`, but the col_offset parameter is omitted. @@ -355,7 +362,7 @@ in various ways. There is a separate er documentation. There is no C API for warning control. -.. c:function:: int PyErr_WarnExplicit(PyObject *category, const char *message, const char *filename, int lineno, const char *module, PyObject *registry) +.. c:function:: int PyErr_WarnExplicitObject(PyObject *category, PyObject *message, PyObject *filename, int lineno, PyObject *module, PyObject *registry) Issue a warning message with explicit control over all warning attributes. This is a straightforward wrapper around the Python function @@ -365,6 +372,15 @@ in various ways. There is a separate er *filename* is decoded from the filesystem encoding (:func:`sys.getfilesystemencoding`). + .. versionadded:: 3.3 + + +.. c:function:: int PyErr_WarnExplicit(PyObject *category, const char *message, const char *filename, int lineno, const char *module, PyObject *registry) + + Similar to :c:func:`PyErr_WarnExplicitObject` except that *message* and + *module* are UTF-8 encoded strings, and *filename* is decoded from the + filesystem encoding (:func:`sys.getfilesystemencoding`). + .. c:function:: int PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, const char *format, ...) diff -r 8fb3a6f9b0a4 Include/ast.h --- a/Include/ast.h Mon Aug 26 14:05:19 2013 +0200 +++ b/Include/ast.h Mon Aug 26 16:10:52 2013 +0200 @@ -10,6 +10,11 @@ PyAPI_FUNC(mod_ty) PyAST_FromNode( PyCompilerFlags *flags, const char *filename, /* decoded from the filesystem encoding */ PyArena *arena); +PyAPI_FUNC(mod_ty) PyAST_FromNodeObject( + const node *n, + PyCompilerFlags *flags, + PyObject *filename, + PyArena *arena); #ifdef __cplusplus } diff -r 8fb3a6f9b0a4 Include/compile.h --- a/Include/compile.h Mon Aug 26 14:05:19 2013 +0200 +++ b/Include/compile.h Mon Aug 26 16:10:52 2013 +0200 @@ -36,7 +36,20 @@ PyAPI_FUNC(PyCodeObject *) PyAST_Compile PyCompilerFlags *flags, int optimize, PyArena *arena); -PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromAST(struct _mod *, const char *); +PyAPI_FUNC(PyCodeObject *) PyAST_CompileObject( + struct _mod *mod, + PyObject *filename, + PyCompilerFlags *flags, + int optimize, + PyArena *arena); +PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromAST( + struct _mod * mod, + const char *filename /* decoded from the filesystem encoding */ + ); +PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromASTObject( + struct _mod * mod, + PyObject *filename + ); /* _Py_Mangle is defined in compile.c */ PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name); diff -r 8fb3a6f9b0a4 Include/parsetok.h --- a/Include/parsetok.h Mon Aug 26 14:05:19 2013 +0200 +++ b/Include/parsetok.h Mon Aug 26 16:10:52 2013 +0200 @@ -42,10 +42,16 @@ PyAPI_FUNC(node *) PyParser_ParseFile (F PyAPI_FUNC(node *) PyParser_ParseStringFlags(const char *, grammar *, int, perrdetail *, int); -PyAPI_FUNC(node *) PyParser_ParseFileFlags(FILE *, const char *, - const char*, grammar *, - int, char *, char *, - perrdetail *, int); +PyAPI_FUNC(node *) PyParser_ParseFileFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + const char *enc, + grammar *g, + int start, + char *ps1, + char *ps2, + perrdetail *err_ret, + int flags); PyAPI_FUNC(node *) PyParser_ParseFileFlagsEx( FILE *fp, const char *filename, /* decoded from the filesystem encoding */ @@ -56,11 +62,24 @@ PyAPI_FUNC(node *) PyParser_ParseFileFla char *ps2, perrdetail *err_ret, int *flags); +PyAPI_FUNC(node *) PyParser_ParseFileObject( + FILE *fp, + PyObject *filename, + const char *enc, + grammar *g, + int start, + char *ps1, + char *ps2, + perrdetail *err_ret, + int *flags); -PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilename(const char *, - const char *, - grammar *, int, - perrdetail *, int); +PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilename( + const char *s, + const char *filename, /* decoded from the filesystem encoding */ + grammar *g, + int start, + perrdetail *err_ret, + int flags); PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilenameEx( const char *s, const char *filename, /* decoded from the filesystem encoding */ @@ -68,6 +87,13 @@ PyAPI_FUNC(node *) PyParser_ParseStringF int start, perrdetail *err_ret, int *flags); +PyAPI_FUNC(node *) PyParser_ParseStringObject( + const char *s, + PyObject *filename, + grammar *g, + int start, + perrdetail *err_ret, + int *flags); /* Note that the following functions are defined in pythonrun.c, not in parsetok.c */ diff -r 8fb3a6f9b0a4 Include/pyerrors.h --- a/Include/pyerrors.h Mon Aug 26 14:05:19 2013 +0200 +++ b/Include/pyerrors.h Mon Aug 26 16:10:52 2013 +0200 @@ -301,9 +301,16 @@ PyAPI_FUNC(void) PyErr_SyntaxLocationEx( const char *filename, /* decoded from the filesystem encoding */ int lineno, int col_offset); +PyAPI_FUNC(void) PyErr_SyntaxLocationObject( + PyObject *filename, + int lineno, + int col_offset); PyAPI_FUNC(PyObject *) PyErr_ProgramText( const char *filename, /* decoded from the filesystem encoding */ int lineno); +PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject( + PyObject *filename, + int lineno); /* The following functions are used to create and modify unicode exceptions from C */ diff -r 8fb3a6f9b0a4 Include/pythonrun.h --- a/Include/pythonrun.h Mon Aug 26 14:05:19 2013 +0200 +++ b/Include/pythonrun.h Mon Aug 26 16:10:52 2013 +0200 @@ -66,6 +66,12 @@ PyAPI_FUNC(struct _mod *) PyParser_ASTFr int start, PyCompilerFlags *flags, PyArena *arena); +PyAPI_FUNC(struct _mod *) PyParser_ASTFromStringObject( + const char *s, + PyObject *filename, + int start, + PyCompilerFlags *flags, + PyArena *arena); PyAPI_FUNC(struct _mod *) PyParser_ASTFromFile( FILE *fp, const char *filename, /* decoded from the filesystem encoding */ @@ -76,6 +82,16 @@ PyAPI_FUNC(struct _mod *) PyParser_ASTFr PyCompilerFlags *flags, int *errcode, PyArena *arena); +PyAPI_FUNC(struct _mod *) PyParser_ASTFromFileObject( + FILE *fp, + PyObject *filename, + const char* enc, + int start, + char *ps1, + char *ps2, + PyCompilerFlags *flags, + int *errcode, + PyArena *arena); #endif #ifndef PyParser_SimpleParseString @@ -122,6 +138,10 @@ PyAPI_FUNC(struct symtable *) Py_Symtabl const char *str, const char *filename, /* decoded from the filesystem encoding */ int start); +PyAPI_FUNC(struct symtable *) Py_SymtableStringObject( + const char *str, + PyObject *filename, + int start); PyAPI_FUNC(void) PyErr_Print(void); PyAPI_FUNC(void) PyErr_PrintEx(int); diff -r 8fb3a6f9b0a4 Include/symtable.h --- a/Include/symtable.h Mon Aug 26 14:05:19 2013 +0200 +++ b/Include/symtable.h Mon Aug 26 16:10:52 2013 +0200 @@ -16,7 +16,7 @@ typedef enum _block_type { FunctionBlock struct _symtable_entry; struct symtable { - const char *st_filename; /* name of file being compiled, + PyObject *st_filename; /* name of file being compiled, decoded from the filesystem encoding */ struct _symtable_entry *st_cur; /* current symbol table entry */ struct _symtable_entry *st_top; /* symbol table entry for module */ @@ -74,6 +74,10 @@ PyAPI_FUNC(struct symtable *) PySymtable mod_ty mod, const char *filename, /* decoded from the filesystem encoding */ PyFutureFeatures *future); +PyAPI_FUNC(struct symtable *) PySymtable_BuildObject( + mod_ty mod, + PyObject *filename, + PyFutureFeatures *future); PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *); PyAPI_FUNC(void) PySymtable_Free(struct symtable *); diff -r 8fb3a6f9b0a4 Include/warnings.h --- a/Include/warnings.h Mon Aug 26 14:05:19 2013 +0200 +++ b/Include/warnings.h Mon Aug 26 16:10:52 2013 +0200 @@ -17,6 +17,13 @@ PyAPI_FUNC(int) PyErr_WarnFormat( Py_ssize_t stack_level, const char *format, /* ASCII-encoded string */ ...); +PyAPI_FUNC(int) PyErr_WarnExplicitObject( + PyObject *category, + PyObject *message, + PyObject *filename, + int lineno, + PyObject *module, + PyObject *registry); PyAPI_FUNC(int) PyErr_WarnExplicit( PyObject *category, const char *message, /* UTF-8 encoded string */ @@ -31,6 +38,7 @@ PyErr_WarnExplicitFormat(PyObject *categ const char *module, PyObject *registry, const char *format, ...); + /* DEPRECATED: Use PyErr_WarnEx() instead. */ #ifndef Py_LIMITED_API #define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1) @@ -40,4 +48,3 @@ PyErr_WarnExplicitFormat(PyObject *categ } #endif #endif /* !Py_WARNINGS_H */ - diff -r 8fb3a6f9b0a4 Modules/parsermodule.c --- a/Modules/parsermodule.c Mon Aug 26 14:05:19 2013 +0200 +++ b/Modules/parsermodule.c Mon Aug 26 16:10:52 2013 +0200 @@ -477,33 +477,46 @@ parser_st2list(PyST_Object *self, PyObje static PyObject* parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw) { - PyObject* res = 0; - PyArena* arena; + PyObject* res = NULL; + PyArena* arena = NULL; mod_ty mod; - char* str = ""; + PyObject* filename = NULL; int ok; static char *keywords[] = {"st", "filename", NULL}; if (self == NULL || PyModule_Check(self)) - ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compilest", keywords, - &PyST_Type, &self, &str); + ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O&:compilest", keywords, + &PyST_Type, &self, + PyUnicode_FSDecoder, &filename); else - ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1], - &str); - - if (ok) { - arena = PyArena_New(); - if (arena) { - mod = PyAST_FromNode(self->st_node, &(self->st_flags), str, arena); - if (mod) { - res = (PyObject *)PyAST_Compile(mod, str, &(self->st_flags), arena); - } - PyArena_Free(arena); - } + ok = PyArg_ParseTupleAndKeywords(args, kw, "|O&:compile", &keywords[1], + PyUnicode_FSDecoder, &filename); + if (!ok) + goto error; + + if (filename == NULL) { + filename = PyUnicode_FromString(""); + if (filename == NULL) + goto error; } - return (res); + arena = PyArena_New(); + if (!arena) + goto error; + + mod = PyAST_FromNodeObject(self->st_node, &self->st_flags, + filename, arena); + if (!mod) + goto error; + + res = (PyObject *)PyAST_CompileObject(mod, filename, + &self->st_flags, -1, arena); +error: + Py_XDECREF(filename); + if (arena != NULL) + PyArena_Free(arena); + return res; } diff -r 8fb3a6f9b0a4 Modules/symtablemodule.c --- a/Modules/symtablemodule.c Mon Aug 26 14:05:19 2013 +0200 +++ b/Modules/symtablemodule.c Mon Aug 26 16:10:52 2013 +0200 @@ -11,12 +11,12 @@ symtable_symtable(PyObject *self, PyObje PyObject *t; char *str; - char *filename; + PyObject *filename; char *startstr; int start; - if (!PyArg_ParseTuple(args, "sss:symtable", &str, &filename, - &startstr)) + if (!PyArg_ParseTuple(args, "sO&s:symtable", + &str, PyUnicode_FSDecoder, &filename, &startstr)) return NULL; if (strcmp(startstr, "exec") == 0) start = Py_file_input; @@ -27,9 +27,11 @@ symtable_symtable(PyObject *self, PyObje else { PyErr_SetString(PyExc_ValueError, "symtable() arg 3 must be 'exec' or 'eval' or 'single'"); + Py_DECREF(filename); return NULL; } - st = Py_SymtableString(str, filename, start); + st = Py_SymtableStringObject(str, filename, start); + Py_DECREF(filename); if (st == NULL) return NULL; t = st->st_blocks; diff -r 8fb3a6f9b0a4 Parser/parsetok.c --- a/Parser/parsetok.c Mon Aug 26 14:05:19 2013 +0200 +++ b/Parser/parsetok.c Mon Aug 26 16:10:52 2013 +0200 @@ -13,7 +13,7 @@ /* Forward */ static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int *); -static int initerr(perrdetail *err_ret, const char* filename); +static int initerr(perrdetail *err_ret, PyObject * filename); /* Parse input coming from a string. Return error code, print some errors. */ node * @@ -41,9 +41,9 @@ PyParser_ParseStringFlagsFilename(const } node * -PyParser_ParseStringFlagsFilenameEx(const char *s, const char *filename, - grammar *g, int start, - perrdetail *err_ret, int *flags) +PyParser_ParseStringObject(const char *s, PyObject *filename, + grammar *g, int start, + perrdetail *err_ret, int *flags) { struct tok_state *tok; int exec_input = start == file_input; @@ -67,6 +67,30 @@ PyParser_ParseStringFlagsFilenameEx(cons return parsetok(tok, g, start, err_ret, flags); } +node * +PyParser_ParseStringFlagsFilenameEx(const char *s, const char *filename_str, + grammar *g, int start, + perrdetail *err_ret, int *flags) +{ + PyObject *filename; + node *n; + filename = NULL; +#ifndef PGEN + if (filename_str != NULL) { + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) { + err_ret->error = E_ERROR; + return NULL; + } + } +#endif + n = PyParser_ParseStringObject(s, filename, g, start, err_ret, flags); +#ifndef PGEN + Py_XDECREF(filename); +#endif + return n; +} + /* Parse input coming from a file. Return error code, print some errors. */ node * @@ -88,9 +112,10 @@ PyParser_ParseFileFlags(FILE *fp, const } node * -PyParser_ParseFileFlagsEx(FILE *fp, const char *filename, - const char *enc, grammar *g, int start, - char *ps1, char *ps2, perrdetail *err_ret, int *flags) +PyParser_ParseFileObject(FILE *fp, PyObject *filename, + const char *enc, grammar *g, int start, + char *ps1, char *ps2, perrdetail *err_ret, + int *flags) { struct tok_state *tok; @@ -108,6 +133,32 @@ PyParser_ParseFileFlagsEx(FILE *fp, cons return parsetok(tok, g, start, err_ret, flags); } +node * +PyParser_ParseFileFlagsEx(FILE *fp, const char *filename, + const char *enc, grammar *g, int start, + char *ps1, char *ps2, perrdetail *err_ret, int *flags) +{ + node *n; + PyObject *fileobj; +#ifndef PGEN + if (filename != NULL) { + fileobj = PyUnicode_DecodeFSDefault(filename); + if (fileobj == NULL) { + err_ret->error = E_ERROR; + return NULL; + } + } + else +#endif + fileobj = NULL; + n = PyParser_ParseFileObject(fp, fileobj, enc, g, + start, ps1, ps2, err_ret, flags); +#ifndef PGEN + Py_XDECREF(fileobj); +#endif + return n; +} + #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD #if 0 static char with_msg[] = @@ -306,7 +357,7 @@ done: } static int -initerr(perrdetail *err_ret, const char *filename) +initerr(perrdetail *err_ret, PyObject *filename) { err_ret->error = E_OK; err_ret->lineno = 0; @@ -315,13 +366,16 @@ initerr(perrdetail *err_ret, const char err_ret->token = -1; err_ret->expected = -1; #ifndef PGEN - if (filename) - err_ret->filename = PyUnicode_DecodeFSDefault(filename); - else + if (filename) { + Py_INCREF(filename); + err_ret->filename = filename; + } + else { err_ret->filename = PyUnicode_FromString(""); - if (err_ret->filename == NULL) { - err_ret->error = E_ERROR; - return -1; + if (err_ret->filename == NULL) { + err_ret->error = E_ERROR; + return -1; + } } #endif return 0; diff -r 8fb3a6f9b0a4 Python/_warnings.c --- a/Python/_warnings.c Mon Aug 26 14:05:19 2013 +0200 +++ b/Python/_warnings.c Mon Aug 26 16:10:52 2013 +0200 @@ -707,14 +707,14 @@ warnings_warn_explicit(PyObject *self, P /* Handle the warning. */ returned = warn_explicit(category, message, filename, lineno, module, - registry, source_line); + registry, source_line); Py_DECREF(source_list); return returned; } standard_call: return warn_explicit(category, message, filename, lineno, module, - registry, NULL); + registry, NULL); } @@ -786,11 +786,26 @@ PyErr_Warn(PyObject *category, char *tex /* Warning with explicit origin */ int +PyErr_WarnExplicitObject(PyObject *category, PyObject *message, + PyObject *filename, int lineno, + PyObject *module, PyObject *registry) +{ + PyObject *res; + if (category == NULL) + category = PyExc_RuntimeWarning; + res = warn_explicit(category, message, filename, lineno, + module, registry, NULL); + if (res == NULL) + return -1; + Py_DECREF(res); + return 0; +} + +int PyErr_WarnExplicit(PyObject *category, const char *text, const char *filename_str, int lineno, const char *module_str, PyObject *registry) { - PyObject *res; PyObject *message = PyUnicode_FromString(text); PyObject *filename = PyUnicode_DecodeFSDefault(filename_str); PyObject *module = NULL; @@ -804,14 +819,8 @@ PyErr_WarnExplicit(PyObject *category, c goto exit; } - if (category == NULL) - category = PyExc_RuntimeWarning; - res = warn_explicit(category, message, filename, lineno, module, registry, - NULL); - if (res == NULL) - goto exit; - Py_DECREF(res); - ret = 0; + ret = PyErr_WarnExplicitObject(category, message, filename, lineno, + module, registry); exit: Py_XDECREF(message); diff -r 8fb3a6f9b0a4 Python/ast.c --- a/Python/ast.c Mon Aug 26 14:05:19 2013 +0200 +++ b/Python/ast.c Mon Aug 26 16:10:52 2013 +0200 @@ -491,7 +491,7 @@ PyAST_Validate(mod_ty mod) struct compiling { char *c_encoding; /* source encoding */ PyArena *c_arena; /* arena for allocating memeory */ - const char *c_filename; /* filename */ + PyObject *c_filename; /* filename */ PyObject *c_normalize; /* Normalization function from unicodedata. */ PyObject *c_normalize_args; /* Normalization argument tuple. */ }; @@ -573,24 +573,13 @@ static int ast_error(struct compiling *c, const node *n, const char *errmsg) { PyObject *value, *errstr, *loc, *tmp; - PyObject *filename_obj; - - loc = PyErr_ProgramText(c->c_filename, LINENO(n)); + + loc = PyErr_ProgramTextObject(c->c_filename, LINENO(n)); if (!loc) { Py_INCREF(Py_None); loc = Py_None; } - if (c->c_filename) { - filename_obj = PyUnicode_DecodeFSDefault(c->c_filename); - if (!filename_obj) { - Py_DECREF(loc); - return 0; - } - } else { - Py_INCREF(Py_None); - filename_obj = Py_None; - } - tmp = Py_BuildValue("(NiiN)", filename_obj, LINENO(n), n->n_col_offset, loc); + tmp = Py_BuildValue("(OiiN)", c->c_filename, LINENO(n), n->n_col_offset, loc); if (!tmp) return 0; errstr = PyUnicode_FromString(errmsg); @@ -673,8 +662,8 @@ num_stmts(const node *n) */ mod_ty -PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename, - PyArena *arena) +PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags, + PyObject *filename, PyArena *arena) { int i, j, k, num; asdl_seq *stmts = NULL; @@ -684,6 +673,7 @@ PyAST_FromNode(const node *n, PyCompiler mod_ty res = NULL; c.c_arena = arena; + /* borrowed reference */ c.c_filename = filename; c.c_normalize = c.c_normalize_args = NULL; if (flags && flags->cf_flags & PyCF_SOURCE_IS_UTF8) { @@ -797,6 +787,21 @@ PyAST_FromNode(const node *n, PyCompiler return res; } +mod_ty +PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename_str, + PyArena *arena) +{ + mod_ty mod; + PyObject *filename; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + mod = PyAST_FromNodeObject(n, flags, filename, arena); + Py_DECREF(filename); + return mod; + +} + /* Return the AST repr. of the operator represented as syntax (|, ^, etc.) */ diff -r 8fb3a6f9b0a4 Python/compile.c --- a/Python/compile.c Mon Aug 26 14:05:19 2013 +0200 +++ b/Python/compile.c Mon Aug 26 16:10:52 2013 +0200 @@ -149,8 +149,7 @@ handled by the symbol analysis pass. */ struct compiler { - const char *c_filename; - PyObject *c_filename_obj; + PyObject *c_filename; struct symtable *c_st; PyFutureFeatures *c_future; /* pointer to module's __future__ */ PyCompilerFlags *c_flags; @@ -288,8 +287,8 @@ compiler_init(struct compiler *c) } PyCodeObject * -PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags, - int optimize, PyArena *arena) +PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, + int optimize, PyArena *arena) { struct compiler c; PyCodeObject *co = NULL; @@ -304,12 +303,10 @@ PyAST_CompileEx(mod_ty mod, const char * if (!compiler_init(&c)) return NULL; + Py_INCREF(filename); c.c_filename = filename; - c.c_filename_obj = PyUnicode_DecodeFSDefault(filename); - if (!c.c_filename_obj) - goto finally; c.c_arena = arena; - c.c_future = PyFuture_FromAST(mod, filename); + c.c_future = PyFuture_FromASTObject(mod, filename); if (c.c_future == NULL) goto finally; if (!flags) { @@ -323,7 +320,7 @@ PyAST_CompileEx(mod_ty mod, const char * c.c_optimize = (optimize == -1) ? Py_OptimizeFlag : optimize; c.c_nestlevel = 0; - c.c_st = PySymtable_Build(mod, filename, c.c_future); + c.c_st = PySymtable_BuildObject(mod, filename, c.c_future); if (c.c_st == NULL) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_SystemError, "no symtable"); @@ -339,6 +336,21 @@ PyAST_CompileEx(mod_ty mod, const char * } PyCodeObject * +PyAST_CompileEx(mod_ty mod, const char *filename_str, PyCompilerFlags *flags, + int optimize, PyArena *arena) +{ + PyObject *filename; + PyCodeObject *co; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + co = PyAST_CompileObject(mod, filename, flags, optimize, arena); + Py_DECREF(filename); + return co; + +} + +PyCodeObject * PyNode_Compile(struct _node *n, const char *filename) { PyCodeObject *co = NULL; @@ -360,9 +372,8 @@ compiler_free(struct compiler *c) PySymtable_Free(c->c_st); if (c->c_future) PyObject_Free(c->c_future); - if (c->c_filename_obj) - Py_DECREF(c->c_filename_obj); Py_DECREF(c->c_stack); + Py_XDECREF(c->c_filename); } static PyObject * @@ -1368,12 +1379,11 @@ get_ref_type(struct compiler *c, PyObjec if (scope == 0) { char buf[350]; PyOS_snprintf(buf, sizeof(buf), - "unknown scope for %.100s in %.100s(%s) in %s\n" + "unknown scope for %.100s in %.100s(%s)\n" "symbols: %s\nlocals: %s\nglobals: %s", PyBytes_AS_STRING(name), PyBytes_AS_STRING(c->u->u_name), PyObject_REPR(c->u->u_ste->ste_id), - c->c_filename, PyObject_REPR(c->u->u_ste->ste_symbols), PyObject_REPR(c->u->u_varnames), PyObject_REPR(c->u->u_names) @@ -2411,6 +2421,7 @@ compiler_assert(struct compiler *c, stmt { static PyObject *assertion_error = NULL; basicblock *end; + PyObject* msg; if (c->c_optimize) return 1; @@ -2421,11 +2432,17 @@ compiler_assert(struct compiler *c, stmt } if (s->v.Assert.test->kind == Tuple_kind && asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) { - const char* msg = - "assertion is always true, perhaps remove parentheses?"; - if (PyErr_WarnExplicit(PyExc_SyntaxWarning, msg, c->c_filename, - c->u->u_lineno, NULL, NULL) == -1) + msg = PyUnicode_FromString("assertion is always true, " + "perhaps remove parentheses?"); + if (msg == NULL) return 0; + if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, + c->c_filename, c->u->u_lineno, + NULL, NULL) == -1) { + Py_DECREF(msg); + return 0; + } + Py_DECREF(msg); } VISIT(c, expr, s->v.Assert.test); end = compiler_new_block(c); @@ -3593,12 +3610,12 @@ compiler_error(struct compiler *c, const PyObject *loc; PyObject *u = NULL, *v = NULL; - loc = PyErr_ProgramText(c->c_filename, c->u->u_lineno); + loc = PyErr_ProgramTextObject(c->c_filename, c->u->u_lineno); if (!loc) { Py_INCREF(Py_None); loc = Py_None; } - u = Py_BuildValue("(OiiO)", c->c_filename_obj, c->u->u_lineno, + u = Py_BuildValue("(OiiO)", c->c_filename, c->u->u_lineno, c->u->u_col_offset, loc); if (!u) goto exit; @@ -4188,7 +4205,7 @@ makecode(struct compiler *c, struct asse nlocals, stackdepth(c), flags, bytecode, consts, names, varnames, freevars, cellvars, - c->c_filename_obj, c->u->u_name, + c->c_filename, c->u->u_name, c->u->u_firstlineno, a->a_lnotab); error: diff -r 8fb3a6f9b0a4 Python/errors.c --- a/Python/errors.c Mon Aug 26 14:05:19 2013 +0200 +++ b/Python/errors.c Mon Aug 26 16:10:52 2013 +0200 @@ -901,7 +901,8 @@ extern PyObject *PyModule_GetWarningsMod void -PyErr_SyntaxLocation(const char *filename, int lineno) { +PyErr_SyntaxLocation(const char *filename, int lineno) +{ PyErr_SyntaxLocationEx(filename, lineno, -1); } @@ -911,7 +912,7 @@ PyErr_SyntaxLocation(const char *filenam to make printing of exceptions believe it is a syntax error. */ void -PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) +PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) { PyObject *exc, *v, *tb, *tmp; _Py_IDENTIFIER(filename); @@ -945,16 +946,10 @@ PyErr_SyntaxLocationEx(const char *filen } } if (filename != NULL) { - tmp = PyUnicode_DecodeFSDefault(filename); - if (tmp == NULL) + if (_PyObject_SetAttrId(v, &PyId_filename, filename)) PyErr_Clear(); - else { - if (_PyObject_SetAttrId(v, &PyId_filename, tmp)) - PyErr_Clear(); - Py_DECREF(tmp); - } - tmp = PyErr_ProgramText(filename, lineno); + tmp = PyErr_ProgramTextObject(filename, lineno); if (tmp) { if (_PyObject_SetAttrId(v, &PyId_text, tmp)) PyErr_Clear(); @@ -984,6 +979,21 @@ PyErr_SyntaxLocationEx(const char *filen PyErr_Restore(exc, v, tb); } +void +PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) +{ + PyObject *fileobj; + if (filename != NULL) { + fileobj = PyUnicode_DecodeFSDefault(filename); + if (fileobj == NULL) + PyErr_Clear(); + } + else + fileobj = NULL; + PyErr_SyntaxLocationObject(fileobj, lineno, col_offset); + Py_XDECREF(fileobj); +} + /* Attempt to load the line of text that the exception refers to. If it fails, it will return NULL but will not set an exception. @@ -991,15 +1001,11 @@ PyErr_SyntaxLocationEx(const char *filen functionality in tb_displayline() in traceback.c. */ PyObject * -PyErr_ProgramText(const char *filename, int lineno) +err_programtext(FILE *fp, int lineno) { - FILE *fp; int i; char linebuf[1000]; - if (filename == NULL || *filename == '\0' || lineno <= 0) - return NULL; - fp = fopen(filename, "r" PY_STDIOTEXTMODE); if (fp == NULL) return NULL; for (i = 0; i < lineno; i++) { @@ -1030,6 +1036,26 @@ PyErr_ProgramText(const char *filename, return NULL; } +PyObject * +PyErr_ProgramText(const char *filename, int lineno) +{ + FILE *fp; + if (filename == NULL || *filename == '\0' || lineno <= 0) + return NULL; + fp = fopen(filename, "r" PY_STDIOTEXTMODE); + return err_programtext(fp, lineno); +} + +PyObject * +PyErr_ProgramTextObject(PyObject *filename, int lineno) +{ + FILE *fp; + if (filename == NULL || lineno <= 0) + return NULL; + fp = _Py_fopen(filename, "r" PY_STDIOTEXTMODE); + return err_programtext(fp, lineno); +} + #ifdef __cplusplus } #endif diff -r 8fb3a6f9b0a4 Python/future.c --- a/Python/future.c Mon Aug 26 14:05:19 2013 +0200 +++ b/Python/future.c Mon Aug 26 16:10:52 2013 +0200 @@ -11,7 +11,7 @@ "from __future__ imports must occur at the beginning of the file" static int -future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename) +future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) { int i; asdl_seq *names; @@ -43,12 +43,12 @@ future_check_features(PyFutureFeatures * } else if (strcmp(feature, "braces") == 0) { PyErr_SetString(PyExc_SyntaxError, "not a chance"); - PyErr_SyntaxLocationEx(filename, s->lineno, s->col_offset); + PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset); return 0; } else { PyErr_Format(PyExc_SyntaxError, UNDEFINED_FUTURE_FEATURE, feature); - PyErr_SyntaxLocationEx(filename, s->lineno, s->col_offset); + PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset); return 0; } } @@ -56,7 +56,7 @@ future_check_features(PyFutureFeatures * } static int -future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename) +future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename) { int i, done = 0, prev_line = 0; stmt_ty first; @@ -101,7 +101,7 @@ future_parse(PyFutureFeatures *ff, mod_t if (done) { PyErr_SetString(PyExc_SyntaxError, ERR_LATE_FUTURE); - PyErr_SyntaxLocationEx(filename, s->lineno, s->col_offset); + PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset); return 0; } if (!future_check_features(ff, s, filename)) @@ -121,7 +121,7 @@ future_parse(PyFutureFeatures *ff, mod_t PyFutureFeatures * -PyFuture_FromAST(mod_ty mod, const char *filename) +PyFuture_FromASTObject(mod_ty mod, PyObject *filename) { PyFutureFeatures *ff; @@ -139,3 +139,18 @@ PyFuture_FromAST(mod_ty mod, const char } return ff; } + + +PyFutureFeatures * +PyFuture_FromAST(mod_ty mod, const char *filename_str) +{ + PyFutureFeatures *ff; + PyObject *filename; + + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + ff = PyFuture_FromASTObject(mod, filename); + Py_DECREF(filename); + return ff; +} diff -r 8fb3a6f9b0a4 Python/pythonrun.c --- a/Python/pythonrun.c Mon Aug 26 14:05:19 2013 +0200 +++ b/Python/pythonrun.c Mon Aug 26 16:10:52 2013 +0200 @@ -2084,46 +2084,62 @@ PyCompileString(const char *str, const c } struct symtable * -Py_SymtableString(const char *str, const char *filename, int start) +Py_SymtableStringObject(const char *str, PyObject *filename, int start) { struct symtable *st; mod_ty mod; PyCompilerFlags flags; - PyArena *arena = PyArena_New(); + PyArena *arena; + + arena = PyArena_New(); if (arena == NULL) return NULL; flags.cf_flags = 0; - mod = PyParser_ASTFromString(str, filename, start, &flags, arena); + mod = PyParser_ASTFromStringObject(str, filename, start, &flags, arena); if (mod == NULL) { PyArena_Free(arena); return NULL; } - st = PySymtable_Build(mod, filename, 0); + st = PySymtable_BuildObject(mod, filename, 0); PyArena_Free(arena); return st; } +struct symtable * +Py_SymtableString(const char *str, const char *filename_str, int start) +{ + PyObject *filename; + struct symtable *st; + + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + st = Py_SymtableStringObject(str, filename, start); + Py_DECREF(filename); + return st; +} + /* Preferred access to parser is through AST. */ mod_ty -PyParser_ASTFromString(const char *s, const char *filename, int start, - PyCompilerFlags *flags, PyArena *arena) +PyParser_ASTFromStringObject(const char *s, PyObject *filename, int start, + PyCompilerFlags *flags, PyArena *arena) { mod_ty mod; PyCompilerFlags localflags; perrdetail err; int iflags = PARSER_FLAGS(flags); - node *n = PyParser_ParseStringFlagsFilenameEx(s, filename, - &_PyParser_Grammar, start, &err, - &iflags); + node *n = PyParser_ParseStringObject(s, filename, + &_PyParser_Grammar, start, &err, + &iflags); if (flags == NULL) { localflags.cf_flags = 0; flags = &localflags; } if (n) { flags->cf_flags |= iflags & PyCF_MASK; - mod = PyAST_FromNode(n, flags, filename, arena); + mod = PyAST_FromNodeObject(n, flags, filename, arena); PyNode_Free(n); } else { @@ -2135,26 +2151,40 @@ PyParser_ASTFromString(const char *s, co } mod_ty -PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc, - int start, char *ps1, - char *ps2, PyCompilerFlags *flags, int *errcode, - PyArena *arena) +PyParser_ASTFromString(const char *s, const char *filename_str, int start, + PyCompilerFlags *flags, PyArena *arena) +{ + PyObject *filename; + mod_ty mod; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + mod = PyParser_ASTFromStringObject(s, filename, start, flags, arena); + Py_DECREF(filename); + return mod; +} + +mod_ty +PyParser_ASTFromFileObject(FILE *fp, PyObject *filename, const char* enc, + int start, char *ps1, + char *ps2, PyCompilerFlags *flags, int *errcode, + PyArena *arena) { mod_ty mod; PyCompilerFlags localflags; perrdetail err; int iflags = PARSER_FLAGS(flags); - node *n = PyParser_ParseFileFlagsEx(fp, filename, enc, - &_PyParser_Grammar, - start, ps1, ps2, &err, &iflags); + node *n = PyParser_ParseFileObject(fp, filename, enc, + &_PyParser_Grammar, + start, ps1, ps2, &err, &iflags); if (flags == NULL) { localflags.cf_flags = 0; flags = &localflags; } if (n) { flags->cf_flags |= iflags & PyCF_MASK; - mod = PyAST_FromNode(n, flags, filename, arena); + mod = PyAST_FromNodeObject(n, flags, filename, arena); PyNode_Free(n); } else { @@ -2167,6 +2197,23 @@ PyParser_ASTFromFile(FILE *fp, const cha return mod; } +mod_ty +PyParser_ASTFromFile(FILE *fp, const char *filename_str, const char* enc, + int start, char *ps1, + char *ps2, PyCompilerFlags *flags, int *errcode, + PyArena *arena) +{ + mod_ty mod; + PyObject *filename; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + mod = PyParser_ASTFromFileObject(fp, filename, enc, start, ps1, ps2, + flags, errcode, arena); + Py_DECREF(filename); + return mod; +} + /* Simplified interface to parsefile -- return node or set exception */ node * diff -r 8fb3a6f9b0a4 Python/symtable.c --- a/Python/symtable.c Mon Aug 26 14:05:19 2013 +0200 +++ b/Python/symtable.c Mon Aug 26 16:10:52 2013 +0200 @@ -233,7 +233,7 @@ symtable_new(void) #define COMPILER_STACK_FRAME_SCALE 3 struct symtable * -PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future) +PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) { struct symtable *st = symtable_new(); asdl_seq *seq; @@ -241,7 +241,12 @@ PySymtable_Build(mod_ty mod, const char PyThreadState *tstate; if (st == NULL) - return st; + return NULL; + if (filename == NULL) { + PySymtable_Free(st); + return NULL; + } + Py_INCREF(filename); st->st_filename = filename; st->st_future = future; @@ -302,9 +307,23 @@ PySymtable_Build(mod_ty mod, const char return NULL; } +struct symtable * +PySymtable_Build(mod_ty mod, const char *filename_str, PyFutureFeatures *future) +{ + PyObject *filename; + struct symtable *st; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + st = PySymtable_BuildObject(mod, filename, future); + Py_DECREF(filename); + return st; +} + void PySymtable_Free(struct symtable *st) { + Py_XDECREF(st->st_filename); Py_XDECREF(st->st_blocks); Py_XDECREF(st->st_stack); PyMem_Free((void *)st); @@ -354,9 +373,9 @@ error_at_directive(PySTEntryObject *ste, if (PyTuple_GET_ITEM(data, 0) == name) break; } - PyErr_SyntaxLocationEx(ste->ste_table->st_filename, - PyLong_AsLong(PyTuple_GET_ITEM(data, 1)), - PyLong_AsLong(PyTuple_GET_ITEM(data, 2))); + PyErr_SyntaxLocationObject(ste->ste_table->st_filename, + PyLong_AsLong(PyTuple_GET_ITEM(data, 1)), + PyLong_AsLong(PyTuple_GET_ITEM(data, 2))); return 0; } @@ -583,8 +602,9 @@ check_unoptimized(const PySTEntryObject* break; } - PyErr_SyntaxLocationEx(ste->ste_table->st_filename, ste->ste_opt_lineno, - ste->ste_opt_col_offset); + PyErr_SyntaxLocationObject(ste->ste_table->st_filename, + ste->ste_opt_lineno, + ste->ste_opt_col_offset); return 0; } @@ -915,15 +935,20 @@ symtable_analyze(struct symtable *st) static int symtable_warn(struct symtable *st, char *msg, int lineno) { - if (PyErr_WarnExplicit(PyExc_SyntaxWarning, msg, st->st_filename, - lineno, NULL, NULL) < 0) { + PyObject *message = PyUnicode_FromString(msg); + if (message == NULL) + return 0; + if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, message, st->st_filename, + lineno, NULL, NULL) < 0) { + Py_DECREF(message); if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) { PyErr_SetString(PyExc_SyntaxError, msg); - PyErr_SyntaxLocationEx(st->st_filename, st->st_cur->ste_lineno, - st->st_cur->ste_col_offset); + PyErr_SyntaxLocationObject(st->st_filename, st->st_cur->ste_lineno, + st->st_cur->ste_col_offset); } return 0; } + Py_DECREF(message); return 1; } @@ -1006,9 +1031,9 @@ symtable_add_def(struct symtable *st, Py if ((flag & DEF_PARAM) && (val & DEF_PARAM)) { /* Is it better to use 'mangled' or 'name' here? */ PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT, name); - PyErr_SyntaxLocationEx(st->st_filename, - st->st_cur->ste_lineno, - st->st_cur->ste_col_offset); + PyErr_SyntaxLocationObject(st->st_filename, + st->st_cur->ste_lineno, + st->st_cur->ste_col_offset); goto error; } val |= flag; @@ -1613,7 +1638,7 @@ symtable_visit_alias(struct symtable *st int lineno = st->st_cur->ste_lineno; int col_offset = st->st_cur->ste_col_offset; PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING); - PyErr_SyntaxLocationEx(st->st_filename, lineno, col_offset); + PyErr_SyntaxLocationObject(st->st_filename, lineno, col_offset); Py_DECREF(store_name); return 0; }