[Python-3000] string.Formatter class

Ron Adam rrr at ronadam.com
Fri Aug 31 04:21:18 CEST 2007



Eric Smith wrote:
> Ron Adam wrote:
>>
>>
>> Eric Smith wrote:
>>> Ron Adam wrote:
>>>>> get_field(field_name, args, kwargs, used_args)
>>>>> Given a field_name as returned by parse, convert it to an object to 
>>>>> be formatted.  The default version takes strings of the form 
>>>>> defined in the PEP, such as "0[name]" or "label.title".  It records 
>>>>> which args have been used in used_args.  args and kwargs are as 
>>>>> passed in to vformat.
>>>>
>>>> Rather than pass the used_args set out and have it modified in a 
>>>> different methods, I think it would be better to pass the arg_used 
>>>> back along with the object.  That keeps all the code that is 
>>>> involved in checking used args is in one method.  The arg_used value 
>>>> may be useful in other ways as well.
>>>>
>>>>      obj, arg_used = self.get_field(field_name, args, kwargs)
>>>>      used_args.add(arg_used)
>>>
>>> I'm really not wild about either solution, but I suppose yours is 
>>> less objectionable than mine.  I'll check this change in tonight 
>>> (before the deadline).
>>
>> Cool.  I looked at other possible ways, but this seemed to be the 
>> easiest to live with.  The alternative is to use an attributes to pass 
>> and hold values, but sense the Formatter class isn't a data class, 
>> that doesn't seem appropriate.
> 
> I agree that attributes seem like the wrong way to go about it.  It also 
> makes recursively calling the formatter impossible without saving state.
> 
> I'm still planning on making this change tonight.
> 
>>> I think you'd have to say:
>>>
>>> if args_used is not None:
>>>    used_args.add(args_used)
>>>
>>> as it's possible that the field was not derived from the args or kwargs.
>>
>> How?  From what I can see an exception would be raised in the 
>> get_value method.
>>
>> When would I ever want to get a None for args_used?
> 
> I meant arg_used.

I understood.

> You're right.  I was confusing get_field with get_value.  (Surely we can 
> pick better names!)


Hmm... how about this?

          if field_name is not None:
              name, sub_names = field_name._formatter_field_name_split()
              obj = self.get_value(name, args, kwargs)
              obj = self.get_sub_value(obj, sub_names)
              obj = self.convert_field(obj, conversion)
              used_args.add(name)

              # format the object and append to the result
              result.append(self.format_field(obj, format_spec))


This doesn't require passing an arg_used value as it's available in vformat.


Get_sub_value replaces get_field.

     def get_sub_value(self, sub_value_name, args, kwargs):
         #  Get sub value of an object.
         #  (indices or attributes)
         for is_attr, i in sub_value_name:
             if is_attr:
                 obj = getattr(obj, i)
             else:
                 obj = obj[i]
         return obj

While it moves more into vformat, I think it's clearer what everything does.


Cheers,
    Ron






More information about the Python-3000 mailing list