Skip to main content

Python/pythonrun.c

Source:

cpython 3.14 @ ab2d84fe1023/Python/pythonrun.c

Python/pythonrun.c implements the high-level parse-compile-execute pipeline. It bridges the interpreter's public API (PyRun_String, PyRun_File) to the lower-level compiler and eval loop. This is the code path taken by exec(), eval(), the python -c flag, and python file.py.

Map

LinesSymbolRole
1-100PyRun_SimpleStringFlags, PyRun_SimpleFileExFlagsSimple top-level entry points
101-300PyRun_StringFlags, PyRun_FileExFlagsCore string and file runners
301-500run_eval_code_obj, run_modExecute a code object
501-700PyRun_InteractiveLoopFlags, PyRun_InteractiveOneObjectFlagsREPL loop
701-900handle_system_exitConverts SystemExit to exit code
901-1100flush_io, _PyObject_CallMethodIdOneArg helpersOutput flushing

Reading

PyRun_StringFlags

The canonical entry point for exec(string, globals, locals):

// CPython: Python/pythonrun.c:1015 PyRun_StringFlags
PyObject *
PyRun_StringFlags(const char *str, int start, PyObject *globals,
PyObject *locals, PyCompilerFlags *flags)
{
PyObject *ret = NULL;
mod_ty mod;
PyArena *arena = _PyArena_New();
...
mod = _PyParser_ASTFromString(str, "<string>", start, flags, arena);
if (mod != NULL)
ret = run_mod(mod, "<string>", globals, locals, flags, arena, NULL);
_PyArena_Free(arena);
return ret;
}

The start parameter is the grammar start symbol: Py_eval_input for expressions, Py_file_input for a module, Py_single_input for interactive mode.

run_mod

// CPython: Python/pythonrun.c:1085 run_mod
static PyObject *
run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals,
PyCompilerFlags *flags, PyArena *arena, PyObject *interactive_src)
{
PyCodeObject *co = _PyAST_Compile(mod, filename, flags, -1, arena);
if (co == NULL) return NULL;
...
PyObject *v = run_eval_code_obj(tstate, co, globals, locals);
Py_DECREF(co);
return v;
}

_PyAST_Compile runs the full compiler pipeline (AST -> symbol table -> bytecode). run_eval_code_obj calls PyEval_EvalCode.

Interactive loop

PyRun_InteractiveLoopFlags reads lines, attempts to compile them as Py_single_input, and prints the result if it is not None. It uses sys.ps1 and sys.ps2 for the prompts.

handle_system_exit

If the code raises SystemExit, handle_system_exit converts the exception to an integer exit code (or prints the exception message and uses exit code 1), then calls Py_FinalizeEx and exit().

gopy notes

The gopy equivalent is pythonrun/runstring.go. PyRun_StringFlags maps to pythonrun.RunString; the parse-compile-eval pipeline is parser.ParseString -> compile.Compile -> vm.EvalCode. The interactive loop is not yet implemented in gopy.