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
Codemodis a subclass ofMetadataDependent, meaning that you can declare metadata dependencies with theMETADATA_DEPENDENCIESclass 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
Trueto 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_parsingand 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,ContextAwareTransformerorContextAwareVisitor.
- 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.bazfor 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.barfor 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
Codemodand implementtransform_module_impl(). This is a subclass ofMatcherDecoratableTransformerso all features of matchers as well asCSTTransformerare 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
MatcherDecoratableVisitororCSTVisitorsince this provides access to the current codemod context. As a result, this class allows access to metadata which was calculated in a parentCodemodthrough theget_metadata()method.Note that you cannot directly run a
ContextAwareVisitorusingtransform_module()because visitors by definition do not transform trees. However, you can instantiate aContextAwareVisitorinside a codemod and pass it to thevisitmethod on any node in order to run information gathering with metadata and context support.Remember that a
ContextAwareVisitoris a subclass ofMetadataDependent, meaning that you still need to declare your metadata dependencies withMETADATA_DEPENDENCIESbefore 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
Codemodtest. Provides facilities for auto-instantiating and executing a codemod, given the args/kwargs that should be passed to it. Set theTRANSFORMclass attribute to theCodemodclass 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
UnitTestso anyCodemodTestcan be executed using your favorite test runner such as theunittestmodule.- 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_skipoption is set toTrue, in which case verify that the codemod skips. Optionally, aCodemodContextcan 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
Codemodthat we wish to run, execute the codemod on the code and return aTransformResult. This should never raise an exception. On success, this returns aTransformSuccesscontaining 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 aSkipFileexception, this will return aTransformSkipcontaining 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 aTransformFailurecontaining the exception that occured as well as any warnings that were generated before the codemod crashed.
- libcst.codemod.TransformResult
alias of
Union[TransformSuccess,TransformFailure,TransformExit,TransformSkip]
- class libcst.codemod.TransformSuccess[source]
A
TransformResultused 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
TransformResultused 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
TransformResultused 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
TransformResultused when the codemod was interrupted by the user (e.g. KeyboardInterrupt).- warning_messages: Sequence[str] = ()
An empty list of warnings, included so that all
TransformResulthave awarning_messagesattribute.
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
Codemodwhich can be invoked on the command-line using thelibcst.tool codemodutility. 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 codemodas 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 codemodwith--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. SeeCodemodCommandandContextAwareTransformerfor 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
MagicArgsCodemodCommandis 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_stubsisTrue, this will include.pyand.pyistub files. If it isFalse, only.pyfiles 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_generatedis not set toTrue, the code will not be modified. Ifformat_codeis set toFalseor the instantiated codemod does not modify the code, the code will not be formatted. If apython_versionis 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
jobsparameter 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_diffis set to a number, changes to files will be printed to stdout withunified_difflines of context. If it is set toNoneor left out, files themselves will be updated with changes and formatting. If apython_versionis 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_progresstoTrue. Files that include the generated code marker will be skipped unless theinclude_generatedparameter 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_blacklistedandhide_generatedare set toTrue. Files that were successfully codemodded will not be printed to stderr unlessshow_successesis 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
contextlines of context. Optionally, assign thefilenameto 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
Modulevisit()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
assyntax, 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
ImportandImportFromstatements 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
Modulevisit()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
CodemodContextand 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
AddImportsVisitorand then call the staticadd_needed_import()method, giving it the current context (found asself.contextfor 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
CSTTransformerso it is possible to instantiate it and pass it to aModulevisit()method. However, it is far easier to use the automatic transform feature ofCodemodCommandand 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
contextto include themoduleand optionallyobjto be imported as well as optionallyaliasto alias the importedmoduleorobjto. When subclassing fromCodemodCommand, this will be performed for you after your transform finishes executing. If you are subclassing from aCodemodinstead, 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 particularmoduleorobjyou 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
CodemodContextand 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
RemoveImportsVisitorand then call the staticremove_unused_import()method, giving it the current context (found asself.contextfor 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 Optionalthat exists in the module as long as there are no uses ofOptionalin that module.As another example:
RemoveImportsVisitor.remove_unused_import(self.context, "typing")
This will remove any
import typingthat exists in the module, as long as there are no references totypingin that module, including references such astyping.Optional.Additionally,
RemoveImportsVisitorincludes 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_nodeto 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
CSTTransformerso it is possible to instantiate it and pass it to aModulevisit()method. However, it is far easier to use the automatic transform feature ofCodemodCommandand 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
contextto include themoduleand optionallyobjwhich is currently imported as well as optionallyaliasthat the importedmoduleorobjis aliased to. When subclassing fromCodemodCommand, this will be performed for you after your transform finishes executing. If you are subclassing from aCodemodinstead, 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 particularmoduleorobjyou 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
nodeor one of its children to be removed in a future invocation of this class by updating thecontextto include themodule,objandaliasfor each import in question. When subclassing fromCodemodCommand, this will be performed for you after your transform finishes executing. If you are subclassing from aCodemodinstead, 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 thisnodeor its children will only be removed if they are not in use at the time of exeuctingtransform_module()on an instance ofAddImportsVisitorin 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
ApplyTypeAnnotationsVisitorand then call the staticstore_stub_in_context()method, giving it the current context (found asself.contextfor all subclasses ofCodemod), the stub module from which you wish to add annotations.For example, you can store the type annotation
intforxusing: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=Truewhen 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
CodemodContextso that type annotations from the stub can be applied in a later invocation of this class.If the
overwrite_existing_annotationsflag isTrue, the codemod will overwrite any existing annotations.If you call this function multiple times, only the last values of
stubandoverwrite_existing_annotationswill 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.Modulevisit()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_importswill contain a set of unusedImportAliasobjects, 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
candidateswhich 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
aliasis 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
noqastyle 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
commentsattribute.- 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
namesattribute of this visitor.- METADATA_DEPENDENCIES: ClassVar[Collection['ProviderT']] = (<class 'libcst.metadata.name_provider.QualifiedNameProvider'>,)
The set of metadata dependencies declared by this class.