Visitors
- class libcst.CSTVisitor[source]
The low-level base visitor class for traversing a CST. This should be used in conjunction with the
visit()
method on aCSTNode
to visit each element in a tree starting with that node. UnlikeCSTTransformer
, instances of this class cannot modify the tree.When visiting nodes using a
CSTVisitor
, the return value ofvisit()
will equal the passed in tree.- 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.
- class libcst.CSTTransformer[source]
The low-level base visitor class for traversing a CST and creating an updated copy of the original CST. This should be used in conjunction with the
visit()
method on aCSTNode
to visit each element in a tree starting with that node, and possibly returning a new node in its place.When visiting nodes using a
CSTTransformer
, the return value ofvisit()
will be a new tree with any changes made inon_leave()
calls reflected in its children.- 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 | FlattenSentinel[CSTNodeT] [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.
- libcst.RemoveFromParent() RemovalSentinel [source]
A convenience method for requesting that this node be removed by its parent. Use this in place of returning
RemovalSentinel
directly. For example, to remove all arguments unconditionally:def leave_Arg( self, original_node: cst.Arg, updated_node: cst.Arg ) -> Union[cst.Arg, cst.RemovalSentinel]: return RemoveFromParent()
- class libcst.RemovalSentinel[source]
A
RemovalSentinel.REMOVE
value should be returned by aCSTTransformer.on_leave()
method when we want to remove that child from its parent. As a convenience, this can be constructed by callinglibcst.RemoveFromParent()
.The parent node should make a best-effort to remove the child, but may raise an exception when removing the child doesn’t make sense, or could change the semantics in an unexpected way. For example, a function definition with no name doesn’t make sense, but removing one of the arguments is valid.
In we can’t automatically remove the child, the developer should instead remove the child by constructing a new parent in the parent’s
on_leave()
call.We use this instead of
None
to force developers to be explicit about deletions. BecauseNone
is the default return value for a function with no return statement, it would be too easy to accidentally delete nodes from the tree by forgetting to return a value.- REMOVE = 1
- class libcst.FlattenSentinel[source]
A
FlattenSentinel
may be returned by aCSTTransformer.on_leave()
method when one wants to replace a node with multiple nodes. The replaced node must be contained in a Sequence attribute such asbody
. This is generally the case forBaseStatement
andBaseSmallStatement
. For example to insert a print before every return:def leave_Return( self, original_node: cst.Return, updated_node: cst.Return ) -> Union[cst.Return, cst.RemovalSentinel, cst.FlattenSentinel[cst.BaseSmallStatement]]: log_stmt = cst.Expr(cst.parse_expression("print('returning')")) return cst.FlattenSentinel([log_stmt, updated_node])
Returning an empty
FlattenSentinel
is equivalent to returningcst.RemovalSentinel.REMOVE
and is subject to its requirements.
Visit and Leave Helper Functions
While it is possible to subclass from CSTVisitor
or CSTTransformer
and override the on_visit
/on_leave
/on_visit_attribute
/on_leave_attribute
functions
directly, it is not recommended. The default implementation for both visitors will look up any
visit_<Type[CSTNode]>
, leave_<Type[CSTNode]>
, visit_<Type[CSTNode]>_<attribute>
and
leave_<Type[CSTNode]>_<attribute>
method on the visitor subclass and call them directly.
If such a function exists for the node in question, the visitor base class will call the relevant
function, respecting the above outlined semantics. If the function does not exist, the visitor base
class will assume that you do not care about that node and visit its children for you without
requiring a default implementation.
Much like on_visit
, visit_<Type[CSTNode]>
return a boolean specifying whether or not LibCST
should visit a node’s children. As a convenience, you can return None
instead of a boolean value
from your visit_<Type[CSTNode]>
functions. Returning a None
value is treated as a request for
default behavior, which causes the visitor to traverse children. It is equivalent to returning
True
, but requires no explicit return.
For example, the below visitor will visit every function definition, traversing to its children only
if the function name doesn’t include the word “foo”. Notice that we don’t need to provide our own
on_visit
or on_leave
function, nor do we need to provide visit and leave functions for the
rest of the nodes which we do not care about. This will have the effect of visiting all strings not
inside of functions that have “foo” in the name. Note that we take advantage of default behavior when
we decline to return a value in visit_SimpleString
.
class FooingAround(libcst.CSTVisitor):
def visit_FunctionDef(self, node: libcst.FunctionDef) -> bool:
return "foo" not in node.name.value
def visit_SimpleString(self, node: libcst.SimpleString) -> None:
print(node.value)
An example Python REPL using the above visitor is as follows:
>>> import libcst
>>> demo = libcst.parse_module("'abc'\n'123'\ndef foo():\n 'not printed'")
>>> _ = demo.visit(FooingAround())
'abc'
'123'
Traversal Order
Traversal of any parsed tree directly matches the order that tokens appear in the source which
was parsed. LibCST will first call on_visit
for the node. Then, for each of the node’s
child attributes, LibCST will call on_visit_attribute
for the node’s attribute, followed
by running the same visit algorithm on each child node in the node’s attribute. Then,
on_leave_attribute
is called. After each attribute has been fully traversed, LibCST will
call on_leave
for the node. Note that LibCST will only call on_visit_attribute
and
on_leave_attribute
for attributes in which there might be a LibCST node as a child. It
will not call attribute visitors for attributes which are built-in python types.
For example, take the following simple tree generated by calling parse_expression("1+2")
.
BinaryOperation(
left=Integer(
value='1',
lpar=[],
rpar=[],
),
operator=Add(
whitespace_before=SimpleWhitespace(
value='',
),
whitespace_after=SimpleWhitespace(
value='',
),
),
right=Integer(
value='2',
lpar=[],
rpar=[],
),
lpar=[],
rpar=[],
)
Assuming you have a visitor that overrides every convenience helper method available, methods will be called in this order:
visit_BinaryOperation
visit_BinaryOperation_lpar
leave_BinaryOperation_lpar
visit_BinaryOperation_left
visit_Integer
visit_Integer_lpar
leave_Integer_lpar
visit_Integer_rpar
leave_Integer_rpar
leave_Integer
leave_BinaryOperation_left
visit_BinaryOperation_operator
visit_Add
visit_Add_whitespace_before
visit_SimpleWhitespace
leave_SimpleWhitespace
leave_Add_whitespace_before
visit_Add_whitespace_after
visit_SimpleWhitespace
leave_SimpleWhitespace
leave_Add_whitespace_after
leave_Add
leave_BinaryOperation_operator
visit_BinaryOperation_right
visit_Integer
visit_Integer_lpar
leave_Integer_lpar
visit_Integer_rpar
leave_Integer_rpar
leave_Integer
leave_BinaryOperation_right
visit_BinaryOperation_rpar
leave_BinaryOperation_rpar
leave_BinaryOperation
Batched Visitors
A batchable visitor class is provided to facilitate performing operations that can be performed in parallel in a single traversal over a CST. An example of this is metadata computation.
- class libcst.BatchableCSTVisitor[source]
The low-level base visitor class for traversing a CST as part of a batched set of traversals. This should be used in conjunction with the
visit_batched()
function or thevisit_batched()
method fromMetadataWrapper
to visit a tree. Instances of this class cannot modify the tree.
- libcst.visit_batched(node: CSTNodeT, batchable_visitors: Iterable[BatchableCSTVisitor], before_visit: Callable[[CSTNode], None] | None = None, after_leave: Callable[[CSTNode], None] | None = None) CSTNodeT [source]
Do a batched traversal over
node
with allvisitors
.before_visit
andafter_leave
are provided as optional hooks to execute before thevisit_<Type[CSTNode]>
and after theleave_<Type[CSTNode]>
methods from each visitor invisitor
are executed by the batched visitor.This function does not handle metadata dependency resolution for
visitors
. Seevisit_batched()
fromMetadataWrapper
for batched traversal with metadata dependency resolution.