[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