[Zope-dev] Re: "hasattr" geddon
Shane Hathaway
shane at hathawaymix.org
Sat Jul 10 04:41:07 EDT 2004
On Friday 09 July 2004 11:50 am, Casey Duncan wrote:
> On Fri, 9 Jul 2004 16:22:17 +0200
> Dieter Maurer <dieter at 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
More information about the Zope-Dev
mailing list