Does “sys.settrace” work properly in Python 3.5 but not in Python 3.6?

落爺英雄遲暮 提交于 2021-01-27 21:01:20

问题


While trying to answer another question, it dawned on me that you can have code run any time in a thread when you theoretically should not have control. CPython has a settrace function for registering a tracing function in one's code. To test this idea from the use of a class, the following code was written. The problem is that tracing does not seem to occur, and no data is generated in the tracing log. What is causing the problem in the code shown below?

#! /usr/bin/env python3
import atexit
import collections
import pprint
import sys


def main():
    i = create_instance()
    print(len(i.data), flush=True)


def create_instance():
    instance = Tracer()
    return instance


class Tracer:

    def __init__(self):
        self.data = []
        sys.settrace(self.trace)
        atexit.register(pprint.pprint, self.data)
        atexit.register(sys.settrace, None)

    def trace(self, frame, event, arg):
        print('Tracing ...', flush=True)
        self.data.append(TraceRecord(frame, event, arg))
        return self.trace


TraceRecord = collections.namedtuple('TraceRecord', 'frame, event, arg')


if __name__ == '__main__':
    main()

Addendum:

The problem is not apparent when running Python 3.5 on Windows. However, tracing does not occur in Python 3.6 such that the trace log is not printed. If someone can confirm the bug for me as a well-presented answer, there is a good chance the submission would be accepted and awarded the bounty.


回答1:


I tried your program, and indeed as posted it does not have anything to trace. The built-in functions print() and len() do not generate trace events, presumably since they are defined by the platform and it is assumed that their internals work correctly and are not interesting.

The documentation states:

The trace function is invoked (with event set to 'call') whenever a new local scope is entered;

I modified your program to define a function and to call it. When I did this, then your trace function was called.

The function I defined:

def doSomething():
  print("Hello World")

My version of your main() function:

def main():
  i = create_instance()
  print(len(i.data))
  doSomething()
  print(len(i.data))

The output I see:

 0
 Tracing ...
 Tracing ...
 Hello World
 Tracing ...
 3


来源:https://stackoverflow.com/questions/42932655/does-sys-settrace-work-properly-in-python-3-5-but-not-in-python-3-6

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!