github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-runtime-src/third_party/pypy/_functools.py (about)

     1  """ Supplies the internal functions for functools.py in the standard library """
     2  
     3  __all__ = ['reduce', 'partial']
     4  
     5  # reduce() has moved to _functools in Python 2.6+.
     6  def reduce(function, iterable, initializer=None):
     7      it = iter(iterable)
     8      if initializer is None:
     9          try:
    10              initializer = next(it)
    11          except StopIteration:
    12              raise TypeError('reduce() of empty sequence with no initial value')
    13      accum_value = initializer
    14      for x in it:
    15          accum_value = function(accum_value, x)
    16      return accum_value
    17  
    18  class partial(object):
    19      """
    20      partial(func, *args, **keywords) - new function with partial application
    21      of the given arguments and keywords.
    22      """
    23  
    24      __slots__ = ('_func', '_args', '_keywords', '__dict__')
    25  
    26      def __init__(*args, **keywords):
    27          if len(args) < 2:
    28              raise TypeError('__init__() takes at least 2 arguments (%d given)'
    29                              % len(args))
    30          self, func, args = args[0], args[1], args[2:]
    31          if not callable(func):
    32              raise TypeError("the first argument must be callable")
    33          self._func = func
    34          self._args = args
    35          self._keywords = keywords
    36  
    37      def __delattr__(self, key):
    38          if key == '__dict__':
    39              raise TypeError("a partial object's dictionary may not be deleted")
    40          object.__delattr__(self, key)
    41  
    42      # @property
    43      def func(self):
    44          return self._func
    45      # TODO: Make this a decorator once they're implemented.
    46      func = property(func)
    47  
    48      # @property
    49      def args(self):
    50          return self._args
    51      # TODO: Make this a decorator once they're implemented.
    52      args = property(args)
    53  
    54      # @property
    55      def keywords(self):
    56          return self._keywords
    57      # TODO: Make this a decorator once they're implemented.
    58      keywords = property(keywords)
    59  
    60      def __call__(self, *fargs, **fkeywords):
    61          if self._keywords:
    62              fkeywords = dict(self._keywords, **fkeywords)
    63          return self._func(*(self._args + fargs), **fkeywords)
    64  
    65      def __reduce__(self):
    66          d = dict((k, v) for k, v in self.__dict__.iteritems() if k not in
    67                  ('_func', '_args', '_keywords'))
    68          if len(d) == 0:
    69              d = None
    70          return (type(self), (self._func,),
    71                  (self._func, self._args, self._keywords, d))
    72  
    73      def __setstate__(self, state):
    74          if not isinstance(state, tuple) or len(state) != 4:
    75              raise TypeError("invalid partial state")
    76  
    77          func, args, keywords, d = state
    78  
    79          if (not callable(func) or not isinstance(args, tuple) or
    80              (keywords is not None and not isinstance(keywords, dict))):
    81              raise TypeError("invalid partial state")
    82  
    83          self._func = func
    84          self._args = tuple(args)
    85  
    86          if keywords is None:
    87              keywords = {}
    88          elif type(keywords) is not dict:
    89              keywords = dict(keywords)
    90          self._keywords = keywords
    91  
    92          if d is None:
    93              self.__dict__.clear()
    94          else:
    95              self.__dict__.update(d)