Index: Python/sysmodule.c =================================================================== --- Python/sysmodule.c (revision 59566) +++ Python/sysmodule.c (working copy) @@ -397,6 +397,28 @@ ); static PyObject * +sys_gettrace(PyObject *self, PyObject *args) +{ + PyThreadState *tstate = PyThreadState_GET(); + PyObject *temp = tstate->c_traceobj; + + if (temp == NULL) { + temp = Py_None; + } + + Py_XINCREF(temp); + + return temp; +} + +PyDoc_STRVAR(gettrace_doc, +"gettrace()\n\ +\n\ +Return the global debug tracing function set with sys.settrace.\n\ +See the debugger chapter in the library manual." +); + +static PyObject * sys_setprofile(PyObject *self, PyObject *args) { if (trace_init() == -1) @@ -417,6 +439,28 @@ ); static PyObject * +sys_getprofile(PyObject *self, PyObject *args) +{ + PyThreadState *tstate = PyThreadState_GET(); + PyObject *temp = tstate->c_profileobj; + + if (temp == NULL) { + temp = Py_None; + } + + Py_XINCREF(temp); + + return temp; +} + +PyDoc_STRVAR(getprofile_doc, +"getprofile()\n\ +\n\ +Return the profiling function set with sys.setprofile.\n\ +See the profiler chapter in the library manual." +); + +static PyObject * sys_setcheckinterval(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_Py_CheckInterval)) @@ -792,12 +836,14 @@ setdlopenflags_doc}, #endif {"setprofile", sys_setprofile, METH_O, setprofile_doc}, + {"getprofile", sys_getprofile, METH_NOARGS, getprofile_doc}, {"setrecursionlimit", sys_setrecursionlimit, METH_VARARGS, setrecursionlimit_doc}, #ifdef WITH_TSC {"settscdump", sys_settscdump, METH_VARARGS, settscdump_doc}, #endif {"settrace", sys_settrace, METH_O, settrace_doc}, + {"gettrace", sys_gettrace, METH_NOARGS, gettrace_doc}, {"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc}, {NULL, NULL} /* sentinel */ }; @@ -940,8 +986,10 @@ exc_clear() -- clear the exception state for the current thread\n\ exit() -- exit the interpreter by raising SystemExit\n\ getdlopenflags() -- returns flags to be used for dlopen() calls\n\ +getprofile() -- get the global profiling function\n\ getrefcount() -- return the reference count for an object (plus one :-)\n\ getrecursionlimit() -- return the max recursion depth for the interpreter\n\ +gettrace() -- get the global debug tracing function\n\ setcheckinterval() -- control how often the interpreter checks for events\n\ setdlopenflags() -- set the flags to be used for dlopen() calls\n\ setprofile() -- set the global profiling function\n\ Index: Doc/library/sys.rst =================================================================== --- Doc/library/sys.rst (revision 59566) +++ Doc/library/sys.rst (working copy) @@ -353,7 +353,33 @@ This function should be used for internal and specialized purposes only. +.. function:: getprofile() + .. index:: + single: profile function + single: profiler + + Get the profiler function as set by :func:`setprofile`. + + .. versionadded:: 2.6 + +.. function:: gettrace() + + .. index:: + single: trace function + single: debugger + + Get the trace function as set by :func:`settrace`. + + .. note:: + + The :func:`gettrace` function is intended only for implementing debuggers, + profilers, coverage tools and the like. Its behavior is part of the + implementation platform, rather than part of the language definition, and thus + may not be available in all Python implementations. + + .. versionadded:: 2.6 + .. function:: getwindowsversion() Return a tuple containing five components, describing the Windows version Index: Lib/test/test_trace.py =================================================================== --- Lib/test/test_trace.py (revision 59566) +++ Lib/test/test_trace.py (working copy) @@ -268,6 +268,20 @@ self.compare_events(func.func_code.co_firstlineno, tracer.events, func.events) + def set_and_retrieve_none(self): + sys.settrace(None) + assert sys.gettrace() is None + + def set_and_retrieve_func(self): + def fn(*args): + pass + + sys.settrace(fn) + try: + assert sys.gettrace() is fn + finally: + sys.settrace(None) + def test_01_basic(self): self.run_test(basic) def test_02_arigo(self): Index: Lib/test/test_profilehooks.py =================================================================== --- Lib/test/test_profilehooks.py (revision 59566) +++ Lib/test/test_profilehooks.py (working copy) @@ -4,7 +4,23 @@ from test import test_support +class TestGetProfile(unittest.TestCase): + def setUp(self): + sys.setprofile(None) + def tearDown(self): + sys.setprofile(None) + + def test_empty(self): + assert sys.getprofile() == None + + def test_setget(self): + def fn(*args): + pass + + sys.setprofile(fn) + assert sys.getprofile() == fn + class HookWatcher: def __init__(self): self.frames = [] @@ -359,6 +375,7 @@ def test_main(): test_support.run_unittest( + TestGetProfile, ProfileHookTestCase, ProfileSimulatorTestCase )