Multiline f strings in v1.17 - syntax error

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
chrisb2
Posts: 28
Joined: Sat Apr 01, 2017 4:19 am

Multiline f strings in v1.17 - syntax error

Post by chrisb2 » Mon Sep 13, 2021 8:12 am

I have some existing string formatting I tried to convert to an f string, but it would be longer than the pep8 line size limit, so I tried to use a multiline string (as per solution 1 of https://izziswift.com/multiline-f-string-in-python/) as follows:

Code: Select all

x = 1
y = 2
a = (
  f"{x}"
  f"{y}"
)
but this gives

Code: Select all

Traceback (most recent call last):
  File "<stdin>", line 4
SyntaxError: invalid syntax
I have tried solutions 2 and 3 from the link above but although they work they do not give a single output line.

Any suggestions?
Should I raise an issue in Github?

thanks,
Chris

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Multiline f strings in v1.17 - syntax error

Post by stijn » Mon Sep 13, 2021 8:47 am

This is shown in tests/cpydiff/core_fstring_concat.py so it is not supported. I don't think there is a nice way around it other than joining manually

Code: Select all

a = "".join([
  f"{x}",
  f"{y}"
])

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Multiline f strings in v1.17 - syntax error

Post by pythoncoder » Mon Sep 13, 2021 5:39 pm

There is a comma missing in the original code sample: it fails even on a single line. The following works on the Unix build:

Code: Select all

MicroPython v1.17 on 2021-09-02; linux version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>>
paste mode; Ctrl-C to cancel, Ctrl-D to finish
=== x = 1
=== y = 2
=== a = (
=== f"{x}",
=== f"{y}"
=== )
=== 
>>> a
('1', '2')
>>> 
Peter Hinch
Index to my micropython libraries.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Multiline f strings in v1.17 - syntax error

Post by pythoncoder » Mon Sep 13, 2021 6:16 pm

Perhaps I spoke too soon, but the fault isn't as described. It is not related to multi-line format. This works on CPython but not MP:

Code: Select all

f"{x}" f"{y}"
produces 12 on CPython but errors on MP.
Peter Hinch
Index to my micropython libraries.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Multiline f strings in v1.17 - syntax error

Post by pythoncoder » Tue Sep 14, 2021 6:37 am

I have raised this ticket.
Peter Hinch
Index to my micropython libraries.

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Multiline f strings in v1.17 - syntax error

Post by stijn » Tue Sep 14, 2021 8:54 am

It's a known difference :) see my reply above

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Multiline f strings in v1.17 - syntax error

Post by pythoncoder » Tue Sep 14, 2021 11:06 am

Yes. Just to clarify for anyone looking at this.

I took it that your reply above related to multi-line use. In fact your code works under MP without the join because you added the comma. This works under MP (returning a 2-tuple):

Code: Select all

x = 1
y = 2
a = (
  f"{x}",
  f"{y}"
)
What doesn't work, and is documented, is the following (whether on a single or multiple lines):

Code: Select all

x = 1
y = 2
a = f"{x}" f"{y}"
This is intended to return 12 and does so under cPython. Under MicroPython you can write

Code: Select all

a = f"{x}" + f"{y}"
or (better)

Code: Select all

a = "".join((f"{x}", f"{y}"))
Peter Hinch
Index to my micropython libraries.

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Multiline f strings in v1.17 - syntax error

Post by jimmo » Wed Sep 15, 2021 12:29 am

I would recommend using + to be explicit about the concatenation (assuming your linter doesn't get too clever and remove it, although black doesn't seem to), but a slight variation on solution 2 is

Code: Select all

c = f"""{a}\
{b}"""
(where the backslash prevents the newline. black also leaves this unchanged).
chrisb2 wrote:
Mon Sep 13, 2021 8:12 am
Any suggestions?
I'm curious as to whether this came from library code or something you wrote -- obviously we'd love to make this scenario work, but it would come at a code size complexity. I'm glad in this case you got SyntaxError, but there are cases where it does the wrong thing. Any feedback about "real world" Python code is useful to guide how we might deal with the trade-offs here.

chrisb2
Posts: 28
Joined: Sat Apr 01, 2017 4:19 am

Re: Multiline f strings in v1.17 - syntax error

Post by chrisb2 » Wed Sep 15, 2021 5:14 am

This comes from my own code, where the following function is part of a module which talks to a DS3231 RTC:

Code: Select all

def timestamp():
    """Get current timezone date/time from RTC as DD-MM-YYYY HH24:MM:SS."""
    dt = datetime()
    return '%02d-%02d-%d %02d:%02d:%02d' % \
           (dt.day, dt.month, dt.year, dt.hour, dt.minute, dt.second)
I tried to convert the return to an f string.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Multiline f strings in v1.17 - syntax error

Post by pythoncoder » Wed Sep 15, 2021 7:15 am

@jimmo I was led to believe that string join is better than + from the point of view of allocation. Is this no longer the case?
Peter Hinch
Index to my micropython libraries.

Post Reply