[Zope-dev] Re: "hasattr" geddon
Shane Hathaway
shane at hathawaymix.org
Sun Jul 11 19:28:12 EDT 2004
On Saturday 10 July 2004 15:55 pm, Tim Peters wrote:
> [Shane Hathaway]
>
> > Here is what often happens in Zope:
> >
> > def setFoo(self, value):
> > try:
> > self.foo = value
> > except:
> > LOG("Oops", ERROR, "Some error happened", error=sys.exc_info())
> > self.change_count += 1
> > self.get_indexes().update(self)
> >
> > Some piece of code has a legitimate reason to catch but log all
> > exceptions. Some other piece of code updates indexes. The database has
> > now committed a partial transaction.
>
> I need more words -- I don't see a commit() in that code, and I don't
> know what "partial transaction" might mean (in ZODB you can commit a
> transaction, or abort it -- there's no facility I know of for a
> partial commit (or a partial abort, for that matter)).
Commit occurs later, in the publisher. It is a partial transaction because
the first part was implicitly aborted. The change to "self.foo" was aborted,
while the change to self.change_count and the indexes was not.
> > Even worse, this can happen within the indexes, making the indexes
> > inconsistent with themselves.
>
> Sorry, since I didn't understand the first part, I'm way lost here.
>
> > Once a conflict error has occurred on any object, the rest of the
> > transaction is on shaky grounds.
>
> Which is why the current ZODB releases intend to prevent committing a
> transaction if a conflict error occurred during the transaction. It
> shouldn't matter to this ZODB machinery if the application suppressed
> the original conflict error(s), ZODB remembers that it raised
> ReadConflictError regardless (via the Connection._conflicts
> set-implemented-as-a-dict).
Well, you described what I'm asking for: "prevent committing a transaction if
a conflict error occurred during the transaction". I don't believe it's
doing that, though. If a conflict occurs on any object (read conflict or
write conflict), ZODB should prevent any attempt to commit even if no one
tries to change that object a second time.
> Dieter already wrote it <wink>. Zope/ZODB's use of Python's machinery
> is sometimes so far from the goals Guido had in mind that Zope is
> alone in wanting a Python change. For example, I don't know of other
> apps where calling hasattr() can have disastrous consequences.
I think it's wrong that hasattr can have disastrous consequences. I think
Zope is more wrong than hasattr. However, I don't like hasattr now because I
had no idea that it hides errors.
> That's certainly not needed for "ordinary" uses, like
>
> if hasattr(errno, "WSAEWOULDBLOCK"): # Windows
>
> Uses of hasattr() on base Python objects and modules is safe (as I
> believe it is in *almost* all applications outside our part of the
> Python world).
In your example, imagine that errno has a __getattribute__ hook that tries to
interface with C code. Imagine some kind of linker error occurs and a
meaningful error results, but hasattr swallows it. Wouldn't you like to know
about the linker error rather than receive a possibly wrong answer?
Shane
More information about the Zope-Dev
mailing list