On 9/12/07, Ian Bicking <[EMAIL PROTECTED]> wrote: > > Mike Orr wrote: > > On 9/12/07, Ben Bangert <[EMAIL PROTECTED]> wrote: > >> On Sep 11, 2007, at 10:54 PM, Max Ischenko wrote: > >> > >>> > >>> I wonder if this _current_obj thingy is documented somewhere. > >> I see, this is just an instance of > >> http://pythonpaste.org/class-paste.wsgiwrappers.WSGIRequest.html > >> > >> The Pylons globals (c, g, session, request, response) are all object > >> proxies > >> that actually relay all access to the real objects. This is to ensure > >> thread > >> safety and request safety in your application. Using '_current_obj()' > >> retrieves the real object they're proxying to. > > > > The proxying is mostly transparent but certain operations like dir() I > > think refer to the proxy rather than the proxied object. At which > > time you have to have memorized the ._current_obj() trick. There are > > also similar proxy objects like in SQLAlchemy that have a different > > method name for the same thing (something like. currentObj()), so you > > have to memorize that too. It's a bit of a hassle. Maybe we should > > have a standalone proxying library that all these objects from > > different projects could use. > > I can imagine a fancier proxy which was given an archetype (or just > class) of the object it was proxying to. I think CherryPy does this -- > Robert Brewer described it at some length on his blog, I think. > > I guess it would look a little like: > > class ProxyDescriptor(object): > def __init__(self, attr, archetype): > self.attr = attr > self.archetype = archetype > self.__doc__ = getattr(archetype, '__doc__', None) > # Sadly no way to match signatures currently with the archetype > # unless the decorator module already has a technique? > def __get__(self, obj, type=None): > if obj is None: > # This doesn't actually have to return self; if it doesn't > # then introspection tools will probably do better, but it > # also obscures what's going on > return self > return getattr(obj._current_obj(), self.attr) > def __set__(self, obj, value): > setattr(obj._current_obj(), self.attr, value) > def __delete__(self, obj): > delattr(obj._current_obj(), self.attr) > def __repr__(self): > return '<%s for %s=%r>' % ( > self.__class__.__name__, self.attr, self.archetype) > > def proxy(getter, archetype): > attrs = dict(_current_obj=getter, _archetype=archetype) > for name in dir(archetype): > attrs[name] = ProxyDescriptor(name, getattr(archetype, name)) > cls = type('%sProxy' % archetype.__name__, (object,), attrs) > return cls() > > > Then proxy(current_request, WSGIRequest) should result in a smart proxy. > All, of course, untested. Also, there may be attributes in the object > that should be proxied, but are not (instance variables in particular). > Generally I'm not confident dir() is complete; something that looks > through __mro__ would be more complete.
I'm not sure if this class is better, but the use case is, somebody wants to access an attribute like request.params but they don't remember what the attribute is called. So they try dir(request) and help(request), but the methods listed refer to the proxy rather than the real object. This has happened to me multiple times. Our hypothetical user remembers reading on the mailing list some time ago that there's a method to get the current object, and looks down the list for it. dir(request) shows '_current_obj', which if they're lucky they'll recognize, and if they're very lucky they'll realize it's a method rather than an attribute. Hopefully they won't get distracted by '_current_obj_orig' and '_current_obj_restoration'. help(request) shows docstrings which helps, but for some reason the '_current_obj' method is not listed at all. If we can somehow coax help() to be more helpful, that would at least help users find the method they need to call. I'm not sure if the problem is that ._current_obj is defined in a base class or something. -- 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 -~----------~----~----~----~------~----~------~--~---
