summaryrefslogtreecommitdiffstats
path: root/Python/pythonrun.c
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2023-06-19 22:55:23 (GMT)
committerGitHub <noreply@github.com>2023-06-19 22:55:23 (GMT)
commita5c2ad0c3d23d2b1e61ab8e0d7ee64f7e1288547 (patch)
treebe5628b6a936b27c41b6343d9ceacafeac934ff8 /Python/pythonrun.c
parent33f0a8578b729e67c482daedc2660648afd0ee78 (diff)
downloadcpython-a5c2ad0c3d23d2b1e61ab8e0d7ee64f7e1288547.zip
cpython-a5c2ad0c3d23d2b1e61ab8e0d7ee64f7e1288547.tar.gz
cpython-a5c2ad0c3d23d2b1e61ab8e0d7ee64f7e1288547.tar.bz2
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.
Diffstat (limited to 'Python/pythonrun.c')
-rw-r--r--Python/pythonrun.c182
1 files changed, 108 insertions, 74 deletions
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 05e7b43..f9e798e 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_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;
}