ruff target-version: Target a Python Version
target-version sets the minimum Python version Ruff assumes, which changes which upgrade rules fire and how some code is formatted.
Rules like pyupgrade (UP) only rewrite syntax that is valid on your target. Set target-version so Ruff does not suggest features your minimum Python lacks.
What it does
target-version names the oldest Python version your code must run on (for example py38 or py311). Ruff uses it to decide which version-dependent rules apply and to guide formatting decisions, so UP rules do not propose syntax newer than your target.
Common usage
[tool.ruff]
target-version = "py311"Behavior
| Item | What it does |
|---|---|
| target-version | Lowest supported Python (py37 .. py313, etc.) |
| --target-version <ver> | Override on the command line |
| inferred from requires-python | Used if target-version is unset and project.requires-python exists |
| affects UP rules | pyupgrade only rewrites to syntax valid on the target |
In CI
Set target-version to match your real minimum (or rely on requires-python in pyproject.toml). A target that is too new makes Ruff suggest fixes that break older interpreters in your support matrix; a target too old suppresses useful modernizations.
Common errors in CI
UP rules rewriting to f-strings or new union syntax that then fail on an older interpreter means target-version is set higher than your minimum Python. An invalid value like py3.11 (use py311) produces a config parse error. If target-version and requires-python disagree, the explicit target-version wins, which can surprise CI matrices.