[Patches] [ python-Patches-471852 ] getattr with default catches too much

noreply@sourceforge.net noreply@sourceforge.net
Tue, 16 Oct 2001 13:38:22 -0700


Patches item #471852, was opened at 2001-10-16 13:38
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=305470&aid=471852&group_id=5470

Category: Core (C code)
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Nobody/Anonymous (nobody)
Assigned to: Nobody/Anonymous (nobody)
Summary: getattr with default catches too much

Initial Comment:
getattr.__doc__ sez:

'''
getattr(object, name[, default]) -> value

Get a named attribute from an object; getattr(x, 'y')
is equivalent to x.y.
When a default argument is given, it is returned when
the attribute doesn't
exist; without it, an exception is raised in that case.
'''

What really happens is that, when given a default,
getattr catches *all* exceptions.  In addition to the
generally poor practice of silently catching all
exceptions, the documentation implies that only
AttributeError is caught.

I think getattr should be changed to catch only
AttributeError, and the documentation changed to:

'''
Get a named attribute from an object.  getattr(x, 'y')
is equivalent to x.y.
When a default argument is given, it is returned when
'x' raises an
AttributeError.
'''

If the patch is rejected, I suggest the docstring be
changed to:

'''
Get a named attribute from an object.  getattr(x, 'y')
is equivalent to x.y.  If getattr is given a default
and 'x' raises an exception, it will catch the
exception and return the default.

Note that any exception will be caught, not just
AttributeError, which can hide bugs if 'x' is a class
with a __getattr__ method.
'''


*** Python/bltinmodule.c        Tue Oct 16 13:14:54
2001
--- Python/bltinmodule.c.old    Tue Oct 16 13:14:49
2001
***************
*** 619,627 ****
                return NULL;
        }
        result = PyObject_GetAttr(v, name);
!       if (result == NULL && dflt != NULL
!                 &&
PyErr_ExceptionMatches(PyExc_AttributeError))
!         {
                PyErr_Clear();
                Py_INCREF(dflt);
                result = dflt;
--- 619,625 ----
                return NULL;
        }
        result = PyObject_GetAttr(v, name);
!       if (result == NULL && dflt != NULL) {
                PyErr_Clear();
                Py_INCREF(dflt);
                result = dflt;


----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=305470&aid=471852&group_id=5470