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

     1  # Copyright 2007 Google, Inc. All Rights Reserved.
     2  # Licensed to PSF under a Contributor Agreement.
     3  
     4  """Abstract Base Classes (ABCs) for collections, according to PEP 3119.
     5  
     6  DON'T USE THIS MODULE DIRECTLY!  The classes here should be imported
     7  via collections; they are defined here only to alleviate certain
     8  bootstrapping issues.  Unit tests are in test_collections.
     9  """
    10  
    11  import abc
    12  ABCMeta = abc.ABCMeta
    13  abstractmethod = abc.abstractmethod
    14  import sys
    15  
    16  __all__ = ["Hashable", "Iterable", "Iterator",
    17             "Sized", "Container", "Callable",
    18             "Set", "MutableSet",
    19             "Mapping", "MutableMapping",
    20             "MappingView", #"KeysView", "ItemsView", "ValuesView",
    21             "Sequence", "MutableSequence",
    22             ]
    23  
    24  ### ONE-TRICK PONIES ###
    25  
    26  def _hasattr(C, attr):
    27      try:
    28          return any(attr in B.__dict__ for B in C.__mro__)
    29      except AttributeError:
    30          # Old-style class
    31          return hasattr(C, attr)
    32  
    33  
    34  class Hashable(object):
    35      __metaclass__ = ABCMeta
    36  
    37      @abstractmethod
    38      def __hash__(self):
    39          return 0
    40  
    41      @classmethod
    42      def __subclasshook__(cls, C):
    43          if cls is Hashable:
    44              try:
    45                  for B in C.__mro__:
    46                      if "__hash__" in B.__dict__:
    47                          if B.__dict__["__hash__"]:
    48                              return True
    49                          break
    50              except AttributeError:
    51                  # Old-style class
    52                  if getattr(C, "__hash__", None):
    53                      return True
    54          return NotImplemented
    55  
    56  
    57  class Iterable(object):
    58      __metaclass__ = ABCMeta
    59  
    60      @abstractmethod
    61      def __iter__(self):
    62          while False:
    63              yield None
    64  
    65      @classmethod
    66      def __subclasshook__(cls, C):
    67          if cls is Iterable:
    68              if _hasattr(C, "__iter__"):
    69                  return True
    70          return NotImplemented
    71  
    72  Iterable.register(str)
    73  
    74  
    75  class Iterator(Iterable):
    76  
    77      @abstractmethod
    78      def next(self):
    79          'Return the next item from the iterator. When exhausted, raise StopIteration'
    80          raise StopIteration
    81  
    82      def __iter__(self):
    83          return self
    84  
    85      @classmethod
    86      def __subclasshook__(cls, C):
    87          if cls is Iterator:
    88              if _hasattr(C, "next") and _hasattr(C, "__iter__"):
    89                  return True
    90          return NotImplemented
    91  
    92  
    93  class Sized(object):
    94      __metaclass__ = ABCMeta
    95  
    96      @abstractmethod
    97      def __len__(self):
    98          return 0
    99  
   100      @classmethod
   101      def __subclasshook__(cls, C):
   102          if cls is Sized:
   103              if _hasattr(C, "__len__"):
   104                  return True
   105          return NotImplemented
   106  
   107  
   108  class Container(object):
   109      __metaclass__ = ABCMeta
   110  
   111      @abstractmethod
   112      def __contains__(self, x):
   113          return False
   114  
   115      @classmethod
   116      def __subclasshook__(cls, C):
   117          if cls is Container:
   118              if _hasattr(C, "__contains__"):
   119                  return True
   120          return NotImplemented
   121  
   122  
   123  class Callable(object):
   124      __metaclass__ = ABCMeta
   125  
   126      @abstractmethod
   127      def __call__(self, *args, **kwds):
   128          return False
   129  
   130      @classmethod
   131      def __subclasshook__(cls, C):
   132          if cls is Callable:
   133              if _hasattr(C, "__call__"):
   134                  return True
   135          return NotImplemented
   136  
   137  
   138  ### SETS ###
   139  
   140  
   141  class Set(Sized, Iterable, Container):
   142      """A set is a finite, iterable container.
   143  
   144      This class provides concrete generic implementations of all
   145      methods except for __contains__, __iter__ and __len__.
   146  
   147      To override the comparisons (presumably for speed, as the
   148      semantics are fixed), redefine __le__ and __ge__,
   149      then the other operations will automatically follow suit.
   150      """
   151  
   152      def __le__(self, other):
   153          if not isinstance(other, Set):
   154              return NotImplemented
   155          if len(self) > len(other):
   156              return False
   157          for elem in self:
   158              if elem not in other:
   159                  return False
   160          return True
   161  
   162      def __lt__(self, other):
   163          if not isinstance(other, Set):
   164              return NotImplemented
   165          return len(self) < len(other) and self.__le__(other)
   166  
   167      def __gt__(self, other):
   168          if not isinstance(other, Set):
   169              return NotImplemented
   170          return len(self) > len(other) and self.__ge__(other)
   171  
   172      def __ge__(self, other):
   173          if not isinstance(other, Set):
   174              return NotImplemented
   175          if len(self) < len(other):
   176              return False
   177          for elem in other:
   178              if elem not in self:
   179                  return False
   180          return True
   181  
   182      def __eq__(self, other):
   183          if not isinstance(other, Set):
   184              return NotImplemented
   185          return len(self) == len(other) and self.__le__(other)
   186  
   187      def __ne__(self, other):
   188          return not (self == other)
   189  
   190      @classmethod
   191      def _from_iterable(cls, it):
   192          '''Construct an instance of the class from any iterable input.
   193  
   194          Must override this method if the class constructor signature
   195          does not accept an iterable for an input.
   196          '''
   197          return cls(it)
   198  
   199      def __and__(self, other):
   200          if not isinstance(other, Iterable):
   201              return NotImplemented
   202          return self._from_iterable(value for value in other if value in self)
   203  
   204      __rand__ = __and__
   205  
   206      def isdisjoint(self, other):
   207          'Return True if two sets have a null intersection.'
   208          for value in other:
   209              if value in self:
   210                  return False
   211          return True
   212  
   213      def __or__(self, other):
   214          if not isinstance(other, Iterable):
   215              return NotImplemented
   216          chain = (e for s in (self, other) for e in s)
   217          return self._from_iterable(chain)
   218  
   219      __ror__ = __or__
   220  
   221      def __sub__(self, other):
   222          if not isinstance(other, Set):
   223              if not isinstance(other, Iterable):
   224                  return NotImplemented
   225              other = self._from_iterable(other)
   226          return self._from_iterable(value for value in self
   227                                     if value not in other)
   228  
   229      def __rsub__(self, other):
   230          if not isinstance(other, Set):
   231              if not isinstance(other, Iterable):
   232                  return NotImplemented
   233              other = self._from_iterable(other)
   234          return self._from_iterable(value for value in other
   235                                     if value not in self)
   236  
   237      def __xor__(self, other):
   238          if not isinstance(other, Set):
   239              if not isinstance(other, Iterable):
   240                  return NotImplemented
   241              other = self._from_iterable(other)
   242          return (self - other) | (other - self)
   243  
   244      __rxor__ = __xor__
   245  
   246      # Sets are not hashable by default, but subclasses can change this
   247      __hash__ = None
   248  
   249      def _hash(self):
   250          """Compute the hash value of a set.
   251  
   252          Note that we don't define __hash__: not all sets are hashable.
   253          But if you define a hashable set type, its __hash__ should
   254          call this function.
   255  
   256          This must be compatible __eq__.
   257  
   258          All sets ought to compare equal if they contain the same
   259          elements, regardless of how they are implemented, and
   260          regardless of the order of the elements; so there's not much
   261          freedom for __eq__ or __hash__.  We match the algorithm used
   262          by the built-in frozenset type.
   263          """
   264          MAX = sys.maxint
   265          MASK = 2 * MAX + 1
   266          n = len(self)
   267          h = 1927868237 * (n + 1)
   268          h &= MASK
   269          for x in self:
   270              hx = hash(x)
   271              h ^= (hx ^ (hx << 16) ^ 89869747)  * 3644798167
   272              h &= MASK
   273          h = h * 69069 + 907133923
   274          h &= MASK
   275          if h > MAX:
   276              h -= MASK + 1
   277          if h == -1:
   278              h = 590923713
   279          return h
   280  
   281  Set.register(frozenset)
   282  
   283  
   284  class MutableSet(Set):
   285      """A mutable set is a finite, iterable container.
   286  
   287      This class provides concrete generic implementations of all
   288      methods except for __contains__, __iter__, __len__,
   289      add(), and discard().
   290  
   291      To override the comparisons (presumably for speed, as the
   292      semantics are fixed), all you have to do is redefine __le__ and
   293      then the other operations will automatically follow suit.
   294      """
   295  
   296      @abstractmethod
   297      def add(self, value):
   298          """Add an element."""
   299          raise NotImplementedError
   300  
   301      @abstractmethod
   302      def discard(self, value):
   303          """Remove an element.  Do not raise an exception if absent."""
   304          raise NotImplementedError
   305  
   306      def remove(self, value):
   307          """Remove an element. If not a member, raise a KeyError."""
   308          if value not in self:
   309              raise KeyError(value)
   310          self.discard(value)
   311  
   312      def pop(self):
   313          """Return the popped value.  Raise KeyError if empty."""
   314          it = iter(self)
   315          try:
   316              value = next(it)
   317          except StopIteration:
   318              raise KeyError
   319          self.discard(value)
   320          return value
   321  
   322      def clear(self):
   323          """This is slow (creates N new iterators!) but effective."""
   324          try:
   325              while True:
   326                  self.pop()
   327          except KeyError:
   328              pass
   329  
   330      def __ior__(self, it):
   331          for value in it:
   332              self.add(value)
   333          return self
   334  
   335      def __iand__(self, it):
   336          for value in (self - it):
   337              self.discard(value)
   338          return self
   339  
   340      def __ixor__(self, it):
   341          if it is self:
   342              self.clear()
   343          else:
   344              if not isinstance(it, Set):
   345                  it = self._from_iterable(it)
   346              for value in it:
   347                  if value in self:
   348                      self.discard(value)
   349                  else:
   350                      self.add(value)
   351          return self
   352  
   353      def __isub__(self, it):
   354          if it is self:
   355              self.clear()
   356          else:
   357              for value in it:
   358                  self.discard(value)
   359          return self
   360  
   361  MutableSet.register(set)
   362  
   363  
   364  ### MAPPINGS ###
   365  
   366  
   367  class Mapping(Sized, Iterable, Container):
   368  
   369      """A Mapping is a generic container for associating key/value
   370      pairs.
   371  
   372      This class provides concrete generic implementations of all
   373      methods except for __getitem__, __iter__, and __len__.
   374  
   375      """
   376  
   377      @abstractmethod
   378      def __getitem__(self, key):
   379          raise KeyError
   380  
   381      def get(self, key, default=None):
   382          'D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.'
   383          try:
   384              return self[key]
   385          except KeyError:
   386              return default
   387  
   388      def __contains__(self, key):
   389          try:
   390              self[key]
   391          except KeyError:
   392              return False
   393          else:
   394              return True
   395  
   396      def iterkeys(self):
   397          'D.iterkeys() -> an iterator over the keys of D'
   398          return iter(self)
   399  
   400      def itervalues(self):
   401          'D.itervalues() -> an iterator over the values of D'
   402          for key in self:
   403              yield self[key]
   404  
   405      def iteritems(self):
   406          'D.iteritems() -> an iterator over the (key, value) items of D'
   407          for key in self:
   408              yield (key, self[key])
   409  
   410      def keys(self):
   411          "D.keys() -> list of D's keys"
   412          return list(self)
   413  
   414      def items(self):
   415          "D.items() -> list of D's (key, value) pairs, as 2-tuples"
   416          return [(key, self[key]) for key in self]
   417  
   418      def values(self):
   419          "D.values() -> list of D's values"
   420          return [self[key] for key in self]
   421  
   422      # Mappings are not hashable by default, but subclasses can change this
   423      __hash__ = None
   424  
   425      def __eq__(self, other):
   426          if not isinstance(other, Mapping):
   427              return NotImplemented
   428          return dict(self.items()) == dict(other.items())
   429  
   430      def __ne__(self, other):
   431          return not (self == other)
   432  
   433  class MappingView(Sized):
   434  
   435      def __init__(self, mapping):
   436          self._mapping = mapping
   437  
   438      def __len__(self):
   439          return len(self._mapping)
   440  
   441      def __repr__(self):
   442          #return '{0.__class__.__name__}({0._mapping!r})'.format(self)
   443          return '%s(%r)' % (self.__class__.__name__, self._mapping)
   444  
   445  
   446  #class KeysView(MappingView, Set):
   447  #
   448  #    @classmethod
   449  #    def _from_iterable(self, it):
   450  #        return set(it)
   451  #
   452  #    def __contains__(self, key):
   453  #        return key in self._mapping
   454  #
   455  #    def __iter__(self):
   456  #        for key in self._mapping:
   457  #            yield key
   458  #
   459  #KeysView.register(type({}.viewkeys()))
   460  #
   461  #class ItemsView(MappingView, Set):
   462  #
   463  #    @classmethod
   464  #    def _from_iterable(self, it):
   465  #        return set(it)
   466  #
   467  #    def __contains__(self, item):
   468  #        key, value = item
   469  #        try:
   470  #            v = self._mapping[key]
   471  #        except KeyError:
   472  #            return False
   473  #        else:
   474  #            return v == value
   475  #
   476  #    def __iter__(self):
   477  #        for key in self._mapping:
   478  #            yield (key, self._mapping[key])
   479  #
   480  #ItemsView.register(type({}.viewitems()))
   481  #
   482  #class ValuesView(MappingView):
   483  #
   484  #    def __contains__(self, value):
   485  #        for key in self._mapping:
   486  #            if value == self._mapping[key]:
   487  #                return True
   488  #        return False
   489  #
   490  #    def __iter__(self):
   491  #        for key in self._mapping:
   492  #            yield self._mapping[key]
   493  #
   494  #ValuesView.register(type({}.viewvalues()))
   495  
   496  class MutableMapping(Mapping):
   497  
   498      """A MutableMapping is a generic container for associating
   499      key/value pairs.
   500  
   501      This class provides concrete generic implementations of all
   502      methods except for __getitem__, __setitem__, __delitem__,
   503      __iter__, and __len__.
   504  
   505      """
   506  
   507      @abstractmethod
   508      def __setitem__(self, key, value):
   509          raise KeyError
   510  
   511      @abstractmethod
   512      def __delitem__(self, key):
   513          raise KeyError
   514  
   515      __marker = object()
   516  
   517      def pop(self, key, default=__marker):
   518          '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
   519            If key is not found, d is returned if given, otherwise KeyError is raised.
   520          '''
   521          try:
   522              value = self[key]
   523          except KeyError:
   524              if default is self.__marker:
   525                  raise
   526              return default
   527          else:
   528              del self[key]
   529              return value
   530  
   531      def popitem(self):
   532          '''D.popitem() -> (k, v), remove and return some (key, value) pair
   533             as a 2-tuple; but raise KeyError if D is empty.
   534          '''
   535          try:
   536              key = next(iter(self))
   537          except StopIteration:
   538              raise KeyError
   539          value = self[key]
   540          del self[key]
   541          return key, value
   542  
   543      def clear(self):
   544          'D.clear() -> None.  Remove all items from D.'
   545          try:
   546              while True:
   547                  self.popitem()
   548          except KeyError:
   549              pass
   550  
   551      def update(*args, **kwds):
   552          ''' D.update([E, ]**F) -> None.  Update D from mapping/iterable E and F.
   553              If E present and has a .keys() method, does:     for k in E: D[k] = E[k]
   554              If E present and lacks .keys() method, does:     for (k, v) in E: D[k] = v
   555              In either case, this is followed by: for k, v in F.items(): D[k] = v
   556          '''
   557          if not args:
   558              raise TypeError("descriptor 'update' of 'MutableMapping' object "
   559                              "needs an argument")
   560          self = args[0]
   561          args = args[1:]
   562          if len(args) > 1:
   563              raise TypeError('update expected at most 1 arguments, got %d' %
   564                              len(args))
   565          if args:
   566              other = args[0]
   567              if isinstance(other, Mapping):
   568                  for key in other:
   569                      self[key] = other[key]
   570              elif hasattr(other, "keys"):
   571                  for key in other.keys():
   572                      self[key] = other[key]
   573              else:
   574                  for key, value in other:
   575                      self[key] = value
   576          for key, value in kwds.items():
   577              self[key] = value
   578  
   579      def setdefault(self, key, default=None):
   580          'D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D'
   581          try:
   582              return self[key]
   583          except KeyError:
   584              self[key] = default
   585          return default
   586  
   587  MutableMapping.register(dict)
   588  
   589  
   590  ### SEQUENCES ###
   591  
   592  
   593  class Sequence(Sized, Iterable, Container):
   594      """All the operations on a read-only sequence.
   595  
   596      Concrete subclasses must override __new__ or __init__,
   597      __getitem__, and __len__.
   598      """
   599  
   600      @abstractmethod
   601      def __getitem__(self, index):
   602          raise IndexError
   603  
   604      def __iter__(self):
   605          i = 0
   606          try:
   607              while True:
   608                  v = self[i]
   609                  yield v
   610                  i += 1
   611          except IndexError:
   612              return
   613  
   614      def __contains__(self, value):
   615          for v in self:
   616              if v == value:
   617                  return True
   618          return False
   619  
   620      def __reversed__(self):
   621          for i in reversed(range(len(self))):
   622              yield self[i]
   623  
   624      def index(self, value):
   625          '''S.index(value) -> integer -- return first index of value.
   626             Raises ValueError if the value is not present.
   627          '''
   628          for i, v in enumerate(self):
   629              if v == value:
   630                  return i
   631          raise ValueError
   632  
   633      def count(self, value):
   634          'S.count(value) -> integer -- return number of occurrences of value'
   635          return sum(1 for v in self if v == value)
   636  
   637  Sequence.register(tuple)
   638  Sequence.register(basestring)
   639  #Sequence.register(buffer)
   640  Sequence.register(xrange)
   641  
   642  
   643  class MutableSequence(Sequence):
   644  
   645      """All the operations on a read-only sequence.
   646  
   647      Concrete subclasses must provide __new__ or __init__,
   648      __getitem__, __setitem__, __delitem__, __len__, and insert().
   649  
   650      """
   651  
   652      @abstractmethod
   653      def __setitem__(self, index, value):
   654          raise IndexError
   655  
   656      @abstractmethod
   657      def __delitem__(self, index):
   658          raise IndexError
   659  
   660      @abstractmethod
   661      def insert(self, index, value):
   662          'S.insert(index, object) -- insert object before index'
   663          raise IndexError
   664  
   665      def append(self, value):
   666          'S.append(object) -- append object to the end of the sequence'
   667          self.insert(len(self), value)
   668  
   669      def reverse(self):
   670          'S.reverse() -- reverse *IN PLACE*'
   671          n = len(self)
   672          for i in range(n//2):
   673              self[i], self[n-i-1] = self[n-i-1], self[i]
   674  
   675      def extend(self, values):
   676          'S.extend(iterable) -- extend sequence by appending elements from the iterable'
   677          for v in values:
   678              self.append(v)
   679  
   680      def pop(self, index=-1):
   681          '''S.pop([index]) -> item -- remove and return item at index (default last).
   682             Raise IndexError if list is empty or index is out of range.
   683          '''
   684          v = self[index]
   685          del self[index]
   686          return v
   687  
   688      def remove(self, value):
   689          '''S.remove(value) -- remove first occurrence of value.
   690             Raise ValueError if the value is not present.
   691          '''
   692          del self[self.index(value)]
   693  
   694      def __iadd__(self, values):
   695          self.extend(values)
   696          return self
   697  
   698  MutableSequence.register(list)