disappearing exceptions

In several places in the C code, there are instances where all exceptions can be completely ignored (akin to a bare except statement.) after a PyObject_GetAttr call. A week ago, I fixed one of these in hasattr (issue 2196) by propagating exceptions that don't inherit Exception (SystemExit, KeyboardInterrupt). However, there is another patch that propagates anything that is not a AttributeError (issue 1574217). How should we approach this? -- Cheers, Benjamin Peterson "There's no place like 127.0.0.1."

Benjamin Peterson schrieb:
In several places in the C code, there are instances where all exceptions can be completely ignored (akin to a bare except statement.) after a PyObject_GetAttr call.
A week ago, I fixed one of these in hasattr (issue 2196) by propagating exceptions that don't inherit Exception (SystemExit, KeyboardInterrupt). However, there is another patch that propagates anything that is not a AttributeError (issue 1574217).
How should we approach this?
Oh, you are bringing something to my mind. In Python 2.x hasattr() swallows every exception. This is a major issue for applications like ZODB, because database conflict errors must be propagated to the conflict resolution machinery. Shane Hathaway said once: --- That said, I was surprised to discover that Python 2.3 implements hasattr this way (from bltinmodule.c): 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 should not swallow all errors, especially now that descriptors make computed attributes quite common. getattr() only recently started catching only AttributeErrors, but apparently hasattr is lagging behind. I suggest the consistency between getattr and hasattr should be fixed in Python, not Zope. --- Thankfully this issue was fixed in Python 2.6 and 3.0. In newer versions of Python hasattr() only swallows exception based on the Exception class but not BaseExceptions. We should make sure all code in the core behaves the same way. Exceptions based on BaseException must *never* be swallowed. The behavior may even be worse a macro and it should be documented in large, friendly and red letters in the C API docs. *wink* Christian

On Tue, May 20, 2008 at 5:38 PM, Christian Heimes <lists@cheimes.de> wrote:
Thankfully this issue was fixed in Python 2.6 and 3.0. In newer versions of Python hasattr() only swallows exception based on the Exception class but not BaseExceptions. We should make sure all code in the core behaves the same way. Exceptions based on BaseException must *never* be swallowed. The behavior may even be worse a macro and it should be documented in large, friendly and red letters in the C API docs. *wink*
Speaking of the C-API, I was thinking of introducing a new function called PyObject_SafeHasAttr that functions just like PyObject_HasAttr except it can fail.
Christian
-- Cheers, Benjamin Peterson "There's no place like 127.0.0.1."

On Tue, May 20, 2008 at 6:44 PM, Christian Heimes <lists@cheimes.de> wrote:
Benjamin Peterson schrieb:
Speaking of the C-API, I was thinking of introducing a new function called PyObject_SafeHasAttr that functions just like PyObject_HasAttr except it can fail.
How do you define "fail" in this context?
If PyObject_GetAttr raises an exception that is not an AttributeError, it can return -1 to fail. -- Cheers, Benjamin Peterson "There's no place like 127.0.0.1."

Christian Heimes wrote:
Thankfully this issue was fixed in Python 2.6 and 3.0. In newer versions of Python hasattr() only swallows exception based on the Exception class but not BaseExceptions.
Shouldn't it only be catching AttributeError, though?
We should make sure all code in the core behaves the same way. Exceptions based on BaseException must *never* be swallowed.
Seems to me that all code in the core that catches exceptions should only be catching the exceptions it really needs to catch. That requires looking at each case individually rather than a blanket "catch Exception" recommendation (although that might still be an improvement over the status quo). -- Greg

Greg writes:
Christian Heimes wrote:
Thankfully this issue was fixed in Python 2.6 and 3.0. In newer versions of Python hasattr() only swallows exception based on the Exception class but not BaseExceptions.
Shouldn't it only be catching AttributeError, though?
This has come up before - eg http://www.mail-archive.com/python-3000@python.org/msg11630.html - which itself starts with the words "This issue has been raised before" :) It points at http://bugs.python.org/issue504714 regarding 2.x - however, if you follow that thread above, it seems Guido is against changing this behaviour even for 3k. cheers, Mark
participants (4)
-
Benjamin Peterson
-
Christian Heimes
-
Greg Ewing
-
Mark Hammond