diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 05e7b4370869afd..0355d776504f4cc 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -179,90 +179,118 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flag } -/* A PyRun_InteractiveOneObject() auxiliary function that does not print the - * error on failure. */ +// Call _PyParser_ASTFromFile() with sys.stdin.encoding, sys.ps1 and sys.ps2 static int -PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, - PyCompilerFlags *flags) +pyrun_one_parse_ast(FILE *fp, PyObject *filename, + PyCompilerFlags *flags, PyArena *arena, mod_ty *pmod) { - PyObject *m, *d, *v, *w, *oenc = NULL; - mod_ty mod; - PyArena *arena; - const char *ps1 = "", *ps2 = "", *enc = NULL; - int errcode = 0; PyThreadState *tstate = _PyThreadState_GET(); + // Get sys.stdin.encoding (as UTF-8) + PyObject *attr; // borrowed ref + PyObject *encoding_obj = NULL; + const char *encoding = NULL; if (fp == stdin) { - /* Fetch encoding from sys.stdin if possible. */ - v = _PySys_GetAttr(tstate, &_Py_ID(stdin)); - if (v && v != Py_None) { - oenc = PyObject_GetAttr(v, &_Py_ID(encoding)); - if (oenc) - enc = PyUnicode_AsUTF8(oenc); - if (!enc) - PyErr_Clear(); + attr = _PySys_GetAttr(tstate, &_Py_ID(stdin)); + if (attr && attr != Py_None) { + encoding_obj = PyObject_GetAttr(attr, &_Py_ID(encoding)); + if (encoding_obj) { + encoding = PyUnicode_AsUTF8(encoding_obj); + if (!encoding) { + PyErr_Clear(); + } + } } } - v = _PySys_GetAttr(tstate, &_Py_ID(ps1)); - if (v != NULL) { - v = PyObject_Str(v); - if (v == NULL) + + // Get sys.ps1 (as UTF-8) + attr = _PySys_GetAttr(tstate, &_Py_ID(ps1)); + PyObject *ps1_obj = NULL; + const char *ps1 = ""; + if (attr != NULL) { + ps1_obj = PyObject_Str(attr); + if (ps1_obj == NULL) { PyErr_Clear(); - else if (PyUnicode_Check(v)) { - ps1 = PyUnicode_AsUTF8(v); + } + else if (PyUnicode_Check(ps1_obj)) { + ps1 = PyUnicode_AsUTF8(ps1_obj); if (ps1 == NULL) { PyErr_Clear(); ps1 = ""; } } } - w = _PySys_GetAttr(tstate, &_Py_ID(ps2)); - if (w != NULL) { - w = PyObject_Str(w); - if (w == NULL) + + // Get sys.ps2 (as UTF-8) + attr = _PySys_GetAttr(tstate, &_Py_ID(ps2)); + PyObject *ps2_obj = NULL; + const char *ps2 = ""; + if (attr != NULL) { + ps2_obj = PyObject_Str(attr); + if (ps2_obj == NULL) { PyErr_Clear(); - else if (PyUnicode_Check(w)) { - ps2 = PyUnicode_AsUTF8(w); + } + else if (PyUnicode_Check(ps2_obj)) { + ps2 = PyUnicode_AsUTF8(ps2_obj); if (ps2 == NULL) { PyErr_Clear(); ps2 = ""; } } } - arena = _PyArena_New(); - if (arena == NULL) { - Py_XDECREF(v); - Py_XDECREF(w); - Py_XDECREF(oenc); - return -1; - } - - 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); + int errcode = 0; + *pmod = _PyParser_ASTFromFile(fp, filename, encoding, + Py_single_input, ps1, ps2, + flags, &errcode, arena); + Py_XDECREF(ps1_obj); + Py_XDECREF(ps2_obj); + Py_XDECREF(encoding_obj); + + if (*pmod == NULL) { if (errcode == E_EOF) { PyErr_Clear(); return E_EOF; } return -1; } - m = PyImport_AddModuleObject(&_Py_ID(__main__)); - if (m == NULL) { + return 0; +} + + +/* A PyRun_InteractiveOneObject() auxiliary function that does not print the + * error on failure. */ +static int +PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, + PyCompilerFlags *flags) +{ + PyArena *arena = _PyArena_New(); + if (arena == NULL) { + return -1; + } + + mod_ty mod; + int parse_res = pyrun_one_parse_ast(fp, filename, flags, arena, &mod); + if (parse_res != 0) { + _PyArena_Free(arena); + return parse_res; + } + + PyObject *main_mod = Py_XNewRef(PyImport_AddModuleObject(&_Py_ID(__main__))); + if (main_mod == NULL) { _PyArena_Free(arena); return -1; } - d = PyModule_GetDict(m); - v = run_mod(mod, filename, d, d, flags, arena); + PyObject *main_dict = PyModule_GetDict(main_mod); // borrowed ref + + PyObject *res = run_mod(mod, filename, main_dict, main_dict, flags, arena); _PyArena_Free(arena); - if (v == NULL) { + Py_DECREF(main_mod); + if (res == NULL) { return -1; } - Py_DECREF(v); + Py_DECREF(res); + flush_io(); return 0; } @@ -376,22 +404,22 @@ int _PyRun_SimpleFileObject(FILE *fp, PyObject *filename, int closeit, PyCompilerFlags *flags) { - PyObject *m, *d, *v; - int set_file_name = 0, ret = -1; + int ret = -1; - m = PyImport_AddModule("__main__"); - if (m == NULL) + PyObject *main_module = Py_XNewRef(PyImport_AddModule("__main__")); + if (main_module == NULL) return -1; - Py_INCREF(m); - d = PyModule_GetDict(m); - if (_PyDict_GetItemStringWithError(d, "__file__") == NULL) { + PyObject *dict = PyModule_GetDict(main_module); // borrowed ref + + int set_file_name = 0; + if (_PyDict_GetItemStringWithError(dict, "__file__") == NULL) { if (PyErr_Occurred()) { goto done; } - if (PyDict_SetItemString(d, "__file__", filename) < 0) { + if (PyDict_SetItemString(dict, "__file__", filename) < 0) { goto done; } - if (PyDict_SetItemString(d, "__cached__", Py_None) < 0) { + if (PyDict_SetItemString(dict, "__cached__", Py_None) < 0) { goto done; } set_file_name = 1; @@ -402,6 +430,7 @@ _PyRun_SimpleFileObject(FILE *fp, PyObject *filename, int closeit, goto done; } + PyObject *v; if (pyc) { FILE *pyc_fp; /* Try to run a pyc file. First, re-open in binary */ @@ -415,42 +444,43 @@ _PyRun_SimpleFileObject(FILE *fp, PyObject *filename, int closeit, goto done; } - if (set_main_loader(d, filename, "SourcelessFileLoader") < 0) { + if (set_main_loader(dict, filename, "SourcelessFileLoader") < 0) { fprintf(stderr, "python: failed to set __main__.__loader__\n"); ret = -1; fclose(pyc_fp); goto done; } - v = run_pyc_file(pyc_fp, d, d, flags); + v = run_pyc_file(pyc_fp, dict, dict, flags); } else { /* When running from stdin, leave __main__.__loader__ alone */ if (PyUnicode_CompareWithASCIIString(filename, "") != 0 && - set_main_loader(d, filename, "SourceFileLoader") < 0) { + set_main_loader(dict, filename, "SourceFileLoader") < 0) { fprintf(stderr, "python: failed to set __main__.__loader__\n"); ret = -1; goto done; } - v = pyrun_file(fp, filename, Py_file_input, d, d, + v = pyrun_file(fp, filename, Py_file_input, dict, dict, closeit, flags); } flush_io(); if (v == NULL) { - Py_CLEAR(m); + Py_CLEAR(main_module); PyErr_Print(); goto done; } Py_DECREF(v); ret = 0; + done: if (set_file_name) { - if (PyDict_DelItemString(d, "__file__")) { + if (PyDict_DelItemString(dict, "__file__")) { PyErr_Clear(); } - if (PyDict_DelItemString(d, "__cached__")) { + if (PyDict_DelItemString(dict, "__cached__")) { PyErr_Clear(); } } - Py_XDECREF(m); + Py_XDECREF(main_module); return ret; } @@ -472,17 +502,21 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, int PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags) { - PyObject *m, *d, *v; - m = PyImport_AddModule("__main__"); - if (m == NULL) + PyObject *main_module = Py_XNewRef(PyImport_AddModule("__main__")); + if (main_module == NULL) { return -1; - d = PyModule_GetDict(m); - v = PyRun_StringFlags(command, Py_file_input, d, d, flags); - if (v == NULL) { + } + PyObject *dict = PyModule_GetDict(main_module); // borrowed ref + + PyObject *res = PyRun_StringFlags(command, Py_file_input, + dict, dict, flags); + Py_DECREF(main_module); + if (res == NULL) { PyErr_Print(); return -1; } - Py_DECREF(v); + + Py_DECREF(res); return 0; }