Package grizzled :: Module proxy
[hide private]
[frames] | no frames]

Source Code for Module grizzled.proxy

  1  # NOTE: Documentation is intended to be processed by epydoc and contains 
  2  # epydoc markup. 
  3   
  4  """ 
  5  Overview 
  6  ======== 
  7   
  8  The ``grizzled.forwarder`` module contain classes that make building proxies 
  9  easier. 
 10  """ 
 11   
 12  from __future__ import absolute_import 
 13   
 14  __docformat__ = "restructuredtext en" 
 15   
 16  # --------------------------------------------------------------------------- 
 17  # Imports 
 18  # --------------------------------------------------------------------------- 
 19   
 20  import logging 
 21  from types import MethodType 
 22   
 23  # --------------------------------------------------------------------------- 
 24  # Exports 
 25  # --------------------------------------------------------------------------- 
 26   
 27  __all__ = ['Forwarder'] 
 28   
 29  # --------------------------------------------------------------------------- 
 30  # Constants 
 31  # --------------------------------------------------------------------------- 
 32   
 33  # --------------------------------------------------------------------------- 
 34  # Logging 
 35  # --------------------------------------------------------------------------- 
 36   
 37  log = logging.getLogger('grizzled.proxy') 
 38   
 39  # --------------------------------------------------------------------------- 
 40  # Public classes 
 41  # --------------------------------------------------------------------------- 
 42   
43 -class Forwarder(object):
44 """ 45 The ``grizzled.forwarder.Forwarder`` class is intended to be used as 46 a mixin, to make it easier for classes to forward calls to another 47 class. The mix ``Forwarder`` into a class, simply include it as 48 one of the base classes. 49 50 **WARNING**: ``Forwarder`` intercepts calls to ``__getattr__``, so 51 don't mix it in if your class is already overriding ``__getattr__``. 52 53 Examples 54 -------- 55 56 Forward all unimplemented methods to a file: 57 58 .. python:: 59 60 from grizzled.forwarder import Forwarder 61 62 class MyFileWrapper(Forwarder): 63 def __init__(self, file): 64 Forwarder.__init__(self, file) 65 66 w = MyFileWrapper(open('/tmp/foo')) 67 for line in w.readlines(): 68 print line 69 70 Forward all unimplemented calls, *except* ``name``, to the specified 71 object. Calls to ``name`` will raise an ``AttributeError``: 72 73 74 .. python:: 75 76 from grizzled.forwarder import Forwarder 77 78 class MyFileWrapper(Forwarder): 79 def __init__(self, file): 80 Forwarder.__init__(self, file, 'name') 81 """ 82
83 - def __init__(self, wrapped, *exceptions):
84 """ 85 Initialize a new ``Forwarder`` that will pass unimplemented calls 86 (method calls, attribute accesses, etc.) to the specified object. 87 88 :Parameters: 89 wrapped : object 90 the object to which to pass unknown attributes 91 exceptions : str 92 one or more names (as separate arguments) of methods 93 that should not be intercepted (and will, therefore, 94 result in ``AttributeError`` exceptions if invoked, 95 absent any other intervention). 96 """ 97 self._wrapped = wrapped 98 self._exceptions = [e for e in exceptions[0]] # arg tuple to list
99
100 - def __getattr__(self, name):
101 # Now that we've intercepted __getattr__, we can't access our own 102 # attributes directly. Use __getattribute__ to access them. 103 obj = self.__getattribute__('_wrapped') 104 exceptions = self.__getattribute__('_exceptions') 105 if (obj is None) or (name in exceptions): 106 self.__getattribute__(name) 107 108 else: 109 try: 110 attr = getattr(obj, name) 111 if isinstance(obj, MethodType): 112 return new.instancemethod(attr.im_func, self, obj.__class__) 113 else: 114 return attr 115 except AttributeError: 116 # Recast error message as being from this class. 117 raise AttributeError("'%s' object has no attribute '%s'" % 118 (self.__class__.__name__, name))
119