Matchers
Matchers are provided as a way of asking whether a particular LibCST node and its
children match a particular shape. It is possible to write a visitor that
tracks attributes using visit_<Node>
methods. It is also possible to implement
manual instance checking and traversal of a node’s children. However, both are
cumbersome to write and hard to understand. Matchers offer a more concise way of
defining what attributes on a node matter when matching against predefined patterns.
To accomplish this, a matcher has been created which corresponds to each LibCST
node documented in Nodes. Matchers default each of their attributes
to the special sentinel matcher DoNotCare()
. When constructing
a matcher, you can initialize the node with only the values of attributes that
you are concerned with, leaving the rest of the attributes set to
DoNotCare()
in order to skip comparing against them.
Matcher APIs
Functions
Matchers can be used either by calling matches()
or
findall()
directly, or by using various decorators to
selectively control when LibCST calls visitor functions.
- libcst.matchers.matches(node: MaybeSentinel | RemovalSentinel | CSTNode, matcher: BaseMatcherNode, *, metadata_resolver: MetadataDependent | MetadataWrapper | None = None) bool [source]
Given an arbitrary node from a LibCST tree, and an arbitrary matcher, returns
True
if the node matches the shape defined by the matcher. Note that the node can also be aRemovalSentinel
or aMaybeSentinel
in order to use matches directly on transform results and node attributes. In these cases,matches()
will always returnFalse
.The matcher can be any concrete matcher that subclasses from
BaseMatcherNode
, or aOneOf
/AllOf
special matcher. It cannot be aMatchIfTrue
or aDoesNotMatch()
matcher since these are redundant. It cannot be aAtLeastN
orAtMostN
matcher because these types are wildcards which can only be used inside sequences.
- libcst.matchers.findall(tree: MaybeSentinel | RemovalSentinel | CSTNode | MetadataWrapper, matcher: BaseMatcherNode | MatchIfTrue[CSTNode] | _BaseMetadataMatcher, *, metadata_resolver: MetadataDependent | MetadataWrapper | None = None) Sequence[CSTNode] [source]
Given an arbitrary node from a LibCST tree and an arbitrary matcher, iterates over that node and all children returning a sequence of all child nodes that match the given matcher. Note that the tree can also be a
RemovalSentinel
or aMaybeSentinel
in order to use findall directly on transform results and node attributes. In these cases,findall()
will always return an empty sequence. Note also that instead of a LibCST tree, you can instead pass in aMetadataWrapper
. This mirrors the fact that you can callvisit
on aMetadataWrapper
in order to iterate over it with a transform. If you provide a wrapper for the tree and do not set themetadata_resolver
parameter specifically, it will automatically be set to the wrapper for you.The matcher can be any concrete matcher that subclasses from
BaseMatcherNode
, or aOneOf
/AllOf
special matcher. Unlikematches()
, it can also be aMatchIfTrue
orDoesNotMatch()
matcher, since we are traversing the tree looking for matches. It cannot be aAtLeastN
orAtMostN
matcher because these types are wildcards which can only be used inside sequences.
- libcst.matchers.extract(node: MaybeSentinel | RemovalSentinel | CSTNode, matcher: BaseMatcherNode, *, metadata_resolver: MetadataDependent | MetadataWrapper | None = None) Dict[str, CSTNode | Sequence[CSTNode]] | None [source]
Given an arbitrary node from a LibCST tree, and an arbitrary matcher, returns a dictionary of extracted children of the tree if the node matches the shape defined by the matcher. Note that the node can also be a
RemovalSentinel
or aMaybeSentinel
in order to use extract directly on transform results and node attributes. In these cases,extract()
will always returnNone
.If the node matches the shape defined by the matcher, the return will be a dictionary whose keys are defined by the
SaveMatchedNode()
name parameter, and the values will be the node or sequence that was present at that location in the shape defined by the matcher. In the case of multipleSaveMatchedNode()
matches with the same name, parent nodes will take prioirity over child nodes, and nodes later in sequences will take priority over nodes earlier in sequences.The matcher can be any concrete matcher that subclasses from
BaseMatcherNode
, or aOneOf
/AllOf
special matcher. It cannot be aMatchIfTrue
or aDoesNotMatch()
matcher since these are redundant. It cannot be aAtLeastN
orAtMostN
matcher because these types are wildcards which can only be used inside sequences.
- libcst.matchers.extractall(tree: MaybeSentinel | RemovalSentinel | CSTNode | MetadataWrapper, matcher: BaseMatcherNode | MatchIfTrue[CSTNode] | _BaseMetadataMatcher, *, metadata_resolver: MetadataDependent | MetadataWrapper | None = None) Sequence[Dict[str, CSTNode | Sequence[CSTNode]]] [source]
Given an arbitrary node from a LibCST tree and an arbitrary matcher, iterates over that node and all children returning a sequence of dictionaries representing the saved and extracted children specified by
SaveMatchedNode()
for each match found in the tree. This is analogous to running afindall()
over a tree, then runningextract()
with the same matcher over each of the returned nodes. Note that the tree can also be aRemovalSentinel
or aMaybeSentinel
in order to use extractall directly on transform results and node attributes. In these cases,extractall()
will always return an empty sequence. Note also that instead of a LibCST tree, you can instead pass in aMetadataWrapper
. This mirrors the fact that you can callvisit
on aMetadataWrapper
in order to iterate over it with a transform. If you provide a wrapper for the tree and do not set themetadata_resolver
parameter specifically, it will automatically be set to the wrapper for you.The matcher can be any concrete matcher that subclasses from
BaseMatcherNode
, or aOneOf
/AllOf
special matcher. Unlikematches()
, it can also be aMatchIfTrue
orDoesNotMatch()
matcher, since we are traversing the tree looking for matches. It cannot be aAtLeastN
orAtMostN
matcher because these types are wildcards which can only be usedi inside sequences.
- libcst.matchers.replace(tree: MaybeSentinel | RemovalSentinel | CSTNode | MetadataWrapper, matcher: BaseMatcherNode | MatchIfTrue[CSTNode] | _BaseMetadataMatcher, replacement: MaybeSentinel | RemovalSentinel | CSTNode | Callable[[CSTNode, Dict[str, CSTNode | Sequence[CSTNode]]], MaybeSentinel | RemovalSentinel | CSTNode], *, metadata_resolver: MetadataDependent | MetadataWrapper | None = None) MaybeSentinel | RemovalSentinel | CSTNode [source]
Given an arbitrary node from a LibCST tree and an arbitrary matcher, iterates over that node and all children and replaces each node that matches the supplied matcher with a supplied replacement. Note that the replacement can either be a valid node type, or a callable which takes the matched node and a dictionary of any extracted child values and returns a valid node type. If you provide a valid LibCST node type,
replace()
will replace every node that matches the supplied matcher with the replacement node. If you provide a callable,replace()
will runextract()
over all matched nodes and call the callable with both the node that should be replaced and the dictionary returned byextract()
. Under all circumstances a new tree is returned.extract()
should be viewed as a short-cut to writing a transform which also returns a new tree even when no changes are applied.Note that the tree can also be a
RemovalSentinel
or aMaybeSentinel
in order to use replace directly on transform results and node attributes. In these cases,replace()
will return the sameRemovalSentinel
orMaybeSentinel
. Note also that instead of a LibCST tree, you can instead pass in aMetadataWrapper
. This mirrors the fact that you can callvisit
on aMetadataWrapper
in order to iterate over it with a transform. If you provide a wrapper for the tree and do not set themetadata_resolver
parameter specifically, it will automatically be set to the wrapper for you.The matcher can be any concrete matcher that subclasses from
BaseMatcherNode
, or aOneOf
/AllOf
special matcher. Unlikematches()
, it can also be aMatchIfTrue
orDoesNotMatch()
matcher, since we are traversing the tree looking for matches. It cannot be aAtLeastN
orAtMostN
matcher because these types are wildcards which can only be usedi inside sequences.
Decorators
The following decorators can be placed onto a method in a visitor or transformer in order to convert it into a visitor which is called when the provided matcher is true.
- libcst.matchers.visit(matcher: BaseMatcherNode) Callable[[_CSTVisitFuncT], _CSTVisitFuncT] [source]
A decorator that allows a method inside a
MatcherDecoratableTransformer
or aMatcherDecoratableVisitor
visitor to be called when visiting a node that matches the provided matcher. Note that you can use this in combination withcall_if_inside()
andcall_if_not_inside()
decorators. Unlike explicitvisit_<Node>
andleave_<Node>
methods, functions decorated with this decorator cannot stop child traversal by returningFalse
. Decorated visit functions should always have a return annotation ofNone
.There is no restriction on the number of visit decorators allowed on a method. There is also no restriction on the number of methods that may be decorated with the same matcher. When multiple visit decorators are found on the same method, they act as a simple or, and the method will be called when any one of the contained matches is
True
.
- libcst.matchers.leave(matcher: BaseMatcherNode) Callable[[_CSTVisitFuncT], _CSTVisitFuncT] [source]
A decorator that allows a method inside a
MatcherDecoratableTransformer
or aMatcherDecoratableVisitor
visitor to be called when leaving a node that matches the provided matcher. Note that you can use this in combination withcall_if_inside()
andcall_if_not_inside()
decorators.There is no restriction on the number of leave decorators allowed on a method. There is also no restriction on the number of methods that may be decorated with the same matcher. When multiple leave decorators are found on the same method, they act as a simple or, and the method will be called when any one of the contained matches is
True
.
The following decorators can be placed onto any existing visit_<Node>
or
leave_<Node>
visitor, as well as any visitor created using either
visit()
or leave()
. They control
whether the visitor itself gets called or skipped by LibCST when traversing a tree.
Note that when a visitor function is skipped, its children will still be visited
based on the rules set forth in Visitors. Namely, if you have a separate
visit_<Node>
visitor that returns False
for a particular node, we will not
traverse to its children.
- libcst.matchers.call_if_inside(matcher: BaseMatcherNode) Callable[[_CSTVisitFuncT], _CSTVisitFuncT] [source]
A decorator for visit and leave methods inside a
MatcherDecoratableTransformer
or aMatcherDecoratableVisitor
. A method that is decorated with this decorator will only be called if it or one of its parents matches the supplied matcher. Use this to selectively gate visit and leave methods to be called only when inside of another relevant node. Note that this works for both node and attribute methods, so you can decorate avisit_<Node>
or avisit_<Node>_<Attr>
method.
- libcst.matchers.call_if_not_inside(matcher: BaseMatcherNode) Callable[[_CSTVisitFuncT], _CSTVisitFuncT] [source]
A decorator for visit and leave methods inside a
MatcherDecoratableTransformer
or aMatcherDecoratableVisitor
. A method that is decorated with this decorator will only be called if it or one of its parents does not match the supplied matcher. Use this to selectively gate visit and leave methods to be called only when outside of another relevant node. Note that this works for both node and attribute methods, so you can decorate avisit_<Node>
or avisit_<Node>_<Attr>
method.
When using matcher decorators, your visitors must subclass from
MatcherDecoratableVisitor
instead of libcst.CSTVisitor
,
and from MatcherDecoratableTransformer
instead of
libcst.CSTTransformer
. This is so that visitors and transformers not making
use of matcher decorators do not pay the extra cost of their implementation. Note that
if you do not subclass from MatcherDecoratableVisitor
or
MatcherDecoratableTransformer
, you can still use the
matches()
function.
Both of these classes are strict subclasses of their corresponding LibCST base class, so they can be used anywhere that expects a LibCST base class. See Visitors for more information.
- class libcst.matchers.MatcherDecoratableVisitor[source]
This class provides all of the features of a
libcst.CSTVisitor
, and additionally supports various decorators to control when methods get called when traversing a tree. Use this instead of alibcst.CSTVisitor
if you wish to do more powerful decorator-based visiting.- on_visit(node: CSTNode) bool [source]
Called every time a node is visited, before we’ve visited its children.
Returns
True
if children should be visited, and returnsFalse
otherwise.
- on_leave(original_node: CSTNode) None [source]
Called every time we leave a node, after we’ve visited its children. If the
on_visit()
function for this node returnsFalse
, this function will still be called on that node.
- on_visit_attribute(node: CSTNode, attribute: str) None [source]
Called before a node’s child attribute is visited and after we have called
on_visit()
on the node. A node’s child attributes are visited in the order that they appear in source that this node originates from.
- on_leave_attribute(original_node: CSTNode, attribute: str) None [source]
Called after a node’s child attribute is visited and before we have called
on_leave()
on the node.
- matches(node: MaybeSentinel | RemovalSentinel | CSTNode, matcher: BaseMatcherNode) bool [source]
A convenience method to call
matches()
without requiring an explicit parameter for metadata. Since our instance is an instance oflibcst.MetadataDependent
, we work as a metadata resolver. Please see documentation formatches()
as it is identical to this function.
- findall(tree: MaybeSentinel | RemovalSentinel | CSTNode, matcher: BaseMatcherNode | MatchIfTrue[CSTNode] | MatchMetadata | MatchMetadataIfTrue) Sequence[CSTNode] [source]
A convenience method to call
findall()
without requiring an explicit parameter for metadata. Since our instance is an instance oflibcst.MetadataDependent
, we work as a metadata resolver. Please see documentation forfindall()
as it is identical to this function.
- extract(node: MaybeSentinel | RemovalSentinel | CSTNode, matcher: BaseMatcherNode) Dict[str, CSTNode | Sequence[CSTNode]] | None [source]
A convenience method to call
extract()
without requiring an explicit parameter for metadata. Since our instance is an instance oflibcst.MetadataDependent
, we work as a metadata resolver. Please see documentation forextract()
as it is identical to this function.
- extractall(tree: MaybeSentinel | RemovalSentinel | CSTNode, matcher: BaseMatcherNode | MatchIfTrue[CSTNode] | MatchMetadata | MatchMetadataIfTrue) Sequence[Dict[str, CSTNode | Sequence[CSTNode]]] [source]
A convenience method to call
extractall()
without requiring an explicit parameter for metadata. Since our instance is an instance oflibcst.MetadataDependent
, we work as a metadata resolver. Please see documentation forextractall()
as it is identical to this function.
- replace(tree: MaybeSentinel | RemovalSentinel | CSTNode, matcher: BaseMatcherNode | MatchIfTrue[CSTNode] | MatchMetadata | MatchMetadataIfTrue, replacement: MaybeSentinel | RemovalSentinel | CSTNode | Callable[[CSTNode, Dict[str, CSTNode | Sequence[CSTNode]]], MaybeSentinel | RemovalSentinel | CSTNode]) MaybeSentinel | RemovalSentinel | CSTNode [source]
A convenience method to call
replace()
without requiring an explicit parameter for metadata. Since our instance is an instance oflibcst.MetadataDependent
, we work as a metadata resolver. Please see documentation forreplace()
as it is identical to this function.
- class libcst.matchers.MatcherDecoratableTransformer[source]
This class provides all of the features of a
libcst.CSTTransformer
, and additionally supports various decorators to control when methods get called when traversing a tree. Use this instead of alibcst.CSTTransformer
if you wish to do more powerful decorator-based visiting.- on_visit(node: CSTNode) bool [source]
Called every time a node is visited, before we’ve visited its children.
Returns
True
if children should be visited, and returnsFalse
otherwise.
- on_leave(original_node: CSTNodeT, updated_node: CSTNodeT) CSTNodeT | RemovalSentinel [source]
Called every time we leave a node, after we’ve visited its children. If the
on_visit()
function for this node returnsFalse
, this function will still be called on that node.original_node
is guaranteed to be the same node as is passed toon_visit()
, so it is safe to do state-based checks using theis
operator. Modifications should always be performed on theupdated_node
so as to not overwrite changes made by child visits.Returning
RemovalSentinel.REMOVE
indicates that the node should be removed from its parent. This is not always possible, and may raise an exception if this node is required. As a convenience, you can useRemoveFromParent()
as an alias toRemovalSentinel.REMOVE
.
- on_visit_attribute(node: CSTNode, attribute: str) None [source]
Called before a node’s child attribute is visited and after we have called
on_visit()
on the node. A node’s child attributes are visited in the order that they appear in source that this node originates from.
- on_leave_attribute(original_node: CSTNode, attribute: str) None [source]
Called after a node’s child attribute is visited and before we have called
on_leave()
on the node.Unlike
on_leave()
, this function does not allow modifications to the tree and is provided solely for state management.
- matches(node: MaybeSentinel | RemovalSentinel | CSTNode, matcher: BaseMatcherNode) bool [source]
A convenience method to call
matches()
without requiring an explicit parameter for metadata. Since our instance is an instance oflibcst.MetadataDependent
, we work as a metadata resolver. Please see documentation formatches()
as it is identical to this function.
- findall(tree: MaybeSentinel | RemovalSentinel | CSTNode, matcher: BaseMatcherNode | MatchIfTrue[CSTNode] | MatchMetadata | MatchMetadataIfTrue) Sequence[CSTNode] [source]
A convenience method to call
findall()
without requiring an explicit parameter for metadata. Since our instance is an instance oflibcst.MetadataDependent
, we work as a metadata resolver. Please see documentation forfindall()
as it is identical to this function.
- extract(node: MaybeSentinel | RemovalSentinel | CSTNode, matcher: BaseMatcherNode) Dict[str, CSTNode | Sequence[CSTNode]] | None [source]
A convenience method to call
extract()
without requiring an explicit parameter for metadata. Since our instance is an instance oflibcst.MetadataDependent
, we work as a metadata resolver. Please see documentation forextract()
as it is identical to this function.
- extractall(tree: MaybeSentinel | RemovalSentinel | CSTNode, matcher: BaseMatcherNode | MatchIfTrue[CSTNode] | MatchMetadata | MatchMetadataIfTrue) Sequence[Dict[str, CSTNode | Sequence[CSTNode]]] [source]
A convenience method to call
extractall()
without requiring an explicit parameter for metadata. Since our instance is an instance oflibcst.MetadataDependent
, we work as a metadata resolver. Please see documentation forextractall()
as it is identical to this function.
- replace(tree: MaybeSentinel | RemovalSentinel | CSTNode, matcher: BaseMatcherNode | MatchIfTrue[CSTNode] | MatchMetadata | MatchMetadataIfTrue, replacement: MaybeSentinel | RemovalSentinel | CSTNode | Callable[[CSTNode, Dict[str, CSTNode | Sequence[CSTNode]]], MaybeSentinel | RemovalSentinel | CSTNode]) MaybeSentinel | RemovalSentinel | CSTNode [source]
A convenience method to call
replace()
without requiring an explicit parameter for metadata. Since our instance is an instance oflibcst.MetadataDependent
, we work as a metadata resolver. Please see documentation forreplace()
as it is identical to this function.
Traversal Order
Visit and leave functions created using visit()
or
leave()
follow the traversal order rules laid out in
LibCST’s visitor Traversal Order with one additional rule. Any
visit function created using the visit()
decorator will be
called before a visit_<Node>
function if it is defined for your visitor.
The order in which various visit functions which are created with
visit()
are called is indeterminate, but all such functions
will be called before calling the visit_<Node>
method. Similarly, any leave
function created using the leave()
decorator will be called
after a leave_<Node>
function if it is defined for your visitor. The order
in which various leave functions which are created with
leave()
are called is indeterminate, but all such functions
will be called after calling the visit_<Node>
function if it is defined for
your visitor.
This has a few implications. The first is that if you return False
from a
visit_<Node>
method, we are guaranteed to call your decorated visit functions
as well. Second, when modifying a node in both leave_<Node>
and a visitor
created with leave()
, the original_node
will be unchanged
for both and the updated_node
available to the decorated leave method will be
the node that is returned by the leave_<Node>
method. Chaining modifications
across multiple leave functions is supported, but must be done with care.
Matcher Types
Concrete Matchers
For each node found in Nodes, a corresponding concrete matcher
has been generated. Each matcher has attributes identical to its LibCST node
counterpart. For example, libcst.Expr
includes the value
and semicolon
attributes, and therefore libcst.matchers.Expr
similarly includes the same
attributes. Just as libcst.Expr
’s value
is typed as taking a
libcst.BaseExpression
, libcst.matchers.Expr
’s value
is typed
as taking a libcst.matchers.BaseExpression
. For every node that exists in
LibCST, both concrete and abstract, a corresponding matcher has been defined.
There are a few special cases to the rules laid out above. For starters, matchers
don’t support evaluating MaybeSentinel
. There is no way to specify
that you wish to match against a MaybeSentinel
except with the
DoNotCare()
matcher. This tends not to be an issue in
practice because MaybeSentinel
is only found on syntax nodes.
While there are base classes such as libcst.matchers.BaseExpression
, you
cannot match directly on them. They are provided for typing purposes only in order
to exactly match the types on LibCST node attributes. If you need to match on
all concrete subclasses of a base class, we recommend using the special matcher
OneOf
.
- class libcst.matchers.BaseMatcherNode[source]
Base class that all concrete matchers subclass from.
OneOf
andAllOf
also subclass from this in order to allow them to be used in any place that a concrete matcher is allowed. This means that, for example, you can callmatches()
with a concrete matcher, or aOneOf
with several concrete matchers as options.
Special Matchers
Special matchers are matchers that don’t have a corresponding LibCST node. Concrete
matchers only match against their corresponding LibCST node, limiting their use
under certain circumstances. Special matchers fill in the gap by allowing
higher-level logic constructs such as inversion. You can use any special matcher
in place of a concrete matcher when specifying matcher attributes. Additionally,
you can also use the AllOf
and
OneOf
special matchers in place of a concrete matcher
when calling matches()
or using decorators.
- class libcst.matchers.OneOf[source]
Matcher that matches any one of its options. Useful when you want to match against one of several options for a single node. You can also construct a
OneOf
matcher by using Python’s bitwise or operator with concrete matcher classes.For example, you could match against
True
/False
like:m.OneOf(m.Name("True"), m.Name("False"))
Or you could use the shorthand, like:
m.Name("True") | m.Name("False")
- class libcst.matchers.AllOf[source]
Matcher that matches all of its options. Useful when you want to match against a concrete matcher and a
MatchIfTrue
at the same time. Also useful when you want to match against a concrete matcher and aDoesNotMatch()
at the same time. You can also construct aAllOf
matcher by using Python’s bitwise and operator with concrete matcher classes.For example, you could match against
True
in a roundabout way like:m.AllOf(m.Name(), m.Name("True"))
Or you could use the shorthand, like:
m.Name() & m.Name("True")
Similar to
OneOf
, this can be used in place of any concrete matcher.Real-world cases where
AllOf
is useful are hard to come by but they are still provided for the limited edge cases in which they make sense. In the example above, we are redundantly matching against any LibCSTName
node as well as LibCSTName
nodes that have thevalue
ofTrue
. We could drop the first option entirely and get the same result. Often, if you are using aAllOf
, you can refactor your code to be simpler.For example, the following matches any function call to
foo
, and any function call which takes zero arguments:m.AllOf(m.Call(func=m.Name("foo")), m.Call(args=()))
This could be refactored into the following equivalent concrete matcher:
m.Call(func=m.Name("foo"), args=())
- class libcst.matchers.TypeOf[source]
Matcher that matches any one of the given types. Useful when you want to work with trees where a common property might belong to more than a single type.
For example, if you want either a binary operation or a boolean operation where the left side has a name
foo
:m.TypeOf(m.BinaryOperation, m.BooleanOperation)(left = m.Name("foo"))
Or you could use the shorthand, like:
(m.BinaryOperation | m.BooleanOperation)(left = m.Name("foo"))
Also
TypeOf
matchers can be used with initalizing in the default state of other node matchers (without passing any extra patterns):m.Name | m.SimpleString
The will be equal to:
m.OneOf(m.Name(), m.SimpleString())
- property options: Iterator[BaseMatcherNode]
- libcst.matchers.DoesNotMatch(obj: _OtherNodeT) _OtherNodeT [source]
Matcher helper that inverts the match result of its child. You can also invert a matcher by using Python’s bitwise invert operator on concrete matchers or any special matcher.
For example, the following matches against any identifier that isn’t
True
/False
:m.DoesNotMatch(m.OneOf(m.Name("True"), m.Name("False")))
Or you could use the shorthand, like:
~(m.Name("True") | m.Name("False"))
This can be used in place of any concrete matcher as long as it is not the root matcher. Calling
matches()
directly on aDoesNotMatch()
is redundant since you can invert the return ofmatches()
using a bitwise not.
- class libcst.matchers.MatchIfTrue[source]
Matcher that matches if its child callable returns
True
. The child callable should take one argument which is the attribute on the LibCST node we are trying to match against. This is useful if you want to do complex logic to determine if an attribute should match or not. One example of this is theMatchRegex()
matcher build on top ofMatchIfTrue
which takes a regular expression and matches any string attribute where a regex match is found.For example, to match on any identifier spelled with the letter
e
:m.Name(value=m.MatchIfTrue(lambda value: "e" in value))
This can be used in place of any concrete matcher as long as it is not the root matcher. Calling
matches()
directly on aMatchIfTrue
is redundant since you can just call the child callable directly with the node you are passing tomatches()
.
- libcst.matchers.MatchRegex(regex: str | Pattern[str]) MatchIfTrue[str] [source]
Used as a convenience wrapper to
MatchIfTrue
which allows for matching a string attribute against a regex.regex
can be any regular expression string or a compiledPattern
. This uses Python’s re module under the hood and is compatible with syntax documented on docs.python.org.For example, to match against any identifier that is at least one character long and only contains alphabetical characters:
m.Name(value=m.MatchRegex(r'[A-Za-z]+'))
This can be used in place of any string literal when constructing a concrete matcher.
- class libcst.matchers.MatchMetadata[source]
Matcher that looks up the metadata on the current node using the provided metadata provider and compares the value on the node against the value provided to
MatchMetadata
. If the metadata provider is unresolved, aLookupError
exeption will be raised and ask you to provide aMetadataWrapper
. If the metadata value does not exist for a particular node,MatchMetadata
will be considered not a match.For example, to match against any function call which has one parameter which is used in a load expression context:
m.Call( args=[ m.Arg( m.MatchMetadata( meta.ExpressionContextProvider, meta.ExpressionContext.LOAD, ) ) ] )
To match against any
Name
node for the identifierfoo
which is the target of an assignment:m.Name( value="foo", metadata=m.MatchMetadata( meta.ExpressionContextProvider, meta.ExpressionContext.STORE, ) )
This can be used in place of any concrete matcher as long as it is not the root matcher. Calling
matches()
directly on aMatchMetadata
is redundant since you can just check the metadata on the root node that you are passing tomatches()
.- property key: Type[BaseMetadataProvider[object]]
The metadata provider that we will use to fetch values when identifying whether a node matches this matcher. We compare the value returned from the metadata provider to the value provided in
value
when determining a match.
- class libcst.matchers.MatchMetadataIfTrue[source]
Matcher that looks up the metadata on the current node using the provided metadata provider and passes it to a callable which can inspect the metadata further, returning
True
if the matcher should be considered a match. If the metadata provider is unresolved, aLookupError
exeption will be raised and ask you to provide aMetadataWrapper
. If the metadata value does not exist for a particular node,MatchMetadataIfTrue
will be considered not a match.For example, to match against any arg whose qualified name might be
typing.Dict
:m.Call( args=[ m.Arg( m.MatchMetadataIfTrue( meta.QualifiedNameProvider, lambda qualnames: any(n.name == "typing.Dict" for n in qualnames) ) ) ] )
To match against any
Name
node for the identifierfoo
as long as that identifier is found at the beginning of an unindented line:m.Name( value="foo", metadata=m.MatchMetadataIfTrue( meta.PositionProvider, lambda position: position.start.column == 0, ) )
This can be used in place of any concrete matcher as long as it is not the root matcher. Calling
matches()
directly on aMatchMetadataIfTrue
is redundant since you can just check the metadata on the root node that you are passing tomatches()
.- property key: Type[BaseMetadataProvider[object]]
The metadata provider that we will use to fetch values when identifying whether a node matches this matcher. We pass the value returned from the metadata provider to the callable given to us in
func
.
- libcst.matchers.SaveMatchedNode(matcher: _OtherNodeT, name: str) _OtherNodeT [source]
Matcher helper that captures the matched node that matched against a matcher class, making it available in the dictionary returned by
extract()
orextractall()
.For example, the following will match against any binary operation whose left and right operands are not integers, saving those expressions for later inspection. If used inside
extract()
orextractall()
, the resulting dictionary will contain the keysleft_operand
andright_operand
:m.BinaryOperation( left=m.SaveMatchedNode( m.DoesNotMatch(m.Integer()), "left_operand", ), right=m.SaveMatchedNode( m.DoesNotMatch(m.Integer()), "right_operand", ), )
This can be used in place of any concrete matcher as long as it is not the root matcher. Calling
extract()
directly on aSaveMatchedNode()
is redundant since you already have the reference to the node itself.
- libcst.matchers.DoNotCare() DoNotCareSentinel [source]
Used when you want to match exactly one node, but you do not care what node it is. Useful inside sequences such as a
libcst.matchers.Call
’s args attribte. You do not need to use this for concrete matcher attributes sinceDoNotCare()
is already the default.For example, the following matcher would match against any function calls with three arguments, regardless of the arguments themselves and regardless of the function name that we were calling:
m.Call(args=[m.DoNotCare(), m.DoNotCare(), m.DoNotCare()])
Sequence Wildcard Matchers
Sequence wildcard matchers are matchers that only get used when constructing a sequence to match against. Not all LibCST nodes have attributes which are sequences, but for those that do, sequence wildcard matchers offer a great degree of flexibility. Unlike all other matcher types, these allow you to match against more than one LibCST node, much like wildcards in regular expressions do.
LibCST does not implicitly match on partial sequences for you. So, when matching
against a sequence you will need to provide a complete pattern. This often means
using helpers such as ZeroOrMore()
as the first and last
element of your sequence. Think of it as the difference between Python’s
re.match and
re.fullmatch functions.
LibCST matchers behave like the latter so that it is possible to specify sequences
which must start with, end with or be exactly equal to some pattern.
- class libcst.matchers.AtLeastN[source]
Matcher that matches
n
or more LibCST nodes in a row in a sequence.AtLeastN
defaults to matching against theDoNotCare()
matcher, so if you do not specify a matcher as a child,AtLeastN
will match only by count. If you do specify a matcher as a child,AtLeastN
will instead make sure that each LibCST node matches the matcher supplied.For example, this will match all function calls with at least 3 arguments:
m.Call(args=[m.AtLeastN(n=3)])
This will match all function calls with 3 or more integer arguments:
m.Call(args=[m.AtLeastN(n=3, matcher=m.Arg(m.Integer()))])
You can combine sequence matchers with concrete matchers and special matchers and it will behave as you expect. For example, this will match all function calls that have 2 or more integer arguments in a row, followed by any arbitrary argument:
m.Call(args=[m.AtLeastN(n=2, matcher=m.Arg(m.Integer())), m.DoNotCare()])
And finally, this will match all function calls that have at least 5 arguments, the final one being an integer:
m.Call(args=[m.AtLeastN(n=4), m.Arg(m.Integer())])
- property n: int
The number of nodes in a row that must match
AtLeastN.matcher
for this matcher to be considered a match. If there are less thann
matches, this matcher will not be considered a match. If there are equal to or more thann
matches, this matcher will be considered a match.
- property matcher: _MatcherT | DoNotCareSentinel
The matcher which each node in a sequence needs to match.
- libcst.matchers.ZeroOrMore(matcher: _MatcherT | DoNotCareSentinel = DoNotCareSentinel.DEFAULT) AtLeastN[_MatcherT | DoNotCareSentinel] [source]
Used as a convenience wrapper to
AtLeastN
whenn
is equal to0
. Use this when you want to match against any number of nodes in a sequence.For example, this will match any function call with zero or more arguments, as long as all of the arguments are integers:
m.Call(args=[m.ZeroOrMore(m.Arg(m.Integer()))])
This will match any function call where the first argument is an integer and it doesn’t matter what the rest of the arguments are:
m.Call(args=[m.Arg(m.Integer()), m.ZeroOrMore()])
You will often want to use
ZeroOrMore
on both sides of a concrete matcher in order to match against sequences that contain a particular node in an arbitrary location. For example, the following will match any function call that takes in at least one string argument anywhere:m.Call(args=[m.ZeroOrMore(), m.Arg(m.SimpleString()), m.ZeroOrMore()])
- class libcst.matchers.AtMostN[source]
Matcher that matches
n
or fewer LibCST nodes in a row in a sequence.AtMostN
defaults to matching against theDoNotCare()
matcher, so if you do not specify a matcher as a child,AtMostN
will match only by count. If you do specify a matcher as a child,AtMostN
will instead make sure that each LibCST node matches the matcher supplied.For example, this will match all function calls with 3 or fewer arguments:
m.Call(args=[m.AtMostN(n=3)])
This will match all function calls with 0, 1 or 2 string arguments:
m.Call(args=[m.AtMostN(n=2, matcher=m.Arg(m.SimpleString()))])
You can combine sequence matchers with concrete matchers and special matchers and it will behave as you expect. For example, this will match all function calls that have 0, 1 or 2 string arguments in a row, followed by an arbitrary argument:
m.Call(args=[m.AtMostN(n=2, matcher=m.Arg(m.SimpleString())), m.DoNotCare()])
And finally, this will match all function calls that have at least 2 arguments, the final one being a string:
m.Call(args=[m.AtMostN(n=2), m.Arg(m.SimpleString())])
- property n: int
The number of nodes in a row that must match
AtLeastN.matcher
for this matcher to be considered a match. If there are less than or equal ton
matches, then this matcher will be considered a match. Any more thann
matches in a row and this matcher will stop matching and be considered not a match.
- property matcher: _MatcherT | DoNotCareSentinel
The matcher which each node in a sequence needs to match.
- libcst.matchers.ZeroOrOne(matcher: _MatcherT | DoNotCareSentinel = DoNotCareSentinel.DEFAULT) AtMostN[_MatcherT | DoNotCareSentinel] [source]
Used as a convenience wrapper to
AtMostN
whenn
is equal to1
. This is effectively a maybe clause.For example, this will match any function call with zero or one integer argument:
m.Call(args=[m.ZeroOrOne(m.Arg(m.Integer()))])
This will match any function call that has two or three arguments, and the first and last arguments are strings:
m.Call(args=[m.Arg(m.SimpleString()), m.ZeroOrOne(), m.Arg(m.SimpleString())])