Skip to content

(Python) f-string nested replacement field in a format spec closes subst at the wrong brace #4503

Description

@maximilliangrand

Which language: Python (specified explicitly, not auto-detect)
Version: 11.12.0
Using: highlight (not highlightAuto)

Describe the issue
A nested replacement field inside an f-string format spec (dynamic width/precision, e.g. f"{x:{w}}") closes the subst region on the inner }. The field's own closing } is then emitted as plain string text, and the subst span ends up brace-unbalanced.

Sample Code to Reproduce

f"{x:{w}}"

Actualhljs.highlight('f"{x:{w}}"', {language:'python'}).value:

<span class="hljs-string">f&quot;<span class="hljs-subst">{x:{w}</span>}&quot;</span>

The subst span is {x:{w} (an unmatched {) and the final } renders in string color instead of as part of the field. f"{value:{width}.{prec}f}" fails the same way.

Expected behavior
The whole {x:{w}} is a single replacement field, and the nested {w} is itself a field. This is valid Python — {w} sets the width dynamically (f"{x:{w}}" with x=42, w=6' 42'). The closing } should belong to the field, not leak into the string, and the subst region should be brace-balanced.

Cause
SUBST in src/languages/python.js (begin:/\{/, end:/\}/) does not contain itself (SUBST.contains = [STRING, NUMBER, PROMPT]), so it ends at the first inner } and cannot handle nested replacement fields.

Assisted-by: Claude Opus 4 (high)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions