On Mon, Jan 19, 2009 at 9:44 AM, Mark Hildreth
<[email protected]> wrote:
>
> hasattr returns true because of the way that tmpl_context ("c") is 
> implemented.
>
> https://www.knowledgetap.com/hg/pylons-dev/file/98d7b9278acd/pylons/util.py#l115
>
> You have ContextObj, and AttribSafeContextObj. By default, Pylons uses
> AttribSafeContextObj. Looking at the code, you can see that the
> __getattr__ method is overridden. This returns an empty string. For
> more infoon __getattr__, see here:
>
> http://docs.python.org/reference/datamodel.html#object.__getattr__
>
> Now, hasattr returns true because, no matter what name you put, if it
> is not found on the actual context, it will still be "found" since we
> are by default returning an empty string.
>
> When you use strict_c, you are using the ContextObj, which does not
> override __getattr__, and as such has the default behavior of raising
> an exception as well as returning false from hasattr when the
> attribute is not found.

This is a bit low level for mk's question.  When strict_c is true, 'c'
acts as a normal Python object, raising an error if a nonexistent
attribute is accessed.  When strict_c is false, nonexistent attributes
return the empty string.  This is partly to imitate other
frameworks/languages, partly for backward compatibility, and partly
because the main developers like it that way.  I would argue for the
opposite because it's hard to notice or debug a variable that
magically defaulted to something unexpected.

'c' -- as well as the other context globals (request, response,
session, cache, app_globals, and config) -- are StackedObjectProxy
objects.  This allows multiple instances of Pylons applications to
exist in the same process and share the module globals.  With
StackedObjectProxy, 'c' is the proxy object, and 'c._current_obj()' is
the actual value that was pushed onto it.  Normally the proxy calls
._current_obj() behind the scenes so you don't have to, but in certain
cases it doesn't.  'c.hasattr' doesn't; that's why you're getting the
proxy object instead.  'dir(c)' also doesn't, so you have to call
'dir(c._current_obj())' if you want to know which attributes have been
set.  I suppose you could say that dict access is transparent while
method calls aren't, but that may not cover all the cases.

-- 
Mike Orr <[email protected]>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to