refex.python.matchers
¶
base_matchers
¶
Control Flow Matchers¶
-
class
Anything
(**kwargs)¶ Matches anything, similar to the regex
.
.Also available as
_
in--mode=py
.
-
class
Unless
(**kwargs)¶ Inverts a matcher and discard its bindings.
-
class
AllOf
(**kwargs)¶ Matches if and only if all submatchers do, and merges the results.
-
class
AnyOf
(**kwargs)¶ Matches if at least one submatcher does, and returns the first result.
-
class
Once
(**kwargs)¶ Runs the submatcher at most once successfully.
Matches if the submatcher has ever matched, including in this run. Fails if the matcher has not ever matched.
If
key
is provided, then any otherOnce()
with the same key shares state, and is considered equivalent for the sake of the above.
Examples¶
These matchers will match anything:
Anything()
Unless(Unless(Anything()))
AllOf(Anything(), Anything())
AllOf(Anything())
AllOf()
These matchers will match nothing:
Unless(Anything())
AllOf(Unless(Anything()))
AnyOf()
Binding Manipulation Matchers¶
-
class
Bind
(**kwargs)¶ Binds an AST-matcher expression to a name in the result.
- Parameters
name – The name to bind to. Valid names must be words that don’t begin with a double-underscore (
__
).submatcher – The matcher whose result will be bound to
name
.on_conflict – A conflict resolution strategy. Must be a member of
matcher.BindConflict
, orNone
for the default strategy (ACCEPT
).on_merge – A merge strategy. Must be a member of
matcher.BindMerge
, or None for the default strategy (KEEP_LAST
).
-
class
Rebind
(**kwargs)¶ Change the binding settings for all bindings in a submatcher.
For example, one might want bindings in one part of the AST matcher to merge with each other, but then want it to be an error if these conflict anywhere else.
- Parameters
submatcher – The matcher whose bindings to rewrite.
on_conflict – A conflict resolution strategy. Must be a member of
matcher.BindConflict
, orNone
ifon_conflict
is not to be changed.on_merge – A merge strategy. Must be a member of
matcher.BindMerge
, orNone
ifon_merge
is not to be changed.
-
class
StringMatch
(**kwargs)¶ Creates a synthetic string match.
For example,
Bind("foo", StringMatch("asd"))`
will result in being able to use$foo
in substitutions, where it will be replaced withasd
.Since this produces a simple string match, it can only be used inside of non-syntactic templates, such as ShTemplate.
Python Data Structure Matchers¶
-
class
Equals
(**kwargs)¶ Matches a candidate iff it equals
value
.
-
class
TypeIs
(**kwargs)¶ Matches a candidate iff its type is precisely
_type
.For example,
TypeIs(ast.Expr)
is roughly equivalent to the emptyast_matchers.Expr()
.(This does not check any type information for the code that this candidate AST node might represent.)
-
class
Contains
(**kwargs)¶ Matches a collection if any item matches the given matcher.
Fails the match if the candidate is not iterable.
-
class
HasItem
(**kwargs)¶ Matches a container iff
submatcher
matchescontainer[index]
.Fails the match if the container doesn’t contain the key, or if the candidate node is not a container at all.
-
class
ItemsAre
(**kwargs)¶ Matches a sequence with an exact set of elements.
The matched sequence must have exactly the same number of elements (support
len()
) and each element will be matched against the corresponding matcher inmatchers
.For example, this will create a matcher to match
[1, 2]
, witha=1
andb=2
:>>> m = ItemsAre([Bind('a'), Bind('b')])
File Content Matchers¶
-
class
MatchesRegex
(**kwargs)¶ Matches a candidate iff it matches the
regex
.The match must be complete – the regex must match the full AST, not just a substring of it. (i.e. this has
re.fullmatch
semantics.)Any named groups are added to the bindings – e.g.
(xyz)
does not add anything to the bindings, but(?P<name>xyz)
will bindname
to the subspan'xyz'
.The bound matches are neither lexical nor syntactic, but purely on codepoint spans.
-
class
FileMatchesRegex
(**kwargs)¶ Matches iff
regex
matches anywhere in the candidate’s file.
syntax_matchers
¶
High level pattern matchers on AST nodes.
These should be preferred to ast_matchers
, as they
are safer and less brittle.
These are also available on the command line:
Syntax¶
Syntax patterns use $
-prefixed words as metavariables, where
that variable can stand for any syntax tree. For example, $x + 3
matches
any addition operation where the right hand side is 3
.
Additional restrictions can be placed on the tree using the restrictions
parameter. For example, restrictions={'x': ExprPattern('4')}
specifies
that $x
is not a wildcard, but rather, only matches an ExprPattern(4)
.
Warning
Patterns will match _exactly_ the same AST – down to the order of members in a set. These patterns are still useful tools, but should be combined with other matchers to match exactly what you want.
>>> list(matcher.find_iter(
... ExprPattern('{1, 2}'),
... matcher.parse_ast('{2, 1}'))) # fails
[]
Metavariables¶
Metavariables can be reused in a pattern, which constrains them to match an
equivalent AST (BindConflict.MERGE_EQUIVALENT_AST
).
For example, [$x for $x in $y]
will match [a for a in b]
, but not
[a1 for a2 in b]
.
For convenience, these are rebound to normal Bind()
variables outside of the
pattern matcher.
ExprPattern¶
-
class
ExprPattern
(**kwargs)¶ An AST matcher for a pattern expression.
ExprPattern creates a matcher that exactly matches a given AST, but also allows placeholders. For example, this will match any addition of two variables named literally foo and bar:
ExprPattern('foo + bar')
But this will match any addition expression at all:
ExprPattern('$foo + $bar')
In addition, whatever expressions $foo or $bar matched will be a bound variable in the match (under ‘foo’ and ‘bar’).
- Parameters
pattern – The pattern to match, an expression.
restrictions – (optional) A dict mapping metavariables to matchers.
StmtPattern¶
-
class
StmtPattern
(**kwargs)¶ An AST matcher for a pattern statement.
StmtPattern
is likeExprPattern
, but for an entire (single) statement!Like
ExprPattern
,StmtPattern
creates a matcher that exactly matches a given AST, but also allows placeholders. For example, this will match any assignment where the literal variablefoo
is set to the literal variablebar
:StmtPattern('foo = bar')
But this will match any assignment statement at all:
StmtPattern('$foo = $bar'}
- Parameters
pattern – The pattern to match, a statement.
restrictions – (optional) A dict mapping metavariables to matchers.
Tree-walking Matchers¶
-
class
HasParent
(**kwargs)¶ Matches an AST node if its direct parent matches the submatcher.
An AST node in this context is considered to be an AST object or a list object. Only direct parents are yielded – the exact object x s.t. the candidate is
x.y
orx[y]
, for somey
. There is no recursive traversal of any kind.Fails the match if the candidate node is not an AST object or list.
-
class
IsOrHasAncestor
(**kwargs)¶ Matches a candidate if it or any ancestor matches the submatcher.
If the candidate directly matches, then that match is returned. Otherwise, the candidate is recursively traversed using
HasParent
until a match is found.
-
class
HasAncestor
(**kwargs)¶ Matches an AST node if any ancestor matches the submatcher.
This is equivalent to
HasParent(IsOrHasAncestor(...))
.
-
class
HasChild
(**kwargs)¶ Matches an AST node if a direct child matches the submatcher.
An AST node in this context is considered to be an AST object or a list object. Only direct children are yielded –
AST.member
orlist[index]
. There is no recursive traversal of any kind.Fails the match if the candidate node is not an AST object or list.
-
class
IsOrHasDescendant
(**kwargs)¶ Matches a candidate if it or any descendant matches the submatcher.
If the candidate directly matches, then that match is returned. Otherwise, the candidate is recursively traversed using
HasChild
until a match is found.
-
class
HasDescendant
(**kwargs)¶ Matches an AST node if any descendant matches the submatcher.
This is equivalent to
HasChild(IsOrHasDescendant(...))
.
-
class
HasFirstAncestor
(first_ancestor, also_matches)¶ The first ancestor to match
first_ancestor
also matchesalso_matches
.For example, “the function that I am currently in is a generator function” is a matcher that one might want to create, and can be created using
HasFirstAncestor
.
-
class
HasPrevSibling
(**kwargs)¶ Matches a node if the immediate prior sibling in the node list matches
submatcher
.
-
class
HasNextSibling
(**kwargs)¶ Matches a node if the immediate next sibling in the node list matches
submatcher
.
High Level Syntax Matchers¶
-
class
NamedFunctionDefinition
(**kwargs)¶ A matcher for a named function definition.
This includes both regular functions and async functions.
- Parameters
body – The matcher for the function body.
returns – The matcher for the return type annotation.
-
class
InNamedFunction
(**kwargs)¶ Matches anything directly inside of a function that matches
submatcher
.
-
class
WithTopLevelImport
(**kwargs)¶ Matches an AST node if there is a top level import for the given module.
- Parameters
submatcher – The matcher to filter results from.
module_name – The fully-qualified module name as a string. e.g.
'os.path'
.as_name – The variable name the module is imported as. Defaults to the name one would get from e.g.
from os import path
.
lexical_matchers
¶
lexical_matchers
provides lexical tweaks and
filters on lexical matches.
-
class
HasComments
(**kwargs)¶ Filter results to only those lexical spans that have comments inside.
- Parameters
submatcher – A Matcher matching a LexicalMatch.
-
class
NoComments
(**kwargs)¶ Filter results to only those lexical spans that have no comments inside.
- Parameters
submatcher – A Matcher matching a LexicalMatch.
ast_matchers
¶
Automatically generated low-level AST node matchers.
For each AST node in the ast
module, there is a matcher with the same
name, which accepts submatchers for each of its attributes.
For example, if the Python grammar has an entry like:
UnaryOp(unaryop op, expr operand)
Then the following matcher will match any ast.UnaryOp
:
ast_matchers.UnaryOp()
And this will match any ast.UnaryOp
with an op
attribute matching
submatcher1
, and an operand
attribute matching submatcher2
:
ast_matchers.UnaryOp(op=submatcher1, operand=submatcher2)
(See the unit tests for more examples.)
-
class
Subscript
(**kwargs)¶
-
class
Num
(**kwargs)¶
-
class
Bytes
(**kwargs)¶
-
class
Str
(**kwargs)¶
-
class
NameConstant
(**kwargs)¶
-
class
Ellipsis
(**kwargs)¶
-
class
AST
(**kwargs)¶
-
class
Add
(**kwargs)¶
-
class
And
(**kwargs)¶
-
class
AnnAssign
(**kwargs)¶
-
class
Assert
(**kwargs)¶
-
class
Assign
(**kwargs)¶
-
class
AsyncFor
(**kwargs)¶
-
class
AsyncFunctionDef
(**kwargs)¶
-
class
AsyncWith
(**kwargs)¶
-
class
Attribute
(**kwargs)¶
-
class
AugAssign
(**kwargs)¶
-
class
AugLoad
(**kwargs)¶
-
class
AugStore
(**kwargs)¶
-
class
Await
(**kwargs)¶
-
class
BinOp
(**kwargs)¶
-
class
BitAnd
(**kwargs)¶
-
class
BitOr
(**kwargs)¶
-
class
BitXor
(**kwargs)¶
-
class
BoolOp
(**kwargs)¶
-
class
Break
(**kwargs)¶
-
class
Call
(**kwargs)¶
-
class
ClassDef
(**kwargs)¶
-
class
Compare
(**kwargs)¶
-
class
Constant
(**kwargs)¶
-
class
Continue
(**kwargs)¶
-
class
Del
(**kwargs)¶
-
class
Delete
(**kwargs)¶
-
class
Dict
(**kwargs)¶
-
class
DictComp
(**kwargs)¶
-
class
Div
(**kwargs)¶
-
class
Eq
(**kwargs)¶
-
class
ExceptHandler
(**kwargs)¶
-
class
Expr
(**kwargs)¶
-
class
Expression
(**kwargs)¶
-
class
ExtSlice
(**kwargs)¶
-
class
FloorDiv
(**kwargs)¶
-
class
For
(**kwargs)¶
-
class
FormattedValue
(**kwargs)¶
-
class
FunctionDef
(**kwargs)¶
-
class
GeneratorExp
(**kwargs)¶
-
class
Global
(**kwargs)¶
-
class
Gt
(**kwargs)¶
-
class
GtE
(**kwargs)¶
-
class
If
(**kwargs)¶
-
class
IfExp
(**kwargs)¶
-
class
Import
(**kwargs)¶
-
class
ImportFrom
(**kwargs)¶
-
class
In
(**kwargs)¶
-
class
Index
(**kwargs)¶
-
class
Interactive
(**kwargs)¶
-
class
Invert
(**kwargs)¶
-
class
Is
(**kwargs)¶
-
class
IsNot
(**kwargs)¶
-
class
JoinedStr
(**kwargs)¶
-
class
LShift
(**kwargs)¶
-
class
Lambda
(**kwargs)¶
-
class
List
(**kwargs)¶
-
class
ListComp
(**kwargs)¶
-
class
Load
(**kwargs)¶
-
class
Lt
(**kwargs)¶
-
class
LtE
(**kwargs)¶
-
class
MatMult
(**kwargs)¶
-
class
Mod
(**kwargs)¶
-
class
Module
(**kwargs)¶
-
class
Mult
(**kwargs)¶
-
class
Name
(**kwargs)¶
-
class
Nonlocal
(**kwargs)¶
-
class
Not
(**kwargs)¶
-
class
NotEq
(**kwargs)¶
-
class
NotIn
(**kwargs)¶
-
class
Or
(**kwargs)¶
-
class
Param
(**kwargs)¶
-
class
Pass
(**kwargs)¶
-
class
Pow
(**kwargs)¶
-
class
RShift
(**kwargs)¶
-
class
Raise
(**kwargs)¶
-
class
Return
(**kwargs)¶
-
class
Set
(**kwargs)¶
-
class
SetComp
(**kwargs)¶
-
class
Slice
(**kwargs)¶
-
class
Starred
(**kwargs)¶
-
class
Store
(**kwargs)¶
-
class
Sub
(**kwargs)¶
-
class
Suite
(**kwargs)¶
-
class
Try
(**kwargs)¶
-
class
Tuple
(**kwargs)¶
-
class
UAdd
(**kwargs)¶
-
class
USub
(**kwargs)¶
-
class
UnaryOp
(**kwargs)¶
-
class
While
(**kwargs)¶
-
class
With
(**kwargs)¶
-
class
Yield
(**kwargs)¶
-
class
YieldFrom
(**kwargs)¶
-
class
alias
(**kwargs)¶
-
class
arg
(**kwargs)¶
-
class
arguments
(**kwargs)¶
-
class
boolop
(**kwargs)¶
-
class
cmpop
(**kwargs)¶
-
class
comprehension
(**kwargs)¶
-
class
excepthandler
(**kwargs)¶
-
class
expr
(**kwargs)¶
-
class
expr_context
(**kwargs)¶
-
class
keyword
(**kwargs)¶
-
class
mod
(**kwargs)¶
-
class
operator
(**kwargs)¶
-
class
slice
(**kwargs)¶
-
class
stmt
(**kwargs)¶
-
class
unaryop
(**kwargs)¶
-
class
withitem
(**kwargs)¶
extern_matchers
¶
Matchers for integrating with external tooling.
-
class
RewriteFile
(metavariable_prefix: str)¶ Base class for whole-file rewrites.
-
class
ExternalCommand
(metavariable_prefix: str, command: Union[str, Sequence[str]], shell: bool = False)¶ Runs an external command to modify a file.