Skip to content

Add nested-string-quote-style formatting option#24312

Merged
MichaReiser merged 2 commits into
astral-sh:mainfrom
matthewlloyd:0.15.8-nested-string-quote-style-pr
Mar 31, 2026
Merged

Add nested-string-quote-style formatting option#24312
MichaReiser merged 2 commits into
astral-sh:mainfrom
matthewlloyd:0.15.8-nested-string-quote-style-pr

Conversation

@matthewlloyd
Copy link
Copy Markdown
Contributor

@matthewlloyd matthewlloyd commented Mar 30, 2026

Introduces a new formatter option nested-string-quote-style that leverages Python 3.12's PEP 701 to use preferred quotes inside f- and t-string expressions rather than alternating quote styles for compatibility.

When set to preferred and targeting Python 3.12+, the formatter uses the user's preferred quote style (following the quote-style setting) inside f-string expressions.

When set to alternating (default) or targeting Python versions below 3.12, the formatter continues to alternate quotes.

Implements: #14118
Replaces PR: #23098

Introduces a new formatter option `nested-string-quote-style` that leverages Python 3.12's PEP 701 to use preferred quotes inside f-string expressions rather than alternating quote styles for compatibility.

When set to `preferred` and targeting Python 3.12+, the formatter uses the user's preferred quote style (following the `quote-style` setting) inside f-string expressions.

When set to `alternating` (default) or targeting Python versions below 3.12, the formatter continues to alternate quotes.
@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot Bot commented Mar 30, 2026

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Formatter (stable)

✅ ecosystem check detected no format changes.

Formatter (preview)

✅ ecosystem check detected no format changes.

@MichaReiser MichaReiser added formatter Related to the formatter configuration Related to settings and configuration labels Mar 31, 2026
Copy link
Copy Markdown
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. This looks good to me.

I only have a few small comments about adding some more tests and around documentation

Comment thread crates/ruff_python_formatter/src/string/normalize.rs
Comment thread crates/ruff_python_formatter/src/options.rs Outdated
Comment thread crates/ruff_workspace/src/options.rs Outdated
* Add many tests
* Adjust documentation text
Copy link
Copy Markdown
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. This is great

@MichaReiser MichaReiser changed the title Add nested-string-quote-style formatting option Add nested-string-quote-style formatting option Mar 31, 2026
@MichaReiser MichaReiser merged commit 6468a35 into astral-sh:main Mar 31, 2026
42 checks passed
@matthewlloyd
Copy link
Copy Markdown
Contributor Author

Thanks also for your patience and thorough review!

carljm added a commit that referenced this pull request Apr 1, 2026
* main:
  [ty] Add missing test case for inline functional TypedDict with an invalid type passed to the `name` parameter (#24334)
  [ty] Use `_cls` as argument name for `collections.namedtuple` (#24333)
  [ty] Emit diagnostic for functional TypedDict with non-literal name (#24331)
  Add `nested-string-quote-style` formatting option (#24312)
  `RUF010`: Mark fix as unsafe when it deletes a comment
  [ty] Fix semantic token classification for properties accessed on instances (#24065)
  publish installers to `/installers/ruff/latest` on the mirror (#24247)
nicopauss pushed a commit to Intersec/lib-common that referenced this pull request Jun 4, 2026
##### [\`v0.15.10\`](https://github.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#01510)

Released on 2026-04-09.

##### Preview features

- \[`flake8-logging`] Allow closures in except handlers (`LOG004`) ([#24464](astral-sh/ruff#24464))
- \[`flake8-self`] Make `SLF` diagnostics robust to non-self-named variables ([#24281](astral-sh/ruff#24281))
- \[`flake8-simplify`] Make the fix for `collapsible-if` safe in `preview` (`SIM102`) ([#24371](astral-sh/ruff#24371))

##### Bug fixes

- Avoid emitting multi-line f-string elements before Python 3.12 ([#24377](astral-sh/ruff#24377))
- Avoid syntax error from `E502` fixes in f-strings and t-strings ([#24410](astral-sh/ruff#24410))
- Strip form feeds from indent passed to `dedent_to` ([#24381](astral-sh/ruff#24381))
- \[`pyupgrade`] Fix panic caused by handling of octals (`UP012`) ([#24390](astral-sh/ruff#24390))
- Reject multi-line f-string elements before Python 3.12 ([#24355](astral-sh/ruff#24355))

##### Rule changes

- \[`ruff`] Treat f-string interpolation as potential side effect (`RUF019`) ([#24426](astral-sh/ruff#24426))

##### Server

- Add support for custom file extensions ([#24463](astral-sh/ruff#24463))

##### Documentation

- Document adding fixes in CONTRIBUTING.md ([#24393](astral-sh/ruff#24393))
- Fix JSON typo in settings example ([#24517](astral-sh/ruff#24517))

##### Contributors

- [@charliermarsh](https://github.com/charliermarsh)
- [@dylwil3](https://github.com/dylwil3)
- [@silverstein](https://github.com/silverstein)
- [@anishgirianish](https://github.com/anishgirianish)
- [@shizukushq](https://github.com/shizukushq)
- [@zanieb](https://github.com/zanieb)
- [@AlexWaygood](https://github.com/AlexWaygood)
##### [\`v0.15.9\`](https://github.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#0159)

Released on 2026-04-02.

##### Preview features

- \[`pyflakes`] Flag annotated variable redeclarations as `F811` in preview mode ([#24244](astral-sh/ruff#24244))
- \[`ruff`] Allow dunder-named assignments in non-strict mode for `RUF067` ([#24089](astral-sh/ruff#24089))

##### Bug fixes

- \[`flake8-errmsg`] Avoid shadowing existing `msg` in fix for `EM101` ([#24363](astral-sh/ruff#24363))
- \[`flake8-simplify`] Ignore pre-initialization references in `SIM113` ([#24235](astral-sh/ruff#24235))
- \[`pycodestyle`] Fix `W391` fixes for consecutive empty notebook cells ([#24236](astral-sh/ruff#24236))
- \[`pyupgrade`] Fix `UP008` nested class matching ([#24273](astral-sh/ruff#24273))
- \[`pyupgrade`] Ignore strings with string-only escapes (`UP012`) ([#16058](astral-sh/ruff#16058))
- \[`ruff`] `RUF072`: skip formfeeds on dedent ([#24308](astral-sh/ruff#24308))
- \[`ruff`] Avoid re-using symbol in `RUF024` fix ([#24316](astral-sh/ruff#24316))
- \[`ruff`] Parenthesize expression in `RUF050` fix ([#24234](astral-sh/ruff#24234))
- Disallow starred expressions as values of starred expressions ([#24280](astral-sh/ruff#24280))

##### Rule changes

- \[`flake8-simplify`] Suppress `SIM105` for `except*` before Python 3.12 ([#23869](astral-sh/ruff#23869))
- \[`pyflakes`] Extend `F507` to flag `%`-format strings with zero placeholders ([#24215](astral-sh/ruff#24215))
- \[`pyupgrade`] `UP018` should detect more unnecessarily wrapped literals (UP018) ([#24093](astral-sh/ruff#24093))
- \[`pyupgrade`] Fix `UP008` callable scope handling to support lambdas ([#24274](astral-sh/ruff#24274))
- \[`ruff`] `RUF010`: Mark fix as unsafe when it deletes a comment ([#24270](astral-sh/ruff#24270))

##### Formatter

- Add `nested-string-quote-style` formatting option ([#24312](astral-sh/ruff#24312))

##### Documentation

- \[`flake8-bugbear`] Clarify RUF071 fix safety for non-path string comparisons ([#24149](astral-sh/ruff#24149))
- \[`flake8-type-checking`] Clarify import cycle wording for `TC001`/`TC002`/`TC003` ([#24322](astral-sh/ruff#24322))

##### Other changes

- Avoid rendering fix lines with trailing whitespace after `|` ([#24343](astral-sh/ruff#24343))

##### Contributors

- [@charliermarsh](https://github.com/charliermarsh)
- [@MichaReiser](https://github.com/MichaReiser)
- [@tranhoangtu-it](https://github.com/tranhoangtu-it)
- [@dylwil3](https://github.com/dylwil3)
- [@zsol](https://github.com/zsol)
- [@renovate](https://github.com/renovate)
- [@bitloi](https://github.com/bitloi)
- [@danparizher](https://github.com/danparizher)
- [@chinar-amrutkar](https://github.com/chinar-amrutkar)
- [@second-ed](https://github.com/second-ed)
- [@getehen](https://github.com/getehen)
- [@Redovo1](https://github.com/Redovo1)
- [@matthewlloyd](https://github.com/matthewlloyd)
- [@zanieb](https://github.com/zanieb)
- [@InSyncWithFoo](https://github.com/InSyncWithFoo)
- [@RenzoMXD](https://github.com/RenzoMXD)

Renovate-Branch: renovate/2024.6-ruff-0.15.x
Change-Id: Id4bd542d4f128b509284d9dcda312f2b39c29964
Priv-Id: 28ebcacdeffa50cec7a52eee59091a75ca5e9539
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

configuration Related to settings and configuration formatter Related to the formatter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants