Commit 4b2fd0ab authored by Victor Stinner's avatar Victor Stinner

Close #11619: The parser and the import machinery do not encode Unicode

filenames anymore on Windows.
parent 7ef28690
...@@ -235,7 +235,7 @@ in various ways. There is a separate error indicator for each thread. ...@@ -235,7 +235,7 @@ in various ways. There is a separate error indicator for each thread.
Similar to :c:func:`PyErr_SetFromErrnoWithFilenameObject`, but the filename Similar to :c:func:`PyErr_SetFromErrnoWithFilenameObject`, but the filename
is given as a C string. *filename* is decoded from the filesystem encoding is given as a C string. *filename* is decoded from the filesystem encoding
(:func:`sys.getfilesystemencoding`). (:func:`os.fsdecode`).
.. c:function:: PyObject* PyErr_SetFromWindowsErr(int ierr) .. c:function:: PyObject* PyErr_SetFromWindowsErr(int ierr)
...@@ -267,7 +267,7 @@ in various ways. There is a separate error indicator for each thread. ...@@ -267,7 +267,7 @@ in various ways. There is a separate error indicator for each thread.
Similar to :c:func:`PyErr_SetFromWindowsErrWithFilenameObject`, but the Similar to :c:func:`PyErr_SetFromWindowsErrWithFilenameObject`, but the
filename is given as a C string. *filename* is decoded from the filesystem filename is given as a C string. *filename* is decoded from the filesystem
encoding (:func:`sys.getfilesystemencoding`). Availability: Windows. encoding (:func:`os.fsdecode`). Availability: Windows.
.. c:function:: PyObject* PyErr_SetExcFromWindowsErrWithFilenameObject(PyObject *type, int ierr, PyObject *filename) .. c:function:: PyObject* PyErr_SetExcFromWindowsErrWithFilenameObject(PyObject *type, int ierr, PyObject *filename)
...@@ -293,20 +293,27 @@ in various ways. There is a separate error indicator for each thread. ...@@ -293,20 +293,27 @@ in various ways. There is a separate error indicator for each thread.
.. versionadded:: 3.3 .. 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 Set file, line, and offset information for the current exception. If the
current exception is not a :exc:`SyntaxError`, then it sets additional current exception is not a :exc:`SyntaxError`, then it sets additional
attributes, which make the exception printing subsystem think the exception attributes, which make the exception printing subsystem think the exception
is a :exc:`SyntaxError`. *filename* is decoded from the filesystem encoding is a :exc:`SyntaxError`.
(:func:`sys.getfilesystemencoding`).
.. versionadded:: 3.2 .. versionadded:: 3.4
.. 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:`os.fsdecode`).
.. versionadded:: 3.2
.. c:function:: void PyErr_SyntaxLocation(char *filename, int lineno) .. 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. omitted.
...@@ -355,15 +362,22 @@ in various ways. There is a separate error indicator for each thread. ...@@ -355,15 +362,22 @@ in various ways. There is a separate error indicator for each thread.
documentation. There is no C API for warning control. 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 Issue a warning message with explicit control over all warning attributes. This
is a straightforward wrapper around the Python function is a straightforward wrapper around the Python function
:func:`warnings.warn_explicit`, see there for more information. The *module* :func:`warnings.warn_explicit`, see there for more information. The *module*
and *registry* arguments may be set to *NULL* to get the default effect and *registry* arguments may be set to *NULL* to get the default effect
described there. *message* and *module* are UTF-8 encoded strings, described there.
*filename* is decoded from the filesystem encoding
(:func:`sys.getfilesystemencoding`). .. versionadded:: 3.4
.. 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:`os.fsdecode`).
.. c:function:: int PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, const char *format, ...) .. c:function:: int PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, const char *format, ...)
......
...@@ -258,16 +258,15 @@ the same library that the Python runtime is using. ...@@ -258,16 +258,15 @@ the same library that the Python runtime is using.
*optimize* set to ``-1``. *optimize* set to ``-1``.
.. c:function:: PyObject* Py_CompileStringExFlags(const char *str, const char *filename, int start, PyCompilerFlags *flags, int optimize) .. c:function:: PyObject* Py_CompileStringObject(const char *str, PyObject *filename, int start, PyCompilerFlags *flags, int optimize)
Parse and compile the Python source code in *str*, returning the resulting code Parse and compile the Python source code in *str*, returning the resulting code
object. The start token is given by *start*; this can be used to constrain the object. The start token is given by *start*; this can be used to constrain the
code which can be compiled and should be :const:`Py_eval_input`, code which can be compiled and should be :const:`Py_eval_input`,
:const:`Py_file_input`, or :const:`Py_single_input`. The filename specified by :const:`Py_file_input`, or :const:`Py_single_input`. The filename specified by
*filename* is used to construct the code object and may appear in tracebacks or *filename* is used to construct the code object and may appear in tracebacks or
:exc:`SyntaxError` exception messages, it is decoded from the filesystem :exc:`SyntaxError` exception messages. This returns *NULL* if the code
encoding (:func:`sys.getfilesystemencoding`). This returns *NULL* if the cannot be parsed or compiled.
code cannot be parsed or compiled.
The integer *optimize* specifies the optimization level of the compiler; a The integer *optimize* specifies the optimization level of the compiler; a
value of ``-1`` selects the optimization level of the interpreter as given by value of ``-1`` selects the optimization level of the interpreter as given by
...@@ -275,9 +274,16 @@ the same library that the Python runtime is using. ...@@ -275,9 +274,16 @@ the same library that the Python runtime is using.
``__debug__`` is true), ``1`` (asserts are removed, ``__debug__`` is false) ``__debug__`` is true), ``1`` (asserts are removed, ``__debug__`` is false)
or ``2`` (docstrings are removed too). or ``2`` (docstrings are removed too).
.. versionadded:: 3.2 .. versionadded:: 3.4
.. c:function:: PyObject* Py_CompileStringExFlags(const char *str, const char *filename, int start, PyCompilerFlags *flags, int optimize)
Like :c:func:`Py_CompileStringExFlags`, but *filename* is a byte string
decoded from the filesystem encoding (:func:`os.fsdecode`).
.. versionadded:: 3.2
.. c:function:: PyObject* PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) .. c:function:: PyObject* PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals)
This is a simplified interface to :c:func:`PyEval_EvalCodeEx`, with just This is a simplified interface to :c:func:`PyEval_EvalCodeEx`, with just
......
...@@ -10,6 +10,11 @@ PyAPI_FUNC(mod_ty) PyAST_FromNode( ...@@ -10,6 +10,11 @@ PyAPI_FUNC(mod_ty) PyAST_FromNode(
PyCompilerFlags *flags, PyCompilerFlags *flags,
const char *filename, /* decoded from the filesystem encoding */ const char *filename, /* decoded from the filesystem encoding */
PyArena *arena); PyArena *arena);
PyAPI_FUNC(mod_ty) PyAST_FromNodeObject(
const node *n,
PyCompilerFlags *flags,
PyObject *filename,
PyArena *arena);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -36,7 +36,20 @@ PyAPI_FUNC(PyCodeObject *) PyAST_CompileEx( ...@@ -36,7 +36,20 @@ PyAPI_FUNC(PyCodeObject *) PyAST_CompileEx(
PyCompilerFlags *flags, PyCompilerFlags *flags,
int optimize, int optimize,
PyArena *arena); 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 */ /* _Py_Mangle is defined in compile.c */
PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name); PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name);
......
...@@ -42,10 +42,16 @@ PyAPI_FUNC(node *) PyParser_ParseFile (FILE *, const char *, grammar *, int, ...@@ -42,10 +42,16 @@ PyAPI_FUNC(node *) PyParser_ParseFile (FILE *, const char *, grammar *, int,
PyAPI_FUNC(node *) PyParser_ParseStringFlags(const char *, grammar *, int, PyAPI_FUNC(node *) PyParser_ParseStringFlags(const char *, grammar *, int,
perrdetail *, int); perrdetail *, int);
PyAPI_FUNC(node *) PyParser_ParseFileFlags(FILE *, const char *, PyAPI_FUNC(node *) PyParser_ParseFileFlags(
const char*, grammar *, FILE *fp,
int, char *, char *, const char *filename, /* decoded from the filesystem encoding */
perrdetail *, int); const char *enc,
grammar *g,
int start,
char *ps1,
char *ps2,
perrdetail *err_ret,
int flags);
PyAPI_FUNC(node *) PyParser_ParseFileFlagsEx( PyAPI_FUNC(node *) PyParser_ParseFileFlagsEx(
FILE *fp, FILE *fp,
const char *filename, /* decoded from the filesystem encoding */ const char *filename, /* decoded from the filesystem encoding */
...@@ -56,11 +62,24 @@ PyAPI_FUNC(node *) PyParser_ParseFileFlagsEx( ...@@ -56,11 +62,24 @@ PyAPI_FUNC(node *) PyParser_ParseFileFlagsEx(
char *ps2, char *ps2,
perrdetail *err_ret, perrdetail *err_ret,
int *flags); 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 *, PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilename(
const char *, const char *s,
grammar *, int, const char *filename, /* decoded from the filesystem encoding */
perrdetail *, int); grammar *g,
int start,
perrdetail *err_ret,
int flags);
PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilenameEx( PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilenameEx(
const char *s, const char *s,
const char *filename, /* decoded from the filesystem encoding */ const char *filename, /* decoded from the filesystem encoding */
...@@ -68,6 +87,13 @@ PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilenameEx( ...@@ -68,6 +87,13 @@ PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilenameEx(
int start, int start,
perrdetail *err_ret, perrdetail *err_ret,
int *flags); 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, /* Note that the following functions are defined in pythonrun.c,
not in parsetok.c */ not in parsetok.c */
......
...@@ -301,9 +301,16 @@ PyAPI_FUNC(void) PyErr_SyntaxLocationEx( ...@@ -301,9 +301,16 @@ PyAPI_FUNC(void) PyErr_SyntaxLocationEx(
const char *filename, /* decoded from the filesystem encoding */ const char *filename, /* decoded from the filesystem encoding */
int lineno, int lineno,
int col_offset); int col_offset);
PyAPI_FUNC(void) PyErr_SyntaxLocationObject(
PyObject *filename,
int lineno,
int col_offset);
PyAPI_FUNC(PyObject *) PyErr_ProgramText( PyAPI_FUNC(PyObject *) PyErr_ProgramText(
const char *filename, /* decoded from the filesystem encoding */ const char *filename, /* decoded from the filesystem encoding */
int lineno); int lineno);
PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject(
PyObject *filename,
int lineno);
/* The following functions are used to create and modify unicode /* The following functions are used to create and modify unicode
exceptions from C */ exceptions from C */
......
...@@ -66,6 +66,12 @@ PyAPI_FUNC(struct _mod *) PyParser_ASTFromString( ...@@ -66,6 +66,12 @@ PyAPI_FUNC(struct _mod *) PyParser_ASTFromString(
int start, int start,
PyCompilerFlags *flags, PyCompilerFlags *flags,
PyArena *arena); 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( PyAPI_FUNC(struct _mod *) PyParser_ASTFromFile(
FILE *fp, FILE *fp,
const char *filename, /* decoded from the filesystem encoding */ const char *filename, /* decoded from the filesystem encoding */
...@@ -76,6 +82,16 @@ PyAPI_FUNC(struct _mod *) PyParser_ASTFromFile( ...@@ -76,6 +82,16 @@ PyAPI_FUNC(struct _mod *) PyParser_ASTFromFile(
PyCompilerFlags *flags, PyCompilerFlags *flags,
int *errcode, int *errcode,
PyArena *arena); 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 #endif
#ifndef PyParser_SimpleParseString #ifndef PyParser_SimpleParseString
...@@ -117,11 +133,20 @@ PyAPI_FUNC(PyObject *) Py_CompileStringExFlags( ...@@ -117,11 +133,20 @@ PyAPI_FUNC(PyObject *) Py_CompileStringExFlags(
int start, int start,
PyCompilerFlags *flags, PyCompilerFlags *flags,
int optimize); int optimize);
PyAPI_FUNC(PyObject *) Py_CompileStringObject(
const char *str,
PyObject *filename, int start,
PyCompilerFlags *flags,
int optimize);
#endif #endif
PyAPI_FUNC(struct symtable *) Py_SymtableString( PyAPI_FUNC(struct symtable *) Py_SymtableString(
const char *str, const char *str,
const char *filename, /* decoded from the filesystem encoding */ const char *filename, /* decoded from the filesystem encoding */
int start); 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_Print(void);
PyAPI_FUNC(void) PyErr_PrintEx(int); PyAPI_FUNC(void) PyErr_PrintEx(int);
......
...@@ -16,7 +16,7 @@ typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock } ...@@ -16,7 +16,7 @@ typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock }
struct _symtable_entry; struct _symtable_entry;
struct symtable { struct symtable {
const char *st_filename; /* name of file being compiled, PyObject *st_filename; /* name of file being compiled,
decoded from the filesystem encoding */ decoded from the filesystem encoding */
struct _symtable_entry *st_cur; /* current symbol table entry */ struct _symtable_entry *st_cur; /* current symbol table entry */
struct _symtable_entry *st_top; /* symbol table entry for module */ struct _symtable_entry *st_top; /* symbol table entry for module */
...@@ -74,6 +74,10 @@ PyAPI_FUNC(struct symtable *) PySymtable_Build( ...@@ -74,6 +74,10 @@ PyAPI_FUNC(struct symtable *) PySymtable_Build(
mod_ty mod, mod_ty mod,
const char *filename, /* decoded from the filesystem encoding */ const char *filename, /* decoded from the filesystem encoding */
PyFutureFeatures *future); 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(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *);
PyAPI_FUNC(void) PySymtable_Free(struct symtable *); PyAPI_FUNC(void) PySymtable_Free(struct symtable *);
......
...@@ -17,6 +17,13 @@ PyAPI_FUNC(int) PyErr_WarnFormat( ...@@ -17,6 +17,13 @@ PyAPI_FUNC(int) PyErr_WarnFormat(
Py_ssize_t stack_level, Py_ssize_t stack_level,
const char *format, /* ASCII-encoded string */ 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( PyAPI_FUNC(int) PyErr_WarnExplicit(
PyObject *category, PyObject *category,
const char *message, /* UTF-8 encoded string */ const char *message, /* UTF-8 encoded string */
......
...@@ -22,7 +22,7 @@ import test.support ...@@ -22,7 +22,7 @@ import test.support
from test.support import ( from test.support import (
EnvironmentVarGuard, TESTFN, check_warnings, forget, is_jython, EnvironmentVarGuard, TESTFN, check_warnings, forget, is_jython,
make_legacy_pyc, rmtree, run_unittest, swap_attr, swap_item, temp_umask, make_legacy_pyc, rmtree, run_unittest, swap_attr, swap_item, temp_umask,
unlink, unload, create_empty_file, cpython_only) unlink, unload, create_empty_file, cpython_only, TESTFN_UNENCODABLE)
from test import script_helper from test import script_helper
...@@ -1055,6 +1055,14 @@ class ImportTracebackTests(unittest.TestCase): ...@@ -1055,6 +1055,14 @@ class ImportTracebackTests(unittest.TestCase):
finally: finally:
importlib.SourceLoader.load_module = old_load_module importlib.SourceLoader.load_module = old_load_module
@unittest.skipUnless(TESTFN_UNENCODABLE, 'need TESTFN_UNENCODABLE')
def test_unencodable_filename(self):
# Issue #11619: The Python parser and the import machinery must not
# encode filenames, especially on Windows
pyname = script_helper.make_script('', TESTFN_UNENCODABLE, 'pass')
name = pyname[:-3]
script_helper.assert_python_ok("-c", "mod = __import__(%a)" % name)
if __name__ == '__main__': if __name__ == '__main__':
# Test needs to be a package, so we can do relative imports. # Test needs to be a package, so we can do relative imports.
......
...@@ -10,6 +10,9 @@ Projected Release date: 2013-09-08 ...@@ -10,6 +10,9 @@ Projected Release date: 2013-09-08
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #11619: The parser and the import machinery do not encode Unicode
filenames anymore on Windows.
- Issue #18808: Non-daemon threads are now automatically joined when - Issue #18808: Non-daemon threads are now automatically joined when
a sub-interpreter is shutdown (it would previously dump a fatal error). a sub-interpreter is shutdown (it would previously dump a fatal error).
......
...@@ -477,33 +477,46 @@ parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw) ...@@ -477,33 +477,46 @@ parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw)
static PyObject* static PyObject*
parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw) parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw)
{ {
PyObject* res = 0; PyObject* res = NULL;
PyArena* arena; PyArena* arena = NULL;
mod_ty mod; mod_ty mod;
char* str = "<syntax-tree>"; PyObject* filename = NULL;
int ok; int ok;
static char *keywords[] = {"st", "filename", NULL}; static char *keywords[] = {"st", "filename", NULL};
if (self == NULL || PyModule_Check(self)) if (self == NULL || PyModule_Check(self))
ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compilest", keywords, ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O&:compilest", keywords,
&PyST_Type, &self, &str); &PyST_Type, &self,
PyUnicode_FSDecoder, &filename);
else else
ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1], ok = PyArg_ParseTupleAndKeywords(args, kw, "|O&:compile", &keywords[1],
&str); PyUnicode_FSDecoder, &filename);
if (!ok)
if (ok) { goto error;
arena = PyArena_New();
if (arena) { if (filename == NULL) {
mod = PyAST_FromNode(self->st_node, &(self->st_flags), str, arena); filename = PyUnicode_FromString("<syntax-tree>");
if (mod) { if (filename == NULL)
res = (PyObject *)PyAST_Compile(mod, str, &(self->st_flags), arena); goto error;
}
PyArena_Free(arena);
}
} }
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;
} }
......
...@@ -11,12 +11,12 @@ symtable_symtable(PyObject *self, PyObject *args) ...@@ -11,12 +11,12 @@ symtable_symtable(PyObject *self, PyObject *args)
PyObject *t; PyObject *t;
char *str; char *str;
char *filename; PyObject *filename;
char *startstr; char *startstr;
int start; int start;
if (!PyArg_ParseTuple(args, "sss:symtable", &str, &filename, if (!PyArg_ParseTuple(args, "sO&s:symtable",
&startstr)) &str, PyUnicode_FSDecoder, &filename, &startstr))
return NULL; return NULL;
if (strcmp(startstr, "exec") == 0) if (strcmp(startstr, "exec") == 0)
start = Py_file_input; start = Py_file_input;
...@@ -27,9 +27,11 @@ symtable_symtable(PyObject *self, PyObject *args) ...@@ -27,9 +27,11 @@ symtable_symtable(PyObject *self, PyObject *args)
else { else {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"symtable() arg 3 must be 'exec' or 'eval' or 'single'"); "symtable() arg 3 must be 'exec' or 'eval' or 'single'");
Py_DECREF(filename);
return NULL; return NULL;
} }
st = Py_SymtableString(str, filename, start); st = Py_SymtableStringObject(str, filename, start);
Py_DECREF(filename);
if (st == NULL) if (st == NULL)
return NULL; return NULL;
t = st->st_blocks; t = st->st_blocks;
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
/* Forward */ /* Forward */
static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int *); 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. */ /* Parse input coming from a string. Return error code, print some errors. */
node * node *
...@@ -41,9 +41,9 @@ PyParser_ParseStringFlagsFilename(const char *s, const char *filename, ...@@ -41,9 +41,9 @@ PyParser_ParseStringFlagsFilename(const char *s, const char *filename,
} }
node * node *
PyParser_ParseStringFlagsFilenameEx(const char *s, const char *filename, PyParser_ParseStringObject(const char *s, PyObject *filename,
grammar *g, int start, grammar *g, int start,
perrdetail *err_ret, int *flags) perrdetail *err_ret, int *flags)
{ {
struct tok_state *tok; struct tok_state *tok;
int exec_input = start == file_input; int exec_input = start == file_input;
...@@ -67,6 +67,29 @@ PyParser_ParseStringFlagsFilenameEx(const char *s, const char *filename, ...@@ -67,6 +67,29 @@ PyParser_ParseStringFlagsFilenameEx(const char *s, const char *filename,
return parsetok(tok, g, start, err_ret, flags); 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)
{
node *n;
PyObject *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. */ /* Parse input coming from a file. Return error code, print some errors. */
node * node *
...@@ -88,9 +111,10 @@ PyParser_ParseFileFlags(FILE *fp, const char *filename, const char *enc, ...@@ -88,9 +111,10 @@ PyParser_ParseFileFlags(FILE *fp, const char *filename, const char *enc,
} }
node * node *
PyParser_ParseFileFlagsEx(FILE *fp, const char *filename, PyParser_ParseFileObject(FILE *fp, PyObject *filename,
const char *enc, grammar *g, int start, const char *enc, grammar *g, int start,
char *ps1, char *ps2, perrdetail *err_ret, int *flags) char *ps1, char *ps2, perrdetail *err_ret,
int *flags)
{ {
struct tok_state *tok; struct tok_state *tok;
...@@ -108,6 +132,30 @@ PyParser_ParseFileFlagsEx(FILE *fp, const char *filename, ...@@ -108,6 +132,30 @@ PyParser_ParseFileFlagsEx(FILE *fp, const char *filename,
return parsetok(tok, g, start, err_ret, flags); 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 = NULL;
#ifndef PGEN
if (filename != NULL) {
fileobj = PyUnicode_DecodeFSDefault(filename);
if (fileobj == NULL) {
err_ret->error = E_ERROR;
return NULL;
}
}
#endif
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 #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
#if 0 #if 0
static char with_msg[] = static char with_msg[] =
...@@ -306,7 +354,7 @@ done: ...@@ -306,7 +354,7 @@ done:
} }
static int static int
initerr(perrdetail *err_ret, const char *filename) initerr(perrdetail *err_ret, PyObject *filename)
{ {
err_ret->error = E_OK; err_ret->error = E_OK;
err_ret->lineno = 0; err_ret->lineno = 0;
...@@ -315,13 +363,16 @@ initerr(perrdetail *err_ret, const char *filename) ...@@ -315,13 +363,16 @@ initerr(perrdetail *err_ret, const char *filename)
err_ret->token = -1; err_ret->token = -1;
err_ret->expected = -1; err_ret->expected = -1;
#ifndef PGEN #ifndef PGEN
if (filename) if (filename) {
err_ret->filename = PyUnicode_DecodeFSDefault(filename); Py_INCREF(filename);
else err_ret->filename = filename;
}
else {
err_ret->filename = PyUnicode_FromString("<string>"); err_ret->filename = PyUnicode_FromString("<string>");
if (err_ret->filename == NULL) { if (err_ret->filename == NULL) {
err_ret->error = E_ERROR; err_ret->error = E_ERROR;
return -1; return -1;
}
} }
#endif #endif
return 0; return 0;
......
...@@ -707,14 +707,14 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) ...@@ -707,14 +707,14 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
/* Handle the warning. */ /* Handle the warning. */
returned = warn_explicit(category, message, filename, lineno, module, returned = warn_explicit(category, message, filename, lineno, module,
registry, source_line); registry, source_line);
Py_DECREF(source_list); Py_DECREF(source_list);
return returned; return returned;
} }
standard_call: standard_call:
return warn_explicit(category, message, filename, lineno, module, return warn_explicit(category, message, filename, lineno, module,
registry, NULL); registry, NULL);
} }
...@@ -785,12 +785,27 @@ PyErr_Warn(PyObject *category, char *text) ...@@ -785,12 +785,27 @@ PyErr_Warn(PyObject *category, char *text)
} }
/* Warning with explicit origin */ /* 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 int
PyErr_WarnExplicit(PyObject *category, const char *text, PyErr_WarnExplicit(PyObject *category, const char *text,
const char *filename_str, int lineno, const char *filename_str, int lineno,
const char *module_str, PyObject *registry) const char *module_str, PyObject *registry)
{ {
PyObject *res;
PyObject *message = PyUnicode_FromString(text); PyObject *message = PyUnicode_FromString(text);
PyObject *filename = PyUnicode_DecodeFSDefault(filename_str); PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
PyObject *module = NULL; PyObject *module = NULL;
...@@ -804,14 +819,8 @@ PyErr_WarnExplicit(PyObject *category, const char *text, ...@@ -804,14 +819,8 @@ PyErr_WarnExplicit(PyObject *category, const char *text,
goto exit; goto exit;
} }
if (category == NULL) ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
category = PyExc_RuntimeWarning; module, registry);
res = warn_explicit(category, message, filename, lineno, module, registry,
NULL);
if (res == NULL)
goto exit;
Py_DECREF(res);
ret = 0;
exit: exit:
Py_XDECREF(message); Py_XDECREF(message);
......
...@@ -491,7 +491,7 @@ PyAST_Validate(mod_ty mod) ...@@ -491,7 +491,7 @@ PyAST_Validate(mod_ty mod)
struct compiling { struct compiling {
char *c_encoding; /* source encoding */ char *c_encoding; /* source encoding */
PyArena *c_arena; /* arena for allocating memeory */ 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; /* Normalization function from unicodedata. */
PyObject *c_normalize_args; /* Normalization argument tuple. */ PyObject *c_normalize_args; /* Normalization argument tuple. */
}; };
...@@ -573,24 +573,13 @@ static int ...@@ -573,24 +573,13 @@ static int
ast_error(struct compiling *c, const node *n, const char *errmsg) ast_error(struct compiling *c, const node *n, const char *errmsg)
{ {
PyObject *value, *errstr, *loc, *tmp; 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) { if (!loc) {
Py_INCREF(Py_None); Py_INCREF(Py_None);
loc = Py_None; loc = Py_None;
} }
if (c->c_filename) { tmp = Py_BuildValue("(OiiN)", c->c_filename, LINENO(n), n->n_col_offset, loc);
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);
if (!tmp) if (!tmp)
return 0; return 0;
errstr = PyUnicode_FromString(errmsg); errstr = PyUnicode_FromString(errmsg);
...@@ -673,8 +662,8 @@ num_stmts(const node *n) ...@@ -673,8 +662,8 @@ num_stmts(const node *n)
*/ */
mod_ty mod_ty
PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename, PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags,
PyArena *arena) PyObject *filename, PyArena *arena)
{ {
int i, j, k, num; int i, j, k, num;
asdl_seq *stmts = NULL; asdl_seq *stmts = NULL;
...@@ -684,6 +673,7 @@ PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename, ...@@ -684,6 +673,7 @@ PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename,
mod_ty res = NULL; mod_ty res = NULL;
c.c_arena = arena; c.c_arena = arena;
/* borrowed reference */
c.c_filename = filename; c.c_filename = filename;
c.c_normalize = c.c_normalize_args = NULL; c.c_normalize = c.c_normalize_args = NULL;
if (flags && flags->cf_flags & PyCF_SOURCE_IS_UTF8) { if (flags && flags->cf_flags & PyCF_SOURCE_IS_UTF8) {
...@@ -797,6 +787,21 @@ PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename, ...@@ -797,6 +787,21 @@ PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename,
return res; 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.) /* Return the AST repr. of the operator represented as syntax (|, ^, etc.)
*/ */
......
...@@ -579,8 +579,7 @@ static PyObject * ...@@ -579,8 +579,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; PyObject *filename;
char *filename;
char *startstr; char *startstr;
int mode = -1; int mode = -1;
int dont_inherit = 0; int dont_inherit = 0;
...@@ -596,12 +595,11 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) ...@@ -596,12 +595,11 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&s|iii:compile", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&s|iii:compile", kwlist,
&cmd, &cmd,
PyUnicode_FSConverter, &filename_obj, PyUnicode_FSDecoder, &filename,
&startstr, &supplied_flags, &startstr, &supplied_flags,
&dont_inherit, &optimize)) &dont_inherit, &optimize))
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 &
...@@ -659,8 +657,8 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) ...@@ -659,8 +657,8 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
PyArena_Free(arena); PyArena_Free(arena);
goto error; goto error;
} }
result = (PyObject*)PyAST_CompileEx(mod, filename, result = (PyObject*)PyAST_CompileObject(mod, filename,
&cf, optimize, arena); &cf, optimize, arena);
PyArena_Free(arena); PyArena_Free(arena);
} }
goto finally; goto finally;
...@@ -670,13 +668,13 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) ...@@ -670,13 +668,13 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
if (str == NULL) if (str == NULL)
goto error; goto error;
result = Py_CompileStringExFlags(str, filename, start[mode], &cf, optimize); result = Py_CompileStringObject(str, filename, start[mode], &cf, optimize);
goto finally; goto finally;
error: error:
result = NULL; result = NULL;
finally: finally:
Py_DECREF(filename_obj); Py_DECREF(filename);
return result; return result;
} }
......
...@@ -149,8 +149,7 @@ handled by the symbol analysis pass. ...@@ -149,8 +149,7 @@ handled by the symbol analysis pass.
*/ */
struct compiler { struct compiler {
const char *c_filename; PyObject *c_filename;
PyObject *c_filename_obj;
struct symtable *c_st; struct symtable *c_st;
PyFutureFeatures *c_future; /* pointer to module's __future__ */ PyFutureFeatures *c_future; /* pointer to module's __future__ */
PyCompilerFlags *c_flags; PyCompilerFlags *c_flags;
...@@ -288,8 +287,8 @@ compiler_init(struct compiler *c) ...@@ -288,8 +287,8 @@ compiler_init(struct compiler *c)
} }
PyCodeObject * PyCodeObject *
PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags, PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags,
int optimize, PyArena *arena) int optimize, PyArena *arena)
{ {
struct compiler c; struct compiler c;
PyCodeObject *co = NULL; PyCodeObject *co = NULL;
...@@ -304,12 +303,10 @@ PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags, ...@@ -304,12 +303,10 @@ PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags,
if (!compiler_init(&c)) if (!compiler_init(&c))
return NULL; return NULL;
Py_INCREF(filename);
c.c_filename = 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_arena = arena;
c.c_future = PyFuture_FromAST(mod, filename); c.c_future = PyFuture_FromASTObject(mod, filename);
if (c.c_future == NULL) if (c.c_future == NULL)
goto finally; goto finally;
if (!flags) { if (!flags) {
...@@ -323,7 +320,7 @@ PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags, ...@@ -323,7 +320,7 @@ PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags,
c.c_optimize = (optimize == -1) ? Py_OptimizeFlag : optimize; c.c_optimize = (optimize == -1) ? Py_OptimizeFlag : optimize;
c.c_nestlevel = 0; 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 (c.c_st == NULL) {
if (!PyErr_Occurred()) if (!PyErr_Occurred())
PyErr_SetString(PyExc_SystemError, "no symtable"); PyErr_SetString(PyExc_SystemError, "no symtable");
...@@ -338,6 +335,21 @@ PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags, ...@@ -338,6 +335,21 @@ PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags,
return co; return co;
} }
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 * PyCodeObject *
PyNode_Compile(struct _node *n, const char *filename) PyNode_Compile(struct _node *n, const char *filename)
{ {
...@@ -360,8 +372,7 @@ compiler_free(struct compiler *c) ...@@ -360,8 +372,7 @@ compiler_free(struct compiler *c)
PySymtable_Free(c->c_st); PySymtable_Free(c->c_st);
if (c->c_future) if (c->c_future)
PyObject_Free(c->c_future); PyObject_Free(c->c_future);
if (c->c_filename_obj) Py_XDECREF(c->c_filename);
Py_DECREF(c->c_filename_obj);
Py_DECREF(c->c_stack); Py_DECREF(c->c_stack);
} }
...@@ -1368,12 +1379,11 @@ get_ref_type(struct compiler *c, PyObject *name) ...@@ -1368,12 +1379,11 @@ get_ref_type(struct compiler *c, PyObject *name)
if (scope == 0) { if (scope == 0) {
char buf[350]; char buf[350];
PyOS_snprintf(buf, sizeof(buf), 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", "symbols: %s\nlocals: %s\nglobals: %s",
PyBytes_AS_STRING(name), PyBytes_AS_STRING(name),
PyBytes_AS_STRING(c->u->u_name), PyBytes_AS_STRING(c->u->u_name),
PyObject_REPR(c->u->u_ste->ste_id), PyObject_REPR(c->u->u_ste->ste_id),
c->c_filename,
PyObject_REPR(c->u->u_ste->ste_symbols), PyObject_REPR(c->u->u_ste->ste_symbols),
PyObject_REPR(c->u->u_varnames), PyObject_REPR(c->u->u_varnames),
PyObject_REPR(c->u->u_names) PyObject_REPR(c->u->u_names)
...@@ -2411,6 +2421,7 @@ compiler_assert(struct compiler *c, stmt_ty s) ...@@ -2411,6 +2421,7 @@ compiler_assert(struct compiler *c, stmt_ty s)
{ {
static PyObject *assertion_error = NULL; static PyObject *assertion_error = NULL;
basicblock *end; basicblock *end;
PyObject* msg;
if (c->c_optimize) if (c->c_optimize)
return 1; return 1;
...@@ -2421,11 +2432,17 @@ compiler_assert(struct compiler *c, stmt_ty s) ...@@ -2421,11 +2432,17 @@ compiler_assert(struct compiler *c, stmt_ty s)
} }
if (s->v.Assert.test->kind == Tuple_kind && if (s->v.Assert.test->kind == Tuple_kind &&
asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) { asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) {
const char* msg = msg = PyUnicode_FromString("assertion is always true, "
"assertion is always true, perhaps remove parentheses?"; "perhaps remove parentheses?");
if (PyErr_WarnExplicit(PyExc_SyntaxWarning, msg, c->c_filename, if (msg == NULL)
c->u->u_lineno, NULL, NULL) == -1) return 0;
if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg,
c->c_filename, c->u->u_lineno,
NULL, NULL) == -1) {
Py_DECREF(msg);
return 0; return 0;
}
Py_DECREF(msg);
} }
VISIT(c, expr, s->v.Assert.test); VISIT(c, expr, s->v.Assert.test);
end = compiler_new_block(c); end = compiler_new_block(c);
...@@ -3593,12 +3610,12 @@ compiler_error(struct compiler *c, const char *errstr) ...@@ -3593,12 +3610,12 @@ compiler_error(struct compiler *c, const char *errstr)
PyObject *loc; PyObject *loc;
PyObject *u = NULL, *v = NULL; 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) { if (!loc) {
Py_INCREF(Py_None); Py_INCREF(Py_None);
loc = 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); c->u->u_col_offset, loc);
if (!u) if (!u)
goto exit; goto exit;
...@@ -4188,7 +4205,7 @@ makecode(struct compiler *c, struct assembler *a) ...@@ -4188,7 +4205,7 @@ makecode(struct compiler *c, struct assembler *a)
nlocals, stackdepth(c), flags, nlocals, stackdepth(c), flags,
bytecode, consts, names, varnames, bytecode, consts, names, varnames,
freevars, cellvars, freevars, cellvars,
c->c_filename_obj, c->u->u_name, c->c_filename, c->u->u_name,
c->u->u_firstlineno, c->u->u_firstlineno,
a->a_lnotab); a->a_lnotab);
error: error:
......
...@@ -901,7 +901,8 @@ extern PyObject *PyModule_GetWarningsModule(void); ...@@ -901,7 +901,8 @@ extern PyObject *PyModule_GetWarningsModule(void);
void void
PyErr_SyntaxLocation(const char *filename, int lineno) { PyErr_SyntaxLocation(const char *filename, int lineno)
{
PyErr_SyntaxLocationEx(filename, lineno, -1); PyErr_SyntaxLocationEx(filename, lineno, -1);
} }
...@@ -911,7 +912,7 @@ PyErr_SyntaxLocation(const char *filename, int lineno) { ...@@ -911,7 +912,7 @@ PyErr_SyntaxLocation(const char *filename, int lineno) {
to make printing of exceptions believe it is a syntax error. */ to make printing of exceptions believe it is a syntax error. */
void 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; PyObject *exc, *v, *tb, *tmp;
_Py_IDENTIFIER(filename); _Py_IDENTIFIER(filename);
...@@ -945,16 +946,10 @@ PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) ...@@ -945,16 +946,10 @@ PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)
} }
} }
if (filename != NULL) { if (filename != NULL) {
tmp = PyUnicode_DecodeFSDefault(filename); if (_PyObject_SetAttrId(v, &PyId_filename, filename))
if (tmp == NULL)
PyErr_Clear(); 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 (tmp) {
if (_PyObject_SetAttrId(v, &PyId_text, tmp)) if (_PyObject_SetAttrId(v, &PyId_text, tmp))
PyErr_Clear(); PyErr_Clear();
...@@ -984,6 +979,21 @@ PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) ...@@ -984,6 +979,21 @@ PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)
PyErr_Restore(exc, v, tb); 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 /* 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. fails, it will return NULL but will not set an exception.
...@@ -991,15 +1001,11 @@ PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) ...@@ -991,15 +1001,11 @@ PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)
functionality in tb_displayline() in traceback.c. */ functionality in tb_displayline() in traceback.c. */
PyObject * PyObject *
PyErr_ProgramText(const char *filename, int lineno) err_programtext(FILE *fp, int lineno)
{ {
FILE *fp;
int i; int i;
char linebuf[1000]; char linebuf[1000];
if (filename == NULL || *filename == '\0' || lineno <= 0)
return NULL;
fp = fopen(filename, "r" PY_STDIOTEXTMODE);
if (fp == NULL) if (fp == NULL)
return NULL; return NULL;
for (i = 0; i < lineno; i++) { for (i = 0; i < lineno; i++) {
...@@ -1030,6 +1036,26 @@ PyErr_ProgramText(const char *filename, int lineno) ...@@ -1030,6 +1036,26 @@ PyErr_ProgramText(const char *filename, int lineno)
return NULL; 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 #ifdef __cplusplus
} }
#endif #endif
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
"from __future__ imports must occur at the beginning of the file" "from __future__ imports must occur at the beginning of the file"
static int 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; int i;
asdl_seq *names; asdl_seq *names;
...@@ -43,12 +43,12 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename) ...@@ -43,12 +43,12 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename)
} else if (strcmp(feature, "braces") == 0) { } else if (strcmp(feature, "braces") == 0) {
PyErr_SetString(PyExc_SyntaxError, PyErr_SetString(PyExc_SyntaxError,
"not a chance"); "not a chance");
PyErr_SyntaxLocationEx(filename, s->lineno, s->col_offset); PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset);
return 0; return 0;
} else { } else {
PyErr_Format(PyExc_SyntaxError, PyErr_Format(PyExc_SyntaxError,
UNDEFINED_FUTURE_FEATURE, feature); UNDEFINED_FUTURE_FEATURE, feature);
PyErr_SyntaxLocationEx(filename, s->lineno, s->col_offset); PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset);
return 0; return 0;
} }
} }
...@@ -56,7 +56,7 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename) ...@@ -56,7 +56,7 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename)
} }
static int 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; int i, done = 0, prev_line = 0;
stmt_ty first; stmt_ty first;
...@@ -101,7 +101,7 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename) ...@@ -101,7 +101,7 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
if (done) { if (done) {
PyErr_SetString(PyExc_SyntaxError, PyErr_SetString(PyExc_SyntaxError,
ERR_LATE_FUTURE); ERR_LATE_FUTURE);
PyErr_SyntaxLocationEx(filename, s->lineno, s->col_offset); PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset);
return 0; return 0;
} }
if (!future_check_features(ff, s, filename)) if (!future_check_features(ff, s, filename))
...@@ -121,7 +121,7 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename) ...@@ -121,7 +121,7 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
PyFutureFeatures * PyFutureFeatures *
PyFuture_FromAST(mod_ty mod, const char *filename) PyFuture_FromASTObject(mod_ty mod, PyObject *filename)
{ {
PyFutureFeatures *ff; PyFutureFeatures *ff;
...@@ -139,3 +139,18 @@ PyFuture_FromAST(mod_ty mod, const char *filename) ...@@ -139,3 +139,18 @@ PyFuture_FromAST(mod_ty mod, const char *filename)
} }
return ff; 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;
}
...@@ -2051,8 +2051,8 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals, ...@@ -2051,8 +2051,8 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals,
} }
PyObject * PyObject *
Py_CompileStringExFlags(const char *str, const char *filename, int start, Py_CompileStringObject(const char *str, PyObject *filename, int start,
PyCompilerFlags *flags, int optimize) PyCompilerFlags *flags, int optimize)
{ {
PyCodeObject *co; PyCodeObject *co;
mod_ty mod; mod_ty mod;
...@@ -2060,7 +2060,7 @@ Py_CompileStringExFlags(const char *str, const char *filename, int start, ...@@ -2060,7 +2060,7 @@ Py_CompileStringExFlags(const char *str, const char *filename, int start,
if (arena == NULL) if (arena == NULL)
return NULL; return NULL;
mod = PyParser_ASTFromString(str, filename, start, flags, arena); mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena);
if (mod == NULL) { if (mod == NULL) {
PyArena_Free(arena); PyArena_Free(arena);
return NULL; return NULL;
...@@ -2070,11 +2070,24 @@ Py_CompileStringExFlags(const char *str, const char *filename, int start, ...@@ -2070,11 +2070,24 @@ Py_CompileStringExFlags(const char *str, const char *filename, int start,
PyArena_Free(arena); PyArena_Free(arena);
return result; return result;
} }
co = PyAST_CompileEx(mod, filename, flags, optimize, arena); co = PyAST_CompileObject(mod, filename, flags, optimize, arena);
PyArena_Free(arena); PyArena_Free(arena);
return (PyObject *)co; return (PyObject *)co;
} }
PyObject *
Py_CompileStringExFlags(const char *str, const char *filename_str, int start,
PyCompilerFlags *flags, int optimize)
{
PyObject *filename, *co;
filename = PyUnicode_DecodeFSDefault(filename_str);
if (filename == NULL)
return NULL;
co = Py_CompileStringObject(str, filename, start, flags, optimize);
Py_DECREF(filename);
return co;
}
/* For use in Py_LIMITED_API */ /* For use in Py_LIMITED_API */
#undef Py_CompileString #undef Py_CompileString
PyObject * PyObject *
...@@ -2084,46 +2097,62 @@ PyCompileString(const char *str, const char *filename, int start) ...@@ -2084,46 +2097,62 @@ PyCompileString(const char *str, const char *filename, int start)
} }
struct symtable * struct symtable *
Py_SymtableString(const char *str, const char *filename, int start) Py_SymtableStringObject(const char *str, PyObject *filename, int start)
{ {
struct symtable *st; struct symtable *st;
mod_ty mod; mod_ty mod;
PyCompilerFlags flags; PyCompilerFlags flags;
PyArena *arena = PyArena_New(); PyArena *arena;
arena = PyArena_New();
if (arena == NULL) if (arena == NULL)
return NULL; return NULL;
flags.cf_flags = 0; flags.cf_flags = 0;
mod = PyParser_ASTFromString(str, filename, start, &flags, arena); mod = PyParser_ASTFromStringObject(str, filename, start, &flags, arena);
if (mod == NULL) { if (mod == NULL) {
PyArena_Free(arena); PyArena_Free(arena);
return NULL; return NULL;
} }
st = PySymtable_Build(mod, filename, 0); st = PySymtable_BuildObject(mod, filename, 0);
PyArena_Free(arena); PyArena_Free(arena);
return st; 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. */ /* Preferred access to parser is through AST. */
mod_ty mod_ty
PyParser_ASTFromString(const char *s, const char *filename, int start, PyParser_ASTFromStringObject(const char *s, PyObject *filename, int start,
PyCompilerFlags *flags, PyArena *arena) PyCompilerFlags *flags, PyArena *arena)
{ {
mod_ty mod; mod_ty mod;
PyCompilerFlags localflags; PyCompilerFlags localflags;
perrdetail err; perrdetail err;
int iflags = PARSER_FLAGS(flags); int iflags = PARSER_FLAGS(flags);
node *n = PyParser_ParseStringFlagsFilenameEx(s, filename, node *n = PyParser_ParseStringObject(s, filename,
&_PyParser_Grammar, start, &err, &_PyParser_Grammar, start, &err,
&iflags); &iflags);
if (flags == NULL) { if (flags == NULL) {
localflags.cf_flags = 0; localflags.cf_flags = 0;
flags = &localflags; flags = &localflags;
} }
if (n) { if (n) {
flags->cf_flags |= iflags & PyCF_MASK; flags->cf_flags |= iflags & PyCF_MASK;
mod = PyAST_FromNode(n, flags, filename, arena); mod = PyAST_FromNodeObject(n, flags, filename, arena);
PyNode_Free(n); PyNode_Free(n);
} }
else { else {
...@@ -2135,26 +2164,40 @@ PyParser_ASTFromString(const char *s, const char *filename, int start, ...@@ -2135,26 +2164,40 @@ PyParser_ASTFromString(const char *s, const char *filename, int start,
} }
mod_ty mod_ty
PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc, PyParser_ASTFromString(const char *s, const char *filename_str, int start,
int start, char *ps1, PyCompilerFlags *flags, PyArena *arena)
char *ps2, PyCompilerFlags *flags, int *errcode, {
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; mod_ty mod;
PyCompilerFlags localflags; PyCompilerFlags localflags;
perrdetail err; perrdetail err;
int iflags = PARSER_FLAGS(flags); int iflags = PARSER_FLAGS(flags);
node *n = PyParser_ParseFileFlagsEx(fp, filename, enc, node *n = PyParser_ParseFileObject(fp, filename, enc,
&_PyParser_Grammar, &_PyParser_Grammar,
start, ps1, ps2, &err, &iflags); start, ps1, ps2, &err, &iflags);
if (flags == NULL) { if (flags == NULL) {
localflags.cf_flags = 0; localflags.cf_flags = 0;
flags = &localflags; flags = &localflags;
} }
if (n) { if (n) {
flags->cf_flags |= iflags & PyCF_MASK; flags->cf_flags |= iflags & PyCF_MASK;
mod = PyAST_FromNode(n, flags, filename, arena); mod = PyAST_FromNodeObject(n, flags, filename, arena);
PyNode_Free(n); PyNode_Free(n);
} }
else { else {
...@@ -2167,6 +2210,23 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc, ...@@ -2167,6 +2210,23 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc,
return mod; 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 */ /* Simplified interface to parsefile -- return node or set exception */
node * node *
......
...@@ -233,7 +233,7 @@ symtable_new(void) ...@@ -233,7 +233,7 @@ symtable_new(void)
#define COMPILER_STACK_FRAME_SCALE 3 #define COMPILER_STACK_FRAME_SCALE 3
struct symtable * 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(); struct symtable *st = symtable_new();
asdl_seq *seq; asdl_seq *seq;
...@@ -241,7 +241,12 @@ PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future) ...@@ -241,7 +241,12 @@ PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future)
PyThreadState *tstate; PyThreadState *tstate;
if (st == NULL) if (st == NULL)
return st; return NULL;
if (filename == NULL) {
PySymtable_Free(st);
return NULL;
}
Py_INCREF(filename);
st->st_filename = filename; st->st_filename = filename;
st->st_future = future; st->st_future = future;
...@@ -302,9 +307,23 @@ PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future) ...@@ -302,9 +307,23 @@ PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future)
return NULL; 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 void
PySymtable_Free(struct symtable *st) PySymtable_Free(struct symtable *st)
{ {
Py_XDECREF(st->st_filename);
Py_XDECREF(st->st_blocks); Py_XDECREF(st->st_blocks);
Py_XDECREF(st->st_stack); Py_XDECREF(st->st_stack);
PyMem_Free((void *)st); PyMem_Free((void *)st);
...@@ -354,9 +373,9 @@ error_at_directive(PySTEntryObject *ste, PyObject *name) ...@@ -354,9 +373,9 @@ error_at_directive(PySTEntryObject *ste, PyObject *name)
if (PyTuple_GET_ITEM(data, 0) == name) if (PyTuple_GET_ITEM(data, 0) == name)
break; break;
} }
PyErr_SyntaxLocationEx(ste->ste_table->st_filename, PyErr_SyntaxLocationObject(ste->ste_table->st_filename,
PyLong_AsLong(PyTuple_GET_ITEM(data, 1)), PyLong_AsLong(PyTuple_GET_ITEM(data, 1)),
PyLong_AsLong(PyTuple_GET_ITEM(data, 2))); PyLong_AsLong(PyTuple_GET_ITEM(data, 2)));
return 0; return 0;
} }
...@@ -583,8 +602,9 @@ check_unoptimized(const PySTEntryObject* ste) { ...@@ -583,8 +602,9 @@ check_unoptimized(const PySTEntryObject* ste) {
break; break;
} }
PyErr_SyntaxLocationEx(ste->ste_table->st_filename, ste->ste_opt_lineno, PyErr_SyntaxLocationObject(ste->ste_table->st_filename,
ste->ste_opt_col_offset); ste->ste_opt_lineno,
ste->ste_opt_col_offset);
return 0; return 0;
} }
...@@ -915,15 +935,20 @@ symtable_analyze(struct symtable *st) ...@@ -915,15 +935,20 @@ symtable_analyze(struct symtable *st)
static int static int
symtable_warn(struct symtable *st, char *msg, int lineno) symtable_warn(struct symtable *st, char *msg, int lineno)
{ {
if (PyErr_WarnExplicit(PyExc_SyntaxWarning, msg, st->st_filename, PyObject *message = PyUnicode_FromString(msg);
lineno, NULL, NULL) < 0) { 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)) { if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
PyErr_SetString(PyExc_SyntaxError, msg); PyErr_SetString(PyExc_SyntaxError, msg);
PyErr_SyntaxLocationEx(st->st_filename, st->st_cur->ste_lineno, PyErr_SyntaxLocationObject(st->st_filename, st->st_cur->ste_lineno,
st->st_cur->ste_col_offset); st->st_cur->ste_col_offset);
} }
return 0; return 0;
} }
Py_DECREF(message);
return 1; return 1;
} }
...@@ -1006,9 +1031,9 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag) ...@@ -1006,9 +1031,9 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag)
if ((flag & DEF_PARAM) && (val & DEF_PARAM)) { if ((flag & DEF_PARAM) && (val & DEF_PARAM)) {
/* Is it better to use 'mangled' or 'name' here? */ /* Is it better to use 'mangled' or 'name' here? */
PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT, name); PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT, name);
PyErr_SyntaxLocationEx(st->st_filename, PyErr_SyntaxLocationObject(st->st_filename,
st->st_cur->ste_lineno, st->st_cur->ste_lineno,
st->st_cur->ste_col_offset); st->st_cur->ste_col_offset);
goto error; goto error;
} }
val |= flag; val |= flag;
...@@ -1613,7 +1638,7 @@ symtable_visit_alias(struct symtable *st, alias_ty a) ...@@ -1613,7 +1638,7 @@ symtable_visit_alias(struct symtable *st, alias_ty a)
int lineno = st->st_cur->ste_lineno; int lineno = st->st_cur->ste_lineno;
int col_offset = st->st_cur->ste_col_offset; int col_offset = st->st_cur->ste_col_offset;
PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING); 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); Py_DECREF(store_name);
return 0; return 0;
} }
......
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