A tool and pre-commit hook to automatically upgrade Python syntax for newer versions of the language.
npx @tessl/cli install tessl/pypi-pyupgrade@3.20.00
# pyupgrade
1
2
A tool and pre-commit hook to automatically upgrade Python syntax for newer versions of the language. pyupgrade modernizes Python code by transforming legacy syntax patterns into their modern equivalents, supporting upgrades across Python versions from 3.6 through 3.14+.
3
4
## Package Information
5
6
- **Package Name**: pyupgrade
7
- **Language**: Python
8
- **Installation**: `pip install pyupgrade`
9
- **Minimum Python Version**: 3.9+
10
11
## Core Imports
12
13
For command-line usage:
14
```bash
15
pyupgrade [OPTIONS] [FILES]
16
```
17
18
For programmatic usage:
19
```python
20
from pyupgrade._main import main
21
from pyupgrade._data import Settings
22
```
23
24
## Basic Usage
25
26
### Command Line Interface
27
28
```bash
29
# Upgrade a single file
30
pyupgrade example.py
31
32
# Upgrade multiple files
33
pyupgrade src/*.py
34
35
# Upgrade for specific Python version
36
pyupgrade --py311-plus src/*.py
37
38
# Use as pre-commit hook
39
pyupgrade --py310-plus --keep-percent-format src/*.py
40
```
41
42
### Programmatic Interface
43
44
```python
45
from pyupgrade._main import main, _fix_plugins, _fix_tokens
46
from pyupgrade._data import Settings
47
48
# Use main function
49
exit_code = main(['--py310-plus', 'example.py'])
50
51
# Transform code programmatically
52
settings = Settings(min_version=(3, 10), keep_percent_format=True)
53
upgraded_code = _fix_plugins(source_code, settings)
54
upgraded_code = _fix_tokens(upgraded_code)
55
```
56
57
## Architecture
58
59
pyupgrade uses a two-phase transformation approach:
60
61
- **Plugin System**: AST-based transformations for complex syntax upgrades (set literals, f-strings, type annotations, etc.)
62
- **Token System**: Token-level transformations for simpler patterns (escape sequences, parentheses, format strings)
63
64
The plugin system uses a registration mechanism where plugins register callbacks for specific AST node types. Each plugin can examine the AST and generate token-level transformations that are applied during the second phase.
65
66
## Capabilities
67
68
### Command Line Interface
69
70
Command-line tool for upgrading Python files with extensive configuration options for different Python versions and preservation settings.
71
72
```python { .api }
73
def main(argv: Sequence[str] | None = None) -> int:
74
"""
75
Main entry point for command-line interface.
76
77
Args:
78
argv: Command line arguments (None uses sys.argv)
79
80
Returns:
81
Exit code (0 for success, 1 for failure/changes made)
82
"""
83
```
84
85
[Command Line Interface](./cli.md)
86
87
### Core Transformation Engine
88
89
Core functionality for applying syntax transformations through plugin and token systems.
90
91
```python { .api }
92
def _fix_plugins(contents_text: str, settings: Settings) -> str:
93
"""Apply plugin-based AST transformations."""
94
95
def _fix_tokens(contents_text: str) -> str:
96
"""Apply token-level transformations."""
97
98
class Settings(NamedTuple):
99
min_version: Version = (3,)
100
keep_percent_format: bool = False
101
keep_mock: bool = False
102
keep_runtime_typing: bool = False
103
```
104
105
[Core Transformation Engine](./core-engine.md)
106
107
### Plugin System
108
109
Extensible plugin architecture for registering AST-based syntax transformations.
110
111
```python { .api }
112
def register(tp: type[AST_T]) -> Callable[[ASTFunc[AST_T]], ASTFunc[AST_T]]:
113
"""Register transformation function for AST node type."""
114
115
def visit(funcs: ASTCallbackMapping, tree: ast.Module, settings: Settings) -> dict[Offset, list[TokenFunc]]:
116
"""Visit AST and collect transformation callbacks."""
117
118
class State(NamedTuple):
119
settings: Settings
120
from_imports: dict[str, set[str]]
121
in_annotation: bool = False
122
```
123
124
[Plugin System](./plugin-system.md)
125
126
### AST Utilities
127
128
Helper functions for working with Python AST nodes during transformations.
129
130
```python { .api }
131
def ast_parse(contents_text: str) -> ast.Module:
132
"""Parse Python source into AST."""
133
134
def ast_to_offset(node: ast.expr | ast.stmt) -> Offset:
135
"""Convert AST node position to token offset."""
136
137
def is_name_attr(node: ast.AST, imports: dict[str, set[str]], mods: tuple[str, ...], names: Container[str]) -> bool:
138
"""Check if node matches imported name or attribute."""
139
```
140
141
[AST Utilities](./ast-utilities.md)
142
143
### Token Manipulation
144
145
Comprehensive token-level manipulation utilities for precise code transformations.
146
147
```python { .api }
148
def parse_call_args(tokens: list[Token], i: int) -> tuple[list[tuple[int, int]], int]:
149
"""Parse function call arguments from tokens."""
150
151
def replace_call(tokens: list[Token], start: int, end: int, args: list[tuple[int, int]], tmpl: str, *, parens: Sequence[int] = ()) -> None:
152
"""Replace function call with template."""
153
154
class Block(NamedTuple):
155
"""Code block boundaries in tokens."""
156
start: int
157
colon: int
158
block: int
159
end: int
160
line: bool
161
```
162
163
[Token Manipulation](./token-manipulation.md)
164
165
### String Processing
166
167
Specialized utilities for processing and transforming string literals and format strings.
168
169
```python { .api }
170
def parse_format(s: str) -> list[DotFormatPart]:
171
"""Parse format string into component parts."""
172
173
def unparse_parsed_string(parsed: list[DotFormatPart]) -> str:
174
"""Convert parsed format parts back to string."""
175
176
def is_codec(encoding: str, name: str) -> bool:
177
"""Check if encoding matches codec name."""
178
```
179
180
[String Processing](./string-processing.md)
181
182
## Types
183
184
```python { .api }
185
# Version and callback types
186
Version = tuple[int, ...]
187
TokenFunc = Callable[[int, list[Token]], None]
188
ASTFunc = Callable[[State, AST_T, ast.AST], Iterable[tuple[Offset, TokenFunc]]]
189
190
# String format processing
191
DotFormatPart = tuple[str, Optional[str], Optional[str], Optional[str]]
192
193
# Token manipulation structures
194
class Victims(NamedTuple):
195
starts: list[int]
196
ends: list[int]
197
first_comma_index: int | None
198
arg_index: int
199
```