[Python-Dev] Adding __format__ to classic classes

Guido van Rossum guido at python.org
Thu Feb 14 01:03:27 CET 2008


On Feb 13, 2008 2:57 PM, Eric Smith <eric+python-dev at trueblade.com> wrote:
>
> Guido van Rossum wrote:
> > On Feb 13, 2008 2:20 PM, Eric Smith <eric+python-dev at trueblade.com> wrote:
> >> Nick Coghlan wrote:
> >>> Eric Smith wrote:
> >>>> I hate to be dense, but could you point me to some code that does
> >>>> something similar but looks up the method by name?
> >>> I was going to suggest __enter__/__exit__, but that code relies mainly
> >>> on existing opcodes and just does an attribute lookup rather than
> >>> explicitly bypassing the instance dictionary.
> >>>
> >>> However, the source code for cPickle may provide some ideas (when it
> >>> looks up _reduce__/__getstate__/etc).
> >> Those do look promising.  Thanks!
> >
> > Or look in classobject.c itself; e.g. instance_str().
>
> It uses a static helper function instance_getattr(), which while it
> looks like what I want, I can't get to.

Well, it just implements PyObject_GetAttr for classic class instances...

> So I've come up with the following.  I haven't checked for leaks yet,
> but at least it appears to do what I want, for both classic and
> new-style classes.  I'm still porting over test cases from 3.0, so I'm
> not convinced this is correct, yet.
>
> /* Check for a __format__ method. */
> meth = PyObject_GetAttr(value, str__format__);
> if (meth)
>      result = PyObject_CallFunctionObjArgs(meth, spec, NULL);
> else {

You'd need PyErr_Clear() here the way this is written. But the
following call is redundant -- if that _PyType_Lookup() call finds
something, PyObject_GetAttr() will have found that too (or something
else).

>      meth = _PyType_Lookup(Py_TYPE(value), str__format__);
>      if (meth)
>          result = PyObject_CallFunctionObjArgs(meth, value, spec, NULL);
>      else {
>         PyErr_Format(PyExc_TypeError,
>                  "Type %.100s doesn't define __format__",
>                  Py_TYPE(value)->tp_name);
>          goto done;
>      }
> }

Since PyObject_GetAttr() sets an AttributeError exception already, I
question the benefit of setting a different exception.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-Dev mailing list