pytilities.overloading.compositeparameter

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

# Source Code for Module pytilities.overloading.compositeparameter

      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  from . import Parameter
     24
     25  _logger = logging.getLogger("pytilities.overloading.compositeparameter")
     26
     27 -class CompositeParameter(Parameter):
     28
     29      """
     30      `Parameter` that consists of more parameters.
     31
     32      This parameter matches lists, tuples and dicts, of which all elements match
     33      the list of child parameters.
     34
     35      When this parameter is written to a dict, its child parameters are
     36      expanded. E.g. for a composite parameter with childs 'x' and 'y', a read
     37      value of (1, 3) and a dict d of {}; after writing to d, d will equal {x:1, y:3},
     38      and not {{x:1, y:3}}.
     39
     40      Methods:
     41
     42          - all of `Parameter`
     43      """
     44
     45 -    def __init__(self, name, params, matcher = (tuple, list, dict), *args, **kwargs):
     46          """
     47          Construct a `CompositeParameter`.
     48
     49          Parameters:
     50
     51              `name` :: string
     52                  name of the parameter, used for keyword arguments. Must be
     53                  unique.
     54
     55              `params` :: (Parameter...)
     56                  the child parameters of the composite
     57
     58              `matcher` :: f(value) -> matched::bool
     59                        :: (type...) = (tuple, list, dict)
     60                        :: type
     61                  the parameter will match only if this matcher matches the arg
     62                  and its child args match the elements of the arg. It is
     63                  unlikely you'll need a value other than the default.
     64
     65              `default`
     66                  default value for the parameter, omit if param has no default
     67          """
     68          Parameter.__init__(self, name, matcher, *args, **kwargs)
     69          self.__params = params
     70          self.__arg_matcher = self._matcher
     71          self._matcher = self.__match
     72
     73 -    def __match(self, value):
     74          # is list, whatever
     75          if not self.__arg_matcher(value):
     76              return False
     77
     78          # check count
     79          if len(value) != len(self.__params):
     80              return False
     81
     82          # match child params
     83          if isinstance(value, dict):
     84              for param in self.__params:
     85                  if not param.read_kwargs(kwargs):
     86                      _logger.debug("Overload failed to match, failed at %s" %
     87                                    param)
     88                      return False
     89          else:
     90              for arg, param in zip(value, self.__params):
     91                  if not param.read_arg(arg):
     92                      _logger.debug("Overload failed to match, failed at %s" %
     93                                    param)
     94                      return False
     95
     96          return True
     97
     98 -    def write(self, kwargs):
     99          assert self._matched, \
    100                 "write() may only be called after a succesful read()"
    101
    102          for param in self.__params:
    103              param.write(kwargs)
    104
    105
    106  # a shortcut
    107  CompositeParam = CompositeParameter
    108