[Python-bugs-list] [ python-Bugs-420304 ] getattr function w/ default
noreply@sourceforge.net
noreply@sourceforge.net
Mon, 07 May 2001 21:26:38 -0700
Bugs item #420304, was updated on 2001-04-30 17:14
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=420304&group_id=5470
Category: Python Interpreter Core
Group: None
Status: Open
Resolution: None
>Priority: 6
Submitted By: Greg Chapman (glchapman)
>Assigned to: Jeremy Hylton (jhylton)
Summary: getattr function w/ default
Initial Comment:
In Python 2.1, when calling the builtin getattr
function and supplying the (optional) default
argument, this default is returned on any exception
raised during PyObject_GetAttr, even if the exception
is not an AttributeError. I did not expect this
behavior after reading the getattr documentation. Is
this the intended behavior? (If so, I think the
documentation should be made clearer on this point.)
Example (providing a non-string as the attribute name):
>>> class Test:
... pass
...
>>> t = Test()
>>> getattr(t, 1, "hello")
'hello'
>>>
----------------------------------------------------------------------
>Comment By: Jeremy Hylton (jhylton)
Date: 2001-05-07 21:26
Message:
Logged In: YES
user_id=31392
This looks like a bug to me, too. I think a non-string attr
argument
to getattr() should raise TypeError.
----------------------------------------------------------------------
Comment By: Michael Hudson (mwh)
Date: 2001-05-04 04:11
Message:
Logged In: YES
user_id=6656
But consider this:
>>> getattr({},1)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: attribute name must be string
>>> getattr({},1,"e")
'e'
or
>>> getattr(None,u"\343","e")
'e'
>>> getattr(None,u"\343")
Traceback (most recent call last):
File "<stdin>", line 1, in ?
UnicodeError: ASCII encoding error: ordinal not in range(128)
Here's a possible patch:
Index: bltinmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v
retrieving revision 2.200
diff -c -r2.200 bltinmodule.c
*** bltinmodule.c 2001/05/02 07:39:38 2.200
--- bltinmodule.c 2001/05/04 11:09:35
***************
*** 845,850 ****
--- 845,854 ----
The globals and locals are dictionaries, defaulting to the
current\n\
globals and locals. If only globals is given, locals
defaults to it.";
+ /* Internal API needed by builtin_getattr(): */
+ extern
+ PyObject *_PyUnicode_AsDefaultEncodedString(PyObject *unicode,
+ const char *errors);
static PyObject *
builtin_getattr(PyObject *self, PyObject *args)
***************
*** 854,859 ****
--- 858,874 ----
if (!PyArg_ParseTuple(args, "OO|O:getattr", &v,
&name, &dflt))
return NULL;
+ if (PyUnicode_Check(name)) {
+ name =
_PyUnicode_AsDefaultEncodedString(name, NULL);
+ if (name == NULL)
+ return NULL;
+ }
+ else if (!PyString_Check(name)) {
+ PyErr_Format(PyExc_TypeError,
+ "getattr: attribute name must be string, not
\%.500s\",
+ name->ob_type->tp_name);
+ return NULL;
+ }
result = PyObject_GetAttr(v, name);
if (result == NULL && dflt != NULL) {
PyErr_Clear();
... though by the time you've done all that, there's not
much point in calling PyObject_GetAttr at all...
OTOH, this changes behaviour, so maybe one should just
clarify this in the docs.
----------------------------------------------------------------------
Comment By: Chris Cogdon (chriscog)
Date: 2001-05-03 17:55
Message:
Logged In: YES
user_id=67116
Looks like an attribute error to me. consider this:
>>> getattr (t,fred,"thingy")
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: There is no variable named 'fred'
Ie, in your own example, it couldn't find an attribute '1'
in the class, even if its an integer attribute (which is
only obtainable using getattr/setattr). That's exactly what
AttributeError is
----------------------------------------------------------------------
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=420304&group_id=5470