[Python] How to find all exception types at `raise` calls in Python?

Discussão em 'Python' iniciado por Stack, Fevereiro 22, 2025.

  1. Stack

    Stack Membro Participativo

    I need to collect all possible things a given function explicitly raises using the raise keyword for a source analyzer tool I am working on.

    For example:

    from some.package import CustomError

    class NewException(Exception):...

    def something(i):
    if i == 2:
    raise RuntimeError("This is a runtime error")
    else:
    raise CustomError("This is a custom error")

    try:
    something()
    except ValueError:
    raise
    except Exception as e:
    raise NewException(e) from e


    In the case of this function I would like to get a set of {<class RuntimeError>, <class some.package.CustomError>, <class ValueError>, <class [function_path].NewException>}.

    My current (and unfinished) solution is using the ast and inspect module to parse the function's source code into an AST and collect the exceptions there but I am stuck with detecting custom exceptions as the program crashes while evaluating them.

    import inspect
    import ast

    def _analyze_function(function: Callable[..., Any]):
    exceptions: set[type[BaseException]] = set()
    abstract_syntax_tree = ast.parse(inspect.getsource(function), mode="exec")
    for node in ast.walk(abstract_syntax_tree):
    if not isinstance(node, ast.Raise):
    continue

    if node.exc is None:
    print("No exception specified")
    continue

    match type(node.exc):
    case ast.Call:
    call_result = type(eval(ast.unparse(node.exc)))
    if not issubclass(call_result, BaseException):
    continue
    exceptions.add(call_result)
    case _:
    pass


    A problem with this approach is that there is external code execution which could lead to malicious code being evaluated.

    Continue reading...

Compartilhe esta Página