From b6a54d2a2cd0537be8e013a96068a8ffeaee5847 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Wed, 6 Dec 2000 21:47:46 +0000 Subject: [PATCH] _getframe(): New sys module function for getting at the stack frame. Implements and closes SF patch #102106, with Guido's suggested documentation changes. --- Doc/lib/libsys.tex | 11 +++++++++++ Python/sysmodule.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/Doc/lib/libsys.tex b/Doc/lib/libsys.tex index 8199b1b81ee..2fda26e429c 100644 --- a/Doc/lib/libsys.tex +++ b/Doc/lib/libsys.tex @@ -161,6 +161,17 @@ from causing an overflow of the C stack and crashing Python. It can be set by \function{setrecursionlimit()}. \end{funcdesc} +\begin{funcdesc}{_getframe}{\optional{depth}} +Return a frame object from the call stack. If optional integer +\var{depth} is given, return the frame object that many calls below +the top of the stack. If that is deeper than the call stack, +\exception{ValueError} is raised. The default for \var{depth} is +zero, returning the frame at the top of the call stack. + +This function should be used for internal and specialized +purposes only. +\end{funcdesc} + \begin{datadesc}{hexversion} The version number encoded as a single integer. This is guaranteed to increase with each version, including proper support for diff --git a/Python/sysmodule.c b/Python/sysmodule.c index ade90636695..b569a9adfa0 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -15,6 +15,8 @@ Data members: */ #include "Python.h" +#include "compile.h" +#include "frameobject.h" #include "osdefs.h" @@ -284,6 +286,40 @@ sys_getcounts(PyObject *self, PyObject *args) } #endif +static char getframe_doc[] = +"_getframe([depth]) -> frameobject\n\ +\n\ +Return a frame object from the call stack. If optional integer depth is\n\ +given, return the frame object that many calls below the top of the stack.\n\ +If that is deeper than the call stack, ValueError is raised. The default\n\ +for depth is zero, returning the frame at the top of the call stack.\n\ +\n\ +This function should be used for internal and specialized\n\ +purposes only."; + +static PyObject * +sys_getframe(PyObject *self, PyObject *args) +{ + PyFrameObject *f = PyThreadState_Get()->frame; + int depth = -1; + + if (!PyArg_ParseTuple(args, "|i:_getframe", &depth)) + return NULL; + + while (depth > 0 && f != NULL) { + f = f->f_back; + --depth; + } + if (f == NULL) { + PyErr_SetString(PyExc_ValueError, + "call stack is not deep enough"); + return NULL; + } + Py_INCREF(f); + return (PyObject*)f; +} + + #ifdef Py_TRACE_REFS /* Defined in objects.c because it uses static globals if that file */ extern PyObject *_Py_GetObjects(PyObject *, PyObject *); @@ -313,6 +349,7 @@ static PyMethodDef sys_methods[] = { {"getrefcount", sys_getrefcount, 1, getrefcount_doc}, {"getrecursionlimit", sys_getrecursionlimit, 1, getrecursionlimit_doc}, + {"_getframe", sys_getframe, 1, getframe_doc}, #ifdef USE_MALLOPT {"mdebug", sys_mdebug, 1}, #endif