Skip to main content

Python/pythonrun.c

cpython 3.14 @ ab2d84fe1023/Python/pythonrun.c

Python/pythonrun.c provides the high-level entry points for running Python source code from C. PyRun_SimpleFileObject reads and compiles a .py file; PyRun_InteractiveLoopObject drives the REPL; PyRun_StringFlags compiles and evaluates a string. The file is the bridge between the embedding API and the compiler and eval loop.

Map

LinesSymbolRole
1-80includes, parse_syntax_errorError message extraction from SyntaxError
81-250PyRun_SimpleFileObjectOpen, compile, and exec a .py file
251-450PyRun_FileExFlagsCompile file to AST, then to code object, then eval
451-650PyRun_StringFlagsCompile string to code object and eval in given globals/locals
651-800PyRun_InteractiveLoopObjectREPL loop: read, compile, eval, repeat
801-1000Py_CompileStringExFlagsPublic compile-only API
1001-1100handle_system_exitSystemExit value extraction for process exit code

Reading

PyRun_SimpleFileObject: file execution

PyRun_SimpleFileObject opens the file, constructs __dict__ with __file__ set, then calls PyRun_FileExFlags to compile and exec. For .pyc files it reads the magic number and delegates to run_pyc_file.

// CPython: Python/pythonrun.c:110 PyRun_SimpleFileObject
int
PyRun_SimpleFileObject(FILE *fp, PyObject *filename, int closeit,
PyCompilerFlags *flags)
{
...
d = PyModule_GetDict(m);
...
if (maybe_pyc_file(fp, filename, closeit)) {
v = run_pyc_file(fp, d, d, flags);
} else {
v = PyRun_FileExFlags(fp, filename_str, Py_file_input, d, d, closeit, flags);
}

PyRun_StringFlags: compile-then-eval

PyRun_StringFlags is the simplest compile path: it calls Py_CompileStringExFlags to get a code object, then PyEval_EvalCode to execute it in the provided namespace.

// CPython: Python/pythonrun.c:480 PyRun_StringFlags
PyObject *
PyRun_StringFlags(const char *str, int start, PyObject *globals,
PyObject *locals, PyCompilerFlags *flags)
{
PyObject *ret = NULL;
PyObject *v;
v = Py_CompileStringExFlags(str, "<string>", start, flags, -1);
if (v) {
ret = PyEval_EvalCode(v, globals, locals);
Py_DECREF(v);
}
return ret;
}

Interactive loop

PyRun_InteractiveLoopObject calls PyOS_Readline to read one logical line (handling continuation lines), compiles it with Py_single_input mode (which prints the repr of the result), and evals it.

// CPython: Python/pythonrun.c:680 PyRun_InteractiveLoopObject
int
PyRun_InteractiveLoopObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
{
...
do {
ret = PyRun_InteractiveOneObjectEx(fp, filename, flags);
} while (ret != E_EOF);
return 0;
}

gopy notes

pythonrun/runstring.go in gopy implements a simplified version of PyRun_StringFlags: it compiles a source string and evaluates it. The interactive loop and file execution paths are not yet implemented.

CPython 3.14 changes

3.14 added PyRun_StringFlags audit event exec. handle_system_exit now handles BaseExceptionGroup containing a SystemExit. The .pyc execution path gained validation of the allow_code marshal flag.