micropython / micropython

MicroPython - a lean and efficient Python implementation for microcontrollers and constrained systems
https://micropython.org
Other
19.14k stars 7.66k forks source link

Concatenation (without "+" sign) of string and f-string becomes f-string #15633

Closed krzotr closed 1 month ago

krzotr commented 1 month ago

Port, board and/or hardware

windows port, linux port, esp32

MicroPython version

MicroPython 91f4a6b on 2024-08-08; linux [GCC 14.0.1] version MicroPython 91f4a6b on 2024-08-08; win32 [GCC 14.1.1] version MicroPython 91f4a6b on 2024-08-08; LILYGO TTGO LoRa32 with ESP32

Reproduction

After run code

def do_something(msg):
    print(msg)

def test():
    var = "Variable 2"

    do_something("This is string line {NORMAL_STRING}"
                 f", And f-string line {var=}")

test()

I got:

Traceback (most recent call last):
  File "a.py", line 12, in <module>
  File "a.py", line 8, in test
KeyError:  NORMAL_STRING

Expected behaviour

I should see the output:

This is string line {NORMAL_STRING}, And f-string line var='Variable 2'

Observed behaviour

Regarding documentation String concatenation

Consider the following code fragments which aim to produce constant strings: var = "foo" + "bar" var1 = "foo" "bar" Each produces the same outcome

If you use "string" + f"string" behavior should be the same as "string" f"string" (concat without + sign)

I split a very long message string and f-string (over 130 characters to max 80) and passed it directly as a parameter to the function. I did not add +, because I thought there was no difference.

As you see string and f-string (concat without +) becomes f-string. If you put {, } characters in the first part of the expression you see KeyError: NORMAL_STRING because the whole expression becomes f-string.

As a workaround, I always need to put + when concat strings and f-string to avoid conversion to f-string and exception KeyError

This works as expected:

    do_something("This is string line {NORMAL_STRING}"
                 + f", And f-string line {var=}")

Additional Information

In CPython 3.12 concatenation works in the same way as + and without - no KeyError exception

Related issue #15216 - I build micropython 91f4a6b on 2024-08-08, so patch from #15216 is included

Code of Conduct

Yes, I agree

dpgeorge commented 1 month ago

Thanks for the report.

This limitation is actually documented as a difference to CPython: https://docs.micropython.org/en/latest/genrst/core_language.html#f-strings-don-t-support-concatenation-with-adjacent-literals-if-the-adjacent-literals-contain-braces

krzotr commented 1 month ago

Oh, I am sorry, I haven't read the whole documentation yet.