Python 2 如何调试exec块注入的代码

Python 2 How to debug code injected by the exec block

该项目 pywebsocket,运行 处于独立模式。

从文件和 运行 到 exec <code-block-in-string> in global_dic 中读入处理程序。处理程序代码然后通过 global_dic[<function-name>] 挂钩。当请求 URL 时,将通过资源处理程序映射调用处理程序函数。

如何跨过exec块中handlers中的代码?在PyCharm具体是怎么做到的?还是在其他工具中?

或者更一般地说,您如何调试 exec 块中的代码?

具体的代码,handlers是通过函数_source_handler_file()mod_pywebsocket/dispatch.py中读入和获取的,like(其实open和read是在调用这个函数之前,只是放在下面解释一下逻辑):

global_dic = {}
handler_definition = open(handler_definition_filepath).read()
exec handler_definition in global_dic
handler = global_dic[handler_name]
return _HandlerSuite(handler)

然后 _HandlerSuite 的实例被主循环保存在一个映射中,并被主循环用来调用基于 URL 资源的处理程序。

gbin回答后更新:

根据 gbin 的示例,代码应该如下所示:

print(3)
toto = 5
def my_handler_func():
    print(88)

py2下:

execfile('other.py', blob)       # this works perfectly
print("blob %s" % blob['toto'])  # 
myhandler = blob['my_handler_func']
myhandler()                      # how to make this stop on print(88)?

代码将在执行 execfile() 时停止在 PyCharm。

但是当它调用注入处理程序 myhandler() 时,我希望它在注入代码块内的 print(88) 处停止。这还没有解决。

要解决第二半的问题,可能的解决方案是将代码拉入Python系统的导入模块记录中。也许通过使用 __import__。但这会污染名称 space。有没有更好的办法?或者有没有一种方法可以导入但仍然保持名称 spaces 隔离?

再次更新:

今天,我用 execfile("...", blob) 触发了相同的代码,它很管用。它在注入的处理程序函数上停止。不知道为什么前几天它不起作用。

如果可以change/override/monkeypatch dispatch.py,可以在python下使用execfile()或exec(compile(...)) 3:

如果您有 other.py 个文件:

print(1)
print(2)
print(3)
toto = 5

py2下:

execfile('other.py', blob)
print("blob %s" % blob['toto'])

py3 下仅供参考:

code_block = compile(open('other.py').read(), 'other.py', 'exec')
blob = {}
exec(code_block, blob)
print("blob %s" % blob['toto'])

现在,如果您在 other.py 中放置一个断点,pycharm 将在其上停止!