]> granicus.if.org Git - python/commitdiff
_getframe(): New sys module function for getting at the stack frame.
authorBarry Warsaw <barry@python.org>
Wed, 6 Dec 2000 21:47:46 +0000 (21:47 +0000)
committerBarry Warsaw <barry@python.org>
Wed, 6 Dec 2000 21:47:46 +0000 (21:47 +0000)
Implements and closes SF patch #102106, with Guido's suggested
documentation changes.

Doc/lib/libsys.tex
Python/sysmodule.c

index 8199b1b81ee5063d3e233a69a1a96110bf187ee7..2fda26e429c3aa356c1a8a755f3765b8b6ce9a7d 100644 (file)
@@ -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
index ade90636695c9a71fd81ec5ed4e6612fe7bbbbb7..b569a9adfa02ee494bcc8816f9a48c142c631b4d 100644 (file)
@@ -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