top | item 37737873

(no title)

thatcherthorn | 2 years ago

As now f-strings can contain any valid Python expression inside expression components, it is now possible to nest f-strings arbitrarily:

>>> f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}"

'2'

Is anyone aware of the change to the interpreter that allows for this?

discuss

order

striking|2 years ago

At https://peps.python.org/pep-0701/#motivation

> When f-strings were originally introduced in PEP 498, the specification was provided without providing a formal grammar for f-strings. Additionally, the specification contains several restrictions that are imposed so the parsing of f-strings could be implemented into CPython without modifying the existing lexer. [...]

> The other issue that f-strings have is that the current implementation in CPython relies on tokenising f-strings as STRING tokens and a post processing of these tokens. This has the following problems: [...]

At https://peps.python.org/pep-0701/#rationale

> By building on top of the new Python PEG Parser (PEP 617), this PEP proposes to redefine “f-strings”, especially emphasizing the clear separation of the string component and the expression (or replacement, {...}) component.

DecoPerson|2 years ago

JavaScript has this with template strings. I use it often:

    s = `something ${cond ? `(${v})` : ''} something`

vscode-plz-stop|2 years ago

This has always worked in a Javascript.

  > `${`${`${`${`${1 + 1}`}`}`}`}`
  '2'
It was simply a limitation with the Python parser.

Heck, it even works in Vimscript

  :echo $'{$'{$'{1 + 1}'}'}'
  2

JohnBooty|2 years ago

Is it uncommon? Ruby does it in a fairly syntactically similar way:

    "Hello, it's #{"#{Time.now}"}"
    => "Hello, it's 2023-10-02 09:41:40 -0400"

NegativeLatency|2 years ago

Ruby can do this:

> puts “h#{”#{i}”}”

You “just” have to make your parser understand how to have all expressions or whatever inside braces. No idea how the python parser works but think about how you can nest json arbitrarily.

mirekrusin|2 years ago

js can do it

  $ node
  > `${`${`${1+1}`}`}`
  '2'

ShamelessC|2 years ago

> Is anyone aware of the change to the interpreter that allows for this?

Why answer your question when I could just brag about how my personal favorite language has supported this for awhile?

/s

seanw444|2 years ago

But did you know Javascript, Ruby, and Vimscript can already do it?

mathisfun123|2 years ago

just replace `f"{` -> `(` and `}"` -> `)` and it's conventional expression eval.