Commit 24988291 authored by Barry Warsaw's avatar Barry Warsaw

_getframe(): New sys module function for getting at the stack frame.

Implements and closes SF patch #102106, with Guido's suggested
documentation changes.
parent b060cf51
......@@ -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
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment