Python 匹配装饰器的 EBNF 语法
Python EBNF Syntax to Match a Decorator
我有一个非常大的项目,我需要将一些模块从 bar
移动到 foo.bar
,然后更新所有函数调用以反映新位置。
这对函数调用很有效,但我在构建匹配装饰器的模式时遇到问题。
我喜欢匹配的代码是::
from unittest.mock import patch
@patch('bar')
def func(self, patcher):
...
我想把上面的补丁改成@patch('foo.bar')
。
我当前的模式在函数调用时匹配 patch
,但在用作装饰器时不匹配::
class FixRenameMockPatch(fixer_base.BaseFix):
PATTERN = """
power<
'patch' args=trailer< '(' [any] ')' >
>
"""
def transform(self, node, results):
...
我真的很难理解 https://docs.python.org/3.8/reference/grammar.html 上的语法,所以我的修复程序主要基于 lib2to3
.
的源代码
如何编写上面的模式来匹配 patch
的所有用途,包括装饰器和上下文管理器?以及完全限定使用的补丁,例如mock.patch
或unittest.mock.patch
?
你可以试试这个
PATTERN = "decorator< '@' 'patch' '(' [any] ')' any* >"
或者
PATTERN = """
decorator< '@' 'patch' '(' [any] ')' any* >
| decorator< '@' dotted_name< 'mock' '.' 'patch' > '(' [any] ')' any* >
"""
如果你也想匹配 @mock.patch
。
有 a script (written in Python2, Py3 version here) 来解析您的文件并显示解析后的模式,我觉得这很有用。例如,您将 test.py
创建为
from unittest.mock import patch
@patch('bar')
def func(self, patcher):
print('foo')
然后运行find_pattern.py
,回车直到出现你要解析的行,然后输入一些字符(下例是y),回车显示解析结果:
$ python find_pattern.py -f test.py
' unittest.mock'
'from unittest.mock import patch'
'from unittest.mock import patch\n'
"\n@patch('bar')\n"
y
decorator< '@' 'patch' '(' "'bar'" ')' '\n' >
我有一个非常大的项目,我需要将一些模块从 bar
移动到 foo.bar
,然后更新所有函数调用以反映新位置。
这对函数调用很有效,但我在构建匹配装饰器的模式时遇到问题。
我喜欢匹配的代码是::
from unittest.mock import patch
@patch('bar')
def func(self, patcher):
...
我想把上面的补丁改成@patch('foo.bar')
。
我当前的模式在函数调用时匹配 patch
,但在用作装饰器时不匹配::
class FixRenameMockPatch(fixer_base.BaseFix):
PATTERN = """
power<
'patch' args=trailer< '(' [any] ')' >
>
"""
def transform(self, node, results):
...
我真的很难理解 https://docs.python.org/3.8/reference/grammar.html 上的语法,所以我的修复程序主要基于 lib2to3
.
如何编写上面的模式来匹配 patch
的所有用途,包括装饰器和上下文管理器?以及完全限定使用的补丁,例如mock.patch
或unittest.mock.patch
?
你可以试试这个
PATTERN = "decorator< '@' 'patch' '(' [any] ')' any* >"
或者
PATTERN = """
decorator< '@' 'patch' '(' [any] ')' any* >
| decorator< '@' dotted_name< 'mock' '.' 'patch' > '(' [any] ')' any* >
"""
如果你也想匹配 @mock.patch
。
有 a script (written in Python2, Py3 version here) 来解析您的文件并显示解析后的模式,我觉得这很有用。例如,您将 test.py
创建为
from unittest.mock import patch
@patch('bar')
def func(self, patcher):
print('foo')
然后运行find_pattern.py
,回车直到出现你要解析的行,然后输入一些字符(下例是y),回车显示解析结果:
$ python find_pattern.py -f test.py
' unittest.mock'
'from unittest.mock import patch'
'from unittest.mock import patch\n'
"\n@patch('bar')\n"
y
decorator< '@' 'patch' '(' "'bar'" ')' '\n' >