Skip to content
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

sys.settrace doesn't disable tracing if a local trace function returns None #56201

Closed
nedbat opened this issue May 4, 2011 · 5 comments
Closed
Assignees
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@nedbat
Copy link
Member

nedbat commented May 4, 2011

BPO 11992
Nosy @arigo, @nedbat, @xdegaye

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = 'https://github.com/nedbat'
closed_at = None
created_at = <Date 2011-05-04.01:58:53.007>
labels = ['type-bug', 'library']
title = "sys.settrace doesn't disable tracing if a local trace function returns None"
updated_at = <Date 2017-01-18.11:32:14.531>
user = 'https://github.com/nedbat'

bugs.python.org fields:

activity = <Date 2017-01-18.11:32:14.531>
actor = 'arigo'
assignee = 'nedbat'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)']
creation = <Date 2011-05-04.01:58:53.007>
creator = 'nedbat'
dependencies = []
files = []
hgrepos = []
issue_num = 11992
keywords = []
message_count = 3.0
messages = ['135089', '206739', '285720']
nosy_count = 3.0
nosy_names = ['arigo', 'nedbat', 'xdegaye']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue11992'
versions = ['Python 2.7', 'Python 3.2']

@nedbat
Copy link
Member Author

nedbat commented May 4, 2011

The docs say:

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 function to be used that scope, or None if the scope shouldn’t be traced.

The local trace function should return a reference to itself (or to another function for further tracing in that scope), or None to turn off tracing in that scope.

It's that last part that's wrong: returning None from the trace function only has an effect on the first call in a new frame. Once the trace function returns a function for a frame, returning None from subsequent calls is ignored. A "local trace function" can't turn off tracing in its scope.

To demonstrate:

    import sys

    UPTO_LINE = 1

    def t(frame, event, arg):
        num = frame.f_lineno
        print("line %d" % num)
        if num < UPTO_LINE:
            return t

    def try_it():
        print("twelve")
        print("thirteen")
        print("fourteen")
        print("fifteen")

    UPTO_LINE = 1
    sys.settrace(t)
    try_it()

    UPTO_LINE = 13
    sys.settrace(t)
    try_it()

Produces:

line 11
twelve
thirteen
fourteen
fifteen
line 11
line 12
twelve
line 13
thirteen
line 14
fourteen
line 15
fifteen
line 15

The first call to try_it() returns None immediately, preventing tracing for the rest of the function. The second call returns None at line 13, but the rest of the function is traced anyway. This behavior is the same in all versions from 2.3 to 3.2, in fact, the 100 lines of code in sysmodule.c responsible for Python tracing functions are completely unchanged through those versions.

@nedbat nedbat added stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels May 4, 2011
@nedbat nedbat self-assigned this May 4, 2011
@xdegaye
Copy link
Mannequin

xdegaye mannequin commented Dec 21, 2013

See also bpo-20040.

@arigo
Copy link
Mannequin

arigo mannequin commented Jan 18, 2017

Confirmed. More interestingly, nowadays (at least in 3.5) test_pdb.py depends on this bug. If we really clear f->f_trace when the trace function returns None, then test_pdb_until_command_for_generator() fails. This is because pdb.py incorrectly thinks there is no breakpoint in the generator function, and returns None. This doesn't actually clear anything, and so it works anyway.

I'd suggest to fix the documentation to reflect the actual behavior of all versions from 2.3 to (at least) 3.5.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@amakelov
Copy link

Hi, I've been trying to turn off tracing selectively in certain functions (e.g., stop tracing calls when they invoke functions defined outside of a certain directory), and running into this problem in Python 3.10 as well. Are you aware of any workaround that would enable this sort of logic?

@brandtbucher
Copy link
Member

Fixed the docs in d9246c7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

3 participants