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 -~----------~----~----~----~------~----~------~--~---
