Skip to content

[3.6] bpo-17799: Explain real behaviour of sys.settrace and sys.setprofile (GH-4056) #5298

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions Doc/c-api/init.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1137,15 +1137,19 @@ Python-level trace functions in previous versions.
function as its first parameter, and may be any Python object, or *NULL*. If
the profile function needs to maintain state, using a different value for *obj*
for each thread provides a convenient and thread-safe place to store it. The
profile function is called for all monitored events except the line-number
events.
profile function is called for all monitored events except :const:`PyTrace_LINE`
and :const:`PyTrace_EXCEPTION`.


.. c:function:: void PyEval_SetTrace(Py_tracefunc func, PyObject *obj)

Set the tracing function to *func*. This is similar to
:c:func:`PyEval_SetProfile`, except the tracing function does receive line-number
events.
events and does not receive any event related to C function objects being called. Any
trace function registered using :c:func:`PyEval_SetTrace` will not receive
:const:`PyTrace_C_CALL`, :const:`PyTrace_C_EXCEPTION` or :const:`PyTrace_C_RETURN`
as a value for the *what* parameter.


.. c:function:: PyObject* PyEval_GetCallStats(PyObject *self)

Expand Down
49 changes: 32 additions & 17 deletions Doc/library/sys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1005,13 +1005,38 @@ always available.
Set the system's profile function, which allows you to implement a Python source
code profiler in Python. See chapter :ref:`profile` for more information on the
Python profiler. The system's profile function is called similarly to the
system's trace function (see :func:`settrace`), but it isn't called for each
executed line of code (only on call and return, but the return event is reported
even when an exception has been set). The function is thread-specific, but
there is no way for the profiler to know about context switches between threads,
so it does not make sense to use this in the presence of multiple threads. Also,
system's trace function (see :func:`settrace`), but it is called with different events,
for example it isn't called for each executed line of code (only on call and return,
but the return event is reported even when an exception has been set). The function is
thread-specific, but there is no way for the profiler to know about context switches between
threads, so it does not make sense to use this in the presence of multiple threads. Also,
its return value is not used, so it can simply return ``None``.

Profile functions should have three arguments: *frame*, *event*, and
*arg*. *frame* is the current stack frame. *event* is a string: ``'call'``,
``'return'``, ``'c_call'``, ``'c_return'``, or ``'c_exception'``. *arg* depends
on the event type.

The events have the following meaning:

``'call'``
A function is called (or some other code block entered). The
profile function is called; *arg* is ``None``.

``'return'``
A function (or other code block) is about to return. The profile
function is called; *arg* is the value that will be returned, or ``None``
if the event is caused by an exception being raised.

``'c_call'``
A C function is about to be called. This may be an extension function or
a built-in. *arg* is the C function object.

``'c_return'``
A C function has returned. *arg* is the C function object.

``'c_exception'``
A C function has raised an exception. *arg* is the C function object.

.. function:: setrecursionlimit(limit)

Expand Down Expand Up @@ -1058,8 +1083,8 @@ always available.

Trace functions should have three arguments: *frame*, *event*, and
*arg*. *frame* is the current stack frame. *event* is a string: ``'call'``,
``'line'``, ``'return'``, ``'exception'``, ``'c_call'``, ``'c_return'``, or
``'c_exception'``. *arg* depends on the event type.
``'line'``, ``'return'`` or ``'exception'``. *arg* depends on
the event type.

The trace function is invoked (with *event* set to ``'call'``) whenever a new
local scope is entered; it should return a reference to a local trace
Expand Down Expand Up @@ -1094,16 +1119,6 @@ always available.
tuple ``(exception, value, traceback)``; the return value specifies the
new local trace function.

``'c_call'``
A C function is about to be called. This may be an extension function or
a built-in. *arg* is the C function object.

``'c_return'``
A C function has returned. *arg* is the C function object.

``'c_exception'``
A C function has raised an exception. *arg* is the C function object.

Note that as an exception is propagated down the chain of callers, an
``'exception'`` event is generated at each level.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Explain real behaviour of sys.settrace and sys.setprofile and their C-API counterparts
regarding which type of events are received in each function. Patch by Pablo Galindo Salgado.