首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何修补python 3断点()内置的?

如何修补python 3断点()内置的?
EN

Stack Overflow用户
提问于 2020-05-19 18:00:50
回答 1查看 153关注 0票数 2

我编写了一个装饰器,如果发生了严重错误,就用断点()停止我的程序。

代码语言:javascript
复制
def the_breakpoint_dec(func):
    @functools.wraps(func):
    async def my_wrapper(func):
       retval=await func(*args,**kwargs)
       return retval if retval else breakpoint()
    return my_wrapper

我正在进行单元测试,希望确保断点命中,而不实际触发它,因此我一直试图用@mock.patch装饰器修补断点(),但它不起作用。我尝试过的20多个断点的一些测试路径是

代码语言:javascript
复制
@mock.patch('pdb.breakpoint')
@mock.patch('builtins.breakpoint')
@mock.patch('builtins.pdb.breakpoint')
@mock.patch('my_module.breakpoint')
@mock.patch('my_module.builtins.breakpoint')
@mock.patch('sys.breakpointhook')
@mock.patch('my_module.sys.breakpointhook')
@mock.patch('my_decorator_module.sys.breakpointhook')
@mock.patch('my_decorator_module.sys.breakpoint')

然后使测试函数def并传入模拟:

代码语言:javascript
复制
#testmodule.py
pytestmark=pytest.mark.asyncio
@mock.patch('just_another_path_to_breakpoint()_that_doesnt_work')
async def test_func_to_test(self, mock_breakpoint, some_other_mock): 
    mock_breakpoint.return_value=None
    await decorated_func()
    mock_breakpoint.assert_called() # never hit because pdb prompt opens in interpreter

正在测试的模块

代码语言:javascript
复制
#moduleundertest.py

class bar:
    @the_breakpoint_dec
    async def decorated_func(self):
        for i in range(3)
            try:
                return await something_likely_to_fail()
            except:
                pass

最初,我想要修补的断点()是从上面提到的装饰器调用的。在几个小时的故障之后,我注释掉了装饰器,并将断点()直接移到了被测试的方法中。修补仍然失败。什么是正确的方式来修补这个内置的,如果必须做一些特殊的事情来修补它时,它在一个装饰,这是什么东西?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-30 18:18:03

要解决问题,请将您的项目升级到3.8!

我试着在3.8版复制你的场景,但做不到,修补工作对我很有帮助。但是,当尝试3.7及以下时,修补程序停止工作,我的程序将进入断点。我对此没有任何解释。

下面是我编写的一个完整的运行示例。它运行function_to_test,模拟成功然后失败(True/False)。正如assert所证明的那样,它只在失败的情况下调用breakpoint(),但是由于我们模拟的breakpoint() --至少在3.8中--测试完全退出。

代码语言:javascript
复制
from unittest import mock
import functools
import asyncio

def break_if_function_fails(func):
    @functools.wraps(func)
    async def my_wrapper(*args, **kwargs):
        retval = await func(*args, **kwargs)
        return retval if retval else breakpoint()
    return my_wrapper

@break_if_function_fails
async def function_to_test(retval):
    return retval

@mock.patch('builtins.breakpoint')
async def do_test(mock_breakpoint):
    print('Entering test')
    await function_to_test(True)
    mock_breakpoint.assert_not_called()
    await function_to_test(False)
    mock_breakpoint.assert_called()
    print('Exiting test')

asyncio.run(do_test())

完全相同的代码没有完成,但在3.7中触发了断点。

如果你必须和3.7呆在一起,你仍然可以

代码语言:javascript
复制
@mock.patch('builtins.breakpoint')
async def do_test(mock_breakpoint):
    backup_breakpoint = builtins.breakpoint
    builtins.breakpoint = mock_breakpoint
    ...
    builtins.breakpoint = backup_breakpoint

但这显然是丑陋的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61897718

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档