pytilities.delegation.delegator

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

# Source Code for Module pytilities.delegation.delegator

      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  __docformat__ = 'reStructuredText'
     20
     21  from pytilities import AttributeCollection, mangle
     22  from pytilities.overloading import overloaded, Overload, Param
     23  from pytilities.types import SequenceType
     24  from . import Profile
     25
     26 -class Delegator(AttributeCollection):
     27
     28      """
     29      An AttributeCollection that delegates attributes of one object to another.
     30
     31      Instance properties:
     32
     33          - `target`: Write-only, target of delegation
     34          - `profile`: Read-write, profile to use for delegation
     35      """
     36
     37 -    def __init__(self, profile=None, target=None):
     38          """
     39          Constructs a delegator.
     40
     41          Parameters:
     42              `profile` :: Profile = None
     43                  delegation profile. If None, an empty profile is created for
     44                  you.
     45
     46              `target` = None
     47                  target of delegation
     48          """
     49          self.__profile = profile or Profile()
     50          self.__object = target
     51          self.__variable_name = None
     52
     53      @property
     54 -    def target(self):
     55          """
     56          Write-only, target for delegation.
     57
     58          Delegated attributes will be delegated to this object.
     59
     60          Overloaded, setter parameters:
     61
     62          :a:
     63              `target_object`
     64                  the object to delegate to
     65          :b:
     66              `args` :: (object, variable_name::string)
     67                  target object will be resolved on every get/set/del by doing
     68                  getattr(object, variable_name)
     69          """
     70          # it really is write only, this is for internal use
     71          if self.__variable_name:
     72              return getattr(self.__object, self.__variable_name)
     73          else:
     74              return self.__object
     75
     76 -    def __set_target_args(self, args):
     77          # (object, variable_name)
     78          self.__object = args[0]
     79          self.__variable_name = args[1]
     80
     81          # mangle the variable_name if necessary
     82          self.__variable_name = mangle(self.__object, self.__variable_name)
     83
     84 -    def __set_target_object(self, target_object):
     85          (self.__object, self.__variable_name) = (target_object, None)
     86
     87      @target.setter
     88      @overloaded((
     89          Overload(__set_target_args,
     90              Param("args", SequenceType)),
     91          Overload(__set_target_object,
     92              Param("target_object"))))
     93 -    def target(self):
     94          pass
     95
     96      @property
     97 -    def profile(self):
     98          """
     99          Read-write, the profile to use for attribute mappings.
    100
    101          Returns ::Profile
    102
    103          Setter parameters:
    104
    105              `value` :: Profile
    106                  the profile
    107          """
    108          return self.__profile
    109
    110      @profile.setter
    111 -    def profile(self, value):
    112          self.__profile = value
    113
    114 -    def getattr_(self, name):
    115          if self.profile.has_readable(name):
    116              return (True, getattr(self.target,
    117                                    mangle(self.target,
    118                                           self.profile.get_readable(name))))
    119          elif self.profile.has_readable("__getattr__"):
    120              # this way we don't forget to delegate __getattr__
    121              try:
    122                  return (True, self.target.__getattr__(name))
    123              except AttributeError:
    124                  pass
    125
    126          return (False, None)
    127
    128 -    def setattr_(self, name, value):
    129          if self.profile.has_writable(name):
    130              setattr(self.target,
    131                      mangle(self.target, self.profile.get_writable(name)),
    132                      value)
    133              return True
    134          elif self.profile.has_readable("__setattr__"):
    135              # this way we don't forget to delegate __setattr__
    136              try:
    137                  return (True, self.target.__setattr__(name, value))
    138              except AttributeError:
    139                  pass
    140
    141          return False
    142
    143 -    def delattr_(self, name):
    144          if self.profile.has_deletable(name):
    145              delattr(self.target,
    146                      mangle(self.target, self.profile.get_deletable(name)))
    147              return True
    148          elif self.profile.has_readable("__delattr__"):
    149              # this way we don't forget to delegate __delattr__
    150              try:
    151                  return (True, self.target.__delattr__(name))
    152              except AttributeError:
    153                  pass
    154
    155          return False
    156