Package pytilities :: Package delegation :: Module decorators
[hide private]
[frames] | no frames]

Source Code for Module pytilities.delegation.decorators

  1  # Copyright (C) 2010 Tim Diels <limyreth@users.sourceforge.net> 
  2  #  
  3  # This file is part of pytilities. 
  4  #  
  5  # pytilities is free software: you can redistribute it and/or modify 
  6  # it under the terms of the GNU General Public License as published by 
  7  # the Free Software Foundation, either version 3 of the License, or 
  8  # (at your option) any later version. 
  9  #  
 10  # pytilities is distributed in the hope that it will be useful, 
 11  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13  # GNU General Public License for more details. 
 14  #  
 15  # You should have received a copy of the GNU General Public License 
 16  # along with pytilities.  If not, see <http://www.gnu.org/licenses/>. 
 17  # 
 18   
 19  """ 
 20  Various decorators to ease delegation 
 21  """ 
 22   
 23  __docformat__ = 'reStructuredText' 
 24   
 25  from types import UnboundMethodType 
 26  import logging 
 27   
 28  from . import Profile, DelegatorFactory 
 29   
 30  # logging stuff 
 31  _logger = logging.getLogger("pytilities.delegation") 
 32   
 33  # Note: we don't care about mangling here, there's no need to. You won't be 
 34  # delegating any private vars anyway, or at least you shouldn't. 
 35   
36 -def delegator_factory():
37 """ 38 Makes a `DelegatorFactory` on the class and adds profiles to it. 39 40 The factory is stored as a class attribute with name _delegator_factory. 41 A Delegator method is installed on the class, it is the same as 42 _delegator_factory.Delegator. 43 44 `Profile`s are created based on the annotations left by `delegated`. 45 """ 46 47 def _delegator_factory(cls): 48 # iterate through attributes and generate profiles 49 # {name: Profile} 50 profiles = {"default": Profile()} # there's always a default 51 for name in cls.__dict__: 52 attribute = getattr(cls, name) 53 54 _logger.debug(name) 55 if isinstance(attribute, property): 56 _logger.debug("prop") 57 data_holder = attribute.fget 58 elif isinstance(attribute, UnboundMethodType): 59 _logger.debug("unbound method!") 60 data_holder = attribute.im_func 61 else: 62 _logger.debug("I have no clue what this is") 63 data_holder = attribute 64 65 if hasattr(data_holder, "__pytilities_delegation_profiles"): 66 _logger.debug("is delegated!") 67 profile_data = data_holder.__pytilities_delegation_profiles 68 for profile_name, modifiers in profile_data.iteritems(): 69 profiles.setdefault(profile_name, Profile()) 70 profiles[profile_name].add_mappings(modifiers, name) 71 72 del data_holder.__pytilities_delegation_profiles 73 74 # make factory with profiles 75 factory = DelegatorFactory() 76 77 for name, profile in profiles.iteritems(): 78 factory.set_profile(name, profile) 79 80 # install stuff on cls 81 setattr(cls, "_delegator_factory", factory) 82 cls.Delegator = factory.Delegator 83 84 return cls
85 86 return _delegator_factory 87
88 -def delegated(profile_name="default", modifiers="rwd"):
89 """ 90 Includes the decorated attribute in the specified delegation profile. 91 92 Parameters: 93 94 `profile_name` :: string 95 name of the `Profile` to add the attribute to 96 97 `modifiers` :: string 98 the types of access to delegate to the target. Possible modifiers 99 are combinations of: 100 101 - `r`: read 102 - `w`: write 103 - `d`: delete 104 """ 105 106 def _delegate(attribute): 107 _logger.debug("%s += %s" % (profile_name, attribute)) 108 if not hasattr(attribute, "__pytilities_delegator_profiles"): 109 if isinstance(attribute, property): 110 # stick data on the getter function, can't set attribs on 111 # properties 112 data_holder = attribute.fget 113 else: 114 data_holder = attribute 115 116 data_holder.__pytilities_delegation_profiles = {} 117 118 data_holder.__pytilities_delegation_profiles[profile_name] = modifiers 119 120 return attribute
121 122 return _delegate 123