@@ -66,6 +66,10 @@ Summary -- Release highlights
6666
6767.. PEP-sized items next.
6868
69+ New grammar features:
70+
71+ * :pep: `701 `: Syntactic formalization of f-strings
72+
6973New typing features:
7074
7175* :pep: `688 `: Making the buffer protocol accessible in Python
@@ -136,22 +140,70 @@ Improved Error Messages
136140New Features
137141============
138142
139- * Add :ref: `perf_profiling ` through the new
140- environment variable :envvar: `PYTHONPERFSUPPORT `,
141- the new command-line option :option: `-X perf <-X> `,
142- as well as the new :func: `sys.activate_stack_trampoline `,
143- :func: `sys.deactivate_stack_trampoline `,
144- and :func: `sys.is_stack_trampoline_active ` APIs.
145- (Design by Pablo Galindo. Contributed by Pablo Galindo and Christian Heimes
146- with contributions from Gregory P. Smith [Google] and Mark Shannon
147- in :gh: `96123 `.)
148- * The extraction methods in :mod: `tarfile `, and :func: `shutil.unpack_archive `,
149- have a new a *filter * argument that allows limiting tar features than may be
150- surprising or dangerous, such as creating files outside the destination
151- directory.
152- See :ref: `tarfile-extraction-filter ` for details.
153- In Python 3.14, the default will switch to ``'data' ``.
154- (Contributed by Petr Viktorin in :pep: `706 `.)
143+ .. _whatsnew312-pep701 :
144+
145+ PEP 701: Syntactic formalization of f-strings
146+ ---------------------------------------------
147+
148+ :pep: `701 ` lifts some restrictions on the usage of f-strings. Expression components
149+ inside f-strings can now be any valid Python expression including backslashes,
150+ unicode escaped sequences, multi-line expressions, comments and strings reusing the
151+ same quote as the containing f-string. Let's cover these in detail:
152+
153+ * Quote reuse: in Python 3.11, reusing the same quotes as the containing f-string
154+ raises a :exc: `SyntaxError `, forcing the user to either use other available
155+ quotes (like using double quotes or triple quotes if the f-string uses single
156+ quotes). In Python 3.12, you can now do things like this:
157+
158+ >>> songs = [' Take me back to Eden' , ' Alkaline' , ' Ascensionism' ]
159+ >>> f " This is the playlist: { " , " .join(songs)} "
160+ 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism
161+
162+ Note that before this change there was no explicit limit in how f-strings can
163+ be nested, but the fact that string quotes cannot be reused inside the
164+ expression component of f-strings made it impossible to nest f-strings
165+ arbitrarily. In fact, this is the most nested f-string that could be written:
166+
167+ >>> f """ { f ''' { f ' { f " { 1 + 1 } " } ' } ''' } """
168+ '2'
169+
170+ As now f-strings can contain any valid Python expression inside expression
171+ components, it is now possible to nest f-strings arbitrarily:
172+
173+ >>> f " { f " { f " { f " { f " { f " { 1 + 1 } " } " } " } " } " } "
174+ '2'
175+
176+ * Multi-line expressions and comments: In Python 3.11, f-strings expressions
177+ must be defined in a single line even if outside f-strings expressions could
178+ span multiple lines (like literal lists being defined over multiple lines),
179+ making them harder to read. In Python 3.12 you can now define expressions
180+ spaning multiple lines and include comments on them:
181+
182+ >>> f " This is the playlist: { " , " .join([
183+ ... ' Take me back to Eden' , # My, my, those eyes like fire
184+ ... ' Alkaline' , # Not acid nor alkaline
185+ ... ' Ascensionism' # Take to the broken skies at last
186+ ... ])}"
187+ 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'
188+
189+ * Backslashes and unicode characters: before Python 3.12 f-string expressions
190+ couldn't contain any ``\ `` character. This also affected unicode escaped
191+ sequences (such as ``\N{snowman} ``) as these contain the ``\N `` part that
192+ previously could not be part of expression components of f-strings. Now, you
193+ can define expressions like this:
194+
195+ >>> print (f " This is the playlist: { " \n " .join(songs)} " )
196+ This is the playlist: Take me back to Eden
197+ Alkaline
198+ Ascensionism
199+ >>> print (f " This is the playlist: { " \N{BLACK HEART SUIT} " .join(songs)} " )
200+ This is the playlist: Take me back to Eden♥Alkaline♥Ascensionism
201+
202+ See :pep: `701 ` for more details.
203+
204+ (Contributed by Pablo Galindo, Batuhan Taskaya, Lysandros Nikolaou, Cristián
205+ Maureira-Fredes and Marta Gómez in :gh: `102856 `. PEP written by Pablo Galindo,
206+ Batuhan Taskaya, Lysandros Nikolaou and Marta Gómez).
155207
156208.. _whatsnew312-pep709 :
157209
@@ -223,6 +275,24 @@ See :pep:`692` for more details.
223275Other Language Changes
224276======================
225277
278+ * Add :ref: `perf_profiling ` through the new
279+ environment variable :envvar: `PYTHONPERFSUPPORT `,
280+ the new command-line option :option: `-X perf <-X> `,
281+ as well as the new :func: `sys.activate_stack_trampoline `,
282+ :func: `sys.deactivate_stack_trampoline `,
283+ and :func: `sys.is_stack_trampoline_active ` APIs.
284+ (Design by Pablo Galindo. Contributed by Pablo Galindo and Christian Heimes
285+ with contributions from Gregory P. Smith [Google] and Mark Shannon
286+ in :gh: `96123 `.)
287+
288+ * The extraction methods in :mod: `tarfile `, and :func: `shutil.unpack_archive `,
289+ have a new a *filter * argument that allows limiting tar features than may be
290+ surprising or dangerous, such as creating files outside the destination
291+ directory.
292+ See :ref: `tarfile-extraction-filter ` for details.
293+ In Python 3.14, the default will switch to ``'data' ``.
294+ (Contributed by Petr Viktorin in :pep: `706 `.)
295+
226296* :class: `types.MappingProxyType ` instances are now hashable if the underlying
227297 mapping is hashable.
228298 (Contributed by Serhiy Storchaka in :gh: `87995 `.)
@@ -543,6 +613,14 @@ tkinter
543613 like ``create_*() `` methods.
544614 (Contributed by Serhiy Storchaka in :gh: `94473 `.)
545615
616+ tokenize
617+ --------
618+
619+ * The :mod: `tokenize ` module includes the changes introduced in :pep: `701 `. (
620+ Contributed by Marta Gómez Macías and Pablo Galindo in :gh: `102856 `.)
621+ See :ref: `whatsnew312-porting-to-python312 ` for more information on the
622+ changes to the :mod: `tokenize ` module.
623+
546624types
547625-----
548626
@@ -687,6 +765,11 @@ Optimizations
687765* Speed up :class: `asyncio.Task ` creation by deferring expensive string formatting.
688766 (Contributed by Itamar O in :gh: `103793 `.)
689767
768+ * The :func: `tokenize.tokenize ` and :func: `tokenize.generate_tokens ` functions are
769+ up to 64% faster as a side effect of the changes required to cover :pep: `701 ` in
770+ the :mod: `tokenize ` module. (Contributed by Marta Gómez Macías and Pablo Galindo
771+ in :gh: `102856 `.)
772+
690773
691774CPython bytecode changes
692775========================
@@ -1130,6 +1213,8 @@ Removed
11301213 Iceape, Firebird, and Firefox versions 35 and below (:gh: `102871 `).
11311214
11321215
1216+ .. _whatsnew312-porting-to-python312 :
1217+
11331218Porting to Python 3.12
11341219======================
11351220
@@ -1201,6 +1286,40 @@ Changes in the Python API
12011286 that may be surprising or dangerous.
12021287 See :ref: `tarfile-extraction-filter ` for details.
12031288
1289+ * The output of the :func: `tokenize.tokenize ` and :func: `tokenize.generate_tokens `
1290+ functions is now changed due to the changes introduced in :pep: `701 `. This
1291+ means that ``STRING `` tokens are not emitted any more for f-strings and the
1292+ tokens described in :pep: `701 ` are now produced instead: ``FSTRING_START ``,
1293+ ``FSRING_MIDDLE `` and ``FSTRING_END `` are now emitted for f-string "string"
1294+ parts in addition to the appropriate tokens for the tokenization in the
1295+ expression components. For example for the f-string ``f"start {1+1} end" ``
1296+ the old version of the tokenizer emitted::
1297+
1298+ 1,0-1,18: STRING 'f"start {1+1} end"'
1299+
1300+ while the new version emits::
1301+
1302+ 1,0-1,2: FSTRING_START 'f"'
1303+ 1,2-1,8: FSTRING_MIDDLE 'start '
1304+ 1,8-1,9: OP '{'
1305+ 1,9-1,10: NUMBER '1'
1306+ 1,10-1,11: OP '+'
1307+ 1,11-1,12: NUMBER '1'
1308+ 1,12-1,13: OP '}'
1309+ 1,13-1,17: FSTRING_MIDDLE ' end'
1310+ 1,17-1,18: FSTRING_END '"'
1311+
1312+ Aditionally, there may be some minor behavioral changes as a consecuence of the
1313+ changes required to support :pep: `701 `. Some of these changes include:
1314+
1315+ * Some final ``DEDENT `` tokens are now emitted within the bounds of the
1316+ input. This means that for a file containing 3 lines, the old version of the
1317+ tokenizer returned a ``DEDENT `` token in line 4 whilst the new version returns
1318+ the token in line 3.
1319+
1320+ * The ``type `` attribute of the tokens emitted when tokenizing some invalid Python
1321+ characters such as ``! `` has changed from ``ERRORTOKEN `` to ``OP ``.
1322+
12041323Build Changes
12051324=============
12061325
0 commit comments