[Patches] better errors for __getattr__/__repr__ confusion

Michael Hudson mwh21@cam.ac.uk
Tue, 6 Jun 2000 21:20:20 +0100 (BST)


In response to a posting by Fran=E7ois Pinard in comp.lang.python, I cooked
up this patch:

Index: classobject.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v
retrieving revision 2.86
diff -u -r2.86 classobject.c
--- classobject.c=092000/05/03 23:44:34=092.86
+++ classobject.c=092000/06/06 20:06:24
@@ -766,6 +766,10 @@
 =09=09return PyString_FromString(buf);
 =09}
 =09res =3D PyEval_CallObject(func, (PyObject *)NULL);
+=09if (res =3D=3D NULL && !PyCallable_Check(func)) {
+=09=09PyErr_SetString(PyExc_TypeError,
+=09    "lookup for '__repr__' returned an uncallable object");
+=09}
 =09Py_DECREF(func);
 =09return res;
 }
Index: object.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v
retrieving revision 2.70
diff -u -r2.70 object.c
--- object.c=092000/05/03 23:44:35=092.70
+++ object.c=092000/06/06 20:06:24
@@ -290,6 +290,10 @@
 =09=09=09return PyObject_Repr(v);
 =09=09}
 =09=09res =3D PyEval_CallObject(func, (PyObject *)NULL);
+=09=09if (res =3D=3D NULL && !PyCallable_Check(func)) {
+=09=09=09PyErr_SetString(PyExc_TypeError,
+=09=09    "lookup for '__str__' returned an uncallable object");
+=09=09}
 =09=09Py_DECREF(func);
 =09}
 =09if (res =3D=3D NULL)

This means that:

[mwh21@atrus build]$ cat s.py=20
class See:

    def __getattr__(self, key):
        print '**', key
        return None

print See()
[mwh21@atrus build]$ ./python s.py
 ** __str__
Traceback (most recent call last):
  File "s.py", line 7, in ?
    print See()
TypeError: lookup for '__str__' returned an uncallable object

I'm not wholly convinced that this error is common enough to justify
checking for it explicitly, but I've structured things so that (I hope!)
there shouldn't be a penalty for code that currently works.  Anyway, I
thought I'd send it in and see what you lot think of it...

Cheers,
M.

Oh, almost forgot:

I confirm that, to the best of my knowledge and belief, this
contribution is free of any claims of third parties under
copyright, patent or other rights or interests ("claims").  To
the extent that I have any such claims, I hereby grant to CNRI a
nonexclusive, irrevocable, royalty-free, worldwide license to
reproduce, distribute, perform and/or display publicly, prepare
derivative versions, and otherwise use this contribution as part
of the Python software and its related documentation, or any
derivative versions thereof, at no cost to CNRI or its licensed
users, and to authorize others to do so.

I acknowledge that CNRI may, at its sole discretion, decide
whether or not to incorporate this contribution in the Python
software and its related documentation.  I further grant CNRI
permission to use my name and other identifying information
provided to CNRI by me for use in connection with the Python
software and its related documentation.