I feel torn on this PEP for a few reasons:
- I very much prefer the leading
\n removal, but Iām unsure of the leading-but-not-trailing \n removal
- I sometimes wish I could embed a multi-line string within another multi-line string and have both automatically dedented (I made a t-string-powered library to demonstrate this wish) and I hoped this PEP might accomplish this but it does not (deliberately it seems, as thereās a complexity trade off)
- I teach Python and this seems like a syntax I would want my students to know about but the mental model for this doesnāt seem nearly as intuitive to teach as traditional multi-line strings (both due to point 1 and 2 and because dedenting is difficult to reason about in general)
All that said, I really like the idea of improving the dedenting mechanisms in Python, whether through a string method, a new syntax, or just an enhancement to textwrap.dedent
On leading & trailing newline removal
I find myself copy-pasting these two functions around between various projects:
This dedent version that removes the leading newline only:
def undent(text):
return dedent(text).removeprefix("\n")
And this version which strips a trailing newline as well (like inspect.cleandoc):
def undent(text):
return dedent(text).removeprefix("\n").removesuffix("\n")
It seems that I use the first version most of the time but I use the second version (to remove both prefix and suffix \n) about one-third of the time.
It would be nice to avoid using .rstrip() with d-strings, but that would make my primary use case more awkward.
On dedenting and re-indenting replacement fields
Given this string:
code = r"""
def strip_each(lines):
new_lines = []
for line in lines:
new_lines.append(line.rstrip("\n"))
return new_lines
""".strip("\n")
I would love it if this:
example = d"""
Example function:
{code}
That function was indented properly!
"""
Resulted in this:
>>> print(example)
Example function:
def strip_each(lines):
new_lines = []
for line in lines:
new_lines.append(line.rstrip("\n"))
return new_lines
That function was indented properly!
But I understand that this could complicate the mental model even further, especially raising questions of āwhat about replacement fields that are mid-lineā.
On teaching this to beginners
The āHow to teach thisā section doesnāt currently address teaching this to new Python programmers.
I suspect that I would teach this most often to folks who have never heard of textwrap.dedent and who may never hear of it (if d-strings become successful enough to supersede its use).
My main concern with teaching this to beginners is explaining how it works. The prefix/suffix newline removal feels a bit magical and Iām suggesting even more (likely unfeasible) magic above, but dedenting is also a bit magical, especially if a {...} replacement field includes a string that contains a newline.
I hope some of the above concerns may be useful to consider. I know Iāve repeated/overlapped at least a bit with previously expressed concerns.
Thanks for pushing this idea forward in various forms over the years @methane! Iāve found what Iāve read from the previous threads inspiring.