### Install Project Dependencies Source: https://github.com/instagram/libcst/blob/main/CONTRIBUTING.md Use 'uv sync' to install all necessary project dependencies after setting up your environment. This ensures all required packages are available for development. ```bash uv sync ``` -------------------------------- ### Install LibCST with Pip Source: https://github.com/instagram/libcst/blob/main/README.rst Install the latest stable release of LibCST from PyPI using pip. ```shell pip install libcst ``` -------------------------------- ### LibCST Visitor Traversal Order Example Source: https://github.com/instagram/libcst/blob/main/docs/source/visitors.rst Details the order in which visitor methods are called during AST traversal. This example shows the sequence for a BinaryOperation node with specific children. ```python 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 ``` -------------------------------- ### Metadata Wrapper and Visitor Example Source: https://github.com/instagram/libcst/blob/main/docs/source/metadata.rst Demonstrates how to use MetadataWrapper with a CSTVisitor to retrieve node positions. ```APIDOC ## Using MetadataWrapper with CSTVisitor ### Description This example shows how to use `MetadataWrapper` in conjunction with a `CSTVisitor` to access metadata, specifically the line and column numbers of `Name` nodes. ### Method N/A (Illustrative Example) ### Endpoint N/A (Illustrative Example) ### Parameters N/A ### Request Example ```python class NamePrinter(cst.CSTVisitor): METADATA_DEPENDENCIES = (cst.metadata.PositionProvider,) def visit_Name(self, node: cst.Name) -> None: pos = self.get_metadata(cst.metadata.PositionProvider, node).start print(f"{node.value} found at line {pos.line}, column {pos.column}") wrapper = cst.metadata.MetadataWrapper(cst.parse_module("x = 1")) result = wrapper.visit(NamePrinter()) # should print "x found at line 1, column 0" ``` ### Response N/A (Illustrative Example) ``` -------------------------------- ### Example Code for Whitespace Consumption Order Source: https://github.com/instagram/libcst/blob/main/libcst/_parser/conversions/README.md Shows a code example where the order of parsing whitespace (trailing comments vs. empty lines) can lead to incorrect consumption. ```python pass # trailing # empty line pass ``` -------------------------------- ### Example Grammar and Program for Whitespace Ownership Source: https://github.com/instagram/libcst/blob/main/libcst/_parser/conversions/README.md Illustrates a grammar rule and a program snippet to demonstrate ambiguity in whitespace ownership between parent and child nodes. ```grammar simple_stmt: (pass_stmt ';')* NEWLINE ``` ```python pass; # comment ``` -------------------------------- ### Get Help for NOOPCommand Codemod Source: https://github.com/instagram/libcst/blob/main/docs/source/codemods.rst Run this command to see help for a specific codemod, including its options and description. This is useful for understanding how to use individual codemods. ```bash python3 -m libcst.tool codemod noop.NOOPCommand --help ``` -------------------------------- ### Example Grammar Production and Parse Tree Source: https://github.com/instagram/libcst/blob/main/libcst/_parser/conversions/README.md Demonstrates a simple grammar production for an addition expression and its corresponding parse tree for the input '1 + 2 + 3'. ```text add_expr: NUMBER ['+' add_expr] 1 + 2 + 3 [H] add_expr / | \ [A] 1 [B] '+' [G] add_expr / | \ [C] 2 [D] '+' [F] add_expr | [E] 3 ``` -------------------------------- ### LibCST AST Structure Example Source: https://github.com/instagram/libcst/blob/main/docs/source/visitors.rst Illustrates the structure of a LibCST AST for a simple expression. This is useful for understanding the node hierarchy that visitors traverse. ```python 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=[], ) ``` -------------------------------- ### Python REPL Example with LibCST Visitor Source: https://github.com/instagram/libcst/blob/main/docs/source/visitors.rst Demonstrates using a custom LibCST visitor in a Python REPL session. Parses a module string and visits it with the custom visitor to observe its behavior. ```python import libcst demo = libcst.parse_module("'abc'\n'123'\ndef foo():\n 'not printed'") _ = demo.visit(FooingAround()) ``` -------------------------------- ### Python Async Context Manager Example Source: https://github.com/instagram/libcst/blob/main/libcst/codemod/tests/codemod_formatter_error_input.py.txt Demonstrates the use of `AsyncExitStack` for managing asynchronous context managers in Python. This snippet includes an explicit syntax error intended to trigger a formatter error. ```python import subprocess from contextlib import AsyncExitStack def fun() -> None: # this is an explicit syntax error to cause formatter error async with AsyncExitStack() as stack: stack ``` -------------------------------- ### Basic Pattern Matching with libcst.matchers Source: https://context7.com/instagram/libcst/llms.txt Introduces basic pattern matching using `libcst.matchers`. This example checks if a parsed expression is a function call using `m.matches()`. ```python import libcst as cst import libcst.matchers as m # Basic pattern matching code = "print('hello')" expr = cst.parse_expression(code) # Check if it's a function call is_call = m.matches(expr, m.Call()) print(is_call) # True ``` -------------------------------- ### Use Wildcards for Argument Matching in libcst Source: https://context7.com/instagram/libcst/llms.txt Employ matchers like AtLeastN to specify flexible argument counts in function call patterns. This example matches calls with at least two arguments. ```python # Using wildcards: ZeroOrMore, AtLeastN, AtMostN module = cst.parse_module("func(a, b, c, d)\n") # Match calls with at least 2 arguments pattern = m.Call(args=[m.AtLeastN(n=2)]) print(m.matches(module.body[0].body[0].value, pattern)) # True ``` -------------------------------- ### Test Codemod Transformations with libcst Source: https://github.com/instagram/libcst/blob/main/docs/source/codemods_tutorial.rst This example demonstrates how to write unit tests for libcst codemods using the CodemodTest class. It includes tests for no-operation scenarios and successful substitutions. ```python from libcst.codemod import CodemodTest from libcst.codemod.commands.constant_folding import ConvertConstantCommand class TestConvertConstantCommand(CodemodTest): # The codemod that will be instantiated for us in assertCodemod. TRANSFORM = ConvertConstantCommand def test_noop(self) -> None: before = """ foo = "bar" """ after = """ foo = "bar" """ # Verify that if we don't have a valid string match, we don't make # any substitutions. self.assertCodemod(before, after, string="baz", constant="BAZ") def test_substitution(self) -> None: before = """ foo = "bar" """ after = """ from utils.constants import BAR foo = BAR """ # Verify that if we do have a valid string match, we make a substitution # as well as import the constant. self.assertCodemod(before, after, string="bar", constant="BAR") ``` -------------------------------- ### Get Node Position with PositionProvider Source: https://github.com/instagram/libcst/blob/main/docs/source/metadata.rst Use PositionProvider to retrieve line and column numbers for CST nodes. Declare PositionProvider in METADATA_DEPENDENCIES and access metadata via get_metadata. ```python class NamePrinter(cst.CSTVisitor): METADATA_DEPENDENCIES = (cst.metadata.PositionProvider,) def visit_Name(self, node: cst.Name) -> None: pos = self.get_metadata(cst.metadata.PositionProvider, node).start print(f"{node.value} found at line {pos.line}, column {pos.column}") wrapper = cst.metadata.MetadataWrapper(cst.parse_module("x = 1")) result = wrapper.visit(NamePrinter()) # should print "x found at line 1, column 0" ``` -------------------------------- ### Find Function Calls with Specific Argument Count Source: https://context7.com/instagram/libcst/llms.txt Filter function calls based on the number of arguments they accept using matchers. This example finds calls with exactly one argument. ```python # Find function calls with specific argument count calls_with_one_arg = m.findall( module, m.Call(args=[m.Arg()]) # Exactly one argument ) ``` -------------------------------- ### Initialize Codemod Directory Source: https://github.com/instagram/libcst/blob/main/docs/source/codemods.rst Run this command to set up a directory for codemodding. It helps in organizing codemods and specifying additional directories where they can be found. ```bash python3 -m libcst.tool initialize --help ``` -------------------------------- ### Initialize Codemodding Environment Source: https://github.com/instagram/libcst/blob/main/docs/source/codemods.rst The `initialize` utility helps set up a directory for codemodding, including specifying additional directories where codemods can be found. ```APIDOC ## Initializing Codemodding Environment ### Description Sets up a directory for codemodding and configures paths for codemod discovery. ### Method Command Line Utility ### Endpoint N/A (Command Line Tool) ### Parameters #### Command Line Arguments - **--help** (flag) - Optional - Displays help information for the initialize utility. ### Request Example ```bash python3 -m libcst.tool initialize --help ``` ### Response N/A (Outputs to console/stderr) ``` -------------------------------- ### Initialize Codemod Configuration Source: https://github.com/instagram/libcst/blob/main/docs/source/codemods_tutorial.rst Run this command in your repository's root to create a `.libcst.codemod.yaml` configuration file. This file allows customization of generated code markers, external formatters, and blacklisting. ```bash python3 -m libcst.tool initialize . ``` -------------------------------- ### Get Modified Code Source: https://github.com/instagram/libcst/blob/main/docs/source/tutorial.ipynb Retrieves the modified Python source code as a string from a libcst module node. ```python print(modified_tree.code) ``` -------------------------------- ### Modify Expression Operator with with_changes() Source: https://context7.com/instagram/libcst/llms.txt Demonstrates using the `with_changes()` method on an immutable CST node to alter its operator. This example changes an addition to a subtraction. ```python import libcst as cst # Modify a simple expression expr = cst.parse_expression("x + y") # Change the operator from Add to Subtract new_expr = expr.with_changes(operator=cst.Subtract()) print(cst.Module([]).code_for_node(new_expr)) # "x - y" ``` -------------------------------- ### Rename Variable with CSTTransformer Source: https://context7.com/instagram/libcst/llms.txt Implement a CSTTransformer to rename a specific variable throughout the code. This example shows how to override `leave_Name` to modify `Name` nodes. ```python import libcst as cst class RenameVariableTransformer(cst.CSTTransformer): """Rename all occurrences of a variable.""" def __init__(self, old_name: str, new_name: str) -> None: self.old_name = old_name self.new_name = new_name def leave_Name( self, original_node: cst.Name, updated_node: cst.Name ) -> cst.Name: if updated_node.value == self.old_name: return updated_node.with_changes(value=self.new_name) return updated_node # Usage source = """ def calculate(data): result = process(data) return result * 2 """ module = cst.parse_module(source) transformer = RenameVariableTransformer("data", "input_data") modified_module = module.visit(transformer) print(modified_module.code) # Output: # def calculate(input_data): # result = process(input_data) # return result * 2 ``` -------------------------------- ### Rust CST Node Macro Source: https://github.com/instagram/libcst/blob/main/native/libcst/README.md Example of the `#[cst_node]` proc macro used in Rust for defining CST nodes. It generates `Deflated` and public `Node` types. ```rust #[derive(Debug, PartialEq, Eq, Clone, Copy)] struct DeflatedFoo<'a, 'input> { _phantom: std::marker::PhantomData<(&'a (), &'input ())>, } #[derive(Debug, PartialEq, Eq, Clone)] struct Foo<'a> { bar: &'a str, } impl<'a, 'input> DeflatedFoo<'a, 'input> { fn into_foo(self, input: &'input str) -> Foo<'a> { Foo { bar: "hello" } // Simplified for example } } #[cfg(test)] mod tests { use super::*; #[test] fn test_cst_node_macro() { let deflated_node = DeflatedFoo::<(), ()> { _phantom: std::marker::PhantomData }; let inflated_node = deflated_node.into_foo("input string"); assert_eq!(inflated_node.bar, "hello"); } } ``` -------------------------------- ### List Available Codemods Source: https://github.com/instagram/libcst/blob/main/docs/source/codemods_tutorial.rst Execute this command from your repository's root to see a list of all codemods available for execution, including their descriptions. ```bash python3 -m libcst.tool list ``` -------------------------------- ### Generate Documents with Poe Source: https://github.com/instagram/libcst/blob/main/README.rst Generate documentation for LibCST by running the 'docs' command group using Poe. ```shell uv run --group docs poe docs ``` -------------------------------- ### Reinstall Package with Uvicorn Source: https://github.com/instagram/libcst/blob/main/README.rst Force a rebuild of the libcst.native module using 'uv sync --reinstall-package'. ```shell uv sync --reinstall-package libcst ``` -------------------------------- ### Run Tests with Poe Source: https://github.com/instagram/libcst/blob/main/CONTRIBUTING.md Use the 'poe test' command to run all project tests and verify that your changes have not introduced any regressions. This is a mandatory step before submitting a pull request. ```bash uv run poe test ``` -------------------------------- ### Format Code with Poe Source: https://github.com/instagram/libcst/blob/main/CONTRIBUTING.md Run the 'poe format' command to format your code according to the project's style guidelines. This should be done before submitting a pull request. ```bash uv run poe format ``` -------------------------------- ### Accessing Position Metadata with MetadataWrapper Source: https://context7.com/instagram/libcst/llms.txt Demonstrates how to use `MetadataWrapper` and `PositionProvider` to retrieve line and column information for nodes in a CST. This is useful for tools that need precise location data. ```python import libcst as cst from libcst.metadata import MetadataWrapper, PositionProvider, ParentNodeProvider source = """ def greet(name): message = f"Hello, {name}" print(message) return message """ # Create wrapper and resolve metadata module = cst.parse_module(source) wrapper = MetadataWrapper(module) # Resolve position metadata positions = wrapper.resolve(PositionProvider) for node, pos in positions.items(): if isinstance(node, cst.Name): print(f"{node.value}: line {pos.start.line}, col {pos.start.column}") ``` -------------------------------- ### Clone the LibCST Repository Source: https://github.com/instagram/libcst/blob/main/CONTRIBUTING.md Clone the official LibCST repository to your local machine. This is the first step in setting up your development environment. ```bash git clone [your fork.git] libcst cd libcst ``` -------------------------------- ### Type Inference Metadata Source: https://github.com/instagram/libcst/blob/main/docs/source/metadata.rst Facilitates automatic inference of data types for expressions, similar to type checkers like Mypy or Pyre. Leverages Pyre Query API and requires `setup watchman`. ```APIDOC ## Type Inference Metadata Enables automatic inference of data types for expressions, aiding in deeper source code understanding. ### Provider - **TypeInferenceProvider**: Provided by `Pyre Query API`. Requires `setup watchman` for incremental typechecking. ``` -------------------------------- ### Convert print() to logging.info() with MatcherDecoratableTransformer Source: https://context7.com/instagram/libcst/llms.txt Demonstrates using `MatcherDecoratableTransformer` to automatically convert `print()` calls to `logging.info()` calls. This requires importing `libcst` and `libcst.matchers`. ```python import libcst as cst import libcst.matchers as m class ConvertPrintToLogging(m.MatcherDecoratableTransformer): """Convert print() calls to logging.info() calls.""" @m.leave(m.Call(func=m.Name("print"))) def convert_print( self, original_node: cst.Call, updated_node: cst.Call, ) -> cst.Call: return updated_node.with_changes( func=cst.Attribute( value=cst.Name("logging"), attr=cst.Name("info") ) ) source = """ print("Starting process") result = compute() print(f"Result: {result}") """ module = cst.parse_module(source) modified = module.visit(ConvertPrintToLogging()) print(modified.code) ``` -------------------------------- ### Using Position Metadata in a Visitor Source: https://context7.com/instagram/libcst/llms.txt Shows how to create a `CSTVisitor` that depends on `PositionProvider` to access node position information during traversal. Use `self.get_metadata` to retrieve the data. ```python # Use in a visitor with metadata access class PositionAwareVisitor(cst.CSTVisitor): METADATA_DEPENDENCIES = (PositionProvider,) def visit_Name(self, node: cst.Name) -> None: pos = self.get_metadata(PositionProvider, node) print(f"Name '{node.value}' at {pos.start.line}:{pos.start.column}") # Visit using the wrapper wrapper.visit(PositionAwareVisitor()) ``` -------------------------------- ### Sync with LibCST Main Version Source: https://github.com/instagram/libcst/blob/main/CONTRIBUTING.md Fetch tags from the official LibCST GitHub repository to ensure your local repository is up-to-date with the main version. ```bash git fetch --tags https://github.com/instagram/libcst ``` -------------------------------- ### Build Native Parser with Cargo Source: https://github.com/instagram/libcst/blob/main/README.rst Build the native parser module for LibCST from the 'native' directory using Cargo. ```shell cargo build ``` -------------------------------- ### Providing Metadata with Providers Source: https://github.com/instagram/libcst/blob/main/docs/source/metadata.rst Details on creating and using metadata provider classes. ```APIDOC ## Providing Metadata ### Description Metadata is generated using provider classes. These can be passed to `MetadataWrapper.resolve()` or declared as dependencies for `libcst.MetadataDependent` classes. Providers are automatically resolved by `MetadataWrapper`. ### Method N/A (Class Documentation) ### Endpoint N/A (Class Documentation) ### Parameters N/A ### Request Example N/A ### Response N/A ``` -------------------------------- ### Parse Python Expression to CST Source: https://github.com/instagram/libcst/blob/main/README.rst Demonstrates parsing a simple Python expression into its CST representation. This shows how formatting details are preserved. ```python BinaryOperation( left=Integer( value='1', lpar=[], ``` -------------------------------- ### Run a Specific Codemod Source: https://github.com/instagram/libcst/blob/main/docs/source/codemods_tutorial.rst Use this command to apply a specific codemod, such as `convert_format_to_fstring.ConvertFormatStringCommand`, to your codebase. Replace `.` with a specific file or directory to target a subset of your repository. ```bash python3 -m libcst.tool codemod convert_format_to_fstring.ConvertFormatStringCommand . ``` -------------------------------- ### Visitor Pattern for Counting Arguments with Matchers Source: https://github.com/instagram/libcst/blob/main/docs/source/best_practices.rst Rewrite complex instance checks in visitors using matchers and visitor methods. This approach is more maintainable and resilient to LibCST changes. ```python class CountBazFoobarArgs(cst.CSTVisitor): """ Given a set of function names, count how many arguments to those function calls are the identifiers "baz" or "foobar". """ def __init__(self, functions: Set[str]) -> None: super().__init__() self.functions: Set[str] = functions self.arg_count: int = 0 def visit_Call(self, node: cst.Call) -> None: # See if the call itself is one of our functions we care about if isinstance(node.func, cst.Name) and node.func.value in self.functions: # Loop through each argument for arg in node.args: # See if the argument is an identifier matching what we want to count if isinstance(arg.value, cst.Name) and arg.value.value in {"baz", "foobar"}: self.arg_count += 1 ``` ```python class CountBazFoobarArgs(m.MatcherDecoratableVisitor): """ Given a set of function names, count how many arguments to those function calls are the identifiers "baz" or "foobar". """ def __init__(self, functions: Set[str]) -> None: super().__init__() self.functions: Set[str] = functions self.arg_count: int = 0 self.call_stack: List[str] = [] def visit_Call(self, node: cst.Call) -> None: # Store all calls in a stack if m.matches(node.func, m.Name()): self.call_stack.append(cst.ensure_type(node.func, cst.Name).value) def leave_Call(self, original_node: cst.Call) -> None: # Pop the latest call off the stack if m.matches(node.func, m.Name()): self.call_stack.pop() @m.visit(m.Arg(m.Name("baz") | m.Name("foobar"))) def _count_args(self, node: cst.Arg) -> None: # See if the most shallow call is one we're interested in, so we can # count the args we care about only in calls we care about. if self.call_stack[-1] in self.functions: self.arg_count += 1 ``` -------------------------------- ### Command-Line Toolkit Functions Source: https://github.com/instagram/libcst/blob/main/docs/source/codemods.rst Helper functions for constructing command-line interfaces and executing transformations. ```APIDOC ## Command-Line Toolkit Functions ### Description Provides utility functions for file gathering, transformation execution, and diffing code, useful for building custom command-line tools. ### Functions - `libcst.codemod.gather_files`: Gathers files for codemodding. - `libcst.codemod.exec_transform_with_prettyprint`: Executes a transformation with pretty printing. - `libcst.codemod.parallel_exec_transform_with_prettyprint`: Executes transformations in parallel with pretty printing. - `libcst.codemod.diff_code`: Generates a diff for code changes. ### Classes - `libcst.codemod.ParallelTransformResult`: Represents the result of a parallel transformation. ``` -------------------------------- ### Scope Analysis with ScopeProvider and MetadataWrapper Source: https://context7.com/instagram/libcst/llms.txt Illustrates how to use `MetadataWrapper` with `ScopeProvider` to analyze variable scopes, assignments, and accesses within a Python module. This is crucial for refactoring and linting tools. ```python import libcst as cst from libcst.metadata import MetadataWrapper, ScopeProvider, QualifiedNameProvider source = """ import os from typing import List global_var = 10 def process(items: List[str]) -> int: result = 0 for item in items: result += len(item) return result + global_var class MyClass: class_var = 20 def method(self): return self.class_var """ module = cst.parse_module(source) wrapper = MetadataWrapper(module) scopes = wrapper.resolve(ScopeProvider) ``` -------------------------------- ### Generate Code from CST with LibCST Source: https://context7.com/instagram/libcst/llms.txt Shows how to convert CST nodes back into source code strings using the `Module.code` property and `Module.code_for_node()` method. Preserves original formatting, encoding, indentation, and newline styles. ```python import libcst as cst # Parse and regenerate code (round-trip) original = "def foo(x, y):\n return x + y\n" module = cst.parse_module(original) # Get the full module code regenerated = module.code assert regenerated == original # Exact round-trip preservation # Generate code for a specific node within the module func_def = module.body[0] func_code = module.code_for_node(func_def) print(func_code) # "def foo(x, y):\n return x + y\n" # Access encoding and formatting info print(module.encoding) # "utf-8" print(module.default_indent) # " " (4 spaces) print(module.default_newline) # "\n" # Get bytes representation with proper encoding module_bytes = module.bytes ``` -------------------------------- ### Check Linters with Poe Source: https://github.com/instagram/libcst/blob/main/CONTRIBUTING.md Run 'poe lint' to check your code against the project's linting rules. This helps maintain code quality and consistency across the project. ```bash uv run poe lint ``` -------------------------------- ### Run Rust Tests Source: https://github.com/instagram/libcst/blob/main/native/libcst/README.md Execute unit and roundtrip tests for libcst written in Rust. Navigate to the 'native' directory and run the 'cargo test' command. ```bash cd native cargo test ``` -------------------------------- ### List Available Codemods Source: https://github.com/instagram/libcst/blob/main/docs/source/codemods.rst The `list` utility helps you discover all codemods that are available based on your current configuration. ```APIDOC ## Listing Available Codemods ### Description Lists all available codemods configured for use. ### Method Command Line Utility ### Endpoint N/A (Command Line Tool) ### Parameters None ### Request Example ```bash python3 -m libcst.tool list ``` ### Response N/A (Outputs list of codemods to console) ``` -------------------------------- ### FullRepoManager Class Source: https://github.com/instagram/libcst/blob/main/docs/source/metadata.rst Manages inter-process communication with Pyre for repository-wide operations. ```APIDOC ## FullRepoManager Class ### Description Manages inter-process communication with Pyre for repository-wide operations. ### Class Definition ```python class libcst.metadata.FullRepoManager ``` ### Initializer ```python def __init__(self) ``` ``` -------------------------------- ### Implement ParamPrinter visitor Source: https://github.com/instagram/libcst/blob/main/docs/source/metadata_tutorial.ipynb This ParamPrinter visitor extends libcst.CSTVisitor and depends on IsParamProvider and PositionProvider. It visits 'Name' nodes and prints their value and position if they are identified as parameters by IsParamProvider. ```python from libcst.metadata import PositionProvider class ParamPrinter(cst.CSTVisitor): METADATA_DEPENDENCIES = (IsParamProvider, PositionProvider,) def visit_Name(self, node: cst.Name) -> None: # Only print out names that are parameters if self.get_metadata(IsParamProvider, node): pos = self.get_metadata(PositionProvider, node).start print(f"{node.value} found at line {pos.line}, column {pos.column}") module = cst.parse_module("def foo(x):\n y = 1\n return x + y") wrapper = cst.MetadataWrapper(module) result = wrapper.visit(ParamPrinter()) # NB: wrapper.visit not module.visit ``` -------------------------------- ### File Path Metadata Source: https://github.com/instagram/libcst/blob/main/docs/source/metadata.rst Provides the absolute file path on disk for any module being visited. Requires an active :class:`~libcst.metadata.FullRepoManager`. ```APIDOC ## File Path Metadata Provides the absolute file path on disk for a module. ### Provider - **FilePathProvider**: Provides the absolute file path. Requires an active :class:`~libcst.metadata.FullRepoManager`. ``` -------------------------------- ### Codemod Command-Line Utility Source: https://github.com/instagram/libcst/blob/main/docs/source/codemods.rst The `codemod` utility allows you to execute codemods from the command line. It supports custom help messages if a codemod class is provided. ```APIDOC ## Running a Codemod ### Description Executes a specified codemod on the project. ### Method Command Line Utility ### Endpoint N/A (Command Line Tool) ### Parameters #### Command Line Arguments - **codemod** (string) - Required - The name or path to the codemod to execute. - **--help** (flag) - Optional - Displays help information for the specified codemod. ### Request Example ```bash python3 -m libcst.tool codemod noop.NOOPCommand --help ``` ### Response N/A (Outputs to console/stderr) ``` -------------------------------- ### Update Native Package Versions Source: https://github.com/instagram/libcst/blob/main/MAINTAINERS.md After publishing the main package, navigate to the native directory and publish the libcst_derive and libcst crates using Cargo with nightly features. ```bash cd native; cargo +nightly publish -Z package-workspace -p libcst_derive -p libcst ``` -------------------------------- ### lib2to3 CST for a function call Source: https://github.com/instagram/libcst/blob/main/docs/source/why_libcst.rst This is a Concrete Syntax Tree (CST) representation using the lib2to3 format for the same function call. CSTs preserve details like comments, whitespace, and newlines, allowing for exact source code reconstruction. ```python Node( file_input, children=[ Node( simple_stmt, children=[ Node( power, children=[ Leaf(NAME, "fn", prefix=""), Node( trailer, children=[ Leaf(LPAR, "(", prefix=""), Node( arglist, children=[ Leaf(NUMBER, "1", prefix=""), Leaf(COMMA, ",", prefix=""), Leaf(NUMBER, "2", prefix=" "), ], ), Leaf(RPAR, ")", prefix=""), ], ), ], ), Leaf( NEWLINE, "\n", prefix=" # calls fn", ), ], prefix="" ), Leaf(ENDMARKER, "", prefix=""), ], prefix="", ) ``` -------------------------------- ### Generate Module with Imports from Template Source: https://context7.com/instagram/libcst/llms.txt Demonstrates using `parse_template_module` to create a module CST node, including import statements and function definitions, from a template string. ```python import libcst as cst from libcst.helpers import ( parse_template_module, parse_template_statement, parse_template_expression, ) # Generate a module with imports module = parse_template_module( "from {mod} import {obj}\n\n{statement}\n", mod=cst.Name("typing"), obj=cst.Name("Optional"), statement=parse_template_statement( "def greet(name: {type}) -> str:\n return f'Hello, {name}!'\n", type=cst.Subscript( value=cst.Name("Optional"), slice=[cst.SubscriptElement(slice=cst.Index(value=cst.Name("str")))] ), name=cst.Name("name") # This won't be substituted in f-string ) ) ``` -------------------------------- ### Accessing Metadata with MetadataWrapper Source: https://github.com/instagram/libcst/blob/main/docs/source/metadata.rst Explains how to use MetadataWrapper to resolve metadata for CST nodes. ```APIDOC ## Accessing Metadata ### Description To work with metadata, you must first wrap a module with a `libcst.metadata.MetadataWrapper`. This wrapper provides `resolve` and `resolve_many` functions for generating metadata. ### Method N/A (Class Documentation) ### Endpoint N/A (Class Documentation) ### Parameters N/A ### Request Example N/A ### Response N/A ``` -------------------------------- ### Run Type Checker with Poe Source: https://github.com/instagram/libcst/blob/main/CONTRIBUTING.md Execute the 'poe typecheck' command to ensure your code passes the project's type checking. This is a crucial step before submitting changes. ```bash uv run poe typecheck ``` -------------------------------- ### Parse Source Code and Resolve Scopes Source: https://github.com/instagram/libcst/blob/main/docs/source/scope_tutorial.ipynb Parses the source code into a CST (Concrete Syntax Tree) and uses MetadataWrapper to resolve scope information. Prints each identified scope. ```python import libcst as cst wrapper = cst.metadata.MetadataWrapper(cst.parse_module(source)) scopes = set(wrapper.resolve(cst.metadata.ScopeProvider).values()) for scope in scopes: print(scope) ``` -------------------------------- ### Check Call with Boolean Arguments using Matcher on Call Node Source: https://github.com/instagram/libcst/blob/main/docs/source/matchers_tutorial.ipynb The most concise way to check for boolean arguments by matching the entire Call node. Requires importing libcst.matchers. ```python import libcst as cst import libcst.matchers as m def best_is_call_with_booleans(node: cst.Call) -> bool: return m.matches( node, m.Call( args=( m.ZeroOrMore(m.Arg(m.Name("True") | m.Name("False"))), ), ), ) ``` -------------------------------- ### Apply BestBoolInverter Transformer Source: https://github.com/instagram/libcst/blob/main/docs/source/matchers_tutorial.ipynb Applies the BestBoolInverter transformer to a parsed module and prints the resulting code. ```python new_module = module.visit(BestBoolInverter()) print(new_module.code) ``` -------------------------------- ### Format Code with cargo fmt Source: https://github.com/instagram/libcst/blob/main/native/libcst/README.md Use the 'cargo fmt' command to format your Rust code according to project conventions. ```bash cargo fmt ``` -------------------------------- ### Command-line CST Printing with LibCST Tool Source: https://context7.com/instagram/libcst/llms.txt Use the `libcst.tool` module from the command line to print CSTs of Python files. Options include showing whitespace and generating Graphviz output. ```bash # Command-line usage: # python -m libcst.tool print myfile.py # python -m libcst.tool print myfile.py --show-whitespace # python -m libcst.tool print myfile.py --graphviz > tree.dot ``` -------------------------------- ### BatchableCSTVisitor Source: https://github.com/instagram/libcst/blob/main/docs/source/visitors.rst A batchable visitor class for performing operations in parallel during a single CST traversal. ```APIDOC ## BatchableCSTVisitor ### Description 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. ### Usage ```python from libcst import BatchableCSTVisitor class MyBatchableVisitor(BatchableCSTVisitor): # Implement visitor methods here pass # Instantiate and use the visitor ``` ``` -------------------------------- ### Analyze Function Scope and Assignments Source: https://context7.com/instagram/libcst/llms.txt Iterates through nodes to find function definitions and prints their scope assignments and accesses. Requires the ScopeProvider metadata. ```python for node, scope in scopes.items(): if isinstance(node, cst.FunctionDef) and node.name.value == "process": print(f"Function 'process' scope assignments:") for assignment in scope.assignments: print(f" - {assignment.name}") print(f"Function 'process' scope accesses:") for access in scope.accesses: print(f" - {access.node.value if isinstance(access.node, cst.Name) else access.node}") ``` -------------------------------- ### visit_batched Source: https://github.com/instagram/libcst/blob/main/docs/source/visitors.rst A function to facilitate batched traversals using BatchableCSTVisitor. ```APIDOC ## visit_batched ### Description Facilitates performing operations that can be performed in parallel in a single traversal over a CST using a batchable visitor. ### Usage ```python from libcst import visit_batched from libcst import parse # Assuming MyBatchableVisitor is defined as above visitor = MyBatchableVisitor() cst = parse("some code") visit_batched(cst, visitor) ``` ``` -------------------------------- ### Controlling CST Display Options Source: https://context7.com/instagram/libcst/llms.txt Customize the output of the `dump` function by controlling the display of whitespace, defaults, and syntax elements. This is useful for focusing on specific aspects of the CST. ```python # Control what's displayed func = cst.parse_statement("def foo(x, y): return x + y\n") print(dump(func, show_whitespace=False, show_defaults=False, show_syntax=False)) ``` -------------------------------- ### Check Call with Boolean Arguments using Matchers Source: https://github.com/instagram/libcst/blob/main/docs/source/matchers_tutorial.ipynb A more concise way to check for boolean arguments using libcst.matchers. Requires importing libcst.matchers. ```python import libcst as cst import libcst.matchers as m def better_is_call_with_booleans(node: cst.Call) -> bool: for arg in node.args: if not m.matches(arg.value, m.Name("True") | m.Name("False")): # Oops, this isn't a True/False literal! return False # We got here, so all arguments are literal boolean values. return True ```