gpt4 book ai didi

python - 匹配 lib2to3 的 1-or-2-arg 函数调用的模式

转载 作者:太空狗 更新时间:2023-10-30 01:28:02 25 4
gpt4 key购买 nike

我有一个脚本可以重写 Python 模块,以便将所有出现的 func(a) 转换为 func2(a is None)。我现在也想支持 func(a, msg) 成为 func2(a is None, msg),但我找不到可以执行此操作的模式。以下显示了我的尝试:

from lib2to3 import refactor, fixer_base
from textwrap import dedent

PATTERN_ONE_ARG = """power< 'func' trailer< '(' arglist< obj1=any > ')' > >"""

PATTERN_ONE_OR_TWO_ARGS = """power< 'func' trailer< '(' arglist< obj1=any [',' obj2=any] > ')' > >"""


class TestFixer(fixer_base.BaseFix):
def __init__(self, options, fixer_log):
# self.PATTERN = PATTERN_ONE_ARG
self.PATTERN = PATTERN_ONE_OR_TWO_ARGS

super().__init__(options, fixer_log)

def transform(self, node, results):
print("found it")
return node


class TestRefactoringTool(refactor.MultiprocessRefactoringTool):
def get_fixers(self):
fixer = TestFixer(self.options, self.fixer_log)
return [fixer], []


def test():
test_script = """
log.print("hi")
func(a, "12345")
func(a, msg="12345")
func(a)
"""
refac.refactor_string(dedent(test_script), 'script')


flags = dict(print_function=True)
refac = TestRefactoringTool([], flags)
test()

对于在 test_script 字符串中找到的每个 func,我应该看到一个“found it”,所以总共有 3 个,但我只看到 2 个打印出来,这意味着模式匹配器未找到 func(a)。我的模式基于 lib2to3.fixes 中可用的修复程序,但我一定遗漏了一个微妙之处。任何人都知道谁来修复 PATTERN_ONE_OR_TWO_ARGS 以便找到所有 3 个函数?

我知道我可以创建一个单独的修复器实例,但使用该模式可以让我免于编写大量代码(我有几十个这样的修复器,那么总数将是 24 个!)。

最佳答案

找到了:

PATTERN_ONE_OR_TWO_ARGS = """
power< 'func' trailer< '('
( not(arglist | argument<any '=' any>) obj1=any
| arglist< obj1=any ',' obj2=any > )
')' > >
"""

如果 transform() 是:

def transform(self, node, results):
if 'obj2' in results:
print("found 2", results['obj1'], results['obj2'])
else:
print("found 1", results['obj1'])
return node

然后为

test_script = """
log.print("hi")
func(a, "12345")
func(a, msg="12345")
func(a)
func(k=a)
"""

输出是

found 2 a  "12345"
found 2 a msg="12345"
found 1 a

我还找到了http://python3porting.com/fixers.html#fixers-chapter这表明我可以覆盖 match() 方法而不是使用模式。四种有趣的模式是:

PATTERN_ONE_ARG_OR_KWARG   = """power< 'func' trailer< '(' not(arglist) obj1=any                         ')' > >"""
PATTERN_ONE_ARG = """power< 'func' trailer< '(' not(arglist | argument<any '=' any>) obj1=any ')' > >"""
PATTERN_ONE_KWARG = """power< 'func' trailer< '(' obj1=argument< any '=' any > ')' > >"""
PATTERN_TWO_ARGS_OR_KWARGS = """power< 'func' trailer< '(' arglist< obj1=any ',' obj2=any > ')' > >"""

关于python - 匹配 lib2to3 的 1-or-2-arg 函数调用的模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35169154/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com