Issue532638
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2002-03-20 18:42 by skip.montanaro, last changed 2022-04-10 16:05 by admin. This issue is now closed.
Files | ||||
---|---|---|---|---|
File name | Uploaded | Description | Edit | |
obj-attr.diff | skip.montanaro, 2002-03-20 18:42 |
Messages (8) | |||
---|---|---|---|
msg39294 - (view) | Author: Skip Montanaro (skip.montanaro) * | Date: 2002-03-20 18:42 | |
A user in c.l.py was confused when import m m.a reported AttributeError: 'module' object has no attribute 'a' The attached patch displays the object's name in the error message if it has a __name__ attribute. This is a bit tricky because of the recursive nature of looking up an attribute during a getattr operation. My solution was to pull the error formatting code into a separate static routine (the same basic thing happens in three places) and define a static variable there that breaks any recursion. While this might not be thread-safe, I think it's okay in this situation. The worst that should happen is you get either an extra round of recursion while looking up a non-existent __name__ ttribute or fail to even check for __name__ and use the default formatting when the object actually has a __name__ attribute. This can only happen if you have two threads who both get attribute errors at the same time, and then only if the process of looking things up takes you back into Python code. Perhaps a similar technique can be provided for other error formatting operations in object.c. Example for objects with and without __name__ attributes: >>> "".foo Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: str object has no attribute 'foo' >>> import string >>> string.foo Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: module object 'string' has no attribute 'foo' Skip |
|||
msg39295 - (view) | Author: Tim Peters (tim.peters) * | Date: 2002-03-20 18:56 | |
Logged In: YES user_id=31435 I'm -1 on this because of the expense: many apps routinely provoke AttributeErrors that are deliberately ignored. All the time that goes into making nice messages is wasted then. A "lazy" exception object that produced a string only when actually needed would be fine (although perhaps an object may manage to change its computed __name__ by then!). |
|||
msg39296 - (view) | Author: Skip Montanaro (skip.montanaro) * | Date: 2002-03-20 21:50 | |
Logged In: YES user_id=44345 hmmm... How much would I have to modify it to get you to change your mind? I'm pretty sure I can get rid of the call to PyObject_HasAttrString without a lot of effort. I can't do much about avoiding at least one PyObject_GetAttrString call though, which obviously means you could wind up back in bytecode. I jumped on this after seeing the request in c.l.py mostly because I've wanted it from time-to-time as well. The extra information is useful at times. |
|||
msg39297 - (view) | Author: Tim Peters (tim.peters) * | Date: 2002-03-20 23:09 | |
Logged In: YES user_id=31435 If it's one cycle slower than it is today when the exception is ignored, Zope will notice it (it uses hasattr for blood). Then Guido will get fired, have to pump gas in Amsterdam for a living, and we'll never hear from him again. How badly do you want to destroy Python <wink>? It may be fruitful to hammer out an efficient alternative on PythonDev. It's not an argument about whether more info would be useful, although <wink> on c.l.py Dale seemed happy enough as soon as someone explained what 'module' was doing in his msg. |
|||
msg39298 - (view) | Author: Dale Strickland-Clark (dalesc) | Date: 2002-03-21 00:36 | |
Logged In: YES user_id=457577 Surely Tim's is more an argument for fixing hasattr so it doesn't depend on an exception? To limit meaningful error messages because they slow normal program flow screams 'bad design' to me. |
|||
msg39299 - (view) | Author: Skip Montanaro (skip.montanaro) * | Date: 2002-03-21 01:50 | |
Logged In: YES user_id=44345 In theory. Python's getattr capability is so dynamic though I suspect there's little hasattr() can do but call getattr() and react to the result. |
|||
msg39300 - (view) | Author: Tim Peters (tim.peters) * | Date: 2002-03-21 02:25 | |
Logged In: YES user_id=31435 hasattr() is defined in terms of whether PyObject_GetAttr() raises an exception, and thanks to __getattr__ hooks can't be computed any faster than calling PyObject_GetAttr(). Which is what the code does: v = PyObject_GetAttr(v, name); if (v == NULL) { PyErr_Clear(); Py_INCREF(Py_False); return Py_False; } Py_DECREF(v); Py_INCREF(Py_True); return Py_True; It's simply not going to get faster than that. I'm not saying you can't have a "better" message here (although since an object's __name__ field doesn't bear any necessary relationship to the variable name(s) through which the object is referenced, it's unclear that the message won't actually be worse in real non-trivial cases: the type name is an object invariant, but the name can be misleading). I am saying the tradeoff is real and needs to be addressed. That's part of "good design", Dale; doing what feels good in the last case you remember is arguably not. |
|||
msg39301 - (view) | Author: Skip Montanaro (skip.montanaro) * | Date: 2002-07-09 23:44 | |
Logged In: YES user_id=44345 Closing since there seems to be no votes in favor, at least not by bots... S |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-10 16:05:07 | admin | set | github: 36293 |
2002-03-20 18:42:49 | skip.montanaro | create |