[Python-ideas] Briefer string format

Steve Dower Steve.Dower at microsoft.com
Mon Jul 20 03:33:48 CEST 2015

Chris Angelico wrote:
> On Mon, Jul 20, 2015 at 10:43 AM, Steve Dower <Steve.Dower at microsoft.com> wrote:
> It'd obviously have to be a compile-time transformation. My point is
> that it would, unlike all other forms of literal, translate into a
> function call.

Excluding dictionary literals, of course. And class definitions. Decorators too, and arguably the descriptor protocol and __getattribute__ make things that look like attribute lookups into function calls. Python is littered with these, so I'm not sure that your point has any historical support.
> How is your "x=x, y=y" version materially different from explicitly
> mentioning locals() or globals()? The only significant difference is
> that your version follows the scope order outward, where locals() and
> globals() call up a specific scope each.

Yes, it follows normal scoping rules and doesn't invent/define/describe new ones for this particular case. There is literally no difference between the function call version and the prefix version wrt scoping.

As an example of why "normal rules" are better than "locals()/globals()", how would you implement this using just locals() and globals()?

>>> def f():
...     x = 123
...     return [f'{x}' for _ in range(1)]
>>> f()

Given that this is the current behaviour:

>>> def f():
...   return [locals()[x] for _ in range(1)]
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in f
  File "<stdin>", line 1, in <listcomp>
KeyError: 'x'

> Will an f"..." format string be mergeable with other strings? All the
> other types of literal can be (apart, of course, from mixing bytes and
> unicode), but this would have to be something somehow different.

I don't mind saying "no" here, especially since the merging is done while compiling, but it would be possible to generate a runtime concatentation here. Again, you only "know" that code (currently) has no runtime effect because, well, because you know it. It's a change, but it isn't world ending.

> In every way that I can think of, this is not a literal - it is a
> construct that results in a run-time operation.

Most new Python developers (with backgrounds in other languages) are surprised that "class" is a construct that results in a run-time operation, and would be surprised that writing a dictionary literal also results in a run-time operation if they ever had reason to notice. I believe the same would apply here.

> A context-dependent operation, at that.

You'll need to explain this one for me - how is it "context-dependent" when you are required to provide a string prefix?

> That's why I'm -1 on this looking like a literal.

I hope you'll reconsider, because I think you're working off some incorrect or over-simplified beliefs. (Though this reply isn't just intended for Chris, but for everyone following the discussion, so I hope *everyone* considers both sides.)


More information about the Python-ideas mailing list