On Friday 09 July 2004 11:50 am, Casey Duncan wrote:
On Fri, 9 Jul 2004 16:22:17 +0200 Dieter Maurer <dieter@handshake.de> wrote: [..]
The "hasattr" replacement in Python's "__builtin__" could look like:
_marker = [] def hasattr(obj, attr): return getattr(obj, attr, _marker) is not _marker
Hmm. I just heard about this "hasattr geddon". hasattr is *good*. Why are we fixing hasattr and bare excepts when the real problem is ZODB? ZODB should *not* be sensitive to the way the application handles ConflictErrors. When a ConflictError (or ReadConflictError) occurs, the transaction should fall into an "uncommitable" state. From this state, you can only abort the transaction; any attempts to write an object or commit cause another ConflictError. Then, only code that can guarantee that the attempted transaction is complete should actually abort the transaction, and fortunately ZPublisher fits that role. Today, the abort is implicit, and that's the mistake that has caused us to litter the code with knowledge of ConflictErrors. With the "uncommitable" state, it would not matter if the application swallows ConflictErrors. 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. Shane