hasattr_unacquired

Bug #142399 reported by Dieter Maurer
2
Affects Status Importance Assigned to Milestone
Zope 2
Invalid
Low
Christian Theune

Bug Description

Zope is lacking an easy way to check whether
an object has an unacquired attribute.

The "aq.explicit" is not safe (for this purpose)
and is not documented.

The attached patch provides a "hasattr_unacquired"
function.

Tags: bug zope
Revision history for this message
Dieter Maurer (d.maurer) wrote :
Revision history for this message
Dieter Maurer (d.maurer) wrote :

Sorry!

Of course, this is not a bug but a feature+solution.

Revision history for this message
Christian Theune (ctheune) wrote :

Status: Pending => Accepted

 Supporters added: ctheune

Hmm. This is a shame. I would have needed that quite often.
I'll go and put this on the trunk right now.

Revision history for this message
Christian Theune (ctheune) wrote :

Ok.

Argh.

I like this patch. It seems obvious not to break anything.
Inspite I'm unable to create a good test for this.

If you like this to go in, please provide me with a
sensible test. The complete Utility package is yet untested and I don't get it right now.

Please also tell if you won't provide a test, then I'll just WONTFIX this issue.

Revision history for this message
Casey Duncan (caseman) wrote :

Use of hasattr here is dangerous since hasattr eats all exceptions (e.g., ZODB conflict errors). I definitely agree that we need something like this in the core. How about some thing like:

def basehasattr(obj, name):
    try:
        getattr(aq_base(obj), name)
    except AttributeError:
        return False
    else:
        return True

Revision history for this message
Dieter Maurer (d.maurer) wrote :

It is almost fine with me -- almost, because we should have a safe 'hasattr' as well. I would replace the builtin one by a senseful one, but Jim already objected. Then, we should have one under a different name,
e.g. "safehasattr" or "zhasattr". This can then be used whereever
we would like to use "hasattr" and especially in "basehasattr"
or "hasattr_unacquired".

Revision history for this message
Stefan H. Holek (stefanholek) wrote :

FWIW, we have defined (and use) these two in Plone:

 def safe_hasattr(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

 def base_hasattr(obj, name):
     """Like safe_hasattr, but also disables acquisition."""
     return safe_hasattr(aq_base(obj), name)

Revision history for this message
Tres Seaver (tseaver) wrote :

Enabling tests from untrusted code on objects whose acquisition context
has been stripped is problematic, because the security machinery needs
the context to verify that the user is defined within the same "authentication
zone" as the object: if the stripped object has the attribute in its dict, but the
user would not be allowed to access that attribute, what should the proposed
helper function return?

Changed in zope2:
importance: Medium → Low
status: Confirmed → Triaged
Revision history for this message
Dieter Maurer (d.maurer) wrote :

The primary purpose of the proposed feature is to get a safe way to ask whether given object "o" truely has attribute "a" i.e. does not acquire it.
This implies the following semantics:

'hasattr_unacquired(o,a) == True if and only if "getattr(o, a) is obtained by looking at "o" only (and not at its acquisition context)'.

It means also, that "hasattr_unacquired(o, a)" should return "True", when "o" truely has "a" but the current user cannot
access "a". Should the user access such an attribute after the test, he will get an "Unauthorized".

One of my primary usage idioms looks like:

     if not hasattr_unacquired(o, id):
        # create child "id"
       ...
     child = getattr(o, id)

Revision history for this message
Colin Watson (cjwatson) wrote :

The zope2 project on Launchpad has been archived at the request of the Zope developers (see https://answers.launchpad.net/launchpad/+question/683589 and https://answers.launchpad.net/launchpad/+question/685285). If this bug is still relevant, please refile it at https://github.com/zopefoundation/zope2.

Changed in zope2:
status: Triaged → Invalid
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.