Merge pull request #2690 from jepler/topic-pep-498-fstrings
Implement partial PEP-498 (f-string) support
This commit is contained in:
commit
d988af02d1
30
locale/ID.po
30
locale/ID.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-03-03 20:13-0600\n"
|
||||
"POT-Creation-Date: 2020-03-09 08:19-0500\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -2080,6 +2080,26 @@ msgstr "argumen keyword ekstra telah diberikan"
|
||||
msgid "extra positional arguments given"
|
||||
msgstr "argumen posisi ekstra telah diberikan"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a '#'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a backslash"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: empty expression not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: expecting '}'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: single '}' is not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c
|
||||
#: shared-bindings/displayio/OnDiskBitmap.c
|
||||
msgid "file must be a file opened in byte mode"
|
||||
@ -2393,6 +2413,10 @@ msgstr ""
|
||||
msgid "long int not supported in this build"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "malformed f-string"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_stage/Layer.c
|
||||
msgid "map buffer too small"
|
||||
msgstr ""
|
||||
@ -2721,6 +2745,10 @@ msgstr ""
|
||||
msgid "queue overflow"
|
||||
msgstr "antrian meluap (overflow)"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "raw f-strings are not implemented"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/fft.c
|
||||
msgid "real and imaginary parts must be of equal length"
|
||||
msgstr ""
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-03-03 20:13-0600\n"
|
||||
"POT-Creation-Date: 2020-03-09 08:19-0500\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -2056,6 +2056,26 @@ msgstr ""
|
||||
msgid "extra positional arguments given"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a '#'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a backslash"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: empty expression not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: expecting '}'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: single '}' is not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c
|
||||
#: shared-bindings/displayio/OnDiskBitmap.c
|
||||
msgid "file must be a file opened in byte mode"
|
||||
@ -2369,6 +2389,10 @@ msgstr ""
|
||||
msgid "long int not supported in this build"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "malformed f-string"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_stage/Layer.c
|
||||
msgid "map buffer too small"
|
||||
msgstr ""
|
||||
@ -2696,6 +2720,10 @@ msgstr ""
|
||||
msgid "queue overflow"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "raw f-strings are not implemented"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/fft.c
|
||||
msgid "real and imaginary parts must be of equal length"
|
||||
msgstr ""
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-03-03 20:13-0600\n"
|
||||
"POT-Creation-Date: 2020-03-09 08:19-0500\n"
|
||||
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
|
||||
"Last-Translator: Pascal Deneaux\n"
|
||||
"Language-Team: Sebastian Plamauer, Pascal Deneaux\n"
|
||||
@ -2085,6 +2085,26 @@ msgstr "Es wurden zusätzliche Keyword-Argumente angegeben"
|
||||
msgid "extra positional arguments given"
|
||||
msgstr "Es wurden zusätzliche Argumente ohne Keyword angegeben"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a '#'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a backslash"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: empty expression not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: expecting '}'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: single '}' is not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c
|
||||
#: shared-bindings/displayio/OnDiskBitmap.c
|
||||
msgid "file must be a file opened in byte mode"
|
||||
@ -2405,6 +2425,10 @@ msgstr ""
|
||||
msgid "long int not supported in this build"
|
||||
msgstr "long int wird in diesem Build nicht unterstützt"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "malformed f-string"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_stage/Layer.c
|
||||
msgid "map buffer too small"
|
||||
msgstr "map buffer zu klein"
|
||||
@ -2734,6 +2758,10 @@ msgstr ""
|
||||
msgid "queue overflow"
|
||||
msgstr "Warteschlangenüberlauf"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "raw f-strings are not implemented"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/fft.c
|
||||
msgid "real and imaginary parts must be of equal length"
|
||||
msgstr ""
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-03-03 20:13-0600\n"
|
||||
"POT-Creation-Date: 2020-03-09 08:19-0500\n"
|
||||
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@ -2056,6 +2056,26 @@ msgstr ""
|
||||
msgid "extra positional arguments given"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a '#'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a backslash"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: empty expression not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: expecting '}'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: single '}' is not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c
|
||||
#: shared-bindings/displayio/OnDiskBitmap.c
|
||||
msgid "file must be a file opened in byte mode"
|
||||
@ -2369,6 +2389,10 @@ msgstr ""
|
||||
msgid "long int not supported in this build"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "malformed f-string"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_stage/Layer.c
|
||||
msgid "map buffer too small"
|
||||
msgstr ""
|
||||
@ -2696,6 +2720,10 @@ msgstr ""
|
||||
msgid "queue overflow"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "raw f-strings are not implemented"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/fft.c
|
||||
msgid "real and imaginary parts must be of equal length"
|
||||
msgstr ""
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-03-03 20:13-0600\n"
|
||||
"POT-Creation-Date: 2020-03-09 08:19-0500\n"
|
||||
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: @sommersoft, @MrCertainly\n"
|
||||
@ -2060,6 +2060,26 @@ msgstr ""
|
||||
msgid "extra positional arguments given"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a '#'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a backslash"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: empty expression not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: expecting '}'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: single '}' is not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c
|
||||
#: shared-bindings/displayio/OnDiskBitmap.c
|
||||
msgid "file must be a file opened in byte mode"
|
||||
@ -2373,6 +2393,10 @@ msgstr ""
|
||||
msgid "long int not supported in this build"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "malformed f-string"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_stage/Layer.c
|
||||
msgid "map buffer too small"
|
||||
msgstr ""
|
||||
@ -2700,6 +2724,10 @@ msgstr ""
|
||||
msgid "queue overflow"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "raw f-strings are not implemented"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/fft.c
|
||||
msgid "real and imaginary parts must be of equal length"
|
||||
msgstr ""
|
||||
|
30
locale/es.po
30
locale/es.po
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-03-03 20:13-0600\n"
|
||||
"POT-Creation-Date: 2020-03-09 08:19-0500\n"
|
||||
"PO-Revision-Date: 2018-08-24 22:56-0500\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@ -2087,6 +2087,26 @@ msgstr "argumento(s) por palabra clave adicionales fueron dados"
|
||||
msgid "extra positional arguments given"
|
||||
msgstr "argumento posicional adicional dado"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a '#'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a backslash"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: empty expression not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: expecting '}'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: single '}' is not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c
|
||||
#: shared-bindings/displayio/OnDiskBitmap.c
|
||||
msgid "file must be a file opened in byte mode"
|
||||
@ -2403,6 +2423,10 @@ msgstr "variable local referenciada antes de la asignación"
|
||||
msgid "long int not supported in this build"
|
||||
msgstr "long int no soportado en esta compilación"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "malformed f-string"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_stage/Layer.c
|
||||
msgid "map buffer too small"
|
||||
msgstr "map buffer muy pequeño"
|
||||
@ -2734,6 +2758,10 @@ msgstr "pow() con 3 argumentos requiere enteros"
|
||||
msgid "queue overflow"
|
||||
msgstr "desbordamiento de cola(queue)"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "raw f-strings are not implemented"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/fft.c
|
||||
msgid "real and imaginary parts must be of equal length"
|
||||
msgstr ""
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-03-03 20:13-0600\n"
|
||||
"POT-Creation-Date: 2020-03-09 08:19-0500\n"
|
||||
"PO-Revision-Date: 2018-12-20 22:15-0800\n"
|
||||
"Last-Translator: Timothy <me@timothygarcia.ca>\n"
|
||||
"Language-Team: fil\n"
|
||||
@ -2101,6 +2101,26 @@ msgstr "dagdag na keyword argument na ibinigay"
|
||||
msgid "extra positional arguments given"
|
||||
msgstr "dagdag na positional argument na ibinigay"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a '#'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a backslash"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: empty expression not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: expecting '}'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: single '}' is not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c
|
||||
#: shared-bindings/displayio/OnDiskBitmap.c
|
||||
msgid "file must be a file opened in byte mode"
|
||||
@ -2419,6 +2439,10 @@ msgstr "local variable na reference bago na i-assign"
|
||||
msgid "long int not supported in this build"
|
||||
msgstr "long int hindi sinusuportahan sa build na ito"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "malformed f-string"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_stage/Layer.c
|
||||
msgid "map buffer too small"
|
||||
msgstr "masyadong maliit ang buffer map"
|
||||
@ -2748,6 +2772,10 @@ msgstr "pow() na may 3 argumento kailangan ng integers"
|
||||
msgid "queue overflow"
|
||||
msgstr "puno na ang pila (overflow)"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "raw f-strings are not implemented"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/fft.c
|
||||
msgid "real and imaginary parts must be of equal length"
|
||||
msgstr ""
|
||||
|
30
locale/fr.po
30
locale/fr.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-03-03 20:13-0600\n"
|
||||
"POT-Creation-Date: 2020-03-09 08:19-0500\n"
|
||||
"PO-Revision-Date: 2019-04-14 20:05+0100\n"
|
||||
"Last-Translator: Pierrick Couturier <arofarn@arofarn.info>\n"
|
||||
"Language-Team: fr\n"
|
||||
@ -2126,6 +2126,26 @@ msgstr "argument(s) nommé(s) supplémentaire(s) donné(s)"
|
||||
msgid "extra positional arguments given"
|
||||
msgstr "argument(s) positionnel(s) supplémentaire(s) donné(s)"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a '#'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a backslash"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: empty expression not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: expecting '}'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: single '}' is not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c
|
||||
#: shared-bindings/displayio/OnDiskBitmap.c
|
||||
msgid "file must be a file opened in byte mode"
|
||||
@ -2443,6 +2463,10 @@ msgstr "variable locale référencée avant d'être assignée"
|
||||
msgid "long int not supported in this build"
|
||||
msgstr "entiers longs non supportés dans cette build"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "malformed f-string"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_stage/Layer.c
|
||||
msgid "map buffer too small"
|
||||
msgstr "tampon trop petit"
|
||||
@ -2780,6 +2804,10 @@ msgstr "pow() avec 3 arguments nécessite des entiers"
|
||||
msgid "queue overflow"
|
||||
msgstr "dépassement de file"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "raw f-strings are not implemented"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/fft.c
|
||||
msgid "real and imaginary parts must be of equal length"
|
||||
msgstr ""
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-03-03 20:13-0600\n"
|
||||
"POT-Creation-Date: 2020-03-09 08:19-0500\n"
|
||||
"PO-Revision-Date: 2018-10-02 16:27+0200\n"
|
||||
"Last-Translator: Enrico Paganin <enrico.paganin@mail.com>\n"
|
||||
"Language-Team: \n"
|
||||
@ -2102,6 +2102,26 @@ msgstr "argomento nominato aggiuntivo fornito"
|
||||
msgid "extra positional arguments given"
|
||||
msgstr "argomenti posizonali extra dati"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a '#'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a backslash"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: empty expression not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: expecting '}'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: single '}' is not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c
|
||||
#: shared-bindings/displayio/OnDiskBitmap.c
|
||||
msgid "file must be a file opened in byte mode"
|
||||
@ -2421,6 +2441,10 @@ msgstr "variabile locale richiamata prima di un assegnamento"
|
||||
msgid "long int not supported in this build"
|
||||
msgstr "long int non supportata in questa build"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "malformed f-string"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_stage/Layer.c
|
||||
msgid "map buffer too small"
|
||||
msgstr "map buffer troppo piccolo"
|
||||
@ -2755,6 +2779,10 @@ msgstr "pow() con 3 argomenti richiede interi"
|
||||
msgid "queue overflow"
|
||||
msgstr "overflow della coda"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "raw f-strings are not implemented"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/fft.c
|
||||
msgid "real and imaginary parts must be of equal length"
|
||||
msgstr ""
|
||||
|
30
locale/ko.po
30
locale/ko.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-03-03 20:13-0600\n"
|
||||
"POT-Creation-Date: 2020-03-09 08:19-0500\n"
|
||||
"PO-Revision-Date: 2019-05-06 14:22-0700\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -2061,6 +2061,26 @@ msgstr ""
|
||||
msgid "extra positional arguments given"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a '#'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a backslash"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: empty expression not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: expecting '}'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: single '}' is not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c
|
||||
#: shared-bindings/displayio/OnDiskBitmap.c
|
||||
msgid "file must be a file opened in byte mode"
|
||||
@ -2374,6 +2394,10 @@ msgstr ""
|
||||
msgid "long int not supported in this build"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "malformed f-string"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_stage/Layer.c
|
||||
msgid "map buffer too small"
|
||||
msgstr ""
|
||||
@ -2701,6 +2725,10 @@ msgstr ""
|
||||
msgid "queue overflow"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "raw f-strings are not implemented"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/fft.c
|
||||
msgid "real and imaginary parts must be of equal length"
|
||||
msgstr ""
|
||||
|
30
locale/pl.po
30
locale/pl.po
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-03-03 20:13-0600\n"
|
||||
"POT-Creation-Date: 2020-03-09 08:19-0500\n"
|
||||
"PO-Revision-Date: 2019-03-19 18:37-0700\n"
|
||||
"Last-Translator: Radomir Dopieralski <circuitpython@sheep.art.pl>\n"
|
||||
"Language-Team: pl\n"
|
||||
@ -2065,6 +2065,26 @@ msgstr "nadmiarowe argumenty nazwane"
|
||||
msgid "extra positional arguments given"
|
||||
msgstr "nadmiarowe argumenty pozycyjne"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a '#'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a backslash"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: empty expression not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: expecting '}'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: single '}' is not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c
|
||||
#: shared-bindings/displayio/OnDiskBitmap.c
|
||||
msgid "file must be a file opened in byte mode"
|
||||
@ -2378,6 +2398,10 @@ msgstr "zmienna lokalna użyta przed przypisaniem"
|
||||
msgid "long int not supported in this build"
|
||||
msgstr "long int jest nieobsługiwany"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "malformed f-string"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_stage/Layer.c
|
||||
msgid "map buffer too small"
|
||||
msgstr "bufor mapy zbyt mały"
|
||||
@ -2706,6 +2730,10 @@ msgstr "trzyargumentowe pow() wymaga liczb całkowitych"
|
||||
msgid "queue overflow"
|
||||
msgstr "przepełnienie kolejki"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "raw f-strings are not implemented"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/fft.c
|
||||
msgid "real and imaginary parts must be of equal length"
|
||||
msgstr ""
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-03-03 20:13-0600\n"
|
||||
"POT-Creation-Date: 2020-03-09 08:19-0500\n"
|
||||
"PO-Revision-Date: 2018-10-02 21:14-0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@ -2078,6 +2078,26 @@ msgstr "argumentos extras de palavras-chave passados"
|
||||
msgid "extra positional arguments given"
|
||||
msgstr "argumentos extra posicionais passados"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a '#'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a backslash"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: empty expression not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: expecting '}'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: single '}' is not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c
|
||||
#: shared-bindings/displayio/OnDiskBitmap.c
|
||||
msgid "file must be a file opened in byte mode"
|
||||
@ -2391,6 +2411,10 @@ msgstr ""
|
||||
msgid "long int not supported in this build"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "malformed f-string"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_stage/Layer.c
|
||||
msgid "map buffer too small"
|
||||
msgstr ""
|
||||
@ -2718,6 +2742,10 @@ msgstr ""
|
||||
msgid "queue overflow"
|
||||
msgstr "estouro de fila"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "raw f-strings are not implemented"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/fft.c
|
||||
msgid "real and imaginary parts must be of equal length"
|
||||
msgstr ""
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: circuitpython-cn\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-03-03 20:13-0600\n"
|
||||
"POT-Creation-Date: 2020-03-09 08:19-0500\n"
|
||||
"PO-Revision-Date: 2019-04-13 10:10-0700\n"
|
||||
"Last-Translator: hexthat\n"
|
||||
"Language-Team: Chinese Hanyu Pinyin\n"
|
||||
@ -2093,6 +2093,26 @@ msgstr "éwài de guānjiàn cí cānshù"
|
||||
msgid "extra positional arguments given"
|
||||
msgstr "gěi chūle éwài de wèizhì cānshù"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a '#'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string expression part cannot include a backslash"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: empty expression not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: expecting '}'"
|
||||
msgstr ""
|
||||
|
||||
#: py/parse.c
|
||||
msgid "f-string: single '}' is not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c
|
||||
#: shared-bindings/displayio/OnDiskBitmap.c
|
||||
msgid "file must be a file opened in byte mode"
|
||||
@ -2407,6 +2427,10 @@ msgstr "fùzhí qián yǐnyòng de júbù biànliàng"
|
||||
msgid "long int not supported in this build"
|
||||
msgstr "cǐ bǎnběn bù zhīchí zhǎng zhěngshù"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "malformed f-string"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_stage/Layer.c
|
||||
msgid "map buffer too small"
|
||||
msgstr "dìtú huǎnchōng qū tài xiǎo"
|
||||
@ -2735,6 +2759,10 @@ msgstr "pow() yǒu 3 cānshù xūyào zhěngshù"
|
||||
msgid "queue overflow"
|
||||
msgstr "duìliè yìchū"
|
||||
|
||||
#: py/parse.c
|
||||
msgid "raw f-strings are not implemented"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/fft.c
|
||||
msgid "real and imaginary parts must be of equal length"
|
||||
msgstr ""
|
||||
|
@ -187,6 +187,9 @@ typedef long mp_off_t;
|
||||
#if !defined(MICROPY_CPYTHON_COMPAT)
|
||||
#define MICROPY_CPYTHON_COMPAT (CIRCUITPY_FULL_BUILD)
|
||||
#endif
|
||||
#if !defined(MICROPY_COMP_FSTRING_LITERAL)
|
||||
#define MICROPY_COMP_FSTRING_LITERAL (MICROPY_CPYTHON_COMPAT)
|
||||
#endif
|
||||
#define MICROPY_MODULE_WEAK_LINKS (CIRCUITPY_FULL_BUILD)
|
||||
#define MICROPY_PY_ALL_SPECIAL_METHODS (CIRCUITPY_FULL_BUILD)
|
||||
#define MICROPY_PY_BUILTINS_COMPLEX (CIRCUITPY_FULL_BUILD)
|
||||
|
166
py/lexer.c
166
py/lexer.c
@ -64,6 +64,12 @@ STATIC bool is_char_or3(mp_lexer_t *lex, byte c1, byte c2, byte c3) {
|
||||
return lex->chr0 == c1 || lex->chr0 == c2 || lex->chr0 == c3;
|
||||
}
|
||||
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
STATIC bool is_char_or4(mp_lexer_t *lex, byte c1, byte c2, byte c3, byte c4) {
|
||||
return lex->chr0 == c1 || lex->chr0 == c2 || lex->chr0 == c3 || lex->chr0 == c4;
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC bool is_char_following(mp_lexer_t *lex, byte c) {
|
||||
return lex->chr1 == c;
|
||||
}
|
||||
@ -107,7 +113,13 @@ STATIC bool is_following_odigit(mp_lexer_t *lex) {
|
||||
|
||||
STATIC bool is_string_or_bytes(mp_lexer_t *lex) {
|
||||
return is_char_or(lex, '\'', '\"')
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
|| (is_char_or4(lex, 'r', 'u', 'b', 'f') && is_char_following_or(lex, '\'', '\"'))
|
||||
|| ((is_char_and(lex, 'r', 'f') || is_char_and(lex, 'f', 'r'))
|
||||
&& is_char_following_following_or(lex, '\'', '\"'))
|
||||
#else
|
||||
|| (is_char_or3(lex, 'r', 'u', 'b') && is_char_following_or(lex, '\'', '\"'))
|
||||
#endif
|
||||
|| ((is_char_and(lex, 'r', 'b') || is_char_and(lex, 'b', 'r'))
|
||||
&& is_char_following_following_or(lex, '\'', '\"'));
|
||||
}
|
||||
@ -121,6 +133,31 @@ STATIC bool is_tail_of_identifier(mp_lexer_t *lex) {
|
||||
return is_head_of_identifier(lex) || is_digit(lex);
|
||||
}
|
||||
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
STATIC void swap_char_banks(mp_lexer_t *lex) {
|
||||
if (lex->vstr_postfix_processing) {
|
||||
lex->chr3 = lex->chr0;
|
||||
lex->chr4 = lex->chr1;
|
||||
lex->chr5 = lex->chr2;
|
||||
lex->chr0 = lex->vstr_postfix.buf[0];
|
||||
lex->chr1 = lex->vstr_postfix.buf[1];
|
||||
lex->chr2 = lex->vstr_postfix.buf[2];
|
||||
|
||||
lex->vstr_postfix_idx = 3;
|
||||
} else {
|
||||
// blindly reset to the "backup" bank when done postfix processing
|
||||
// this restores control to the mp_reader
|
||||
lex->chr0 = lex->chr3;
|
||||
lex->chr1 = lex->chr4;
|
||||
lex->chr2 = lex->chr5;
|
||||
// willfully ignoring setting chr3-5 here - WARNING consider those garbage data now
|
||||
|
||||
vstr_reset(&lex->vstr_postfix);
|
||||
lex->vstr_postfix_idx = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC void next_char(mp_lexer_t *lex) {
|
||||
if (lex->chr0 == '\n') {
|
||||
// a new line
|
||||
@ -136,7 +173,19 @@ STATIC void next_char(mp_lexer_t *lex) {
|
||||
|
||||
lex->chr0 = lex->chr1;
|
||||
lex->chr1 = lex->chr2;
|
||||
lex->chr2 = lex->reader.readbyte(lex->reader.data);
|
||||
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
if (lex->vstr_postfix_processing) {
|
||||
if (lex->vstr_postfix_idx == lex->vstr_postfix.len) {
|
||||
lex->chr2 = '\0';
|
||||
} else {
|
||||
lex->chr2 = lex->vstr_postfix.buf[lex->vstr_postfix_idx++];
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
lex->chr2 = lex->reader.readbyte(lex->reader.data);
|
||||
}
|
||||
|
||||
if (lex->chr1 == '\r') {
|
||||
// CR is a new line, converted to LF
|
||||
@ -151,6 +200,13 @@ STATIC void next_char(mp_lexer_t *lex) {
|
||||
if (lex->chr2 == MP_LEXER_EOF && lex->chr1 != MP_LEXER_EOF && lex->chr1 != '\n') {
|
||||
lex->chr2 = '\n';
|
||||
}
|
||||
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
if (lex->vstr_postfix_processing && lex->chr0 == '\0') {
|
||||
lex->vstr_postfix_processing = false;
|
||||
swap_char_banks(lex);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC void indent_push(mp_lexer_t *lex, size_t indent) {
|
||||
@ -270,7 +326,7 @@ STATIC bool get_hex(mp_lexer_t *lex, size_t num_digits, mp_uint_t *result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
STATIC void parse_string_literal(mp_lexer_t *lex, bool is_raw) {
|
||||
STATIC void parse_string_literal(mp_lexer_t *lex, bool is_raw, bool is_fstring) {
|
||||
// get first quoting character
|
||||
char quote_char = '\'';
|
||||
if (is_char(lex, '\"')) {
|
||||
@ -291,15 +347,71 @@ STATIC void parse_string_literal(mp_lexer_t *lex, bool is_raw) {
|
||||
}
|
||||
|
||||
size_t n_closing = 0;
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
bool in_expression = false;
|
||||
bool expression_eat = true;
|
||||
#endif
|
||||
|
||||
while (!is_end(lex) && (num_quotes > 1 || !is_char(lex, '\n')) && n_closing < num_quotes) {
|
||||
if (is_char(lex, quote_char)) {
|
||||
n_closing += 1;
|
||||
vstr_add_char(&lex->vstr, CUR_CHAR(lex));
|
||||
} else {
|
||||
n_closing = 0;
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
if (is_fstring && is_char(lex, '{')) {
|
||||
vstr_add_char(&lex->vstr, CUR_CHAR(lex));
|
||||
in_expression = !in_expression;
|
||||
expression_eat = in_expression;
|
||||
|
||||
if (lex->vstr_postfix.len == 0) {
|
||||
vstr_add_str(&lex->vstr_postfix, ".format(");
|
||||
}
|
||||
|
||||
next_char(lex);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_fstring && is_char(lex, '}')) {
|
||||
vstr_add_char(&lex->vstr, CUR_CHAR(lex));
|
||||
|
||||
if (in_expression) {
|
||||
in_expression = false;
|
||||
vstr_add_char(&lex->vstr_postfix, ',');
|
||||
}
|
||||
|
||||
next_char(lex);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_expression) {
|
||||
// throw errors for illegal chars inside f-string expressions
|
||||
if (is_char(lex, '#')) {
|
||||
lex->tok_kind = MP_TOKEN_FSTRING_COMMENT;
|
||||
return;
|
||||
} else if (is_char(lex, '\\')) {
|
||||
lex->tok_kind = MP_TOKEN_FSTRING_BACKSLASH;
|
||||
return;
|
||||
} else if (is_char(lex, ':')) {
|
||||
expression_eat = false;
|
||||
}
|
||||
|
||||
unichar c = CUR_CHAR(lex);
|
||||
if (expression_eat) {
|
||||
vstr_add_char(&lex->vstr_postfix, c);
|
||||
} else {
|
||||
vstr_add_char(&lex->vstr, c);
|
||||
}
|
||||
|
||||
next_char(lex);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (is_char(lex, '\\')) {
|
||||
next_char(lex);
|
||||
unichar c = CUR_CHAR(lex);
|
||||
|
||||
if (is_raw) {
|
||||
// raw strings allow escaping of quotes, but the backslash is also emitted
|
||||
vstr_add_char(&lex->vstr, '\\');
|
||||
@ -430,6 +542,15 @@ STATIC bool skip_whitespace(mp_lexer_t *lex, bool stop_at_newline) {
|
||||
}
|
||||
|
||||
void mp_lexer_to_next(mp_lexer_t *lex) {
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
if (lex->vstr_postfix.len && !lex->vstr_postfix_processing) {
|
||||
// end format call injection
|
||||
vstr_add_char(&lex->vstr_postfix, ')');
|
||||
lex->vstr_postfix_processing = true;
|
||||
swap_char_banks(lex);
|
||||
}
|
||||
#endif
|
||||
|
||||
// start new token text
|
||||
vstr_reset(&lex->vstr);
|
||||
|
||||
@ -481,10 +602,19 @@ void mp_lexer_to_next(mp_lexer_t *lex) {
|
||||
// MP_TOKEN_END is used to indicate that this is the first string token
|
||||
lex->tok_kind = MP_TOKEN_END;
|
||||
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
bool saw_normal = false, saw_fstring = false;
|
||||
#endif
|
||||
|
||||
// Loop to accumulate string/bytes literals
|
||||
do {
|
||||
// parse type codes
|
||||
bool is_raw = false;
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
bool is_fstring = false;
|
||||
#else
|
||||
const bool is_fstring = false;
|
||||
#endif
|
||||
mp_token_kind_t kind = MP_TOKEN_STRING;
|
||||
int n_char = 0;
|
||||
if (is_char(lex, 'u')) {
|
||||
@ -503,8 +633,34 @@ void mp_lexer_to_next(mp_lexer_t *lex) {
|
||||
kind = MP_TOKEN_BYTES;
|
||||
n_char = 2;
|
||||
}
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
if (is_char_following(lex, 'f')) {
|
||||
lex->tok_kind = MP_TOKEN_FSTRING_RAW;
|
||||
break;
|
||||
}
|
||||
} else if (is_char(lex, 'f')) {
|
||||
if (is_char_following(lex, 'r')) {
|
||||
lex->tok_kind = MP_TOKEN_FSTRING_RAW;
|
||||
break;
|
||||
}
|
||||
n_char = 1;
|
||||
is_fstring = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
if (is_fstring) {
|
||||
saw_fstring = true;
|
||||
} else {
|
||||
saw_normal = true;
|
||||
}
|
||||
|
||||
if (saw_fstring && saw_normal) {
|
||||
// Can't concatenate f-string with normal string
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set or check token kind
|
||||
if (lex->tok_kind == MP_TOKEN_END) {
|
||||
lex->tok_kind = kind;
|
||||
@ -522,13 +678,12 @@ void mp_lexer_to_next(mp_lexer_t *lex) {
|
||||
}
|
||||
|
||||
// Parse the literal
|
||||
parse_string_literal(lex, is_raw);
|
||||
parse_string_literal(lex, is_raw, is_fstring);
|
||||
|
||||
// Skip whitespace so we can check if there's another string following
|
||||
skip_whitespace(lex, true);
|
||||
|
||||
} while (is_string_or_bytes(lex));
|
||||
|
||||
} else if (is_head_of_identifier(lex)) {
|
||||
lex->tok_kind = MP_TOKEN_NAME;
|
||||
|
||||
@ -682,6 +837,9 @@ mp_lexer_t *mp_lexer_new(qstr src_name, mp_reader_t reader) {
|
||||
lex->num_indent_level = 1;
|
||||
lex->indent_level = m_new(uint16_t, lex->alloc_indent_level);
|
||||
vstr_init(&lex->vstr, 32);
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
vstr_init(&lex->vstr_postfix, 0);
|
||||
#endif
|
||||
|
||||
// store sentinel for first indentation level
|
||||
lex->indent_level[0] = 0;
|
||||
|
16
py/lexer.h
16
py/lexer.h
@ -44,6 +44,14 @@ typedef enum _mp_token_kind_t {
|
||||
MP_TOKEN_INVALID,
|
||||
MP_TOKEN_DEDENT_MISMATCH,
|
||||
MP_TOKEN_LONELY_STRING_OPEN,
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
MP_TOKEN_FSTRING_BACKSLASH,
|
||||
MP_TOKEN_FSTRING_COMMENT,
|
||||
MP_TOKEN_FSTRING_UNCLOSED,
|
||||
MP_TOKEN_FSTRING_UNOPENED,
|
||||
MP_TOKEN_FSTRING_EMPTY_EXP,
|
||||
MP_TOKEN_FSTRING_RAW,
|
||||
#endif
|
||||
|
||||
MP_TOKEN_NEWLINE,
|
||||
MP_TOKEN_INDENT,
|
||||
@ -150,6 +158,9 @@ typedef struct _mp_lexer_t {
|
||||
mp_reader_t reader; // stream source
|
||||
|
||||
unichar chr0, chr1, chr2; // current cached characters from source
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
unichar chr3, chr4, chr5; // current cached characters from alt source
|
||||
#endif
|
||||
|
||||
size_t line; // current source line
|
||||
size_t column; // current source column
|
||||
@ -165,6 +176,11 @@ typedef struct _mp_lexer_t {
|
||||
size_t tok_column; // token source column
|
||||
mp_token_kind_t tok_kind; // token kind
|
||||
vstr_t vstr; // token data
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
vstr_t vstr_postfix; // postfix to apply to string
|
||||
bool vstr_postfix_processing;
|
||||
uint16_t vstr_postfix_idx;
|
||||
#endif
|
||||
} mp_lexer_t;
|
||||
|
||||
mp_lexer_t *mp_lexer_new(qstr src_name, mp_reader_t reader);
|
||||
|
@ -377,6 +377,11 @@
|
||||
#define MICROPY_COMP_RETURN_IF_EXPR (0)
|
||||
#endif
|
||||
|
||||
// Whether to include parsing of f-string literals
|
||||
#ifndef MICROPY_COMP_FSTRING_LITERAL
|
||||
#define MICROPY_COMP_FSTRING_LITERAL (1)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Internal debugging stuff */
|
||||
|
||||
|
61
py/parse.c
61
py/parse.c
@ -924,6 +924,7 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
|
||||
backtrack = false;
|
||||
}
|
||||
for (; i < n; ++i) {
|
||||
//printf("--> inside for @L924\n");
|
||||
uint16_t kind = rule_arg[i] & RULE_ARG_KIND_MASK;
|
||||
if (kind == RULE_ARG_TOK) {
|
||||
if (lex->tok_kind == (rule_arg[i] & RULE_ARG_ARG_MASK)) {
|
||||
@ -1168,15 +1169,57 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
|
||||
) {
|
||||
syntax_error:;
|
||||
mp_obj_t exc;
|
||||
if (lex->tok_kind == MP_TOKEN_INDENT) {
|
||||
exc = mp_obj_new_exception_msg(&mp_type_IndentationError,
|
||||
translate("unexpected indent"));
|
||||
} else if (lex->tok_kind == MP_TOKEN_DEDENT_MISMATCH) {
|
||||
exc = mp_obj_new_exception_msg(&mp_type_IndentationError,
|
||||
translate("unindent does not match any outer indentation level"));
|
||||
} else {
|
||||
exc = mp_obj_new_exception_msg(&mp_type_SyntaxError,
|
||||
translate("invalid syntax"));
|
||||
switch(lex->tok_kind) {
|
||||
case MP_TOKEN_INDENT:
|
||||
exc = mp_obj_new_exception_msg(&mp_type_IndentationError,
|
||||
translate("unexpected indent"));
|
||||
break;
|
||||
case MP_TOKEN_DEDENT_MISMATCH:
|
||||
exc = mp_obj_new_exception_msg(&mp_type_IndentationError,
|
||||
translate("unindent does not match any outer indentation level"));
|
||||
break;
|
||||
#if MICROPY_COMP_FSTRING_LITERAL
|
||||
#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED
|
||||
case MP_TOKEN_FSTRING_BACKSLASH:
|
||||
exc = mp_obj_new_exception_msg(&mp_type_SyntaxError,
|
||||
translate("f-string expression part cannot include a backslash"));
|
||||
break;
|
||||
case MP_TOKEN_FSTRING_COMMENT:
|
||||
exc = mp_obj_new_exception_msg(&mp_type_SyntaxError,
|
||||
translate("f-string expression part cannot include a '#'"));
|
||||
break;
|
||||
case MP_TOKEN_FSTRING_UNCLOSED:
|
||||
exc = mp_obj_new_exception_msg(&mp_type_SyntaxError,
|
||||
translate("f-string: expecting '}'"));
|
||||
break;
|
||||
case MP_TOKEN_FSTRING_UNOPENED:
|
||||
exc = mp_obj_new_exception_msg(&mp_type_SyntaxError,
|
||||
translate("f-string: single '}' is not allowed"));
|
||||
break;
|
||||
case MP_TOKEN_FSTRING_EMPTY_EXP:
|
||||
exc = mp_obj_new_exception_msg(&mp_type_SyntaxError,
|
||||
translate("f-string: empty expression not allowed"));
|
||||
break;
|
||||
case MP_TOKEN_FSTRING_RAW:
|
||||
exc = mp_obj_new_exception_msg(&mp_type_NotImplementedError,
|
||||
translate("raw f-strings are not implemented"));
|
||||
break;
|
||||
#else
|
||||
case MP_TOKEN_FSTRING_BACKSLASH:
|
||||
case MP_TOKEN_FSTRING_COMMENT:
|
||||
case MP_TOKEN_FSTRING_UNCLOSED:
|
||||
case MP_TOKEN_FSTRING_UNOPENED:
|
||||
case MP_TOKEN_FSTRING_EMPTY_EXP:
|
||||
case MP_TOKEN_FSTRING_RAW:
|
||||
exc = mp_obj_new_exception_msg(&mp_type_SyntaxError,
|
||||
translate("malformed f-string"));
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
exc = mp_obj_new_exception_msg(&mp_type_SyntaxError,
|
||||
translate("invalid syntax"));
|
||||
break;
|
||||
}
|
||||
// add traceback to give info about file name and location
|
||||
// we don't have a 'block' name, so just pass the NULL qstr to indicate this
|
||||
|
113
tests/basics/string_pep498_fstring.py
Normal file
113
tests/basics/string_pep498_fstring.py
Normal file
@ -0,0 +1,113 @@
|
||||
# Tests against https://www.python.org/dev/peps/pep-0498/
|
||||
|
||||
assert f'no interpolation' == 'no interpolation'
|
||||
assert f"no interpolation" == 'no interpolation'
|
||||
|
||||
# Quoth the PEP:
|
||||
# Backslashes may not appear anywhere within expressions. Comments, using the
|
||||
# '#' character, are not allowed inside an expression
|
||||
#
|
||||
# CPython (3.7.4 on Linux) raises a SyntaxError here:
|
||||
# >>> f'{#}'
|
||||
# File "<stdin>", line 1
|
||||
# SyntaxError: f-string expression part cannot include '#'
|
||||
# >>> f'{\}'
|
||||
# File "<stdin>", line 1
|
||||
# SyntaxError: f-string expression part cannot include a backslash
|
||||
# >>> f'{\\}'
|
||||
# File "<stdin>", line 1
|
||||
# SyntaxError: f-string expression part cannot include a backslash
|
||||
# >>> f'{\#}'
|
||||
# File "<stdin>", line 1
|
||||
# SyntaxError: f-string expression part cannot include a backslash
|
||||
|
||||
# Backslashes and comments allowed outside expression
|
||||
assert f"\\" == "\\"
|
||||
assert f'#' == '#'
|
||||
|
||||
## But not inside
|
||||
try:
|
||||
eval("f'{\}'")
|
||||
except SyntaxError:
|
||||
pass
|
||||
else:
|
||||
raise AssertionError('f-string with backslash in expression did not raise SyntaxError')
|
||||
|
||||
try:
|
||||
eval("f'{#}'")
|
||||
except SyntaxError:
|
||||
pass
|
||||
else:
|
||||
raise AssertionError('f-string with \'#\' in expression did not raise SyntaxError')
|
||||
|
||||
# Quoth the PEP:
|
||||
# While scanning the string for expressions, any doubled braces '{{' or '}}'
|
||||
# inside literal portions of an f-string are replaced by the corresponding
|
||||
# single brace. Doubled literal opening braces do not signify the start of an
|
||||
# expression. A single closing curly brace '}' in the literal portion of a
|
||||
# string is an error: literal closing curly braces must be doubled '}}' in
|
||||
# order to represent a single closing brace.
|
||||
#
|
||||
# CPython (3.7.4 on Linux) raises a SyntaxError for the last case:
|
||||
# >>> f'{{}'
|
||||
# File "<stdin>", line 1
|
||||
# SyntaxError: f-string: single '}' is not allowed
|
||||
|
||||
assert f'{{}}' == '{}'
|
||||
|
||||
try:
|
||||
eval("f'{{}'")
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
raise RuntimeError('Expected ValueError for invalid f-string literal bracing')
|
||||
|
||||
x = 1
|
||||
assert f'{x}' == '1'
|
||||
|
||||
# Quoth the PEP:
|
||||
# The expressions that are extracted from the string are evaluated in the
|
||||
# context where the f-string appeared. This means the expression has full
|
||||
# access to local and global variables. Any valid Python expression can be
|
||||
# used, including function and method calls. Because the f-strings are
|
||||
# evaluated where the string appears in the source code, there is no additional
|
||||
# expressiveness available with f-strings. There are also no additional
|
||||
# security concerns: you could have also just written the same expression, not
|
||||
# inside of an f-string:
|
||||
|
||||
def foo():
|
||||
return 20
|
||||
|
||||
assert f'result={foo()}' == 'result=20'
|
||||
assert f'result={foo()}' == 'result={}'.format(foo())
|
||||
assert f'result={foo()}' == 'result={result}'.format(result=foo())
|
||||
|
||||
|
||||
# Quoth the PEP:
|
||||
# Adjacent f-strings and regular strings are concatenated. Regular strings are
|
||||
# concatenated at compile time, and f-strings are concatenated at run time. For
|
||||
# example, the expression:
|
||||
#
|
||||
# >>> x = 10
|
||||
# >>> y = 'hi'
|
||||
# >>> 'a' 'b' f'{x}' '{c}' f'str<{y:^4}>' 'd' 'e'
|
||||
#
|
||||
# yields the value: 'ab10{c}str< hi >de'
|
||||
#
|
||||
# Because strings are concatenated at lexer time rather than parser time in
|
||||
# MicroPython for mostly RAM efficiency reasons (see
|
||||
# https://github.com/micropython/micropython/commit/534b7c368dc2af7720f3aaed0c936ef46d773957),
|
||||
# and because f-strings here are implemented as a syntax translation
|
||||
# (f'{something}' => '{}'.format(something)), this particular functionality is unimplemented,
|
||||
# and in the above example, the '{c}' portion will trigger a KeyError on String.format()
|
||||
|
||||
x = 10
|
||||
y = 'hi'
|
||||
assert (f'h' f'i') == 'hi'
|
||||
#assert (f'h' 'i') == 'hi'
|
||||
#assert ('h' f'i') == 'hi'
|
||||
assert f'{x:^4}' == ' 10 '
|
||||
#assert ('a' 'b' f'{x}' f'str<{y:^4}>' 'd' 'e') == 'ab10str< hi >de'
|
||||
|
||||
# Other tests
|
||||
assert f'{{{4*10}}}' == '{40}'
|
0
tests/basics/string_pep498_fstring.py.exp
Normal file
0
tests/basics/string_pep498_fstring.py.exp
Normal file
@ -1,6 +1,6 @@
|
||||
----------------
|
||||
[ 4] rule(1) (n=9)
|
||||
tok(4)
|
||||
tok(10)
|
||||
[ 4] rule(22) (n=4)
|
||||
id(i)
|
||||
[ 4] rule(44) (n=1)
|
||||
@ -9,7 +9,7 @@
|
||||
NULL
|
||||
[ 6] rule(5) (n=2)
|
||||
id(a)
|
||||
tok(14)
|
||||
tok(20)
|
||||
[ 7] rule(5) (n=2)
|
||||
id(b)
|
||||
str(str)
|
||||
|
Loading…
Reference in New Issue
Block a user