mirror of
https://github.com/python/cpython.git
synced 2025-08-22 01:35:16 +00:00
gh-105922: Refactor PyRun_InteractiveOneObjectEx() (#105925)
Refactor PyRun_InteractiveOneObjectEx(), _PyRun_SimpleFileObject() and PyRun_SimpleStringFlags(): * Keep a strong reference to the __main__ module while using its dictionary (PyModule_GetDict()). Use PyImport_AddModule() with Py_XNewRef(). * Declare variables closer to where they are defined. * Rename variables to use name longer than 1 character. * Add pyrun_one_parse_ast() sub-function.
This commit is contained in:
parent
33f0a8578b
commit
a5c2ad0c3d
1 changed files with 107 additions and 73 deletions
|
@ -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);
|
||||
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);
|
||||
|
||||
Py_XDECREF(v);
|
||||
Py_XDECREF(w);
|
||||
Py_XDECREF(oenc);
|
||||
if (mod == NULL) {
|
||||
_PyArena_Free(arena);
|
||||
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_module = Py_XNewRef(PyImport_AddModuleObject(&_Py_ID(__main__)));
|
||||
if (main_module == 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_module); // borrowed ref
|
||||
|
||||
PyObject *res = run_mod(mod, filename, main_dict, main_dict, flags, arena);
|
||||
_PyArena_Free(arena);
|
||||
if (v == NULL) {
|
||||
Py_DECREF(main_module);
|
||||
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, "<stdin>") != 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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue