// the find
asottile/pyupgrade
A tool (and pre-commit hook) to automatically upgrade syntax for newer versions of the language.
pyupgrade is an autoformatter that rewrites Python source files to use newer language idioms — dropping `u''` literals, rewriting `.format()` calls to f-strings, updating typing annotations to PEP 585/604 syntax, and removing six/future compatibility shims. You point it at files (or wire it into pre-commit) with a `--pyXX-plus` flag and it makes the changes for you. It's for teams that want to drop support for older Python versions and clean up the resulting dead code without doing it by hand.
The plugin architecture is clean — each transformation lives in its own file under `_plugins/`, making it easy to audit what the tool actually does. The versioning model (`--py39-plus`, `--py310-plus`, etc.) is the right design: you opt into transforms explicitly, nothing changes without permission. Test coverage is thorough, with a dedicated test file per feature. The `six` removal support is genuinely comprehensive — 60+ rewrites — which is the most painful part of any py2→py3 cleanup.
It operates at the token/AST level and will refuse to fix things it can't prove are safe, which means you still get a bunch of manual work on complex expressions — the f-string conversion in particular is intentionally conservative and misses a lot. There's no dry-run diff mode built in; you either run it and commit or run it and check `git diff` yourself. The `--keep-percent-format` and `--keep-runtime-typing` escape hatches exist but the interaction between flags and per-file `from __future__ import annotations` is subtle and not well-documented. It also doesn't handle reformatting of the changes it makes — you'll need Black or Ruff on top of it if you care about line length after rewrites.