From ripple-env
Use pyupgrade to automatically upgrade Python syntax to newer versions. Activate when: (1) Migrating code from Python 2 to 3, (2) Removing deprecated syntax like 'class Foo(object)', (3) Converting old-style string formatting to f-strings, (4) Updating type hints to modern union syntax (X | Y), (5) Removing obsolete __future__ imports, or (6) Upgrading to a newer Python minimum version.
npx claudepluginhub flexnetos/ripple-envThis skill uses the workspace's default tool permissions.
Pyupgrade is a tool (and pre-commit hook) that automatically upgrades Python syntax for newer versions of the language. It scans your code and applies modern syntax patterns appropriate for your target Python version.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Pyupgrade is a tool (and pre-commit hook) that automatically upgrades Python syntax for newer versions of the language. It scans your code and applies modern syntax patterns appropriate for your target Python version.
Key benefit: Pyupgrade automates tedious manual refactoring when upgrading Python versions, ensuring consistent modern syntax across your codebase.
# Upgrade file to latest Python syntax
pyupgrade file.py
# Upgrade to specific Python version
pyupgrade --py311-plus file.py
# Process entire directory recursively
find . -name "*.py" -exec pyupgrade --py311-plus {} +
# Dry run (show what would change)
pyupgrade --py311-plus file.py && git diff
# Keep percent formatting (opt-out)
pyupgrade --keep-percent-format file.py
# Keep mock imports (opt-out)
pyupgrade --keep-mock file.py
| Flag | Minimum Python | Key Features Enabled |
|---|---|---|
--py36-plus | 3.6 | f-strings, variable annotations |
--py37-plus | 3.7 | async/await improvements |
--py38-plus | 3.8 | Walrus operator, positional-only params |
--py39-plus | 3.9 | dict | dict, list[int] generics |
--py310-plus | 3.10 | X | Y union types, match statements |
--py311-plus | 3.11 | Exception groups, tomllib |
--py312-plus | 3.12 | Type parameter syntax |
--py313-plus | 3.13 | Latest syntax features |
--py314-plus | 3.14 | Bleeding edge features |
# Before
set([1, 2, 3])
set((1, 2, 3))
# After
{1, 2, 3}
# Before
dict((a, b) for a, b in items)
# After
{a: b for a, b in items}
# Before
"Hello, {}".format(name)
"Hello, %s" % name
"Value: {value}".format(value=x)
# After (--py36-plus)
f"Hello, {name}"
f"Hello, {name}"
f"Value: {x}"
# Before
class MyClass(object):
__metaclass__ = ABCMeta
# After
class MyClass:
pass # with ABCMeta via class MyClass(metaclass=ABCMeta)
# Before
class Child(Parent):
def method(self):
super(Child, self).method()
# After
class Child(Parent):
def method(self):
super().method()
# Before
from typing import Optional, Union, List, Dict
def func(x: Optional[int]) -> Union[str, int]:
items: List[Dict[str, int]] = []
# After
def func(x: int | None) -> str | int:
items: list[dict[str, int]] = []
# Before (when targeting 3.10+)
from __future__ import annotations, division, print_function
# After
from __future__ import annotations # only keeps needed ones
# Before
from collections import Mapping, MutableMapping
# After
from collections.abc import Mapping, MutableMapping
# Before
from mock import Mock, patch
# After (unless --keep-mock)
from unittest.mock import Mock, patch
# Before
regex = "\d+\s+"
# After
regex = r"\d+\s+"
# Before
import six
if six.PY2:
text_type = unicode
else:
text_type = str
# After
text_type = str
# Before
OSError
IOError
EnvironmentError
# After (all aliased to OSError in Python 3)
OSError
OSError
OSError
# Before
if x is 1:
pass
# After
if x == 1:
pass
# .pre-commit-config.yaml
repos:
- repo: https://github.com/asottile/pyupgrade
rev: v3.21.2
hooks:
- id: pyupgrade
args: [--py311-plus]
With Ruff: If using Ruff, you can use its UP rules instead:
# pyproject.toml
[tool.ruff.lint]
select = ["UP"]
target-version = "py311"
With Black: Run pyupgrade before Black for consistent formatting:
pyupgrade --py311-plus file.py
black file.py
# Find all Python files and upgrade
find . -name "*.py" -not -path "./.venv/*" -exec pyupgrade --py311-plus {} +
# Or using xargs for better parallelism
find . -name "*.py" -not -path "./.venv/*" | xargs -P 4 pyupgrade --py311-plus
# Stage files, then check
git add -A
git diff --cached --name-only --diff-filter=ACMR | \
grep "\.py$" | \
xargs -r pyupgrade --py311-plus
# Start with conservative upgrade
pyupgrade --py38-plus file.py
# Then progressively upgrade
pyupgrade --py39-plus file.py
pyupgrade --py310-plus file.py
pyupgrade --py311-plus file.py
For complete transformation examples, see references/pyupgrade-transforms.md.