From ripple-env
Use flynt to convert old Python string formatting to f-strings. Activate when: (1) Converting %-formatting to f-strings, (2) Converting .format() calls to f-strings, (3) Modernizing string concatenation to f-strings, (4) Improving code readability through f-string adoption, or (5) Batch-converting legacy Python codebases.
npx claudepluginhub flexnetos/ripple-envThis skill uses the workspace's default tool permissions.
Flynt is an automated tool that transforms Python string formatting from older styles (%-formatting and `.format()`) into modern f-strings, available since Python 3.6.
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`.
Flynt is an automated tool that transforms Python string formatting from older styles (%-formatting and .format()) into modern f-strings, available since Python 3.6.
Why f-strings?
+ operations to f-strings (Python 3.9+).join() on static lists (Python 3.9+)# Convert a single file
flynt file.py
# Convert entire directory (recursive)
flynt src/
# Dry run - see what would change
flynt --dry-run src/
# Print result to stdout instead of modifying
flynt --stdout file.py
# Convert a string snippet
flynt -s '"Hello, %s" % name'
# Verbose output
flynt -v src/
# Quiet mode (no statistics)
flynt -q src/
# Skip %-formatting, only convert .format()
flynt --no-tp src/
# Skip .format(), only convert %-formatting
flynt --no-tf src/
# Convert string concatenations (Python 3.9+)
flynt --transform-concats src/
# Convert static joins (Python 3.9+)
flynt --transform-joins src/
# Limit line length for multiline conversions
flynt --line-length 100 src/
# Only convert single-line expressions
flynt --no-multiline src/
# Aggressive mode (may alter some edge case behavior)
flynt --aggressive src/
# Fail if any changes would be made (for CI)
flynt --fail-on-change src/
# Dry run with diff output
flynt --dry-run src/
# Before
"Hello, %s" % name
"Hello, %s %s" % (first, last)
"Value: %d, Price: %.2f" % (count, price)
"%(name)s is %(age)d years old" % {"name": name, "age": age}
# After
f"Hello, {name}"
f"Hello, {first} {last}"
f"Value: {count}, Price: {price:.2f}"
f"{name} is {age} years old"
# Before
"Hello, {}".format(name)
"Hello, {0} {1}".format(first, last)
"Hello, {name}".format(name=name)
"{} + {} = {}".format(a, b, a + b)
"{:.2f}".format(value)
# After
f"Hello, {name}"
f"Hello, {first} {last}"
f"Hello, {name}"
f"{a} + {b} = {a + b}"
f"{value:.2f}"
# Before
"Hello, " + name + "!"
"Value: " + str(count)
first + " " + last
# After
f"Hello, {name}!"
f"Value: {count}"
f"{first} {last}"
# Before
", ".join(["a", "b", "c"])
" ".join([first, middle, last])
# After
"a, b, c"
f"{first} {middle} {last}"
[tool.flynt]
line-length = 88
transform-concats = true
transform-joins = false
aggressive = false
no-multiline = false
Create ~/.config/flynt.toml:
line-length = 100
verbose = true
Create ~/.flynt.toml:
line-length = 100
verbose = true
# .pre-commit-config.yaml
repos:
- repo: https://github.com/ikamensh/flynt
rev: '1.0.0'
hooks:
- id: flynt
# Skip a single line
message = "Hello, %s" % name # noqa: flynt
# Alternative syntax
message = "Hello, %s" % name # flynt: skip
# Backup first (or use git)
git add -A && git commit -m "Before flynt conversion"
# Run flynt on source directory
flynt src/
# Review changes
git diff
# Run tests to verify
pytest
# Start with dry run
flynt --dry-run src/
# Convert file by file
flynt src/module1.py
pytest tests/test_module1.py
flynt src/module2.py
pytest tests/test_module2.py
# In CI, fail if unconverted strings exist
flynt --fail-on-change --quiet src/
# See exact changes without modifying
flynt --dry-run src/ 2>&1 | less
# Or output to file
flynt --dry-run src/ > flynt-changes.txt 2>&1
--aggressive may change behavior in edge cases--aggressive firstF-string conversion may alter behavior in edge cases:
# Before: prints "1"
'%s' % (1,)
# After: prints "(1,)"
f'{(1,)}'
Flynt skips conversions that would make code less readable:
# Flynt may skip this (too complex)
"result: {}".format(
very_long_function_call_with_many_arguments(
arg1, arg2, arg3
)
)
F-strings are stricter about types:
# Before: works with implicit conversion
"count: %s" % some_object
# After: may need explicit str()
f"count: {some_object}" # Works if __str__ defined
| Tool | F-string Conversion | Other Features |
|---|---|---|
| Flynt | Specialized, thorough | Concat/join conversion |
| Ruff UP032 | Basic conversion | Full linter suite |
| Pyupgrade | Conservative conversion | Full syntax upgrades |
For comprehensive pattern examples, see references/fstring-patterns.md.