undebt
A fast, straightforward, reliable tool for performing massive, automated code refactoring
Top Related Projects
Quick Overview
Undebt is a fast, straightforward, and reliable tool for performing massive, automated code refactoring. Developed by Yelp, it allows developers to write simple patterns for matching and modifying Python code, making it easier to update codebases and maintain consistency across large projects.
Pros
- Fast and efficient, capable of processing large codebases quickly
- Flexible pattern matching system using Python's grammar
- Can be used as a command-line tool or as a Python library
- Supports multi-file operations and in-place modifications
Cons
- Limited to Python code refactoring
- Requires learning a specific pattern syntax
- May require careful testing to ensure refactoring doesn't introduce bugs
- Documentation could be more comprehensive for advanced use cases
Code Examples
- Basic pattern matching and replacement:
from undebt.pattern.util import tokens_as_dict
from undebt.pattern.python import ATOM
pattern = (
tokens_as_dict(ATOM, "old_function")
+ [("(", ")")]
)
replace = "new_function({old_function})"
This example creates a pattern to match old_function()
calls and replace them with new_function(old_function())
.
- Using Undebt as a command-line tool:
undebt -p my_pattern.py -i my_file.py
This command applies the refactoring pattern defined in my_pattern.py
to my_file.py
, modifying it in-place.
- Processing multiple files:
from undebt.cmd.main import main
if __name__ == "__main__":
main(
["--pattern", "my_pattern.py", "--input", "*.py"]
)
This script uses Undebt as a library to apply a pattern to all Python files in the current directory.
Getting Started
To get started with Undebt:
-
Install Undebt:
pip install undebt
-
Create a pattern file (e.g.,
my_pattern.py
):from undebt.pattern.util import tokens_as_dict from undebt.pattern.python import ATOM pattern = tokens_as_dict(ATOM, "print") + [("(", ")")] replace = "logger.info({print})"
-
Run Undebt on your code:
undebt -p my_pattern.py -i your_file.py
This will replace print()
calls with logger.info()
calls in your_file.py
.
Competitor Comparisons
Tools for code analysis, visualizations, or style-preserving source transformation.
Pros of pfff
- Supports multiple programming languages (OCaml, PHP, JavaScript, Java, C++, etc.)
- Offers a wide range of code analysis tools and visualizations
- Provides a framework for building custom static analysis tools
Cons of pfff
- Less actively maintained (last commit in 2019)
- More complex setup and usage due to its comprehensive nature
- Steeper learning curve for users unfamiliar with OCaml
Code Comparison
pfff (OCaml):
let parse_program file =
let ast = Parse_php.parse_program file in
ast
Undebt (Python):
def parse_grammar(grammar):
return Grammar(grammar)
Summary
pfff is a more comprehensive tool supporting multiple languages and offering various code analysis features. However, it's less actively maintained and has a steeper learning curve. Undebt, on the other hand, focuses specifically on automated code refactoring in Python, making it simpler to use for its intended purpose but less versatile overall.
Both tools serve different needs: pfff is better suited for large-scale code analysis across multiple languages, while Undebt excels at targeted Python refactoring tasks. The choice between them depends on the specific requirements of the project and the user's familiarity with the respective technologies.
A formatter for Python files
Pros of YAPF
- More comprehensive code formatting capabilities, covering a wide range of Python syntax
- Highly configurable with style options to match different coding standards
- Actively maintained with regular updates and improvements
Cons of YAPF
- Focuses solely on Python, while Undebt supports multiple languages
- May require more configuration to achieve desired formatting results
- Can be slower for large codebases compared to Undebt's targeted approach
Code Comparison
YAPF example:
def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)
Undebt example (pattern file):
grammar = [
(Literal("def") + NAME + LP + Optional(PARAMS) + RP + COLON,
Literal("def") + NAME + LP + Optional(PARAMS) + RP + COLON + NEWLINE + INDENT)
]
YAPF provides a more straightforward approach to formatting entire Python files, while Undebt requires defining specific patterns for targeted code modifications. YAPF offers greater flexibility in formatting options, but Undebt's pattern-based approach allows for more precise control over specific code changes across multiple languages.
The uncompromising Python code formatter
Pros of Black
- Opinionated and consistent formatting, reducing debates over code style
- Widely adopted in the Python community, with integration in many IDEs and CI tools
- Faster execution time for formatting large codebases
Cons of Black
- Less flexible than Undebt, with fewer customization options
- Limited to Python, while Undebt supports multiple languages
- May make significant changes to existing code formatting
Code Comparison
Black:
def long_function_name(
var_one, var_two, var_three, var_four
):
print(var_one)
Undebt:
def long_function_name(var_one,
var_two,
var_three,
var_four):
print(var_one)
Black enforces a specific style, while Undebt allows for more flexibility in formatting. Black's output is more compact, but Undebt's can be customized to match existing project styles.
Both tools aim to improve code quality and consistency, but they approach the task differently. Black is focused on Python and provides a standardized format, while Undebt offers more versatility across languages and formatting options. The choice between them depends on project requirements and team preferences.
A tool (and pre-commit hook) to automatically upgrade syntax for newer versions of the language.
Pros of pyupgrade
- Specifically designed for Python code modernization
- Actively maintained with frequent updates
- Supports a wide range of Python versions (2.7 to 3.10+)
Cons of pyupgrade
- Limited to Python language upgrades
- Requires manual application of changes
- May not handle complex refactoring scenarios
Code Comparison
pyupgrade example:
# Before
x = dict((a, b) for a, b in some_iterable)
# After
x = {a: b for a, b in some_iterable}
Undebt example:
# Before
def old_function(arg1, arg2):
return arg1 + arg2
# After
def new_function(arg1: int, arg2: int) -> int:
return arg1 + arg2
Summary
pyupgrade focuses on modernizing Python code syntax, while Undebt is a more general-purpose refactoring tool. pyupgrade excels in Python-specific upgrades but lacks broader refactoring capabilities. Undebt offers more flexibility for various languages and complex transformations but requires more setup and configuration. Choose pyupgrade for quick Python modernization tasks, and consider Undebt for more extensive refactoring projects across multiple languages.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Undebt
Undebt is a fast, straightforward, reliable tool for performing massive, automated code refactoring used @Yelp. Undebt lets you define complex find-and-replace rules using standard, straightforward Python that can be applied quickly to an entire code base with a simple command.
To learn about what Undebt is and why we created it, check out our post on the Yelp Engineering Blog.
Get Started
To get started using Undebt, install with
pip install undebt
then head over to our documentation for more information.
Example
While the full list of examples can be found in the documentation, to show you how it's done we'll go in-depth into one example in particular, class_inherit_object.py
. Like most of the examples, this pattern is built for Python, but in theory Undebt could be used with any language. The idea of this pattern is to convert any usage of old-style classes to new-style classes by making all classes that don't inherit from anything else inherit from object
. The code for this pattern is incredibly simpleâa mere four lines not counting imports:
grammar = INDENT + Keyword("class").suppress() + NAME + (Optional(LPAREN + RPAREN) + COLON).suppress()
@tokens_as_list(assert_len=2)
def replace(tokens):
return tokens[0] + "class " + tokens[1] + "(object):"
What's going on here? The basic idea is that grammar
defines what to look for, and replace
defines how to change it. Undebt scans your files looking for grammar
, tokenizes the matching text, passes the tokens to replace
, and replaces the original text with the return value. For a more in-depth explanation of how to use grammar
and replace
in a pattern file, see the pattern files documentation.
In this particular case, grammar
is defined to match an indent (INDENT
), followed by a class definition (+ Keyword("class") + NAME
) that doesn't inherit from anything (+ Optional(LPAREN + RPAREN) + COLON
). Along the way, all the tokens except for the indent and the class name are suppressed, that way replace
only gets those two tokens, which it reassembles into a class definition that inherits from object
. For a full specification of all of the helper objects used here, see the pattern utilities documentation.
To run this pattern on your code:
(1) Install Undebt by entering into your command line
pip install undebt
(2) Run undebt
with class_inherit_object
as the pattern
undebt --pattern undebt.examples.class_inherit_object <file to undebt> ...
For a complete command line example and the full command line help, see the command line documentation, which includes tips and tricks to show how you how to use Undebt with other common Unix utilities.
Top Related Projects
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot