
On Mon, May 3, 2021 at 1:00 PM David Álvarez Lombardi <alvarezdqal@gmail.com> wrote:
Rather than toy examples, how about scouring the Python standard library for some real examples?
Here are 73 of them that I found by grepping through Lib.
https://github.com/python/cpython/blob/master/Lib/email/_encoded_words.py#L9... https://github.com/python/cpython/blob/master/Lib/email/_header_value_parser... https://github.com/python/cpython/blob/master/Lib/email/_header_value_parser... https://github.com/python/cpython/blob/master/Lib/email/_header_value_parser... https://github.com/python/cpython/blob/master/Lib/email/_header_value_parser... https://github.com/python/cpython/blob/master/Lib/email/_header_value_parser... https://github.com/python/cpython/blob/master/Lib/lib2to3/fixes/fix_import.p... https://github.com/python/cpython/blob/master/Lib/lib2to3/fixes/fix_next.py#... https://github.com/python/cpython/blob/master/Lib/lib2to3/refactor.py#L235 https://github.com/python/cpython/blob/master/Lib/msilib/__init__.py#L178 https://github.com/python/cpython/blob/master/Lib/msilib/__init__.py#L290 https://github.com/python/cpython/blob/master/Lib/test/_test_multiprocessing... https://github.com/python/cpython/blob/master/Lib/test/multibytecodec_suppor... https://github.com/python/cpython/blob/master/Lib/test/test_audioop.py#L6 https://github.com/python/cpython/blob/master/Lib/test/test_buffer.py#L853 https://github.com/python/cpython/blob/master/Lib/test/test_code_module.py#L... https://github.com/python/cpython/blob/master/Lib/test/test_code_module.py#L... https://github.com/python/cpython/blob/master/Lib/test/test_codeccallbacks.p... https://github.com/python/cpython/blob/master/Lib/test/test_codeccallbacks.p... https://github.com/python/cpython/blob/master/Lib/test/test_codeccallbacks.p... https://github.com/python/cpython/blob/master/Lib/test/test_codecs.py#L149 https://github.com/python/cpython/blob/master/Lib/test/test_codecs.py#L1544 https://github.com/python/cpython/blob/master/Lib/test/test_codecs.py#L1548 https://github.com/python/cpython/blob/master/Lib/test/test_codecs.py#L1552 https://github.com/python/cpython/blob/master/Lib/test/test_codecs.py#L1556 https://github.com/python/cpython/blob/master/Lib/test/test_codecs.py#L1953 https://github.com/python/cpython/blob/master/Lib/test/test_codecs.py#L1991 https://github.com/python/cpython/blob/master/Lib/test/test_decimal.py#L1092 https://github.com/python/cpython/blob/master/Lib/test/test_decimal.py#L5346 https://github.com/python/cpython/blob/master/Lib/test/test_email/test_email... https://github.com/python/cpython/blob/master/Lib/test/test_email/test_email... https://github.com/python/cpython/blob/master/Lib/test/test_fileinput.py#L91 https://github.com/python/cpython/blob/master/Lib/test/test_fileinput.py#L92 https://github.com/python/cpython/blob/master/Lib/test/test_fileinput.py#L93 https://github.com/python/cpython/blob/master/Lib/test/test_fileinput.py#L94 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L360 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L366 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L372 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L378 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L384 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L391 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L397 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L403 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L409 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L415 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L421 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L427 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L433 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L455 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L457 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L459 https://github.com/python/cpython/blob/master/Lib/test/test_gettext.py#L461 https://github.com/python/cpython/blob/master/Lib/test/test_long.py#L305 https://github.com/python/cpython/blob/master/Lib/test/test_lzma.py#L1049 https://github.com/python/cpython/blob/master/Lib/test/test_lzma.py#L1087 https://github.com/python/cpython/blob/master/Lib/test/test_random.py#L914 https://github.com/python/cpython/blob/master/Lib/test/test_random.py#L921 https://github.com/python/cpython/blob/master/Lib/test/test_random.py#L927 https://github.com/python/cpython/blob/master/Lib/test/test_random.py#L933 https://github.com/python/cpython/blob/master/Lib/test/test_random.py#L968 https://github.com/python/cpython/blob/master/Lib/test/test_re.py#L1013 https://github.com/python/cpython/blob/master/Lib/test/test_strtod.py#L226 https://github.com/python/cpython/blob/master/Lib/test/test_ucn.py#L192 https://github.com/python/cpython/blob/master/Lib/test/test_ucn.py#L65 https://github.com/python/cpython/blob/master/Lib/test/test_unicodedata.py#L... https://github.com/python/cpython/blob/master/Lib/test/test_zipfile.py#L1833 https://github.com/python/cpython/blob/master/Lib/tkinter/__init__.py#L268 https://github.com/python/cpython/blob/master/Lib/unittest/test/test_asserti... https://github.com/python/cpython/blob/master/Lib/unittest/test/test_case.py... https://github.com/python/cpython/blob/master/Lib/urllib/parse.py#L907 https://github.com/python/cpython/blob/master/Lib/xml/etree/ElementTree.py#L...
Tests don't really count, so there's a small handful here. I haven't looked at them all. Some of them definitely could be done this way, but the best way to make your point is to show the current code and your proposed alternative, and show how the new syntax improves things. Not just "it could be done this way", but "this way looks massively better".
Second, f-strings do not restrict the normal usage of strings for freeform text content (apart from making the curly brace characters special).
Not to nit-pick too much, but the following is a valid string but not a valid f-string.
s = f"This is a valid string but invalid f-string {}" File "<stdin>", line 1 s = f"This is a valid string but invalid f-string {}" ^ SyntaxError: f-string: empty expression not allowed
That's exactly because the curly braces are special. Not sure your point here?
Would readers see any merit in a syntax like the following?
dirty = "f8sjGe7" clean = str(char for char in dirty if char in string.ascii_letters) clean 'fsjGe'
Or would it stray too far from the behavior of the str() constructor in general?
The str constructor is also the generic "turn anything into a string" function. If it were not for that, I'd say it's fairly reasonable; but I don't want to see a genexp automatically pump itself and join the results just because someone printed it out. But if you wanted to make a dedicated constructor, eg str.from_substrings(iterable), that would definitely be viable. Would it be useful? Not sure.
I don't intend to reinvent strings, I only mean to leverage an already existing means of signifying modified string construction syntax (prefixes) to align str construction syntax with the comprehensions available for the other most common builtin iterables, avoid the notoriously unintuitive "".join syntax, and improve readability.
Yes, "".join() takes some learning, but if that's the problem being solved, I'd much rather look into simpler solutions. I'd really like to see str.__rmul__() accept any iterable and join it, as mentioned earlier (or maybe that was in a related thread):
class Str(str): ... __rmul__ = str.join ... ["Hello", "world"] * Str(" ") 'Hello world'
or, if it became part of the core: ["Hello", "world"] * " " But in terms of embedding a join expression in the middle of an f-string (NOT cases where the join is the entire expression), I do think it'd be nice to have a mutator syntax that iterates over the thing, formatting each element according to the given definition, and outputting them all together - effectively equivalent to joining with an empty string. ChrisA