[Zope-dev] Re: hasattr implementation for Zope?

Tim Peters tim.peters at gmail.com
Fri May 27 11:52:10 EDT 2005


[Tim Peters]
>> OTOH, defining & importing a utility function-- say, safehasattr()
>> --would make it all explicit.  That's what ZODB does.

[Paul Winkler]
> OK.
> 
> (BTW, I just went grepping for this safehasattr() in zope 2.7.6's
> ZODB and didn't find anything. What's it called?)

No such thing in ZODB 3.2.  In 3.3+, it's called "myhasattr", and is
imported from ZODB.serialize.  It should grow a saner name and move to
ZODB.utils instead:

def myhasattr(obj, name, _marker=object()):
    """Make sure we don't mask exceptions like hasattr().

    We don't want exceptions other than AttributeError to be masked,
    since that too often masks other programming errors.
    Three-argument getattr() doesn't mask those, so we use that to
    implement our own hasattr() replacement.
    """
    return getattr(obj, name, _marker) is not _marker
 
> There are ~700 calls to hasattr() currently in the Zope core (ouch!).
> Are there cases where the current use of hasattr() is considered safe?

Almost certainly, although who knows which?  I don't.  As a general
matter, it's hasattr() applied to a _persistent_ object that's
especially nasty.  Asking whether a persistent object has an attribute
can invoke an arbitrary amount of code, including network activity to
fetch the object's state, and potentially raising (say)
ReadConflictError or assorted socket errors.  It's Bad to hide those.

> Or since it's "broken by design",  should we replace all 700
> calls with this hypothetical safe_hasattr()?

Spend an hour analyzing each one <0.9 wink>.

> [the rest snipped not because it's uninteresting, but
>  because I don't know enough to comment]


More information about the Zope-Dev mailing list