Codemods
LibCST defines a codemod as an automated refactor that can be applied to a codebase of arbitrary size. Codemods are provided as a framework for writing higher-order transforms that consist of other, simpler transforms. It includes provisions for quickly creating a command-line interface to execute a codemod.
Codemod Base
All codemods derive from a common base, Codemod
. This class
includes a context, automatic metadata resolution and multi-pass transform support.
Codemods are intended to be executed using the transform_module()
interface.
- class libcst.codemod.Codemod[source]
Abstract base class that all codemods must subclass from. Classes wishing to perform arbitrary, non-visitor-based mutations on a tree should subclass from this class directly. Classes wishing to perform visitor-based mutation should instead subclass from
ContextAwareTransformer
.Note that a
Codemod
is a subclass ofMetadataDependent
, meaning that you can declare metadata dependencies with theMETADATA_DEPENDENCIES
class property and while you are executing a transform you can callget_metadata()
to retrieve the resolved metadata.- should_allow_multiple_passes() bool [source]
Override this and return
True
to allow your transform to be called repeatedly until the tree doesn’t change between passes. By default, this is off, and should suffice for most transforms.
- warn(warning: str) None [source]
Emit a warning that is displayed to the user who has invoked this codemod.
- property module: Module
Reference to the currently-traversed module. Note that this is only available during the execution of a codemod. The module reference is particularly handy if you want to use
libcst.Module.code_for_node()
orlibcst.Module.config_for_parsing
and don’t wish to track a reference to the top-level module manually.
- abstract transform_module_impl(tree: Module) Module [source]
Override this with your transform. You should take in the tree, optionally mutate it and then return the mutated version. The module reference and all calculated metadata are available for the lifetime of this function.
- transform_module(tree: Module) Module [source]
Transform entrypoint which handles multi-pass logic and metadata calculation for you. This is the method that you should call if you wish to invoke a codemod directly. This is the method that is called by
transform_module()
.
- class libcst.codemod.CodemodContext[source]
A context holding all information that is shared amongst all transforms and visitors in a single codemod invocation. When chaining multiple transforms together, the context holds the state that needs to be passed between transforms. The context is responsible for keeping track of metadata wrappers and the filename of the file that is being modified (if available).
- warnings: List[str]
List of warnings gathered while running a codemod. Add to this list by calling
warn()
method from a class that subclasses fromCodemod
,ContextAwareTransformer
orContextAwareVisitor
.
- scratch: Dict[str, Any]
Scratch dictionary available for codemods which are spread across multiple transforms. Codemods are free to add to this at will.
- filename: str | None = None
The current filename if a codemod is being executed against a file that lives on disk. Populated by
libcst.codemod.parallel_exec_transform_with_prettyprint()
when running codemods from the command line.
- full_module_name: str | None = None
The current module if a codemod is being executed against a file that lives on disk, and the repository root is correctly configured. This Will take the form of a dotted name such as
foo.bar.baz
for a file in the repo namedfoo/bar/baz.py
.
- full_package_name: str | None = None
The current package if a codemod is being executed against a file that lives on disk, and the repository root is correctly configured. This Will take the form of a dotted name such as
foo.bar
for a file in the repo namedfoo/bar/baz.py
- wrapper: MetadataWrapper | None = None
The current top level metadata wrapper for the module being modified. To access computed metadata when inside an actively running codemod, use the
get_metadata()
method onCodemod
.
- metadata_manager: FullRepoManager | None = None
The current repo-level metadata manager for the active codemod.
As a convenience, LibCST-compatible visitors are provided which extend the feature-set
of Codemod
to LibCST visitors and transforms. Remember that
ContextAwareTransformer
is still a
Codemod
, so you should still execute it using
transform_module()
.
- class libcst.codemod.ContextAwareTransformer[source]
A transformer which visits using LibCST. Allows visitor-based mutation of a tree. Classes wishing to do arbitrary non-visitor-based mutation on a tree should instead subclass from
Codemod
and implementtransform_module_impl()
. This is a subclass ofMatcherDecoratableTransformer
so all features of matchers as well asCSTTransformer
are available to subclasses of this class.
- class libcst.codemod.ContextAwareVisitor[source]
A visitor which visits using LibCST. Allows visitor-based collecting of info on a tree. All codemods which wish to implement an information collector should subclass from this instead of directly from
MatcherDecoratableVisitor
orCSTVisitor
since this provides access to the current codemod context. As a result, this class allows access to metadata which was calculated in a parentCodemod
through theget_metadata()
method.Note that you cannot directly run a
ContextAwareVisitor
usingtransform_module()
because visitors by definition do not transform trees. However, you can instantiate aContextAwareVisitor
inside a codemod and pass it to thevisit
method on any node in order to run information gathering with metadata and context support.Remember that a
ContextAwareVisitor
is a subclass ofMetadataDependent
, meaning that you still need to declare your metadata dependencies withMETADATA_DEPENDENCIES
before you can retrieve metadata usingget_metadata()
, even if the parent codemod has listed its own metadata dependencies. Note also that the dependencies listed on this class must be a strict subset of the dependencies listed in the parent codemod.
It is often necessary to bail out of a codemod mid-operation when you realize that
you do not want to operate on a module. This can be for any reason such as realizing
the module includes some operation that you do not support. If you wish to skip a
module, you can raise the SkipFile
exception. For codemods
executed using the transform_module()
interface, all warnings
emitted up to the exception being thrown will be preserved in the result.
- class libcst.codemod.SkipFile[source]
Raise this exception to skip codemodding the current file.
The exception message should be the reason for skipping.
Finally, its often easier to test codemods by writing verification tests instead of
running repeatedly on your project. LibCST makes this easy with
CodemodTest
. Often you can develop the majority of your
codemod using just tests, augmenting functionality when you run into an unexpected
edge case when running it against your repository.
- class libcst.codemod.CodemodTest[source]
Base test class for a
Codemod
test. Provides facilities for auto-instantiating and executing a codemod, given the args/kwargs that should be passed to it. Set theTRANSFORM
class attribute to theCodemod
class you wish to test and callassertCodemod()
inside your test method to verify it transforms various source code chunks correctly.Note that this is a subclass of
UnitTest
so anyCodemodTest
can be executed using your favorite test runner such as theunittest
module.- classmethod addClassCleanup(function, /, *args, **kwargs)
Same as addCleanup, except the cleanup items are called even if setUpClass fails (unlike tearDownClass).
- assertCodeEqual(expected: str, actual: str) None
Given an expected and actual code string, makes sure they equal. This ensures that both the expected and actual are sanitized, so its safe to use this on strings that may have come from a triple-quoted multi-line string.
- assertCodemod(before: str, after: str, *args: object, context_override: CodemodContext | None = None, python_version: str | None = None, expected_warnings: Sequence[str] | None = None, expected_skip: bool = False, **kwargs: object) None
Given a before and after code string, and any args/kwargs that should be passed to the codemod constructor specified in
TRANSFORM
, validate that the codemod executes as expected. Verify that the codemod completes successfully, unless theexpected_skip
option is set toTrue
, in which case verify that the codemod skips. Optionally, aCodemodContext
can be provided. If none is specified, a default, empty context is created for you. Additionally, the python version for the code parser can be overridden to a valid python version string such as “3.6”. If none is specified, the version of the interpreter running your tests will be used. Also, a list of warning strings can be specified andassertCodemod()
will verify that the codemod generates those warnings in the order specified. If it is left out, warnings are not checked.
- assertNoLogs(logger=None, level=None)
Fail unless no log messages of level level or higher are emitted on logger_name or its children.
This method must be used as a context manager.
- classmethod doClassCleanups()
Execute all class cleanup functions. Normally called for you after tearDownClass.
- classmethod enterClassContext(cm)
Same as enterContext, but class-wide.
- enterContext(cm)
Enters the supplied context manager.
If successful, also adds its __exit__ method as a cleanup function and returns the result of the __enter__ method.
Execution Interface
As documented in the Codemod Base section above, codemods are meant to be
programmatically executed using transform_module()
. Executing
in this manner handles all of the featureset of codemods, including metadata calculation
and exception handling.
- libcst.codemod.transform_module(transformer: Codemod, code: str, *, python_version: str | None = None) TransformSuccess | TransformFailure | TransformExit | TransformSkip [source]
Given a module as represented by a string and a
Codemod
that we wish to run, execute the codemod on the code and return aTransformResult
. This should never raise an exception. On success, this returns aTransformSuccess
containing any generated warnings as well as the transformed code. If the codemod is interrupted with a Ctrl+C, this returns aTransformExit
. If the codemod elected to skip by throwing aSkipFile
exception, this will return aTransformSkip
containing the reason for skipping as well as any warnings that were generated before the codemod decided to skip. If the codemod throws an unexpected exception, this will return aTransformFailure
containing the exception that occured as well as any warnings that were generated before the codemod crashed.
- libcst.codemod.TransformResult
alias of
TransformSuccess
|TransformFailure
|TransformExit
|TransformSkip
- class libcst.codemod.TransformSuccess[source]
A
TransformResult
used when the codemod was successful. Stores all the information we might need to display to the user upon success, as well as the transformed file contents.
- class libcst.codemod.TransformFailure[source]
A
TransformResult
used when the codemod failed. Stores all the information we might need to display to the user upon a failure.
- class libcst.codemod.TransformSkip[source]
A
TransformResult
used when the codemod requested to be skipped. This could be because it’s a generated file, or due to filename blacklist, or because the transform raisedSkipFile
.- skip_reason: SkipReason
The reason that we skipped codemodding this module.
- class libcst.codemod.SkipReason[source]
An enumeration of all valid reasons for a codemod to skip.
- GENERATED = 'generated'
The module was skipped because we detected that it was generated code, and we were configured to skip generated files.
- BLACKLISTED = 'blacklisted'
The module was skipped because we detected that it was blacklisted, and we were configured to skip blacklisted files.
- class libcst.codemod.TransformExit[source]
A
TransformResult
used when the codemod was interrupted by the user (e.g. KeyboardInterrupt).- warning_messages: Sequence[str] = ()
An empty list of warnings, included so that all
TransformResult
have awarning_messages
attribute.
Command-Line Support
LibCST includes additional support to facilitate faster development of codemods which
are to be run at the command-line. This is achieved through the
CodemodCommand
class and the codemod
utility which lives
inside libcst.tool
. The CodemodCommand
class provides a
codemod description and an interface to add arguments to the command-line. This is
translated to a custom help message and command-line options that a user can provide
when running a codemod at the command-line.
For a brief overview of supported universal options, run the codemod
utility like so:
python3 -m libcst.tool codemod --help
The utility provides support for gathering up and parallelizing codemods across a series of files or directories, auto-formatting changed code according to a configured formatter, generating a unified diff of changes instead of applying them to files, taking code from stdin and codemodding it before returning to stdout, and printing progress and warnings to stderr during execution of a codemod.
Help is auto-customized if a codemod class is provided, including any added options
and the codemod description. For an example, run the codemod
utility like so:
python3 -m libcst.tool codemod noop.NOOPCommand --help
A second utility, list
, can list all available codemods given your configuration.
Run it like so:
python3 -m libcst.tool list
Finally, to set up a directory for codemodding using these tools, including additional
directories where codemods can be found, use the initialize
utility. To see help
for how to use this, run the initialize
utility like so:
python3 -m libcst.tool initialize --help
The above tools operate against any codemod which subclasses from
CodemodCommand
. Remember that CodemodCommand
is a subclass of Codemod
, so all of the features documented
in the Codemod Base section are available in addition to command-line
support. Any command-line enabled codemod can also be programmatically instantiated
and invoked using the above-documented transform_module()
interface.
- class libcst.codemod.CodemodCommand[source]
A
Codemod
which can be invoked on the command-line using thelibcst.tool codemod
utility. It behaves like any other codemod in that it can be instantiated and run identically to aCodemod
. However, it provides support for providing help text and command-line arguments tolibcst.tool codemod
as well as facilities for automatically running certain common transforms after executing yourtransform_module_impl()
.The following list of transforms are automatically run at this time:
AddImportsVisitor
(adds needed imports to a module).RemoveImportsVisitor
(removes unreferenced imports from a module).
- DESCRIPTION: str = 'No description.'
An overrideable description attribute so that codemods can provide a short summary of what they do. This description will show up in command-line help as well as when listing available codemods.
- static add_args(arg_parser: ArgumentParser) None [source]
Override this to add arguments to the CLI argument parser. These args will show up when the user invokes
libcst.tool codemod
with--help
. They will also be presented to your class’s__init__
method. So, if you define a command with an argument ‘foo’, you should also have a corresponding ‘foo’ positional or keyword argument in your class’s__init__
method.
Additionally, a few convenience classes have been provided which take the boilerplate out of common types of codemods:
- class libcst.codemod.VisitorBasedCodemodCommand[source]
A command that acts identically to a visitor-based transform, but also has the support of
add_args()
and running supported helper transforms after execution. SeeCodemodCommand
andContextAwareTransformer
for additional documentation.
- class libcst.codemod.MagicArgsCodemodCommand[source]
A “magic” args command, which auto-magically looks up the transforms that are yielded from
get_transforms()
and instantiates them using values out of the context. Visitors yielded inget_transforms()
must have constructor arguments that match a key in the contextscratch
. The easiest way to guarantee that is to useadd_args()
to add a command arg that will be parsed for each of the args. However, if you wish to chain transforms, adding to the scratch in one transform will make the value available to the constructor in subsequent transforms as well as the scratch for subsequent transforms.- abstract get_transforms() Generator[Type[Codemod], None, None] [source]
A generator which yields one or more subclasses of
Codemod
. In the general case, you will usually yield a series of classes, but it is possible to programmatically decide which classes to yield depending on the contents of the contextscratch
.Note that you should yield classes, not instances of classes, as the point of
MagicArgsCodemodCommand
is to instantiate them for you with the contents ofscratch
.
Command-Line Toolkit
Several helpers for constructing a command-line interface are provided. These are used
in the codemod
utility to provide LibCST’s de-facto command-line interface but they
are also available to be used directly in the case that circumstances demand a custom
command-line tool.
- libcst.codemod.gather_files(files_or_dirs: Sequence[str], *, include_stubs: bool = False) List[str] [source]
Given a list of files or directories (can be intermingled), return a list of all python files that exist at those locations. If
include_stubs
isTrue
, this will include.py
and.pyi
stub files. If it isFalse
, only.py
files will be included in the returned list.
- libcst.codemod.exec_transform_with_prettyprint(transform: Codemod, code: str, *, include_generated: bool = False, generated_code_marker: str = '@generated', format_code: bool = False, formatter_args: Sequence[str] = (), python_version: str | None = None) str | None [source]
Given an instantiated codemod and a string representing a module, transform that code by executing the transform, optionally invoking the formatter and finally printing any generated warnings to stderr. If the code includes the generated marker at any spot and
include_generated
is not set toTrue
, the code will not be modified. Ifformat_code
is set toFalse
or the instantiated codemod does not modify the code, the code will not be formatted. If apython_version
is provided, then we will parse the module using this version. Otherwise, we will use the version of the currently executing python binary.In all cases a module will be returned. Whether it is changed depends on the input parameters as well as the codemod itself.
- libcst.codemod.parallel_exec_transform_with_prettyprint(transform: Codemod, files: Sequence[str], *, jobs: int | None = None, unified_diff: int | None = None, include_generated: bool = False, generated_code_marker: str = '@generated', format_code: bool = False, formatter_args: Sequence[str] = (), show_successes: bool = False, hide_generated: bool = False, hide_blacklisted: bool = False, hide_progress: bool = False, blacklist_patterns: Sequence[str] = (), python_version: str | None = None, repo_root: str | None = None) ParallelTransformResult [source]
Given a list of files and an instantiated codemod we should apply to them, fork and apply the codemod in parallel to all of the files, including any configured formatter. The
jobs
parameter controls the maximum number of in-flight transforms, and needs to be at least 1. If not included, the number of jobs will automatically be set to the number of CPU cores. Ifunified_diff
is set to a number, changes to files will be printed to stdout withunified_diff
lines of context. If it is set toNone
or left out, files themselves will be updated with changes and formatting. If apython_version
is provided, then we will parse each source file using this version. Otherwise, we will use the version of the currently executing python binary.A progress indicator as well as any generated warnings will be printed to stderr. To supress the interactive progress indicator, set
hide_progress
toTrue
. Files that include the generated code marker will be skipped unless theinclude_generated
parameter is set toTrue
. Similarly, files that match a supplied blacklist of regex patterns will be skipped. Warnings for skipping both blacklisted and generated files will be printed to stderr along with warnings generated by the codemod unlesshide_blacklisted
andhide_generated
are set toTrue
. Files that were successfully codemodded will not be printed to stderr unlessshow_successes
is set toTrue
.To make this API possible, we take an instantiated transform. This is due to the fact that lambdas are not pickleable and pickling functions is undefined. This means we’re implicitly relying on fork behavior on UNIX-like systems, and this function will not work on Windows systems. To create a command-line utility that runs on Windows, please instead see
exec_transform_with_prettyprint()
.
- class libcst.codemod.ParallelTransformResult[source]
The result of running
parallel_exec_transform_with_prettyprint()
against a series of files. This is a simple summary, with counts for number of successfully codemodded files, number of files that we failed to codemod, number of warnings generated when running the codemod across the files, and the number of files that we skipped when running the codemod.
- libcst.codemod.diff_code(oldcode: str, newcode: str, context: int, *, filename: str | None = None) str [source]
Given two strings representing a module before and after a codemod, produce a unified diff of the changes with
context
lines of context. Optionally, assign thefilename
to the change, and if it is not available, assume that the change was performed on stdin/stdout. If no change is detected, return an empty string instead of returning an empty unified diff. This is comparable to revision control software which only shows differences for files that have changed.
Library of Transforms
LibCST additionally includes a library of transforms to reduce the need for boilerplate inside codemods. As of now, the list includes the following helpers.
- class libcst.codemod.visitors.GatherImportsVisitor[source]
Gathers all imports in a module and stores them as attributes on the instance. Intended to be instantiated and passed to a
Module
visit()
method in order to gather up information about imports on a module. Note that this is not a substitute for scope analysis or qualified name support. Please see Scope Analysis for a more robust way of determining the qualified name and definition for an arbitrary node.After visiting a module the following attributes will be populated:
- module_imports
A sequence of strings representing modules that were imported directly, such as in the case of
import typing
. Each module directly imported but not aliased will be included here.- object_mapping
A mapping of strings to sequences of strings representing modules where we imported objects from, such as in the case of
from typing import Optional
. Each from import that was not aliased will be included here, where the keys of the mapping are the module we are importing from, and the value is a sequence of objects we are importing from the module.- module_aliases
A mapping of strings representing modules that were imported and aliased, such as in the case of
import typing as t
. Each module imported this way will be represented as a key in this mapping, and the value will be the local alias of the module.- alias_mapping
A mapping of strings to sequences of tuples representing modules where we imported objects from and aliased using
as
syntax, such as in the case offrom typing import Optional as opt
. Each from import that was aliased will be included here, where the keys of the mapping are the module we are importing from, and the value is a tuple representing the original object name and the alias.- all_imports
A collection of all
Import
andImportFrom
statements that were encountered in the module.
- class libcst.codemod.visitors.GatherExportsVisitor[source]
Gathers all explicit exports in a module and stores them as attributes on the instance. Intended to be instantiated and passed to a
Module
visit()
method in order to gather up information about exports specified in an__all__
variable inside a module.After visiting a module the following attributes will be populated:
- explicit_exported_objects
A sequence of strings representing objects that the module exports directly. Note that when
__all__
is absent, this attribute does not store default exported objects by name.
For more information on
__all__
, please see Python’s Modules Documentation.
- class libcst.codemod.visitors.AddImportsVisitor[source]
Ensures that given imports exist in a module. Given a
CodemodContext
and a sequence of tuples specifying a module to import from as a string. Optionally an object to import from that module and any alias to assign that import, ensures that import exists. It will modify existing imports as necessary if the module in question is already being imported from.This is one of the transforms that is available automatically to you when running a codemod. To use it in this manner, import
AddImportsVisitor
and then call the staticadd_needed_import()
method, giving it the current context (found asself.context
for all subclasses ofCodemod
), the module you wish to import from and optionally an object you wish to import from that module and any alias you would like to assign that import to.For example:
AddImportsVisitor.add_needed_import(self.context, "typing", "Optional")
This will produce the following code in a module, assuming there was no typing import already:
from typing import Optional
As another example:
AddImportsVisitor.add_needed_import(self.context, "typing")
This will produce the following code in a module, assuming there was no import already:
import typing
Note that this is a subclass of
CSTTransformer
so it is possible to instantiate it and pass it to aModule
visit()
method. However, it is far easier to use the automatic transform feature ofCodemodCommand
and schedule an import to be added by callingadd_needed_import()
- static add_needed_import(context: CodemodContext, module: str, obj: str | None = None, asname: str | None = None, relative: int = 0) None [source]
Schedule an import to be added in a future invocation of this class by updating the
context
to include themodule
and optionallyobj
to be imported as well as optionallyalias
to alias the importedmodule
orobj
to. When subclassing fromCodemodCommand
, this will be performed for you after your transform finishes executing. If you are subclassing from aCodemod
instead, you will need to call thetransform_module()
method on the module under modification with an instance of this class after performing your transform. Note that if the particularmodule
orobj
you are requesting to import already exists as an import on the current module at the time of executingtransform_module()
on an instance ofAddImportsVisitor
, this will perform no action in order to avoid adding duplicate imports.
- class libcst.codemod.visitors.RemoveImportsVisitor[source]
Attempt to remove given imports from a module, dependent on whether there are any uses of the imported objects. Given a
CodemodContext
and a sequence of tuples specifying a module to remove as a string. Optionally an object being imported from that module and optionally an alias assigned to that imported object, ensures that that import no longer exists as long as there are no remaining references.Note that static analysis is able to determine safely whether an import is still needed given a particular module, but it is currently unable to determine whether an imported object is re-exported and used inside another module unless that object appears in an
__any__
list.This is one of the transforms that is available automatically to you when running a codemod. To use it in this manner, import
RemoveImportsVisitor
and then call the staticremove_unused_import()
method, giving it the current context (found asself.context
for all subclasses ofCodemod
), the module you wish to remove and optionally an object you wish to stop importing as well as an alias that the object is currently assigned to.For example:
RemoveImportsVisitor.remove_unused_import(self.context, "typing", "Optional")
This will remove any
from typing import Optional
that exists in the module as long as there are no uses ofOptional
in that module.As another example:
RemoveImportsVisitor.remove_unused_import(self.context, "typing")
This will remove any
import typing
that exists in the module, as long as there are no references totyping
in that module, including references such astyping.Optional
.Additionally,
RemoveImportsVisitor
includes a convenience functionremove_unused_import_by_node()
which will attempt to schedule removal of all imports referenced in that node and its children. This is especially useful inside transforms when you are going to remove a node usingRemoveFromParent()
to get rid of a node.For example:
def leave_AnnAssign( self, original_node: cst.AnnAssign, updated_node: cst.AnnAssign, ) -> cst.RemovalSentinel: # Remove all annotated assignment statements, clean up imports. RemoveImportsVisitor.remove_unused_import_by_node(self.context, original_node) return cst.RemovalFromParent()
This will remove all annotated assignment statements from a module as well as clean up any imports that were only referenced in those assignments. Note that we pass the
original_node
to the helper function as it uses scope analysis under the hood which is only computed on the original tree.Note that this is a subclass of
CSTTransformer
so it is possible to instantiate it and pass it to aModule
visit()
method. However, it is far easier to use the automatic transform feature ofCodemodCommand
and schedule an import to be added by callingremove_unused_import()
- METADATA_DEPENDENCIES: Tuple[Type[BaseMetadataProvider[object]]] = (<class 'libcst.metadata.name_provider.QualifiedNameProvider'>, <class 'libcst.metadata.scope_provider.ScopeProvider'>)
The set of metadata dependencies declared by this class.
- static remove_unused_import(context: CodemodContext, module: str, obj: str | None = None, asname: str | None = None) None [source]
Schedule an import to be removed in a future invocation of this class by updating the
context
to include themodule
and optionallyobj
which is currently imported as well as optionallyalias
that the importedmodule
orobj
is aliased to. When subclassing fromCodemodCommand
, this will be performed for you after your transform finishes executing. If you are subclassing from aCodemod
instead, you will need to call thetransform_module()
method on the module under modification with an instance of this class after performing your transform. Note that if the particularmodule
orobj
you are requesting to remove is still in use somewhere in the current module at the time of executingtransform_module()
on an instance ofAddImportsVisitor
, this will perform no action in order to avoid removing an in-use import.
- static remove_unused_import_by_node(context: CodemodContext, node: CSTNode) None [source]
Schedule any imports referenced by
node
or one of its children to be removed in a future invocation of this class by updating thecontext
to include themodule
,obj
andalias
for each import in question. When subclassing fromCodemodCommand
, this will be performed for you after your transform finishes executing. If you are subclassing from aCodemod
instead, you will need to call thetransform_module()
method on the module under modification with an instance of this class after performing your transform. Note that all imports that are referenced by thisnode
or its children will only be removed if they are not in use at the time of exeuctingtransform_module()
on an instance ofAddImportsVisitor
in order to avoid removing an in-use import.
- class libcst.codemod.visitors.ApplyTypeAnnotationsVisitor[source]
Apply type annotations to a source module using the given stub mdules. You can also pass in explicit annotations for functions and attributes and pass in new class definitions that need to be added to the source module.
This is one of the transforms that is available automatically to you when running a codemod. To use it in this manner, import
ApplyTypeAnnotationsVisitor
and then call the staticstore_stub_in_context()
method, giving it the current context (found asself.context
for all subclasses ofCodemod
), the stub module from which you wish to add annotations.For example, you can store the type annotation
int
forx
using:stub_module = parse_module("x: int = ...") ApplyTypeAnnotationsVisitor.store_stub_in_context(self.context, stub_module)
You can apply the type annotation using:
source_module = parse_module("x = 1") ApplyTypeAnnotationsVisitor.transform_module(source_module)
This will produce the following code:
x: int = 1
If the function or attribute already has a type annotation, it will not be overwritten.
To overwrite existing annotations when applying annotations from a stub, use the keyword argument
overwrite_existing_annotations=True
when constructing the codemod or when callingstore_stub_in_context
.- static store_stub_in_context(context: CodemodContext, stub: Module, overwrite_existing_annotations: bool = False, use_future_annotations: bool = False, strict_posargs_matching: bool = True, strict_annotation_matching: bool = False, always_qualify_annotations: bool = False) None [source]
Store a stub module in the
CodemodContext
so that type annotations from the stub can be applied in a later invocation of this class.If the
overwrite_existing_annotations
flag isTrue
, the codemod will overwrite any existing annotations.If you call this function multiple times, only the last values of
stub
andoverwrite_existing_annotations
will take effect.
- class libcst.codemod.visitors.GatherUnusedImportsVisitor[source]
Collects all imports from a module not directly used in the same module. Intended to be instantiated and passed to a
libcst.Module
visit()
method to process the full module.Note that imports that are only used indirectly (from other modules) are still collected.
After visiting a module the attribute
unused_imports
will contain a set of unusedImportAlias
objects, paired with their parent import node.- METADATA_DEPENDENCIES: Tuple[Type[BaseMetadataProvider[object]]] = (<class 'libcst.metadata.name_provider.QualifiedNameProvider'>, <class 'libcst.metadata.scope_provider.ScopeProvider'>)
The set of metadata dependencies declared by this class.
- unused_imports: Set[Tuple[cst.ImportAlias, cst.Import | cst.ImportFrom]]
Contains a set of (alias, parent_import) pairs that are not used in the module after visiting.
- filter_unused_imports(candidates: Iterable[Tuple[ImportAlias, Import | ImportFrom]]) Set[Tuple[ImportAlias, Import | ImportFrom]] [source]
Return the imports in
candidates
which are not used.This function implements the main logic of this visitor, and is called after traversal. It calls
is_in_use()
on each import.Override this in a subclass for additional filtering.
- is_in_use(scope: Scope, alias: ImportAlias) bool [source]
Check if
alias
is in use in the givenscope
.An alias is in use if it’s directly referenced, exported, or appears in a string type annotation. Override this in a subclass for additional filtering.
- class libcst.codemod.visitors.GatherCommentsVisitor[source]
Collects all comments matching a certain regex and their line numbers. This visitor is useful for capturing special-purpose comments, for example
noqa
style lint suppression annotations.Standalone comments are assumed to affect the line following them, and inline ones are recorded with the line they are on.
After visiting a CST, matching comments are collected in the
comments
attribute.- METADATA_DEPENDENCIES: ClassVar[Collection['ProviderT']] = (<class 'libcst.metadata.position_provider.PositionProvider'>,)
The set of metadata dependencies declared by this class.
- class libcst.codemod.visitors.GatherNamesFromStringAnnotationsVisitor[source]
Collects all names from string literals used for typing purposes. This includes annotations like
foo: "SomeType"
, and parameters to special functions related to typing (currently only typing.TypeVar).After visiting, a set of all found names will be available on the
names
attribute of this visitor.- METADATA_DEPENDENCIES: ClassVar[Collection['ProviderT']] = (<class 'libcst.metadata.name_provider.QualifiedNameProvider'>,)
The set of metadata dependencies declared by this class.