[Python-Dev] Adding __format__ to classic classes

Eric Smith eric+python-dev at trueblade.com
Wed Feb 13 21:07:48 CET 2008


Guido van Rossum wrote:
> On Feb 13, 2008 9:48 AM, Eric Smith <eric+python-dev at trueblade.com> wrote:
>> Guido van Rossum wrote:
>>> On Feb 13, 2008 5:28 AM, Eric Smith <eric+python-dev at trueblade.com> wrote:
>>>> When backporting PEP 3101, do we want to add __format__ to classic
>>>> classes?  If so, could someone give me a pointer on how to implement
>>>> this?  I don't see where to hook it up.
>>> You just have to get the '__format__' attribute and call it if it
>>> exists. Isn't that how you do it for new-style classes too?
>>>
>> I'm thinking that I need to add a __format__ to the "most base" old
>> style class, similar to how I added it for object itself (in
>> object_methods[]).  As I currently have it in 2.6, I can call __format__
>> on a new style class, but not a classic class:
>>
>> $ ./python.exe
>> Python 2.6a0 (trunk:60757M, Feb 13 2008, 09:14:18)
>> [GCC 4.0.1 (Apple Inc. build 5465)] on darwin
>> Type "help", "copyright", "credits" or "license" for more information.
>>
>>  >>> class newstyle(object): pass
>> ...
>>  >>> class oldstyle: pass
>> ...
>>
>>  >>> newstyle().__format__('')
>> '<__main__.newstyle object at 0x3d4d90>'
>>
>>  >>> oldstyle().__format__('')
>> Traceback (most recent call last):
>>    File "<stdin>", line 1, in <module>
>> AttributeError: oldstyle instance has no attribute '__format__'
>>
>>  >>>
>>
>> So my question is, to what do I need to add __format__ so that classic
>> classes will have a default implementation?
>>
>> My knowledge of how classic classes are implemented is weak, so I don't
>> know where to add this.
> 
> Ah, I see.
> 
> There is no root class of the classic class hierarchy (that's why
> we're nixing it in 3.0 :-).
> 
> The customary pattern, used everywhere from len() to setattr(), is to
> first check for an (instance) attribute with a special name
> (__format__), and if that isn't found, to use a hard-coded fallback
> implementation. For len() the fallback raises an exception; for
> setattr() it puts the value in the instance __dict__.
> 


Much to my surprise, this already works:

 >>> format(oldstyle(), '+^50s')
'+++++<__main__.oldstyle instance at 0x3d91f8>+++++'
 >>>

So I guess it's a moot point.  I'm using the same code as I use in 3.0, 
where I call:
   meth = _PyType_Lookup(Py_TYPE(value), format_str);
where format_str is "__format__" interned.  And I'm getting a value back 
for old style classes.

Eric.


More information about the Python-Dev mailing list