On Mon, May 3, 2021 at 1:00 PM David Álvarez Lombardi
<alvarezd...@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#L90
> https://github.com/python/cpython/blob/master/Lib/email/_header_value_parser.py#L126
> https://github.com/python/cpython/blob/master/Lib/email/_header_value_parser.py#L134
> https://github.com/python/cpython/blob/master/Lib/email/_header_value_parser.py#L256
> https://github.com/python/cpython/blob/master/Lib/email/_header_value_parser.py#L260
> https://github.com/python/cpython/blob/master/Lib/email/_header_value_parser.py#L283
> https://github.com/python/cpython/blob/master/Lib/lib2to3/fixes/fix_import.py#L29
> https://github.com/python/cpython/blob/master/Lib/lib2to3/fixes/fix_next.py#L69
> 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.py#L4680
> https://github.com/python/cpython/blob/master/Lib/test/multibytecodec_support.py#L309
> 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#L123
> https://github.com/python/cpython/blob/master/Lib/test/test_code_module.py#L139
> https://github.com/python/cpython/blob/master/Lib/test/test_codeccallbacks.py#L515
> https://github.com/python/cpython/blob/master/Lib/test/test_codeccallbacks.py#L521
> https://github.com/python/cpython/blob/master/Lib/test/test_codeccallbacks.py#L824
> 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.py#L3526
> https://github.com/python/cpython/blob/master/Lib/test/test_email/test_email.py#L3535
> 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#L327
> 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_assertions.py#L178
> https://github.com/python/cpython/blob/master/Lib/unittest/test/test_case.py#L704
> https://github.com/python/cpython/blob/master/Lib/urllib/parse.py#L907
> https://github.com/python/cpython/blob/master/Lib/xml/etree/ElementTree.py#L1986

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
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/CWYW5VNIA4NAEVCYPF7Q26ZR24I3FKT7/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to