pytilities.overloading.overload

Package pytilities :: Package overloading :: Module overload |
[hide private]
[frames] | no frames]

# Source Code for Module pytilities.overloading.overload

      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  import logging
     22
     23  _logger = logging.getLogger("pytilities.overloading.overload")
     24
     25 -class Overload(object):
     26      """
     27      A list of parameters that when matched, call an associated operation.
     28
     29      You can think of it as part of an operation signature
     30
     31      Methods:
     32
     33          - `process_call`: Call overload's operation if args match.
     34          - `insert_params`: Insert parameters
     35      """
     36
     37 -    def __init__(self, operation, *params):
     38          """
     39          Construct an Overload
     40
     41          Parameters:
     42
     43              `function`
     44                  the operation to call when a call's args match the params
     45
     46              `params` :: (Parameter...)
     47                  sequence of parameters that args of calls should match. The
     48                  overload will only match when all params are satisfied and no
     49                  args are left.
     50          """
     51          self.__function = operation
     52          self.__params = []
     53          self.insert_params(0, *params)
     54
     55 -    def process_call(self, args, kwargs):
     56          """
     57          Call the overload's operation with args if all args match.
     58
     59          Parameters:
     60
     61              `args` :: (value...)
     62                  positional arguments of the call
     63
     64              `kwargs` :: {name::string : value}
     65                  keyword arguments of the call
     66
     67          Returns (True, return_value) if the args matched, (False, None) otherwise
     68          """
     69
     70          # check for the right amount of args (the rest of the algorithm depends
     71          # on this). Note: this assumes there are no overlaps, so the debug
     72          # message may dictate the wrong reason, but this will do
     73          if len(self.__params) < len(args) + len(kwargs):
     74              _logger.debug("Overload failed to match: unexpected amount of args")
     75              return (False, None)
     76
     77          # match args
     78          for arg, param in zip(args, self.__params):
     79              if not param.read_arg(arg):
     80                  _logger.debug("Overload failed to match, failed at %s" %
     81                                param)
     82                  return (False, None)
     83
     84          # match kwargs
     85          for param in self.__params[len(args):]:
     86              if not param.read_kwargs(kwargs):
     87                  _logger.debug("Overload failed to match, failed at %s" %
     88                                param)
     89                  return (False, None)
     90
     91          # we have a match
     92          # construct a list of arguments for the call
     93          call_args = {}
     94          for param in self.__params:
     95              param.write(call_args)
     96
     97          # make the call
     98          return (True, self.__function(**call_args))
     99
    100 -    def insert_params(self, index, *params):
    101          """
    102          Insert parameters into the current list of parameters at index
    103
    104          Parameters:
    105
    106              `index` :: number
    107                  index of where to insert
    108
    109              `params` :: (Parameter...)
    110                  the parameters to insert
    111          """
    112          self.__params[index:index] = params
    113