微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决如何获得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 举报,一经查实,本站将立刻删除。