Close #11619: The parser and the import machinery do not encode Unicode
filenames anymore on Windows.
This commit is contained in:
parent
33824f6fd7
commit
14e461d5b9
|
@ -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
|
||||
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)
|
||||
|
@ -267,7 +267,7 @@ in various ways. There is a separate error indicator for each thread.
|
|||
|
||||
Similar to :c:func:`PyErr_SetFromWindowsErrWithFilenameObject`, but the
|
||||
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)
|
||||
|
@ -293,20 +293,27 @@ in various ways. There is a separate error indicator for each thread.
|
|||
.. 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.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)
|
||||
|
||||
Like :c:func:`PyErr_SyntaxLocationExc`, but the col_offset parameter is
|
||||
Like :c:func:`PyErr_SyntaxLocationEx`, but the col_offset parameter is
|
||||
omitted.
|
||||
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
||||
.. 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
|
||||
:func:`warnings.warn_explicit`, see there for more information. The *module*
|
||||
and *registry* arguments may be set to *NULL* to get the default effect
|
||||
described there. *message* and *module* are UTF-8 encoded strings,
|
||||
*filename* is decoded from the filesystem encoding
|
||||
(:func:`sys.getfilesystemencoding`).
|
||||
described there.
|
||||
|
||||
.. 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, ...)
|
||||
|
|
|
@ -258,16 +258,15 @@ the same library that the Python runtime is using.
|
|||
*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
|
||||
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`,
|
||||
: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
|
||||
:exc:`SyntaxError` exception messages, it is decoded from the filesystem
|
||||
encoding (:func:`sys.getfilesystemencoding`). This returns *NULL* if the
|
||||
code cannot be parsed or compiled.
|
||||
:exc:`SyntaxError` exception messages. This returns *NULL* if the code
|
||||
cannot be parsed or compiled.
|
||||
|
||||
The integer *optimize* specifies the optimization level of the compiler; a
|
||||
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.
|
|||
``__debug__`` is true), ``1`` (asserts are removed, ``__debug__`` is false)
|
||||
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)
|
||||
|
||||
This is a simplified interface to :c:func:`PyEval_EvalCodeEx`, with just
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -36,7 +36,20 @@ PyAPI_FUNC(PyCodeObject *) PyAST_CompileEx(
|
|||
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);
|
||||
|
|
|
@ -42,10 +42,16 @@ PyAPI_FUNC(node *) PyParser_ParseFile (FILE *, const char *, grammar *, int,
|
|||
|
||||
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_ParseFileFlagsEx(
|
|||
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_ParseStringFlagsFilenameEx(
|
|||
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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -66,6 +66,12 @@ PyAPI_FUNC(struct _mod *) PyParser_ASTFromString(
|
|||
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_ASTFromFile(
|
|||
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
|
||||
|
@ -117,11 +133,20 @@ PyAPI_FUNC(PyObject *) Py_CompileStringExFlags(
|
|||
int start,
|
||||
PyCompilerFlags *flags,
|
||||
int optimize);
|
||||
PyAPI_FUNC(PyObject *) Py_CompileStringObject(
|
||||
const char *str,
|
||||
PyObject *filename, int start,
|
||||
PyCompilerFlags *flags,
|
||||
int optimize);
|
||||
#endif
|
||||
PyAPI_FUNC(struct symtable *) Py_SymtableString(
|
||||
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);
|
||||
|
|
|
@ -16,7 +16,7 @@ typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock }
|
|||
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_Build(
|
|||
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 *);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -22,7 +22,7 @@ import test.support
|
|||
from test.support import (
|
||||
EnvironmentVarGuard, TESTFN, check_warnings, forget, is_jython,
|
||||
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
|
||||
|
||||
|
||||
|
@ -1055,6 +1055,14 @@ class ImportTracebackTests(unittest.TestCase):
|
|||
finally:
|
||||
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__':
|
||||
# Test needs to be a package, so we can do relative imports.
|
||||
|
|
|
@ -10,6 +10,9 @@ Projected Release date: 2013-09-08
|
|||
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
|
||||
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)
|
|||
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 = "<syntax-tree>";
|
||||
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);
|
||||
ok = PyArg_ParseTupleAndKeywords(args, kw, "|O&:compile", &keywords[1],
|
||||
PyUnicode_FSDecoder, &filename);
|
||||
if (!ok)
|
||||
goto error;
|
||||
|
||||
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);
|
||||
}
|
||||
if (filename == NULL) {
|
||||
filename = PyUnicode_FromString("<syntax-tree>");
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -11,12 +11,12 @@ symtable_symtable(PyObject *self, PyObject *args)
|
|||
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, PyObject *args)
|
|||
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;
|
||||
|
|
|
@ -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 char *s, const char *filename,
|
|||
}
|
||||
|
||||
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,29 @@ PyParser_ParseStringFlagsFilenameEx(const char *s, const char *filename,
|
|||
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. */
|
||||
|
||||
node *
|
||||
|
@ -88,9 +111,10 @@ PyParser_ParseFileFlags(FILE *fp, const char *filename, const char *enc,
|
|||
}
|
||||
|
||||
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 +132,30 @@ PyParser_ParseFileFlagsEx(FILE *fp, const char *filename,
|
|||
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
|
||||
#if 0
|
||||
static char with_msg[] =
|
||||
|
@ -306,7 +354,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 +363,16 @@ initerr(perrdetail *err_ret, const char *filename)
|
|||
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("<string>");
|
||||
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;
|
||||
|
|
|
@ -707,14 +707,14 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -785,12 +785,27 @@ PyErr_Warn(PyObject *category, char *text)
|
|||
}
|
||||
|
||||
/* 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, const char *text,
|
|||
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);
|
||||
|
|
37
Python/ast.c
37
Python/ast.c
|
@ -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, PyCompilerFlags *flags, const char *filename,
|
|||
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, PyCompilerFlags *flags, const char *filename,
|
|||
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.)
|
||||
*/
|
||||
|
||||
|
|
|
@ -579,8 +579,7 @@ static PyObject *
|
|||
builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
char *str;
|
||||
PyObject *filename_obj;
|
||||
char *filename;
|
||||
PyObject *filename;
|
||||
char *startstr;
|
||||
int mode = -1;
|
||||
int dont_inherit = 0;
|
||||
|
@ -596,12 +595,11 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&s|iii:compile", kwlist,
|
||||
&cmd,
|
||||
PyUnicode_FSConverter, &filename_obj,
|
||||
PyUnicode_FSDecoder, &filename,
|
||||
&startstr, &supplied_flags,
|
||||
&dont_inherit, &optimize))
|
||||
return NULL;
|
||||
|
||||
filename = PyBytes_AS_STRING(filename_obj);
|
||||
cf.cf_flags = supplied_flags | PyCF_SOURCE_IS_UTF8;
|
||||
|
||||
if (supplied_flags &
|
||||
|
@ -659,8 +657,8 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
PyArena_Free(arena);
|
||||
goto error;
|
||||
}
|
||||
result = (PyObject*)PyAST_CompileEx(mod, filename,
|
||||
&cf, optimize, arena);
|
||||
result = (PyObject*)PyAST_CompileObject(mod, filename,
|
||||
&cf, optimize, arena);
|
||||
PyArena_Free(arena);
|
||||
}
|
||||
goto finally;
|
||||
|
@ -670,13 +668,13 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
if (str == NULL)
|
||||
goto error;
|
||||
|
||||
result = Py_CompileStringExFlags(str, filename, start[mode], &cf, optimize);
|
||||
result = Py_CompileStringObject(str, filename, start[mode], &cf, optimize);
|
||||
goto finally;
|
||||
|
||||
error:
|
||||
result = NULL;
|
||||
finally:
|
||||
Py_DECREF(filename_obj);
|
||||
Py_DECREF(filename);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 *filename, PyCompilerFlags *flags,
|
|||
|
||||
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 *filename, PyCompilerFlags *flags,
|
|||
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");
|
||||
|
@ -338,6 +335,21 @@ PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags,
|
|||
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 *
|
||||
PyNode_Compile(struct _node *n, const char *filename)
|
||||
{
|
||||
|
@ -360,8 +372,7 @@ 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_XDECREF(c->c_filename);
|
||||
Py_DECREF(c->c_stack);
|
||||
}
|
||||
|
||||
|
@ -1368,12 +1379,11 @@ get_ref_type(struct compiler *c, PyObject *name)
|
|||
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_ty s)
|
|||
{
|
||||
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_ty s)
|
|||
}
|
||||
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 char *errstr)
|
|||
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 assembler *a)
|
|||
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:
|
||||
|
|
|
@ -901,7 +901,8 @@ extern PyObject *PyModule_GetWarningsModule(void);
|
|||
|
||||
|
||||
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 *filename, int lineno) {
|
|||
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 *filename, int lineno, int col_offset)
|
|||
}
|
||||
}
|
||||
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 *filename, int lineno, int col_offset)
|
|||
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 *filename, int lineno, int col_offset)
|
|||
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, int lineno)
|
|||
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
|
||||
|
|
|
@ -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 *ff, stmt_ty s, const char *filename)
|
|||
} 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 *ff, stmt_ty s, const char *filename)
|
|||
}
|
||||
|
||||
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_ty mod, const char *filename)
|
|||
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_ty mod, const char *filename)
|
|||
|
||||
|
||||
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 *filename)
|
|||
}
|
||||
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,
|
|||
}
|
||||
|
||||
PyObject *
|
||||
Py_CompileStringExFlags(const char *str, const char *filename, int start,
|
||||
PyCompilerFlags *flags, int optimize)
|
||||
Py_CompileStringObject(const char *str, PyObject *filename, int start,
|
||||
PyCompilerFlags *flags, int optimize)
|
||||
{
|
||||
PyCodeObject *co;
|
||||
mod_ty mod;
|
||||
|
@ -2060,7 +2060,7 @@ Py_CompileStringExFlags(const char *str, const char *filename, int start,
|
|||
if (arena == NULL)
|
||||
return NULL;
|
||||
|
||||
mod = PyParser_ASTFromString(str, filename, start, flags, arena);
|
||||
mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena);
|
||||
if (mod == NULL) {
|
||||
PyArena_Free(arena);
|
||||
return NULL;
|
||||
|
@ -2070,11 +2070,24 @@ Py_CompileStringExFlags(const char *str, const char *filename, int start,
|
|||
PyArena_Free(arena);
|
||||
return result;
|
||||
}
|
||||
co = PyAST_CompileEx(mod, filename, flags, optimize, arena);
|
||||
co = PyAST_CompileObject(mod, filename, flags, optimize, arena);
|
||||
PyArena_Free(arena);
|
||||
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 */
|
||||
#undef Py_CompileString
|
||||
PyObject *
|
||||
|
@ -2084,46 +2097,62 @@ PyCompileString(const char *str, const char *filename, int start)
|
|||
}
|
||||
|
||||
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 +2164,40 @@ PyParser_ASTFromString(const char *s, const char *filename, int start,
|
|||
}
|
||||
|
||||
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 +2210,23 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc,
|
|||
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 *
|
||||
|
|
|
@ -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 *filename, PyFutureFeatures *future)
|
|||
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 *filename, PyFutureFeatures *future)
|
|||
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, PyObject *name)
|
|||
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* ste) {
|
|||
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, PyObject *name, int flag)
|
|||
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, alias_ty a)
|
|||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue