[Python-Dev] Adding __format__ to classic classes
Guido van Rossum
guido at python.org
Wed Feb 13 21:11:20 CET 2008
On Feb 13, 2008 12:07 PM, Eric Smith <eric+python-dev at trueblade.com> wrote:
>
> 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.
But now try overriding __format__(). The 3.0 code uses
_PyType_Lookup() which is not traversing the class dicts for classic
classes, so it won't find __format__ overrides.
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-Dev
mailing list