[Python-Dev] Adding __format__ to classic classes

Eric Smith eric+python-dev at trueblade.com
Wed Feb 13 23:57:46 CET 2008


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.

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 {
     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;
     }
}




More information about the Python-Dev mailing list