[Python-3000] Open Issues for string.format PEP

Ian Bicking ianb at colorstudy.com
Wed Apr 26 18:13:42 CEST 2006


Talin wrote:
> Ian Bicking <ianb <at> colorstudy.com> writes:
>>>I want to go back for a moment to the original question. Whenever someone asks
>>>me "how should we solve this problem?" the first thing I always ask is "do we
>>>really need to?" Once we've answered that, we can then go on to the issue of
>>>coming up with a solution.
>>
>>Without this all dictionaries must be copied.  I think maybe Guido 
>>suggested something involving a shortcut that would not covert the 
>>dictionary, but that shortcut isn't available to Python so the behavior 
>>could be different for custom formatters implemented in Python.  Also, 
>>only dictionaries are allowed after **; that could be changed (maybe 
>>that's part of the signature changes?), but that doesn't change the fact 
>>that only a dictionary can be passed into a function with **.
> 
> 
> I think you are missing some alternatives. You see, the question I was asking
> wasn't "How important is it that we be able to efficiently pass whole
> dictionaries to the format function?" The question was "How important is it to
> be able to pass whole dictionaries at all?" Remember, that anything that you
> can do with **args you can also do by explicitly passing the individual args
> you want.

If you allow for {0.name}, yes.  Otherwise, no, not at all.

> Another alternative is just to fix the efficiency problems with **args. The
> reason that **args is so expensive is because of the need to funnel all calls
> through the existing C API, which requires that all function calls have the
> signature of ( PyTuple *args, PyDict *kwargs ). If you were somehow able to
> bypass or extend the C API, you could take the **args from the function call,
> and directly hook it up to the **args in the formal parameter list, without
> any flattening.

That seems like a tricky optimization that disappear in ways that are 
hard for people to understand.  So:

   def x(**kw):
     return kw

You can pass through the dictionary directly, right?  What about:

   def x(**kw):
     v = kw.pop('template')
     return v.format(**kw)

Well, you need a copy there, unless you want the caller to have their 
dictionary modified.  Or what about:

   def x(template, **kw):
     return template.format(**kw)

Now, if you call it as x('...', **d) then it can be optimized.  But if 
you call it as x('...', var1='foo', **d) it can't?  What about x(**d)?

To me any optimization just feels like a corner case.

> Assumming that neither of those options are available, I would probably then
> do one of the following:
> 
> 1) Create a different method name for the dict case:
> 
>     "{name}".vformat( mydict )

That would be fine.

> 2) Have some sort of reserved, keyword-only argument for dicts:
> 
>     "{name}".format( indirect_args=mydict )

That seems not as nice, but maybe okay.

> 3) Bring back field expressions:
> 
>     "{0.name}".format( mydict )

That would be fine sometimes.

> (Perhaps the '.' operator can mean both '.' and '[]' depending on the type of
> the object.)

As an option that could be nice regardless; I'd be a little nervous 
about enabling that everywhere.  It's a lot less powerful (and less of a 
security issue) than full evaluation, but still leans a bit in that 
direction.  But without auto-calling it's not actually that bad.

-- 
Ian Bicking  /  ianb at colorstudy.com  /  http://blog.ianbicking.org


More information about the Python-3000 mailing list