如何获得Python AST中节点的下一个同级?

问题描述

我写了Flake8-simplifyPyPIGitHub),这是一个Flake8插件,可以找到可以简化的代码

我要找到的一种模式是:

# Bad
for x in iterable:
    if check(x):
        return True
return False

# Good
return any(check(x) for x in iterable)

“不良”部分的AST如下:

[
        For(
            target=Name(id='x',ctx=Store()),iter=Name(id='iterable',ctx=Load()),body=[
                If(
                    test=Call(
                        func=Name(id='check',args=[Name(id='x',ctx=Load())],keywords=[],),body=[
                        Return(
                            value=Constant(value=True,kind=None),],orelse=[],type_comment=None,Return(
            value=Constant(value=False,]

这里的问题是我需要检查For Return。 **在给定Python ast.For节点的情况下,如何获得下一个(同级)节点?

我尝试过的

import ast
from typing import List,Tuple

SIM110 = "SIM110 Use 'return any({check} for {target} in {iterable})'"


class Visitor(ast.NodeVisitor):
    def visit_For(self,node: ast.For) -> None:
        self.errors += _get_sim110(node)
        self.generic_visit(node)


def _get_sim110(node: ast.ForOp) -> List[Tuple[int,int,str]]:
    errors: List[Tuple[int,str]] = []
    if not (
        len(node.body) == 1
        and isinstance(node.body[0],ast.If)
        and len(node.body[0].body) == 1
        and isinstance(node.body[0].body[0],ast.Return)
        and node.body[0].body[0].value is True
        and [Todo: after the For loop is a "return False"]
    ):
        return errors

    # Prepare the message
    check = to_source(node.body[0].test)
    target = to_source(node.target)
    iterable = to_source(node.iter)
    errors.append(
        (
            node.lineno,node.col_offset,SIM110.format(check=check,target=target,iterable=iterable),)
    )
    return errors


def to_source(node: ast.expr) -> str:
    import astor
    source = astor.to_source(node).strip()
    return source

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)