Skip to content

Commit cce205c

Browse files
committed
ignore lines inside {}
1 parent ea901f5 commit cce205c

1 file changed

Lines changed: 64 additions & 28 deletions

File tree

peps/pep-0822.rst

Lines changed: 64 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -155,32 +155,40 @@ Therefore, escape sequences such as ``\x20`` and line-continuation
155155
backslashes are not treated as whitespace, and you cannot use ``\t`` in
156156
indentations.
157157

158-
For ``df`` and ``dt`` strings, physical lines of the literal include lines
159-
inside replacement fields (``{...}``), including lines inside nested string
160-
literals and multiline format specs.
161-
Therefore, such lines also affect the longest common indentation of the outer
162-
literal.
163-
164-
Although lines inside replacement fields participate in calculating the
165-
longest common indentation, the outer d-string does not remove indentation
166-
from the contents of those replacement fields. Dedentation is applied only to
167-
the constant text parts of the outer ``df`` or ``dt`` string. In particular,
168-
the following retain their source indentation:
158+
For ``df`` and ``dt`` strings, a physical line participates in the longest
159+
common indentation calculation only if it starts while the tokenizer is in a
160+
constant text part of that d-string. A line that starts inside a replacement
161+
field (``{...}``) does not participate in the calculation, even if the
162+
replacement field ends and constant text resumes later on the same line.
163+
This includes lines that start inside nested string literals and multiline
164+
format specs in a replacement field.
165+
166+
A line that starts in a constant text part still participates when its first
167+
non-whitespace character opens a replacement field. Its leading whitespace is
168+
part of the outer d-string and constrains how much indentation can be removed
169+
from that line.
170+
171+
Dedentation is applied only to the constant text parts of the outer ``df`` or
172+
``dt`` string. Text inside replacement fields retains its source indentation.
173+
In particular, the following are not dedented:
169174

170175
* The raw source text of ``df`` debug expressions (``{expr=}``).
171176
* The captured expression text of ``dt`` interpolations.
172177
* Multiline string literals in replacement expressions.
173178
* Multiline format specs.
174179

175-
This distinction lets replacement-field lines constrain how much indentation
176-
is removed from the surrounding constant text without rewriting Python source
177-
or format-spec text inside the field.
180+
Ignoring lines that start inside replacement fields prevents the formatting of
181+
an expression from changing the value of the surrounding constant text. It
182+
also ensures that leading whitespace which affects the resulting value is
183+
represented in the string-part tokens rather than in otherwise insignificant
184+
spacing between expression tokens.
178185

179186
If a replacement field expression itself contains another d-string literal,
180187
the nested d-string is supported and is dedented independently according to
181-
its own physical lines. Those same physical lines also participate in the
182-
outer d-string's longest-common-indentation calculation. The outer d-string
183-
does not otherwise dedent the nested literal's contents.
188+
its own physical lines. Those same physical lines do not participate in the
189+
outer d-string's longest-common-indentation calculation because they start
190+
inside its replacement field. The outer d-string does not otherwise dedent the
191+
nested literal's contents.
184192

185193

186194
Examples
@@ -293,8 +301,8 @@ In the following examples, spaces are visualized as ``.`` and tabs as ``--->``.
293301
print(s.strings) # ('Hello,.', '!\n')
294302
print(s.values) # ('World',)
295303
296-
# In df/dt strings, lines inside replacement fields participate in
297-
# the outer longest common indentation calculation.
304+
# A line that starts outside a replacement field participates in the outer
305+
# longest common indentation calculation, even when it contains a field.
298306
s = df"""
299307
..Hello
300308
....{42}
@@ -303,23 +311,33 @@ In the following examples, spaces are visualized as ``.`` and tabs as ``--->``.
303311
304312
s = df"""
305313
..Hello
306-
.{42}
314+
.{42} World
307315
.."""
308-
print(repr(s)) # '.Hello\n42\n'
316+
print(repr(s)) # '.Hello\n42 World\n'
309317
310318
s = df"""
311319
....Hello {1 +
312320
...2}
313321
...."""
314-
print(repr(s)) # '.Hello 3\n'
322+
print(repr(s)) # 'Hello 3\n'
315323
316324
# The source text of a multiline debug expression is not dedented,
317-
# although its physical lines affect the outer common indentation.
325+
# and a line that starts inside the expression does not affect the outer
326+
# common indentation.
318327
s = df"""
319328
....{1 +
320329
..1=}
321330
...."""
322-
print(repr(s)) # '..1 +\n..1=2\n'
331+
print(repr(s)) # '1 +\n..1=2\n'
332+
333+
# A line that starts inside a replacement field is ignored even when the
334+
# field ends and constant text resumes on that line.
335+
s = df"""
336+
....hello {
337+
........1
338+
} world
339+
...."""
340+
print(repr(s)) # 'hello 1 world\n'
323341
324342
# A nested d-string in a replacement field is dedented independently.
325343
s = df"""
@@ -331,16 +349,15 @@ In the following examples, spaces are visualized as ``.`` and tabs as ``--->``.
331349
.."""
332350
print(repr(s)) # 'outer\n..nested\nline\n\n'
333351
334-
# Lines in a nested d-string also constrain the outer indentation.
335-
# Here, the unindented "bar" and "baz" lines make the outer common
336-
# indentation empty, while the nested d-string is evaluated independently.
352+
# Lines in a nested d-string do not constrain the outer indentation. The
353+
# nested d-string is evaluated independently.
337354
s = df"""
338355
....foo {d"""
339356
bar
340357
baz
341358
........"""} spam
342359
...."""
343-
print(repr(s)) # '....foo bar\nbaz\n spam\n'
360+
print(repr(s)) # 'foo bar\nbaz\n spam\n'
344361
345362
346363
How to Teach This
@@ -763,6 +780,25 @@ It makes the dedent rules simpler, and the difference from
763780
specification to users.
764781

765782

783+
Dedent inside replacement fields
784+
--------------------------------
785+
786+
Dedenting expressions inside replacement fields provides too little benefit to
787+
justify the added parser complexity.
788+
Considering not only the complexity of Python's own parser but also the ease
789+
of implementing tools that analyze Python source code, it makes more sense to
790+
dedent only the constant parts.
791+
792+
For example, the dedent amount of a df-string is the same as that of the
793+
df-string obtained by replacing all replacement fields with ``{""}``.
794+
This makes it easier for tools such as :func:`tokenize.tokenize` to calculate
795+
the dedent amount when they encounter a df-string.
796+
797+
Similarly, in Ruby's ``<~`` heredocs and in Julia's and CoffeeScript's
798+
``"""`` strings, the contents of replacement fields are not dedented and do
799+
not contribute to the dedent amount.
800+
801+
766802
Copyright
767803
=========
768804

0 commit comments

Comments
 (0)