Skip to main content

Python/sysmodule.c

cpython 3.14 @ ab2d84fe1023/Python/sysmodule.c

Python/sysmodule.c implements the sys built-in module. It exposes interpreter state (thread state, recursion depth, module table) as Python-accessible attributes, implements sys.settrace/sys.setprofile by writing to the thread state, and provides sys.exit, sys.getrecursionlimit, sys.getframe, sys.exc_info, and other inspection functions. The module is initialized very early in pyinit_core.

Map

LinesSymbolRole
1-100includes, type aliasesPlatform detection, UNLIKELY macro
101-400sys_settrace_impl, sys_setprofile_implTrace/profile hook installation
401-700sys_getframe_impl, sys_exc_info_implFrame and exception introspection
701-1000sys_exit_impl, sys_intern_implExit and string interning
1001-1400sys_getrecursionlimit_impl, sys_setrecursionlimit_implRecursion guard
1401-2000sys_getsizeof_impl, sys_audit_implSize introspection and audit hooks
2001-2800_PySys_InitCore, _PySys_UpdateConfigModule init and config attribute setup
2801-3400sysmodule_exec, PyInit_sysModule registration

Reading

sys.settrace: trace hook installation

sys_settrace_impl stores the trace function in the current thread state. It also sets the c_tracefunc C-level slot that the eval loop checks before every opcode.

// CPython: Python/sysmodule.c:140 sys_settrace_impl
static PyObject *
sys_settrace_impl(PyObject *module, PyObject *o)
{
PyThreadState *tstate = _PyThreadState_GET();
if (o == Py_None)
PyEval_SetTrace(NULL, NULL);
else
PyEval_SetTrace(_PyEval_CallTracing, o);
Py_RETURN_NONE;
}

sys.getframe: frame introspection

sys_getframe_impl walks the frame chain depth steps back from the caller. It returns the PyFrameObject at that depth, which exposes f_locals, f_code, and f_lineno.

// CPython: Python/sysmodule.c:430 sys_getframe_impl
static PyObject *
sys_getframe_impl(PyObject *module, int depth)
{
_PyInterpreterFrame *f = _PyThreadState_GET()->current_frame;
while (f != NULL && depth > 0) {
f = f->previous;
--depth;
}
if (f == NULL || depth != 0) {
PyErr_SetString(PyExc_ValueError, "call stack is not deep enough");
return NULL;
}
return _PyFrame_GetFrameObject(f);
}

_PySys_InitCore: attribute wiring

_PySys_InitCore populates the sys module dict with all the initial attributes: sys.version, sys.platform, sys.argv, sys.path, sys.modules, etc. Most are read from _PyConfig or constructed from C constants at startup.

// CPython: Python/sysmodule.c:2050 _PySys_InitCore
PyStatus
_PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
{
...
SET_SYS("version", version_string);
SET_SYS("platform", PyUnicode_FromString(Py_GetPlatform()));
SET_SYS("modules", tstate->interp->modules);
...

gopy notes

module/sys/module.go in gopy provides a partial sys implementation. sys.argv, sys.version, sys.path, and sys.modules are implemented. sys.settrace and sys.setprofile are stubs; full trace support requires eval-loop changes in vm/eval_gen.go.

CPython 3.14 changes

3.14 added sys.flags.gil_disabled to report the free-threaded GIL status. sys._monitoring was promoted to a public sys.monitoring API. sys.getandroidapilevel was added for the Android port. sys.orig_argv was exposed as a tuple.