aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Python/pythonrun.c
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-04-18 12:39:32 +0300
committershadchin <shadchin@yandex-team.ru>2022-04-18 12:39:32 +0300
commitd4be68e361f4258cf0848fc70018dfe37a2acc24 (patch)
tree153e294cd97ac8b5d7a989612704a0c1f58e8ad4 /contrib/tools/python3/src/Python/pythonrun.c
parent260c02f5ccf242d9d9b8a873afaf6588c00237d6 (diff)
downloadydb-d4be68e361f4258cf0848fc70018dfe37a2acc24.tar.gz
IGNIETFERRO-1816 Update Python 3 from 3.9.12 to 3.10.4
ref:9f96be6d02ee8044fdd6f124b799b270c20ce641
Diffstat (limited to 'contrib/tools/python3/src/Python/pythonrun.c')
-rw-r--r--contrib/tools/python3/src/Python/pythonrun.c669
1 files changed, 189 insertions, 480 deletions
diff --git a/contrib/tools/python3/src/Python/pythonrun.c b/contrib/tools/python3/src/Python/pythonrun.c
index 364101e99d..0f1794acec 100644
--- a/contrib/tools/python3/src/Python/pythonrun.c
+++ b/contrib/tools/python3/src/Python/pythonrun.c
@@ -10,28 +10,22 @@
#include "Python.h"
-#include "Python-ast.h"
-#undef Yield /* undefine macro conflicting with <winbase.h> */
-
+#include "pycore_ast.h" // PyAST_mod2obj
+#include "pycore_compile.h" // _PyAST_Compile()
#include "pycore_interp.h" // PyInterpreterState.importlib
#include "pycore_object.h" // _PyDebug_PrintTotalRefs(),
// _PyType_GetQualName()
-#include "pycore_pyerrors.h" // _PyErr_Fetch
+#include "pycore_parser.h" // _PyParser_ASTFromString()
+#include "pycore_pyerrors.h" // _PyErr_Fetch, _Py_Offer_Suggestions
#include "pycore_pylifecycle.h" // _Py_UnhandledKeyboardInterrupt
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_sysmodule.h" // _PySys_Audit()
-#include "node.h" // node
#include "token.h" // INDENT
-#include "parsetok.h" // perrdetail
#include "errcode.h" // E_EOF
#include "code.h" // PyCodeObject
-#include "symtable.h" // PySymtable_BuildObject()
-#include "ast.h" // PyAST_FromNodeObject()
#include "marshal.h" // PyMarshal_ReadLongFromFile()
-#include "pegen_interface.h" // PyPegen_ASTFrom*
-
#ifdef MS_WINDOWS
# include "malloc.h" // alloca()
#endif
@@ -59,60 +53,81 @@ _Py_static_string(PyId_string, "<string>");
extern "C" {
#endif
-extern Py_EXPORTED_SYMBOL grammar _PyParser_Grammar; /* From graminit.c */
-
/* Forward */
static void flush_io(void);
static PyObject *run_mod(mod_ty, PyObject *, PyObject *, PyObject *,
PyCompilerFlags *, PyArena *);
static PyObject *run_pyc_file(FILE *, PyObject *, PyObject *,
PyCompilerFlags *);
-static void err_input(perrdetail *);
-static void err_free(perrdetail *);
static int PyRun_InteractiveOneObjectEx(FILE *, PyObject *, PyCompilerFlags *);
static PyObject* pyrun_file(FILE *fp, PyObject *filename, int start,
PyObject *globals, PyObject *locals, int closeit,
PyCompilerFlags *flags);
-/* Parse input from a file and execute it */
int
-PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit,
+_PyRun_AnyFileObject(FILE *fp, PyObject *filename, int closeit,
PyCompilerFlags *flags)
{
- if (filename == NULL)
- filename = "???";
- if (Py_FdIsInteractive(fp, filename)) {
- int err = PyRun_InteractiveLoopFlags(fp, filename, flags);
- if (closeit)
+ int decref_filename = 0;
+ if (filename == NULL) {
+ filename = PyUnicode_FromString("???");
+ if (filename == NULL) {
+ PyErr_Print();
+ return -1;
+ }
+ decref_filename = 1;
+ }
+
+ int res;
+ if (_Py_FdIsInteractive(fp, filename)) {
+ res = _PyRun_InteractiveLoopObject(fp, filename, flags);
+ if (closeit) {
fclose(fp);
- return err;
+ }
}
- else
- return PyRun_SimpleFileExFlags(fp, filename, closeit, flags);
+ else {
+ res = _PyRun_SimpleFileObject(fp, filename, closeit, flags);
+ }
+
+ if (decref_filename) {
+ Py_DECREF(filename);
+ }
+ return res;
}
+
+/* Parse input from a file and execute it */
int
-PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags)
+PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit,
+ PyCompilerFlags *flags)
{
- PyObject *filename, *v;
- int ret, err;
- PyCompilerFlags local_flags = _PyCompilerFlags_INIT;
- int nomem_count = 0;
-#ifdef Py_REF_DEBUG
- int show_ref_count = _Py_GetConfig()->show_ref_count;
-#endif
-
- filename = PyUnicode_DecodeFSDefault(filename_str);
- if (filename == NULL) {
- PyErr_Print();
- return -1;
+ PyObject *filename_obj;
+ if (filename != NULL) {
+ filename_obj = PyUnicode_DecodeFSDefault(filename);
+ if (filename_obj == NULL) {
+ PyErr_Print();
+ return -1;
+ }
}
+ else {
+ filename_obj = NULL;
+ }
+ int res = _PyRun_AnyFileObject(fp, filename_obj, closeit, flags);
+ Py_XDECREF(filename_obj);
+ return res;
+}
+
+int
+_PyRun_InteractiveLoopObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
+{
+ PyCompilerFlags local_flags = _PyCompilerFlags_INIT;
if (flags == NULL) {
flags = &local_flags;
}
- v = _PySys_GetObjectId(&PyId_ps1);
+
+ PyObject *v = _PySys_GetObjectId(&PyId_ps1);
if (v == NULL) {
_PySys_SetObjectId(&PyId_ps1, v = PyUnicode_FromString(">>> "));
Py_XDECREF(v);
@@ -122,7 +137,13 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *
_PySys_SetObjectId(&PyId_ps2, v = PyUnicode_FromString("... "));
Py_XDECREF(v);
}
- err = 0;
+
+#ifdef Py_REF_DEBUG
+ int show_ref_count = _Py_GetConfig()->show_ref_count;
+#endif
+ int err = 0;
+ int ret;
+ int nomem_count = 0;
do {
ret = PyRun_InteractiveOneObjectEx(fp, filename, flags);
if (ret == -1 && PyErr_Occurred()) {
@@ -149,35 +170,25 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *
}
#endif
} while (ret != E_EOF);
- Py_DECREF(filename);
return err;
}
-/* compute parser flags based on compiler flags */
-static int PARSER_FLAGS(PyCompilerFlags *flags)
+
+int
+PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
{
- int parser_flags = 0;
- if (!flags)
- return 0;
- if (flags->cf_flags & PyCF_DONT_IMPLY_DEDENT)
- parser_flags |= PyPARSE_DONT_IMPLY_DEDENT;
- if (flags->cf_flags & PyCF_IGNORE_COOKIE)
- parser_flags |= PyPARSE_IGNORE_COOKIE;
- if (flags->cf_flags & CO_FUTURE_BARRY_AS_BDFL)
- parser_flags |= PyPARSE_BARRY_AS_BDFL;
- if (flags->cf_flags & PyCF_TYPE_COMMENTS)
- parser_flags |= PyPARSE_TYPE_COMMENTS;
- return parser_flags;
+ PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename);
+ if (filename_obj == NULL) {
+ PyErr_Print();
+ return -1;
+ }
+
+ int err = _PyRun_InteractiveLoopObject(fp, filename_obj, flags);
+ Py_DECREF(filename_obj);
+ return err;
+
}
-#if 0
-/* Keep an example of flags with future keyword support. */
-#define PARSER_FLAGS(flags) \
- ((flags) ? ((((flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \
- PyPARSE_DONT_IMPLY_DEDENT : 0) \
- | ((flags)->cf_flags & CO_FUTURE_WITH_STATEMENT ? \
- PyPARSE_WITH_IS_KEYWORD : 0)) : 0)
-#endif
/* A PyRun_InteractiveOneObject() auxiliary function that does not print the
* error on failure. */
@@ -190,7 +201,6 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename,
PyArena *arena;
const char *ps1 = "", *ps2 = "", *enc = NULL;
int errcode = 0;
- int use_peg = _PyInterpreterState_GET()->config._use_peg_parser;
_Py_IDENTIFIER(encoding);
_Py_IDENTIFIER(__main__);
@@ -236,7 +246,7 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename,
}
}
}
- arena = PyArena_New();
+ arena = _PyArena_New();
if (arena == NULL) {
Py_XDECREF(v);
Py_XDECREF(w);
@@ -244,21 +254,14 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename,
return -1;
}
- if (use_peg) {
- mod = PyPegen_ASTFromFileObject(fp, filename, Py_single_input,
- enc, ps1, ps2, flags, &errcode, arena);
- }
- else {
- mod = PyParser_ASTFromFileObject(fp, filename, enc,
- Py_single_input, ps1, ps2,
- flags, &errcode, arena);
- }
+ mod = _PyParser_ASTFromFile(fp, filename, enc, Py_single_input,
+ ps1, ps2, flags, &errcode, arena);
Py_XDECREF(v);
Py_XDECREF(w);
Py_XDECREF(oenc);
if (mod == NULL) {
- PyArena_Free(arena);
+ _PyArena_Free(arena);
if (errcode == E_EOF) {
PyErr_Clear();
return E_EOF;
@@ -267,12 +270,12 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename,
}
m = PyImport_AddModuleObject(mod_name);
if (m == NULL) {
- PyArena_Free(arena);
+ _PyArena_Free(arena);
return -1;
}
d = PyModule_GetDict(m);
v = run_mod(mod, filename, d, d, flags, arena);
- PyArena_Free(arena);
+ _PyArena_Free(arena);
if (v == NULL) {
return -1;
}
@@ -392,9 +395,9 @@ set_main_loader(PyObject *d, PyObject *filename, const char *loader_name)
}
-static int
-pyrun_simple_file(FILE *fp, PyObject *filename, int closeit,
- PyCompilerFlags *flags)
+int
+_PyRun_SimpleFileObject(FILE *fp, PyObject *filename, int closeit,
+ PyCompilerFlags *flags)
{
PyObject *m, *d, *v;
int set_file_name = 0, ret = -1;
@@ -404,7 +407,10 @@ pyrun_simple_file(FILE *fp, PyObject *filename, int closeit,
return -1;
Py_INCREF(m);
d = PyModule_GetDict(m);
- if (PyDict_GetItemString(d, "__file__") == NULL) {
+ if (_PyDict_GetItemStringWithError(d, "__file__") == NULL) {
+ if (PyErr_Occurred()) {
+ goto done;
+ }
if (PyDict_SetItemString(d, "__file__", filename) < 0) {
goto done;
}
@@ -480,7 +486,7 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
if (filename_obj == NULL) {
return -1;
}
- int res = pyrun_simple_file(fp, filename_obj, closeit, flags);
+ int res = _PyRun_SimpleFileObject(fp, filename_obj, closeit, flags);
Py_DECREF(filename_obj);
return res;
}
@@ -505,7 +511,9 @@ PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
static int
parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename,
- Py_ssize_t *lineno, Py_ssize_t *offset, PyObject **text)
+ Py_ssize_t *lineno, Py_ssize_t *offset,
+ Py_ssize_t* end_lineno, Py_ssize_t* end_offset,
+ PyObject **text)
{
Py_ssize_t hold;
PyObject *v;
@@ -513,6 +521,8 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename,
_Py_IDENTIFIER(filename);
_Py_IDENTIFIER(lineno);
_Py_IDENTIFIER(offset);
+ _Py_IDENTIFIER(end_lineno);
+ _Py_IDENTIFIER(end_offset);
_Py_IDENTIFIER(text);
*message = NULL;
@@ -560,6 +570,44 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename,
*offset = hold;
}
+ if (Py_TYPE(err) == (PyTypeObject*)PyExc_SyntaxError) {
+ v = _PyObject_GetAttrId(err, &PyId_end_lineno);
+ if (!v) {
+ PyErr_Clear();
+ *end_lineno = *lineno;
+ }
+ else if (v == Py_None) {
+ *end_lineno = *lineno;
+ Py_DECREF(v);
+ } else {
+ hold = PyLong_AsSsize_t(v);
+ Py_DECREF(v);
+ if (hold < 0 && PyErr_Occurred())
+ goto finally;
+ *end_lineno = hold;
+ }
+
+ v = _PyObject_GetAttrId(err, &PyId_end_offset);
+ if (!v) {
+ PyErr_Clear();
+ *end_offset = -1;
+ }
+ else if (v == Py_None) {
+ *end_offset = -1;
+ Py_DECREF(v);
+ } else {
+ hold = PyLong_AsSsize_t(v);
+ Py_DECREF(v);
+ if (hold < 0 && PyErr_Occurred())
+ goto finally;
+ *end_offset = hold;
+ }
+ } else {
+ // SyntaxError subclasses
+ *end_lineno = *lineno;
+ *end_offset = -1;
+ }
+
v = _PyObject_GetAttrId(err, &PyId_text);
if (!v)
goto finally;
@@ -579,8 +627,9 @@ finally:
}
static void
-print_error_text(PyObject *f, Py_ssize_t offset, PyObject *text_obj)
+print_error_text(PyObject *f, Py_ssize_t offset, Py_ssize_t end_offset, PyObject *text_obj)
{
+ size_t caret_repetitions = (end_offset > 0 && end_offset > offset) ? end_offset - offset : 1;
/* Convert text to a char pointer; return if error */
const char *text = PyUnicode_AsUTF8(text_obj);
if (text == NULL)
@@ -640,7 +689,10 @@ print_error_text(PyObject *f, Py_ssize_t offset, PyObject *text_obj)
while (--offset >= 0) {
PyFile_WriteString(" ", f);
}
- PyFile_WriteString("^\n", f);
+ for (size_t caret_iter=0; caret_iter < caret_repetitions ; caret_iter++) {
+ PyFile_WriteString("^", f);
+ }
+ PyFile_WriteString("\n", f);
}
@@ -838,7 +890,7 @@ static void
print_exception(PyObject *f, PyObject *value)
{
int err = 0;
- PyObject *type, *tb;
+ PyObject *type, *tb, *tmp;
_Py_IDENTIFIER(print_file_and_line);
if (!PyExceptionInstance_Check(value)) {
@@ -857,12 +909,15 @@ print_exception(PyObject *f, PyObject *value)
if (tb && tb != Py_None)
err = PyTraceBack_Print(tb, f);
if (err == 0 &&
- _PyObject_HasAttrId(value, &PyId_print_file_and_line))
+ (err = _PyObject_LookupAttrId(value, &PyId_print_file_and_line, &tmp)) > 0)
{
PyObject *message, *filename, *text;
- Py_ssize_t lineno, offset;
+ Py_ssize_t lineno, offset, end_lineno, end_offset;
+ err = 0;
+ Py_DECREF(tmp);
if (!parse_syntax_error(value, &message, &filename,
- &lineno, &offset, &text))
+ &lineno, &offset,
+ &end_lineno, &end_offset, &text))
PyErr_Clear();
else {
PyObject *line;
@@ -879,7 +934,21 @@ print_exception(PyObject *f, PyObject *value)
}
if (text != NULL) {
- print_error_text(f, offset, text);
+ Py_ssize_t line_size;
+ const char* error_line = PyUnicode_AsUTF8AndSize(text, &line_size);
+ // If the location of the error spawn multiple lines, we want
+ // to just print the first one and highlight everything until
+ // the end of that one since we don't support multi-line error
+ // messages.
+ if (end_lineno > lineno) {
+ end_offset = (error_line != NULL) ? line_size : -1;
+ }
+ // Limit the amount of '^' that we can display to
+ // the size of the text in the source line.
+ if (error_line != NULL && end_offset > line_size + 1) {
+ end_offset = line_size + 1;
+ }
+ print_error_text(f, offset, end_offset, text);
Py_DECREF(text);
}
@@ -947,6 +1016,18 @@ print_exception(PyObject *f, PyObject *value)
if (err < 0) {
PyErr_Clear();
}
+ PyObject* suggestions = _Py_Offer_Suggestions(value);
+ if (suggestions) {
+ // Add a trailer ". Did you mean: (...)?"
+ err = PyFile_WriteString(". Did you mean: '", f);
+ if (err == 0) {
+ err = PyFile_WriteObject(suggestions, f, Py_PRINT_RAW);
+ err += PyFile_WriteString("'?", f);
+ }
+ Py_DECREF(suggestions);
+ } else if (PyErr_Occurred()) {
+ PyErr_Clear();
+ }
err += PyFile_WriteString("\n", f);
Py_XDECREF(tb);
Py_DECREF(value);
@@ -1087,26 +1168,20 @@ PyRun_StringFlags(const char *str, int start, PyObject *globals,
mod_ty mod;
PyArena *arena;
PyObject *filename;
- int use_peg = _PyInterpreterState_GET()->config._use_peg_parser;
filename = _PyUnicode_FromId(&PyId_string); /* borrowed */
if (filename == NULL)
return NULL;
- arena = PyArena_New();
+ arena = _PyArena_New();
if (arena == NULL)
return NULL;
- if (use_peg) {
- mod = PyPegen_ASTFromStringObject(str, filename, start, flags, arena);
- }
- else {
- mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena);
- }
+ mod = _PyParser_ASTFromString(str, filename, start, flags, arena);
if (mod != NULL)
ret = run_mod(mod, filename, globals, locals, flags, arena);
- PyArena_Free(arena);
+ _PyArena_Free(arena);
return ret;
}
@@ -1115,21 +1190,14 @@ static PyObject *
pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals,
PyObject *locals, int closeit, PyCompilerFlags *flags)
{
- PyArena *arena = PyArena_New();
+ PyArena *arena = _PyArena_New();
if (arena == NULL) {
return NULL;
}
mod_ty mod;
- int use_peg = _PyInterpreterState_GET()->config._use_peg_parser;
- if (use_peg) {
- mod = PyPegen_ASTFromFileObject(fp, filename, start, NULL, NULL, NULL,
- flags, NULL, arena);
- }
- else {
- mod = PyParser_ASTFromFileObject(fp, filename, NULL, start, 0, 0,
- flags, NULL, arena);
- }
+ mod = _PyParser_ASTFromFile(fp, filename, NULL, start, NULL, NULL,
+ flags, NULL, arena);
if (closeit) {
fclose(fp);
@@ -1142,7 +1210,7 @@ pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals,
else {
ret = NULL;
}
- PyArena_Free(arena);
+ _PyArena_Free(arena);
return ret;
}
@@ -1211,9 +1279,11 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py
_Py_UnhandledKeyboardInterrupt = 0;
/* Set globals['__builtins__'] if it doesn't exist */
- if (globals != NULL && PyDict_GetItemString(globals, "__builtins__") == NULL) {
- if (PyDict_SetItemString(globals, "__builtins__",
- tstate->interp->builtins) < 0) {
+ if (globals != NULL && _PyDict_GetItemStringWithError(globals, "__builtins__") == NULL) {
+ if (PyErr_Occurred() ||
+ PyDict_SetItemString(globals, "__builtins__",
+ tstate->interp->builtins) < 0)
+ {
return NULL;
}
}
@@ -1230,7 +1300,7 @@ run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals,
PyCompilerFlags *flags, PyArena *arena)
{
PyThreadState *tstate = _PyThreadState_GET();
- PyCodeObject *co = PyAST_CompileObject(mod, filename, flags, -1, arena);
+ PyCodeObject *co = _PyAST_Compile(mod, filename, flags, -1, arena);
if (co == NULL)
return NULL;
@@ -1293,28 +1363,22 @@ Py_CompileStringObject(const char *str, PyObject *filename, int start,
{
PyCodeObject *co;
mod_ty mod;
- int use_peg = _PyInterpreterState_GET()->config._use_peg_parser;
- PyArena *arena = PyArena_New();
+ PyArena *arena = _PyArena_New();
if (arena == NULL)
return NULL;
- if (use_peg) {
- mod = PyPegen_ASTFromStringObject(str, filename, start, flags, arena);
- }
- else {
- mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena);
- }
+ mod = _PyParser_ASTFromString(str, filename, start, flags, arena);
if (mod == NULL) {
- PyArena_Free(arena);
+ _PyArena_Free(arena);
return NULL;
}
if (flags && (flags->cf_flags & PyCF_ONLY_AST)) {
PyObject *result = PyAST_mod2obj(mod);
- PyArena_Free(arena);
+ _PyArena_Free(arena);
return result;
}
- co = PyAST_CompileObject(mod, filename, flags, optimize, arena);
- PyArena_Free(arena);
+ co = _PyAST_Compile(mod, filename, flags, optimize, arena);
+ _PyArena_Free(arena);
return (PyObject *)co;
}
@@ -1331,14 +1395,6 @@ Py_CompileStringExFlags(const char *str, const char *filename_str, int start,
return co;
}
-/* For use in Py_LIMITED_API */
-#undef Py_CompileString
-PyObject *
-PyCompileString(const char *str, const char *filename, int start)
-{
- return Py_CompileStringFlags(str, filename, start, NULL);
-}
-
const char *
_Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, PyObject **cmd_copy)
{
@@ -1388,339 +1444,6 @@ _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyComp
return str;
}
-struct symtable *
-Py_SymtableStringObject(const char *str, PyObject *filename, int start)
-{
- PyCompilerFlags flags = _PyCompilerFlags_INIT;
- return _Py_SymtableStringObjectFlags(str, filename, start, &flags);
-}
-
-struct symtable *
-_Py_SymtableStringObjectFlags(const char *str, PyObject *filename, int start, PyCompilerFlags *flags)
-{
- struct symtable *st;
- mod_ty mod;
- int use_peg = _PyInterpreterState_GET()->config._use_peg_parser;
- PyArena *arena;
-
- arena = PyArena_New();
- if (arena == NULL)
- return NULL;
-
- if (use_peg) {
- mod = PyPegen_ASTFromStringObject(str, filename, start, flags, arena);
- }
- else {
- mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena);
- }
- if (mod == NULL) {
- PyArena_Free(arena);
- return NULL;
- }
- 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_ASTFromStringObject(const char *s, PyObject *filename, int start,
- PyCompilerFlags *flags, PyArena *arena)
-{
- mod_ty mod;
- PyCompilerFlags localflags = _PyCompilerFlags_INIT;
- perrdetail err;
- int iflags = PARSER_FLAGS(flags);
- if (flags && (flags->cf_flags & PyCF_ONLY_AST) && flags->cf_feature_version < 7)
- iflags |= PyPARSE_ASYNC_HACKS;
-
- node *n = PyParser_ParseStringObject(s, filename,
- &_PyParser_Grammar, start, &err,
- &iflags);
- if (flags == NULL) {
- flags = &localflags;
- }
- if (n) {
- flags->cf_flags |= iflags & PyCF_MASK;
- mod = PyAST_FromNodeObject(n, flags, filename, arena);
- PyNode_Free(n);
- }
- else {
- err_input(&err);
- mod = NULL;
- }
- err_free(&err);
- return mod;
-}
-
-mod_ty
-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, const char *ps1,
- const char *ps2, PyCompilerFlags *flags, int *errcode,
- PyArena *arena)
-{
- mod_ty mod;
- PyCompilerFlags localflags = _PyCompilerFlags_INIT;
- perrdetail err;
- int iflags = PARSER_FLAGS(flags);
-
- node *n = PyParser_ParseFileObject(fp, filename, enc,
- &_PyParser_Grammar,
- start, ps1, ps2, &err, &iflags);
- if (flags == NULL) {
- flags = &localflags;
- }
- if (n) {
- flags->cf_flags |= iflags & PyCF_MASK;
- mod = PyAST_FromNodeObject(n, flags, filename, arena);
- PyNode_Free(n);
- }
- else {
- err_input(&err);
- if (errcode)
- *errcode = err.error;
- mod = NULL;
- }
- err_free(&err);
- return mod;
-}
-
-mod_ty
-PyParser_ASTFromFile(FILE *fp, const char *filename_str, const char* enc,
- int start, const char *ps1,
- const 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 *
-PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags)
-{
- perrdetail err;
- node *n = PyParser_ParseFileFlags(fp, filename, NULL,
- &_PyParser_Grammar,
- start, NULL, NULL, &err, flags);
- if (n == NULL)
- err_input(&err);
- err_free(&err);
-
- return n;
-}
-
-/* Simplified interface to parsestring -- return node or set exception */
-
-node *
-PyParser_SimpleParseStringFlags(const char *str, int start, int flags)
-{
- perrdetail err;
- node *n = PyParser_ParseStringFlags(str, &_PyParser_Grammar,
- start, &err, flags);
- if (n == NULL)
- err_input(&err);
- err_free(&err);
- return n;
-}
-
-node *
-PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename,
- int start, int flags)
-{
- perrdetail err;
- node *n = PyParser_ParseStringFlagsFilename(str, filename,
- &_PyParser_Grammar, start, &err, flags);
- if (n == NULL)
- err_input(&err);
- err_free(&err);
- return n;
-}
-
-/* May want to move a more generalized form of this to parsetok.c or
- even parser modules. */
-
-void
-PyParser_ClearError(perrdetail *err)
-{
- err_free(err);
-}
-
-void
-PyParser_SetError(perrdetail *err)
-{
- err_input(err);
-}
-
-static void
-err_free(perrdetail *err)
-{
- Py_CLEAR(err->filename);
-}
-
-/* Set the error appropriate to the given input error code (see errcode.h) */
-
-static void
-err_input(perrdetail *err)
-{
- PyObject *v, *w, *errtype, *errtext;
- PyObject *msg_obj = NULL;
- const char *msg = NULL;
- int offset = err->offset;
-
- errtype = PyExc_SyntaxError;
- switch (err->error) {
- case E_ERROR:
- goto cleanup;
- case E_SYNTAX:
- errtype = PyExc_IndentationError;
- if (err->expected == INDENT)
- msg = "expected an indented block";
- else if (err->token == INDENT)
- msg = "unexpected indent";
- else if (err->token == DEDENT)
- msg = "unexpected unindent";
- else if (err->expected == NOTEQUAL) {
- errtype = PyExc_SyntaxError;
- msg = "with Barry as BDFL, use '<>' instead of '!='";
- }
- else {
- errtype = PyExc_SyntaxError;
- msg = "invalid syntax";
- }
- break;
- case E_TOKEN:
- msg = "invalid token";
- break;
- case E_EOFS:
- msg = "EOF while scanning triple-quoted string literal";
- break;
- case E_EOLS:
- msg = "EOL while scanning string literal";
- break;
- case E_INTR:
- if (!PyErr_Occurred())
- PyErr_SetNone(PyExc_KeyboardInterrupt);
- goto cleanup;
- case E_NOMEM:
- PyErr_NoMemory();
- goto cleanup;
- case E_EOF:
- msg = "unexpected EOF while parsing";
- break;
- case E_TABSPACE:
- errtype = PyExc_TabError;
- msg = "inconsistent use of tabs and spaces in indentation";
- break;
- case E_OVERFLOW:
- msg = "expression too long";
- break;
- case E_DEDENT:
- errtype = PyExc_IndentationError;
- msg = "unindent does not match any outer indentation level";
- break;
- case E_TOODEEP:
- errtype = PyExc_IndentationError;
- msg = "too many levels of indentation";
- break;
- case E_DECODE: {
- PyObject *type, *value, *tb;
- PyErr_Fetch(&type, &value, &tb);
- msg = "unknown decode error";
- if (value != NULL)
- msg_obj = PyObject_Str(value);
- Py_XDECREF(type);
- Py_XDECREF(value);
- Py_XDECREF(tb);
- break;
- }
- case E_LINECONT:
- msg = "unexpected character after line continuation character";
- break;
-
- case E_BADSINGLE:
- msg = "multiple statements found while compiling a single statement";
- break;
- default:
- fprintf(stderr, "error=%d\n", err->error);
- msg = "unknown parsing error";
- break;
- }
- /* err->text may not be UTF-8 in case of decoding errors.
- Explicitly convert to an object. */
- if (!err->text) {
- errtext = Py_None;
- Py_INCREF(Py_None);
- } else {
- errtext = PyUnicode_DecodeUTF8(err->text, err->offset,
- "replace");
- if (errtext != NULL) {
- Py_ssize_t len = strlen(err->text);
- offset = (int)PyUnicode_GET_LENGTH(errtext);
- if (len != err->offset) {
- Py_DECREF(errtext);
- errtext = PyUnicode_DecodeUTF8(err->text, len,
- "replace");
- }
- }
- }
- v = Py_BuildValue("(OiiN)", err->filename,
- err->lineno, offset, errtext);
- if (v != NULL) {
- if (msg_obj)
- w = Py_BuildValue("(OO)", msg_obj, v);
- else
- w = Py_BuildValue("(sO)", msg, v);
- } else
- w = NULL;
- Py_XDECREF(v);
- PyErr_SetObject(errtype, w);
- Py_XDECREF(w);
-cleanup:
- Py_XDECREF(msg_obj);
- if (err->text != NULL) {
- PyObject_FREE(err->text);
- err->text = NULL;
- }
-}
-
-
#if defined(USE_STACKCHECK)
#if defined(WIN32) && defined(_MSC_VER)
@@ -1760,20 +1483,6 @@ PyOS_CheckStack(void)
/* Deprecated C API functions still provided for binary compatibility */
-#undef PyParser_SimpleParseFile
-PyAPI_FUNC(node *)
-PyParser_SimpleParseFile(FILE *fp, const char *filename, int start)
-{
- return PyParser_SimpleParseFileFlags(fp, filename, start, 0);
-}
-
-#undef PyParser_SimpleParseString
-PyAPI_FUNC(node *)
-PyParser_SimpleParseString(const char *str, int start)
-{
- return PyParser_SimpleParseStringFlags(str, start, 0);
-}
-
#undef PyRun_AnyFile
PyAPI_FUNC(int)
PyRun_AnyFile(FILE *fp, const char *name)