【问题标题】:How to make static code analysis aware of an Exception throwing function?如何让静态代码分析知道异常抛出函数?
【发布时间】:2019-09-13 22:38:26
【问题描述】:

出于可读性和可重用性的原因,我有一个函数,如果被调用,总是会引发特定异常。但是,静态代码分析似乎没有考虑到这一点,即我收到了不必要的警告。有没有什么好的方法可以避免这些警告,例如,通过让静态代码分析意识到这个函数总是会引发异常的事实?

最小的工作示例:

def raise_an_exception():
    raise Exception("...description...")


def foo(arg):
    if arg:
        x = 1
    else:
        raise_an_exception()
    # causes warning "Local variable 'x' might be referenced before assignment":
    return x + 1


def bar(arg):
    if arg:
        x = 1
    else:
        raise Exception("...description...")
    # causes no warning:
    return x + 1

边界条件:我不想在foo() 中声明xif 语句之前或将x 设置为else 代码块中的任何值,或任何其他类似的解决方法。在bar() 中没有必要,在foo() 中也不需要。

【问题讨论】:

    标签: python function exception warnings


    【解决方案1】:

    对于不能正常返回的函数有一个NoReturn注解:

    from typing import NoReturn
    
    def raise_an_exception() -> NoReturn:
        raise Exception("...description...")
    

    理解类型注解的静态分析工具应该理解这一点并且不会为foo报错。

    【讨论】:

    • 不幸的是,这不起作用,我认为它不起作用是有道理的。警告的原因不在于raise_an_exception() 的返回行为,而在于foo() 中的else 路径,其中x 未设置。如果很明显raise_an_exception() 总是引发异常,那么对于代码分析来说很明显,在输入else 路径后永远无法到达return x + 1 语句。因此,当程序到达return x + 1 语句时,总是会定义x。在bar() 中,代码分析得到了它,但在 foo() 中它因默默无闻而失败。
    • @matheburg:我不知道您使用的是什么分析工具,也不知道它是否理解注释,但对于真正理解NoReturn 的工具,这应该可以工作。分析不需要知道raise_an_exception总是引发异常;它只需要知道该函数无法正常返回。一个永远循环或调用os.exec 的函数也可以。
    • 啊,我明白了。抱歉,我误以为-> NoReturn 会注释没有返回值,但如果意思是函数“没有返回”,那么你是 100% 正确的。但是,Pycharm CE 2019.2.1 并不买账。
    • 我刚刚决定接受这个答案,就像NoReturn 你完美地回答了我的问题,尽管它不能解决我的警告问题。该警告似乎是由于不知情的 linting...
    猜你喜欢
    • 2017-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    • 2014-02-14
    • 2015-08-26
    • 2012-01-30
    相关资源
    最近更新 更多