python (3.12.0)

(root)/
lib/
python3.12/
collections/
__init__.py
       1  '''This module implements specialized container datatypes providing
       2  alternatives to Python's general purpose built-in containers, dict,
       3  list, set, and tuple.
       4  
       5  * namedtuple   factory function for creating tuple subclasses with named fields
       6  * deque        list-like container with fast appends and pops on either end
       7  * ChainMap     dict-like class for creating a single view of multiple mappings
       8  * Counter      dict subclass for counting hashable objects
       9  * OrderedDict  dict subclass that remembers the order entries were added
      10  * defaultdict  dict subclass that calls a factory function to supply missing values
      11  * UserDict     wrapper around dictionary objects for easier dict subclassing
      12  * UserList     wrapper around list objects for easier list subclassing
      13  * UserString   wrapper around string objects for easier string subclassing
      14  
      15  '''
      16  
      17  __all__ = [
      18      'ChainMap',
      19      'Counter',
      20      'OrderedDict',
      21      'UserDict',
      22      'UserList',
      23      'UserString',
      24      'defaultdict',
      25      'deque',
      26      'namedtuple',
      27  ]
      28  
      29  import _collections_abc
      30  import sys as _sys
      31  
      32  from itertools import chain as _chain
      33  from itertools import repeat as _repeat
      34  from itertools import starmap as _starmap
      35  from keyword import iskeyword as _iskeyword
      36  from operator import eq as _eq
      37  from operator import itemgetter as _itemgetter
      38  from reprlib import recursive_repr as _recursive_repr
      39  from _weakref import proxy as _proxy
      40  
      41  try:
      42      from _collections import deque
      43  except ImportError:
      44      pass
      45  else:
      46      _collections_abc.MutableSequence.register(deque)
      47  
      48  try:
      49      from _collections import _deque_iterator
      50  except ImportError:
      51      pass
      52  
      53  try:
      54      from _collections import defaultdict
      55  except ImportError:
      56      pass
      57  
      58  
      59  ################################################################################
      60  ### OrderedDict
      61  ################################################################################
      62  
      63  class ESC[4;38;5;81m_OrderedDictKeysView(ESC[4;38;5;149m_collections_abcESC[4;38;5;149m.ESC[4;38;5;149mKeysView):
      64  
      65      def __reversed__(self):
      66          yield from reversed(self._mapping)
      67  
      68  class ESC[4;38;5;81m_OrderedDictItemsView(ESC[4;38;5;149m_collections_abcESC[4;38;5;149m.ESC[4;38;5;149mItemsView):
      69  
      70      def __reversed__(self):
      71          for key in reversed(self._mapping):
      72              yield (key, self._mapping[key])
      73  
      74  class ESC[4;38;5;81m_OrderedDictValuesView(ESC[4;38;5;149m_collections_abcESC[4;38;5;149m.ESC[4;38;5;149mValuesView):
      75  
      76      def __reversed__(self):
      77          for key in reversed(self._mapping):
      78              yield self._mapping[key]
      79  
      80  class ESC[4;38;5;81m_Link(ESC[4;38;5;149mobject):
      81      __slots__ = 'prev', 'next', 'key', '__weakref__'
      82  
      83  class ESC[4;38;5;81mOrderedDict(ESC[4;38;5;149mdict):
      84      'Dictionary that remembers insertion order'
      85      # An inherited dict maps keys to values.
      86      # The inherited dict provides __getitem__, __len__, __contains__, and get.
      87      # The remaining methods are order-aware.
      88      # Big-O running times for all methods are the same as regular dictionaries.
      89  
      90      # The internal self.__map dict maps keys to links in a doubly linked list.
      91      # The circular doubly linked list starts and ends with a sentinel element.
      92      # The sentinel element never gets deleted (this simplifies the algorithm).
      93      # The sentinel is in self.__hardroot with a weakref proxy in self.__root.
      94      # The prev links are weakref proxies (to prevent circular references).
      95      # Individual links are kept alive by the hard reference in self.__map.
      96      # Those hard references disappear when a key is deleted from an OrderedDict.
      97  
      98      def __new__(cls, /, *args, **kwds):
      99          "Create the ordered dict object and set up the underlying structures."
     100          self = dict.__new__(cls)
     101          self.__hardroot = _Link()
     102          self.__root = root = _proxy(self.__hardroot)
     103          root.prev = root.next = root
     104          self.__map = {}
     105          return self
     106  
     107      def __init__(self, other=(), /, **kwds):
     108          '''Initialize an ordered dictionary.  The signature is the same as
     109          regular dictionaries.  Keyword argument order is preserved.
     110          '''
     111          self.__update(other, **kwds)
     112  
     113      def __setitem__(self, key, value,
     114                      dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link):
     115          'od.__setitem__(i, y) <==> od[i]=y'
     116          # Setting a new item creates a new link at the end of the linked list,
     117          # and the inherited dictionary is updated with the new key/value pair.
     118          if key not in self:
     119              self.__map[key] = link = Link()
     120              root = self.__root
     121              last = root.prev
     122              link.prev, link.next, link.key = last, root, key
     123              last.next = link
     124              root.prev = proxy(link)
     125          dict_setitem(self, key, value)
     126  
     127      def __delitem__(self, key, dict_delitem=dict.__delitem__):
     128          'od.__delitem__(y) <==> del od[y]'
     129          # Deleting an existing item uses self.__map to find the link which gets
     130          # removed by updating the links in the predecessor and successor nodes.
     131          dict_delitem(self, key)
     132          link = self.__map.pop(key)
     133          link_prev = link.prev
     134          link_next = link.next
     135          link_prev.next = link_next
     136          link_next.prev = link_prev
     137          link.prev = None
     138          link.next = None
     139  
     140      def __iter__(self):
     141          'od.__iter__() <==> iter(od)'
     142          # Traverse the linked list in order.
     143          root = self.__root
     144          curr = root.next
     145          while curr is not root:
     146              yield curr.key
     147              curr = curr.next
     148  
     149      def __reversed__(self):
     150          'od.__reversed__() <==> reversed(od)'
     151          # Traverse the linked list in reverse order.
     152          root = self.__root
     153          curr = root.prev
     154          while curr is not root:
     155              yield curr.key
     156              curr = curr.prev
     157  
     158      def clear(self):
     159          'od.clear() -> None.  Remove all items from od.'
     160          root = self.__root
     161          root.prev = root.next = root
     162          self.__map.clear()
     163          dict.clear(self)
     164  
     165      def popitem(self, last=True):
     166          '''Remove and return a (key, value) pair from the dictionary.
     167  
     168          Pairs are returned in LIFO order if last is true or FIFO order if false.
     169          '''
     170          if not self:
     171              raise KeyError('dictionary is empty')
     172          root = self.__root
     173          if last:
     174              link = root.prev
     175              link_prev = link.prev
     176              link_prev.next = root
     177              root.prev = link_prev
     178          else:
     179              link = root.next
     180              link_next = link.next
     181              root.next = link_next
     182              link_next.prev = root
     183          key = link.key
     184          del self.__map[key]
     185          value = dict.pop(self, key)
     186          return key, value
     187  
     188      def move_to_end(self, key, last=True):
     189          '''Move an existing element to the end (or beginning if last is false).
     190  
     191          Raise KeyError if the element does not exist.
     192          '''
     193          link = self.__map[key]
     194          link_prev = link.prev
     195          link_next = link.next
     196          soft_link = link_next.prev
     197          link_prev.next = link_next
     198          link_next.prev = link_prev
     199          root = self.__root
     200          if last:
     201              last = root.prev
     202              link.prev = last
     203              link.next = root
     204              root.prev = soft_link
     205              last.next = link
     206          else:
     207              first = root.next
     208              link.prev = root
     209              link.next = first
     210              first.prev = soft_link
     211              root.next = link
     212  
     213      def __sizeof__(self):
     214          sizeof = _sys.getsizeof
     215          n = len(self) + 1                       # number of links including root
     216          size = sizeof(self.__dict__)            # instance dictionary
     217          size += sizeof(self.__map) * 2          # internal dict and inherited dict
     218          size += sizeof(self.__hardroot) * n     # link objects
     219          size += sizeof(self.__root) * n         # proxy objects
     220          return size
     221  
     222      update = __update = _collections_abc.MutableMapping.update
     223  
     224      def keys(self):
     225          "D.keys() -> a set-like object providing a view on D's keys"
     226          return _OrderedDictKeysView(self)
     227  
     228      def items(self):
     229          "D.items() -> a set-like object providing a view on D's items"
     230          return _OrderedDictItemsView(self)
     231  
     232      def values(self):
     233          "D.values() -> an object providing a view on D's values"
     234          return _OrderedDictValuesView(self)
     235  
     236      __ne__ = _collections_abc.MutableMapping.__ne__
     237  
     238      __marker = object()
     239  
     240      def pop(self, key, default=__marker):
     241          '''od.pop(k[,d]) -> v, remove specified key and return the corresponding
     242          value.  If key is not found, d is returned if given, otherwise KeyError
     243          is raised.
     244  
     245          '''
     246          marker = self.__marker
     247          result = dict.pop(self, key, marker)
     248          if result is not marker:
     249              # The same as in __delitem__().
     250              link = self.__map.pop(key)
     251              link_prev = link.prev
     252              link_next = link.next
     253              link_prev.next = link_next
     254              link_next.prev = link_prev
     255              link.prev = None
     256              link.next = None
     257              return result
     258          if default is marker:
     259              raise KeyError(key)
     260          return default
     261  
     262      def setdefault(self, key, default=None):
     263          '''Insert key with a value of default if key is not in the dictionary.
     264  
     265          Return the value for key if key is in the dictionary, else default.
     266          '''
     267          if key in self:
     268              return self[key]
     269          self[key] = default
     270          return default
     271  
     272      @_recursive_repr()
     273      def __repr__(self):
     274          'od.__repr__() <==> repr(od)'
     275          if not self:
     276              return '%s()' % (self.__class__.__name__,)
     277          return '%s(%r)' % (self.__class__.__name__, dict(self.items()))
     278  
     279      def __reduce__(self):
     280          'Return state information for pickling'
     281          state = self.__getstate__()
     282          if state:
     283              if isinstance(state, tuple):
     284                  state, slots = state
     285              else:
     286                  slots = {}
     287              state = state.copy()
     288              slots = slots.copy()
     289              for k in vars(OrderedDict()):
     290                  state.pop(k, None)
     291                  slots.pop(k, None)
     292              if slots:
     293                  state = state, slots
     294              else:
     295                  state = state or None
     296          return self.__class__, (), state, None, iter(self.items())
     297  
     298      def copy(self):
     299          'od.copy() -> a shallow copy of od'
     300          return self.__class__(self)
     301  
     302      @classmethod
     303      def fromkeys(cls, iterable, value=None):
     304          '''Create a new ordered dictionary with keys from iterable and values set to value.
     305          '''
     306          self = cls()
     307          for key in iterable:
     308              self[key] = value
     309          return self
     310  
     311      def __eq__(self, other):
     312          '''od.__eq__(y) <==> od==y.  Comparison to another OD is order-sensitive
     313          while comparison to a regular mapping is order-insensitive.
     314  
     315          '''
     316          if isinstance(other, OrderedDict):
     317              return dict.__eq__(self, other) and all(map(_eq, self, other))
     318          return dict.__eq__(self, other)
     319  
     320      def __ior__(self, other):
     321          self.update(other)
     322          return self
     323  
     324      def __or__(self, other):
     325          if not isinstance(other, dict):
     326              return NotImplemented
     327          new = self.__class__(self)
     328          new.update(other)
     329          return new
     330  
     331      def __ror__(self, other):
     332          if not isinstance(other, dict):
     333              return NotImplemented
     334          new = self.__class__(other)
     335          new.update(self)
     336          return new
     337  
     338  
     339  try:
     340      from _collections import OrderedDict
     341  except ImportError:
     342      # Leave the pure Python version in place.
     343      pass
     344  
     345  
     346  ################################################################################
     347  ### namedtuple
     348  ################################################################################
     349  
     350  try:
     351      from _collections import _tuplegetter
     352  except ImportError:
     353      _tuplegetter = lambda index, doc: property(_itemgetter(index), doc=doc)
     354  
     355  def namedtuple(typename, field_names, *, rename=False, defaults=None, module=None):
     356      """Returns a new subclass of tuple with named fields.
     357  
     358      >>> Point = namedtuple('Point', ['x', 'y'])
     359      >>> Point.__doc__                   # docstring for the new class
     360      'Point(x, y)'
     361      >>> p = Point(11, y=22)             # instantiate with positional args or keywords
     362      >>> p[0] + p[1]                     # indexable like a plain tuple
     363      33
     364      >>> x, y = p                        # unpack like a regular tuple
     365      >>> x, y
     366      (11, 22)
     367      >>> p.x + p.y                       # fields also accessible by name
     368      33
     369      >>> d = p._asdict()                 # convert to a dictionary
     370      >>> d['x']
     371      11
     372      >>> Point(**d)                      # convert from a dictionary
     373      Point(x=11, y=22)
     374      >>> p._replace(x=100)               # _replace() is like str.replace() but targets named fields
     375      Point(x=100, y=22)
     376  
     377      """
     378  
     379      # Validate the field names.  At the user's option, either generate an error
     380      # message or automatically replace the field name with a valid name.
     381      if isinstance(field_names, str):
     382          field_names = field_names.replace(',', ' ').split()
     383      field_names = list(map(str, field_names))
     384      typename = _sys.intern(str(typename))
     385  
     386      if rename:
     387          seen = set()
     388          for index, name in enumerate(field_names):
     389              if (not name.isidentifier()
     390                  or _iskeyword(name)
     391                  or name.startswith('_')
     392                  or name in seen):
     393                  field_names[index] = f'_{index}'
     394              seen.add(name)
     395  
     396      for name in [typename] + field_names:
     397          if type(name) is not str:
     398              raise TypeError('Type names and field names must be strings')
     399          if not name.isidentifier():
     400              raise ValueError('Type names and field names must be valid '
     401                               f'identifiers: {name!r}')
     402          if _iskeyword(name):
     403              raise ValueError('Type names and field names cannot be a '
     404                               f'keyword: {name!r}')
     405  
     406      seen = set()
     407      for name in field_names:
     408          if name.startswith('_') and not rename:
     409              raise ValueError('Field names cannot start with an underscore: '
     410                               f'{name!r}')
     411          if name in seen:
     412              raise ValueError(f'Encountered duplicate field name: {name!r}')
     413          seen.add(name)
     414  
     415      field_defaults = {}
     416      if defaults is not None:
     417          defaults = tuple(defaults)
     418          if len(defaults) > len(field_names):
     419              raise TypeError('Got more default values than field names')
     420          field_defaults = dict(reversed(list(zip(reversed(field_names),
     421                                                  reversed(defaults)))))
     422  
     423      # Variables used in the methods and docstrings
     424      field_names = tuple(map(_sys.intern, field_names))
     425      num_fields = len(field_names)
     426      arg_list = ', '.join(field_names)
     427      if num_fields == 1:
     428          arg_list += ','
     429      repr_fmt = '(' + ', '.join(f'{name}=%r' for name in field_names) + ')'
     430      tuple_new = tuple.__new__
     431      _dict, _tuple, _len, _map, _zip = dict, tuple, len, map, zip
     432  
     433      # Create all the named tuple methods to be added to the class namespace
     434  
     435      namespace = {
     436          '_tuple_new': tuple_new,
     437          '__builtins__': {},
     438          '__name__': f'namedtuple_{typename}',
     439      }
     440      code = f'lambda _cls, {arg_list}: _tuple_new(_cls, ({arg_list}))'
     441      __new__ = eval(code, namespace)
     442      __new__.__name__ = '__new__'
     443      __new__.__doc__ = f'Create new instance of {typename}({arg_list})'
     444      if defaults is not None:
     445          __new__.__defaults__ = defaults
     446  
     447      @classmethod
     448      def _make(cls, iterable):
     449          result = tuple_new(cls, iterable)
     450          if _len(result) != num_fields:
     451              raise TypeError(f'Expected {num_fields} arguments, got {len(result)}')
     452          return result
     453  
     454      _make.__func__.__doc__ = (f'Make a new {typename} object from a sequence '
     455                                'or iterable')
     456  
     457      def _replace(self, /, **kwds):
     458          result = self._make(_map(kwds.pop, field_names, self))
     459          if kwds:
     460              raise ValueError(f'Got unexpected field names: {list(kwds)!r}')
     461          return result
     462  
     463      _replace.__doc__ = (f'Return a new {typename} object replacing specified '
     464                          'fields with new values')
     465  
     466      def __repr__(self):
     467          'Return a nicely formatted representation string'
     468          return self.__class__.__name__ + repr_fmt % self
     469  
     470      def _asdict(self):
     471          'Return a new dict which maps field names to their values.'
     472          return _dict(_zip(self._fields, self))
     473  
     474      def __getnewargs__(self):
     475          'Return self as a plain tuple.  Used by copy and pickle.'
     476          return _tuple(self)
     477  
     478      # Modify function metadata to help with introspection and debugging
     479      for method in (
     480          __new__,
     481          _make.__func__,
     482          _replace,
     483          __repr__,
     484          _asdict,
     485          __getnewargs__,
     486      ):
     487          method.__qualname__ = f'{typename}.{method.__name__}'
     488  
     489      # Build-up the class namespace dictionary
     490      # and use type() to build the result class
     491      class_namespace = {
     492          '__doc__': f'{typename}({arg_list})',
     493          '__slots__': (),
     494          '_fields': field_names,
     495          '_field_defaults': field_defaults,
     496          '__new__': __new__,
     497          '_make': _make,
     498          '_replace': _replace,
     499          '__repr__': __repr__,
     500          '_asdict': _asdict,
     501          '__getnewargs__': __getnewargs__,
     502          '__match_args__': field_names,
     503      }
     504      for index, name in enumerate(field_names):
     505          doc = _sys.intern(f'Alias for field number {index}')
     506          class_namespace[name] = _tuplegetter(index, doc)
     507  
     508      result = type(typename, (tuple,), class_namespace)
     509  
     510      # For pickling to work, the __module__ variable needs to be set to the frame
     511      # where the named tuple is created.  Bypass this step in environments where
     512      # sys._getframe is not defined (Jython for example) or sys._getframe is not
     513      # defined for arguments greater than 0 (IronPython), or where the user has
     514      # specified a particular module.
     515      if module is None:
     516          try:
     517              module = _sys._getframemodulename(1) or '__main__'
     518          except AttributeError:
     519              try:
     520                  module = _sys._getframe(1).f_globals.get('__name__', '__main__')
     521              except (AttributeError, ValueError):
     522                  pass
     523      if module is not None:
     524          result.__module__ = module
     525  
     526      return result
     527  
     528  
     529  ########################################################################
     530  ###  Counter
     531  ########################################################################
     532  
     533  def _count_elements(mapping, iterable):
     534      'Tally elements from the iterable.'
     535      mapping_get = mapping.get
     536      for elem in iterable:
     537          mapping[elem] = mapping_get(elem, 0) + 1
     538  
     539  try:                                    # Load C helper function if available
     540      from _collections import _count_elements
     541  except ImportError:
     542      pass
     543  
     544  class ESC[4;38;5;81mCounter(ESC[4;38;5;149mdict):
     545      '''Dict subclass for counting hashable items.  Sometimes called a bag
     546      or multiset.  Elements are stored as dictionary keys and their counts
     547      are stored as dictionary values.
     548  
     549      >>> c = Counter('abcdeabcdabcaba')  # count elements from a string
     550  
     551      >>> c.most_common(3)                # three most common elements
     552      [('a', 5), ('b', 4), ('c', 3)]
     553      >>> sorted(c)                       # list all unique elements
     554      ['a', 'b', 'c', 'd', 'e']
     555      >>> ''.join(sorted(c.elements()))   # list elements with repetitions
     556      'aaaaabbbbcccdde'
     557      >>> sum(c.values())                 # total of all counts
     558      15
     559  
     560      >>> c['a']                          # count of letter 'a'
     561      5
     562      >>> for elem in 'shazam':           # update counts from an iterable
     563      ...     c[elem] += 1                # by adding 1 to each element's count
     564      >>> c['a']                          # now there are seven 'a'
     565      7
     566      >>> del c['b']                      # remove all 'b'
     567      >>> c['b']                          # now there are zero 'b'
     568      0
     569  
     570      >>> d = Counter('simsalabim')       # make another counter
     571      >>> c.update(d)                     # add in the second counter
     572      >>> c['a']                          # now there are nine 'a'
     573      9
     574  
     575      >>> c.clear()                       # empty the counter
     576      >>> c
     577      Counter()
     578  
     579      Note:  If a count is set to zero or reduced to zero, it will remain
     580      in the counter until the entry is deleted or the counter is cleared:
     581  
     582      >>> c = Counter('aaabbc')
     583      >>> c['b'] -= 2                     # reduce the count of 'b' by two
     584      >>> c.most_common()                 # 'b' is still in, but its count is zero
     585      [('a', 3), ('c', 1), ('b', 0)]
     586  
     587      '''
     588      # References:
     589      #   http://en.wikipedia.org/wiki/Multiset
     590      #   http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html
     591      #   http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm
     592      #   http://code.activestate.com/recipes/259174/
     593      #   Knuth, TAOCP Vol. II section 4.6.3
     594  
     595      def __init__(self, iterable=None, /, **kwds):
     596          '''Create a new, empty Counter object.  And if given, count elements
     597          from an input iterable.  Or, initialize the count from another mapping
     598          of elements to their counts.
     599  
     600          >>> c = Counter()                           # a new, empty counter
     601          >>> c = Counter('gallahad')                 # a new counter from an iterable
     602          >>> c = Counter({'a': 4, 'b': 2})           # a new counter from a mapping
     603          >>> c = Counter(a=4, b=2)                   # a new counter from keyword args
     604  
     605          '''
     606          super().__init__()
     607          self.update(iterable, **kwds)
     608  
     609      def __missing__(self, key):
     610          'The count of elements not in the Counter is zero.'
     611          # Needed so that self[missing_item] does not raise KeyError
     612          return 0
     613  
     614      def total(self):
     615          'Sum of the counts'
     616          return sum(self.values())
     617  
     618      def most_common(self, n=None):
     619          '''List the n most common elements and their counts from the most
     620          common to the least.  If n is None, then list all element counts.
     621  
     622          >>> Counter('abracadabra').most_common(3)
     623          [('a', 5), ('b', 2), ('r', 2)]
     624  
     625          '''
     626          # Emulate Bag.sortedByCount from Smalltalk
     627          if n is None:
     628              return sorted(self.items(), key=_itemgetter(1), reverse=True)
     629  
     630          # Lazy import to speedup Python startup time
     631          import heapq
     632          return heapq.nlargest(n, self.items(), key=_itemgetter(1))
     633  
     634      def elements(self):
     635          '''Iterator over elements repeating each as many times as its count.
     636  
     637          >>> c = Counter('ABCABC')
     638          >>> sorted(c.elements())
     639          ['A', 'A', 'B', 'B', 'C', 'C']
     640  
     641          # Knuth's example for prime factors of 1836:  2**2 * 3**3 * 17**1
     642          >>> import math
     643          >>> prime_factors = Counter({2: 2, 3: 3, 17: 1})
     644          >>> math.prod(prime_factors.elements())
     645          1836
     646  
     647          Note, if an element's count has been set to zero or is a negative
     648          number, elements() will ignore it.
     649  
     650          '''
     651          # Emulate Bag.do from Smalltalk and Multiset.begin from C++.
     652          return _chain.from_iterable(_starmap(_repeat, self.items()))
     653  
     654      # Override dict methods where necessary
     655  
     656      @classmethod
     657      def fromkeys(cls, iterable, v=None):
     658          # There is no equivalent method for counters because the semantics
     659          # would be ambiguous in cases such as Counter.fromkeys('aaabbc', v=2).
     660          # Initializing counters to zero values isn't necessary because zero
     661          # is already the default value for counter lookups.  Initializing
     662          # to one is easily accomplished with Counter(set(iterable)).  For
     663          # more exotic cases, create a dictionary first using a dictionary
     664          # comprehension or dict.fromkeys().
     665          raise NotImplementedError(
     666              'Counter.fromkeys() is undefined.  Use Counter(iterable) instead.')
     667  
     668      def update(self, iterable=None, /, **kwds):
     669          '''Like dict.update() but add counts instead of replacing them.
     670  
     671          Source can be an iterable, a dictionary, or another Counter instance.
     672  
     673          >>> c = Counter('which')
     674          >>> c.update('witch')           # add elements from another iterable
     675          >>> d = Counter('watch')
     676          >>> c.update(d)                 # add elements from another counter
     677          >>> c['h']                      # four 'h' in which, witch, and watch
     678          4
     679  
     680          '''
     681          # The regular dict.update() operation makes no sense here because the
     682          # replace behavior results in the some of original untouched counts
     683          # being mixed-in with all of the other counts for a mismash that
     684          # doesn't have a straight-forward interpretation in most counting
     685          # contexts.  Instead, we implement straight-addition.  Both the inputs
     686          # and outputs are allowed to contain zero and negative counts.
     687  
     688          if iterable is not None:
     689              if isinstance(iterable, _collections_abc.Mapping):
     690                  if self:
     691                      self_get = self.get
     692                      for elem, count in iterable.items():
     693                          self[elem] = count + self_get(elem, 0)
     694                  else:
     695                      # fast path when counter is empty
     696                      super().update(iterable)
     697              else:
     698                  _count_elements(self, iterable)
     699          if kwds:
     700              self.update(kwds)
     701  
     702      def subtract(self, iterable=None, /, **kwds):
     703          '''Like dict.update() but subtracts counts instead of replacing them.
     704          Counts can be reduced below zero.  Both the inputs and outputs are
     705          allowed to contain zero and negative counts.
     706  
     707          Source can be an iterable, a dictionary, or another Counter instance.
     708  
     709          >>> c = Counter('which')
     710          >>> c.subtract('witch')             # subtract elements from another iterable
     711          >>> c.subtract(Counter('watch'))    # subtract elements from another counter
     712          >>> c['h']                          # 2 in which, minus 1 in witch, minus 1 in watch
     713          0
     714          >>> c['w']                          # 1 in which, minus 1 in witch, minus 1 in watch
     715          -1
     716  
     717          '''
     718          if iterable is not None:
     719              self_get = self.get
     720              if isinstance(iterable, _collections_abc.Mapping):
     721                  for elem, count in iterable.items():
     722                      self[elem] = self_get(elem, 0) - count
     723              else:
     724                  for elem in iterable:
     725                      self[elem] = self_get(elem, 0) - 1
     726          if kwds:
     727              self.subtract(kwds)
     728  
     729      def copy(self):
     730          'Return a shallow copy.'
     731          return self.__class__(self)
     732  
     733      def __reduce__(self):
     734          return self.__class__, (dict(self),)
     735  
     736      def __delitem__(self, elem):
     737          'Like dict.__delitem__() but does not raise KeyError for missing values.'
     738          if elem in self:
     739              super().__delitem__(elem)
     740  
     741      def __repr__(self):
     742          if not self:
     743              return f'{self.__class__.__name__}()'
     744          try:
     745              # dict() preserves the ordering returned by most_common()
     746              d = dict(self.most_common())
     747          except TypeError:
     748              # handle case where values are not orderable
     749              d = dict(self)
     750          return f'{self.__class__.__name__}({d!r})'
     751  
     752      # Multiset-style mathematical operations discussed in:
     753      #       Knuth TAOCP Volume II section 4.6.3 exercise 19
     754      #       and at http://en.wikipedia.org/wiki/Multiset
     755      #
     756      # Outputs guaranteed to only include positive counts.
     757      #
     758      # To strip negative and zero counts, add-in an empty counter:
     759      #       c += Counter()
     760      #
     761      # Results are ordered according to when an element is first
     762      # encountered in the left operand and then by the order
     763      # encountered in the right operand.
     764      #
     765      # When the multiplicities are all zero or one, multiset operations
     766      # are guaranteed to be equivalent to the corresponding operations
     767      # for regular sets.
     768      #     Given counter multisets such as:
     769      #         cp = Counter(a=1, b=0, c=1)
     770      #         cq = Counter(c=1, d=0, e=1)
     771      #     The corresponding regular sets would be:
     772      #         sp = {'a', 'c'}
     773      #         sq = {'c', 'e'}
     774      #     All of the following relations would hold:
     775      #         set(cp + cq) == sp | sq
     776      #         set(cp - cq) == sp - sq
     777      #         set(cp | cq) == sp | sq
     778      #         set(cp & cq) == sp & sq
     779      #         (cp == cq) == (sp == sq)
     780      #         (cp != cq) == (sp != sq)
     781      #         (cp <= cq) == (sp <= sq)
     782      #         (cp < cq) == (sp < sq)
     783      #         (cp >= cq) == (sp >= sq)
     784      #         (cp > cq) == (sp > sq)
     785  
     786      def __eq__(self, other):
     787          'True if all counts agree. Missing counts are treated as zero.'
     788          if not isinstance(other, Counter):
     789              return NotImplemented
     790          return all(self[e] == other[e] for c in (self, other) for e in c)
     791  
     792      def __ne__(self, other):
     793          'True if any counts disagree. Missing counts are treated as zero.'
     794          if not isinstance(other, Counter):
     795              return NotImplemented
     796          return not self == other
     797  
     798      def __le__(self, other):
     799          'True if all counts in self are a subset of those in other.'
     800          if not isinstance(other, Counter):
     801              return NotImplemented
     802          return all(self[e] <= other[e] for c in (self, other) for e in c)
     803  
     804      def __lt__(self, other):
     805          'True if all counts in self are a proper subset of those in other.'
     806          if not isinstance(other, Counter):
     807              return NotImplemented
     808          return self <= other and self != other
     809  
     810      def __ge__(self, other):
     811          'True if all counts in self are a superset of those in other.'
     812          if not isinstance(other, Counter):
     813              return NotImplemented
     814          return all(self[e] >= other[e] for c in (self, other) for e in c)
     815  
     816      def __gt__(self, other):
     817          'True if all counts in self are a proper superset of those in other.'
     818          if not isinstance(other, Counter):
     819              return NotImplemented
     820          return self >= other and self != other
     821  
     822      def __add__(self, other):
     823          '''Add counts from two counters.
     824  
     825          >>> Counter('abbb') + Counter('bcc')
     826          Counter({'b': 4, 'c': 2, 'a': 1})
     827  
     828          '''
     829          if not isinstance(other, Counter):
     830              return NotImplemented
     831          result = Counter()
     832          for elem, count in self.items():
     833              newcount = count + other[elem]
     834              if newcount > 0:
     835                  result[elem] = newcount
     836          for elem, count in other.items():
     837              if elem not in self and count > 0:
     838                  result[elem] = count
     839          return result
     840  
     841      def __sub__(self, other):
     842          ''' Subtract count, but keep only results with positive counts.
     843  
     844          >>> Counter('abbbc') - Counter('bccd')
     845          Counter({'b': 2, 'a': 1})
     846  
     847          '''
     848          if not isinstance(other, Counter):
     849              return NotImplemented
     850          result = Counter()
     851          for elem, count in self.items():
     852              newcount = count - other[elem]
     853              if newcount > 0:
     854                  result[elem] = newcount
     855          for elem, count in other.items():
     856              if elem not in self and count < 0:
     857                  result[elem] = 0 - count
     858          return result
     859  
     860      def __or__(self, other):
     861          '''Union is the maximum of value in either of the input counters.
     862  
     863          >>> Counter('abbb') | Counter('bcc')
     864          Counter({'b': 3, 'c': 2, 'a': 1})
     865  
     866          '''
     867          if not isinstance(other, Counter):
     868              return NotImplemented
     869          result = Counter()
     870          for elem, count in self.items():
     871              other_count = other[elem]
     872              newcount = other_count if count < other_count else count
     873              if newcount > 0:
     874                  result[elem] = newcount
     875          for elem, count in other.items():
     876              if elem not in self and count > 0:
     877                  result[elem] = count
     878          return result
     879  
     880      def __and__(self, other):
     881          ''' Intersection is the minimum of corresponding counts.
     882  
     883          >>> Counter('abbb') & Counter('bcc')
     884          Counter({'b': 1})
     885  
     886          '''
     887          if not isinstance(other, Counter):
     888              return NotImplemented
     889          result = Counter()
     890          for elem, count in self.items():
     891              other_count = other[elem]
     892              newcount = count if count < other_count else other_count
     893              if newcount > 0:
     894                  result[elem] = newcount
     895          return result
     896  
     897      def __pos__(self):
     898          'Adds an empty counter, effectively stripping negative and zero counts'
     899          result = Counter()
     900          for elem, count in self.items():
     901              if count > 0:
     902                  result[elem] = count
     903          return result
     904  
     905      def __neg__(self):
     906          '''Subtracts from an empty counter.  Strips positive and zero counts,
     907          and flips the sign on negative counts.
     908  
     909          '''
     910          result = Counter()
     911          for elem, count in self.items():
     912              if count < 0:
     913                  result[elem] = 0 - count
     914          return result
     915  
     916      def _keep_positive(self):
     917          '''Internal method to strip elements with a negative or zero count'''
     918          nonpositive = [elem for elem, count in self.items() if not count > 0]
     919          for elem in nonpositive:
     920              del self[elem]
     921          return self
     922  
     923      def __iadd__(self, other):
     924          '''Inplace add from another counter, keeping only positive counts.
     925  
     926          >>> c = Counter('abbb')
     927          >>> c += Counter('bcc')
     928          >>> c
     929          Counter({'b': 4, 'c': 2, 'a': 1})
     930  
     931          '''
     932          for elem, count in other.items():
     933              self[elem] += count
     934          return self._keep_positive()
     935  
     936      def __isub__(self, other):
     937          '''Inplace subtract counter, but keep only results with positive counts.
     938  
     939          >>> c = Counter('abbbc')
     940          >>> c -= Counter('bccd')
     941          >>> c
     942          Counter({'b': 2, 'a': 1})
     943  
     944          '''
     945          for elem, count in other.items():
     946              self[elem] -= count
     947          return self._keep_positive()
     948  
     949      def __ior__(self, other):
     950          '''Inplace union is the maximum of value from either counter.
     951  
     952          >>> c = Counter('abbb')
     953          >>> c |= Counter('bcc')
     954          >>> c
     955          Counter({'b': 3, 'c': 2, 'a': 1})
     956  
     957          '''
     958          for elem, other_count in other.items():
     959              count = self[elem]
     960              if other_count > count:
     961                  self[elem] = other_count
     962          return self._keep_positive()
     963  
     964      def __iand__(self, other):
     965          '''Inplace intersection is the minimum of corresponding counts.
     966  
     967          >>> c = Counter('abbb')
     968          >>> c &= Counter('bcc')
     969          >>> c
     970          Counter({'b': 1})
     971  
     972          '''
     973          for elem, count in self.items():
     974              other_count = other[elem]
     975              if other_count < count:
     976                  self[elem] = other_count
     977          return self._keep_positive()
     978  
     979  
     980  ########################################################################
     981  ###  ChainMap
     982  ########################################################################
     983  
     984  class ESC[4;38;5;81mChainMap(ESC[4;38;5;149m_collections_abcESC[4;38;5;149m.ESC[4;38;5;149mMutableMapping):
     985      ''' A ChainMap groups multiple dicts (or other mappings) together
     986      to create a single, updateable view.
     987  
     988      The underlying mappings are stored in a list.  That list is public and can
     989      be accessed or updated using the *maps* attribute.  There is no other
     990      state.
     991  
     992      Lookups search the underlying mappings successively until a key is found.
     993      In contrast, writes, updates, and deletions only operate on the first
     994      mapping.
     995  
     996      '''
     997  
     998      def __init__(self, *maps):
     999          '''Initialize a ChainMap by setting *maps* to the given mappings.
    1000          If no mappings are provided, a single empty dictionary is used.
    1001  
    1002          '''
    1003          self.maps = list(maps) or [{}]          # always at least one map
    1004  
    1005      def __missing__(self, key):
    1006          raise KeyError(key)
    1007  
    1008      def __getitem__(self, key):
    1009          for mapping in self.maps:
    1010              try:
    1011                  return mapping[key]             # can't use 'key in mapping' with defaultdict
    1012              except KeyError:
    1013                  pass
    1014          return self.__missing__(key)            # support subclasses that define __missing__
    1015  
    1016      def get(self, key, default=None):
    1017          return self[key] if key in self else default
    1018  
    1019      def __len__(self):
    1020          return len(set().union(*self.maps))     # reuses stored hash values if possible
    1021  
    1022      def __iter__(self):
    1023          d = {}
    1024          for mapping in map(dict.fromkeys, reversed(self.maps)):
    1025              d |= mapping                        # reuses stored hash values if possible
    1026          return iter(d)
    1027  
    1028      def __contains__(self, key):
    1029          return any(key in m for m in self.maps)
    1030  
    1031      def __bool__(self):
    1032          return any(self.maps)
    1033  
    1034      @_recursive_repr()
    1035      def __repr__(self):
    1036          return f'{self.__class__.__name__}({", ".join(map(repr, self.maps))})'
    1037  
    1038      @classmethod
    1039      def fromkeys(cls, iterable, *args):
    1040          'Create a ChainMap with a single dict created from the iterable.'
    1041          return cls(dict.fromkeys(iterable, *args))
    1042  
    1043      def copy(self):
    1044          'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]'
    1045          return self.__class__(self.maps[0].copy(), *self.maps[1:])
    1046  
    1047      __copy__ = copy
    1048  
    1049      def new_child(self, m=None, **kwargs):      # like Django's Context.push()
    1050          '''New ChainMap with a new map followed by all previous maps.
    1051          If no map is provided, an empty dict is used.
    1052          Keyword arguments update the map or new empty dict.
    1053          '''
    1054          if m is None:
    1055              m = kwargs
    1056          elif kwargs:
    1057              m.update(kwargs)
    1058          return self.__class__(m, *self.maps)
    1059  
    1060      @property
    1061      def parents(self):                          # like Django's Context.pop()
    1062          'New ChainMap from maps[1:].'
    1063          return self.__class__(*self.maps[1:])
    1064  
    1065      def __setitem__(self, key, value):
    1066          self.maps[0][key] = value
    1067  
    1068      def __delitem__(self, key):
    1069          try:
    1070              del self.maps[0][key]
    1071          except KeyError:
    1072              raise KeyError(f'Key not found in the first mapping: {key!r}')
    1073  
    1074      def popitem(self):
    1075          'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.'
    1076          try:
    1077              return self.maps[0].popitem()
    1078          except KeyError:
    1079              raise KeyError('No keys found in the first mapping.')
    1080  
    1081      def pop(self, key, *args):
    1082          'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].'
    1083          try:
    1084              return self.maps[0].pop(key, *args)
    1085          except KeyError:
    1086              raise KeyError(f'Key not found in the first mapping: {key!r}')
    1087  
    1088      def clear(self):
    1089          'Clear maps[0], leaving maps[1:] intact.'
    1090          self.maps[0].clear()
    1091  
    1092      def __ior__(self, other):
    1093          self.maps[0].update(other)
    1094          return self
    1095  
    1096      def __or__(self, other):
    1097          if not isinstance(other, _collections_abc.Mapping):
    1098              return NotImplemented
    1099          m = self.copy()
    1100          m.maps[0].update(other)
    1101          return m
    1102  
    1103      def __ror__(self, other):
    1104          if not isinstance(other, _collections_abc.Mapping):
    1105              return NotImplemented
    1106          m = dict(other)
    1107          for child in reversed(self.maps):
    1108              m.update(child)
    1109          return self.__class__(m)
    1110  
    1111  
    1112  ################################################################################
    1113  ### UserDict
    1114  ################################################################################
    1115  
    1116  class ESC[4;38;5;81mUserDict(ESC[4;38;5;149m_collections_abcESC[4;38;5;149m.ESC[4;38;5;149mMutableMapping):
    1117  
    1118      # Start by filling-out the abstract methods
    1119      def __init__(self, dict=None, /, **kwargs):
    1120          self.data = {}
    1121          if dict is not None:
    1122              self.update(dict)
    1123          if kwargs:
    1124              self.update(kwargs)
    1125  
    1126      def __len__(self):
    1127          return len(self.data)
    1128  
    1129      def __getitem__(self, key):
    1130          if key in self.data:
    1131              return self.data[key]
    1132          if hasattr(self.__class__, "__missing__"):
    1133              return self.__class__.__missing__(self, key)
    1134          raise KeyError(key)
    1135  
    1136      def __setitem__(self, key, item):
    1137          self.data[key] = item
    1138  
    1139      def __delitem__(self, key):
    1140          del self.data[key]
    1141  
    1142      def __iter__(self):
    1143          return iter(self.data)
    1144  
    1145      # Modify __contains__ and get() to work like dict
    1146      # does when __missing__ is present.
    1147      def __contains__(self, key):
    1148          return key in self.data
    1149  
    1150      def get(self, key, default=None):
    1151          if key in self:
    1152              return self[key]
    1153          return default
    1154  
    1155  
    1156      # Now, add the methods in dicts but not in MutableMapping
    1157      def __repr__(self):
    1158          return repr(self.data)
    1159  
    1160      def __or__(self, other):
    1161          if isinstance(other, UserDict):
    1162              return self.__class__(self.data | other.data)
    1163          if isinstance(other, dict):
    1164              return self.__class__(self.data | other)
    1165          return NotImplemented
    1166  
    1167      def __ror__(self, other):
    1168          if isinstance(other, UserDict):
    1169              return self.__class__(other.data | self.data)
    1170          if isinstance(other, dict):
    1171              return self.__class__(other | self.data)
    1172          return NotImplemented
    1173  
    1174      def __ior__(self, other):
    1175          if isinstance(other, UserDict):
    1176              self.data |= other.data
    1177          else:
    1178              self.data |= other
    1179          return self
    1180  
    1181      def __copy__(self):
    1182          inst = self.__class__.__new__(self.__class__)
    1183          inst.__dict__.update(self.__dict__)
    1184          # Create a copy and avoid triggering descriptors
    1185          inst.__dict__["data"] = self.__dict__["data"].copy()
    1186          return inst
    1187  
    1188      def copy(self):
    1189          if self.__class__ is UserDict:
    1190              return UserDict(self.data.copy())
    1191          import copy
    1192          data = self.data
    1193          try:
    1194              self.data = {}
    1195              c = copy.copy(self)
    1196          finally:
    1197              self.data = data
    1198          c.update(self)
    1199          return c
    1200  
    1201      @classmethod
    1202      def fromkeys(cls, iterable, value=None):
    1203          d = cls()
    1204          for key in iterable:
    1205              d[key] = value
    1206          return d
    1207  
    1208  
    1209  ################################################################################
    1210  ### UserList
    1211  ################################################################################
    1212  
    1213  class ESC[4;38;5;81mUserList(ESC[4;38;5;149m_collections_abcESC[4;38;5;149m.ESC[4;38;5;149mMutableSequence):
    1214      """A more or less complete user-defined wrapper around list objects."""
    1215  
    1216      def __init__(self, initlist=None):
    1217          self.data = []
    1218          if initlist is not None:
    1219              # XXX should this accept an arbitrary sequence?
    1220              if type(initlist) == type(self.data):
    1221                  self.data[:] = initlist
    1222              elif isinstance(initlist, UserList):
    1223                  self.data[:] = initlist.data[:]
    1224              else:
    1225                  self.data = list(initlist)
    1226  
    1227      def __repr__(self):
    1228          return repr(self.data)
    1229  
    1230      def __lt__(self, other):
    1231          return self.data < self.__cast(other)
    1232  
    1233      def __le__(self, other):
    1234          return self.data <= self.__cast(other)
    1235  
    1236      def __eq__(self, other):
    1237          return self.data == self.__cast(other)
    1238  
    1239      def __gt__(self, other):
    1240          return self.data > self.__cast(other)
    1241  
    1242      def __ge__(self, other):
    1243          return self.data >= self.__cast(other)
    1244  
    1245      def __cast(self, other):
    1246          return other.data if isinstance(other, UserList) else other
    1247  
    1248      def __contains__(self, item):
    1249          return item in self.data
    1250  
    1251      def __len__(self):
    1252          return len(self.data)
    1253  
    1254      def __getitem__(self, i):
    1255          if isinstance(i, slice):
    1256              return self.__class__(self.data[i])
    1257          else:
    1258              return self.data[i]
    1259  
    1260      def __setitem__(self, i, item):
    1261          self.data[i] = item
    1262  
    1263      def __delitem__(self, i):
    1264          del self.data[i]
    1265  
    1266      def __add__(self, other):
    1267          if isinstance(other, UserList):
    1268              return self.__class__(self.data + other.data)
    1269          elif isinstance(other, type(self.data)):
    1270              return self.__class__(self.data + other)
    1271          return self.__class__(self.data + list(other))
    1272  
    1273      def __radd__(self, other):
    1274          if isinstance(other, UserList):
    1275              return self.__class__(other.data + self.data)
    1276          elif isinstance(other, type(self.data)):
    1277              return self.__class__(other + self.data)
    1278          return self.__class__(list(other) + self.data)
    1279  
    1280      def __iadd__(self, other):
    1281          if isinstance(other, UserList):
    1282              self.data += other.data
    1283          elif isinstance(other, type(self.data)):
    1284              self.data += other
    1285          else:
    1286              self.data += list(other)
    1287          return self
    1288  
    1289      def __mul__(self, n):
    1290          return self.__class__(self.data * n)
    1291  
    1292      __rmul__ = __mul__
    1293  
    1294      def __imul__(self, n):
    1295          self.data *= n
    1296          return self
    1297  
    1298      def __copy__(self):
    1299          inst = self.__class__.__new__(self.__class__)
    1300          inst.__dict__.update(self.__dict__)
    1301          # Create a copy and avoid triggering descriptors
    1302          inst.__dict__["data"] = self.__dict__["data"][:]
    1303          return inst
    1304  
    1305      def append(self, item):
    1306          self.data.append(item)
    1307  
    1308      def insert(self, i, item):
    1309          self.data.insert(i, item)
    1310  
    1311      def pop(self, i=-1):
    1312          return self.data.pop(i)
    1313  
    1314      def remove(self, item):
    1315          self.data.remove(item)
    1316  
    1317      def clear(self):
    1318          self.data.clear()
    1319  
    1320      def copy(self):
    1321          return self.__class__(self)
    1322  
    1323      def count(self, item):
    1324          return self.data.count(item)
    1325  
    1326      def index(self, item, *args):
    1327          return self.data.index(item, *args)
    1328  
    1329      def reverse(self):
    1330          self.data.reverse()
    1331  
    1332      def sort(self, /, *args, **kwds):
    1333          self.data.sort(*args, **kwds)
    1334  
    1335      def extend(self, other):
    1336          if isinstance(other, UserList):
    1337              self.data.extend(other.data)
    1338          else:
    1339              self.data.extend(other)
    1340  
    1341  
    1342  ################################################################################
    1343  ### UserString
    1344  ################################################################################
    1345  
    1346  class ESC[4;38;5;81mUserString(ESC[4;38;5;149m_collections_abcESC[4;38;5;149m.ESC[4;38;5;149mSequence):
    1347  
    1348      def __init__(self, seq):
    1349          if isinstance(seq, str):
    1350              self.data = seq
    1351          elif isinstance(seq, UserString):
    1352              self.data = seq.data[:]
    1353          else:
    1354              self.data = str(seq)
    1355  
    1356      def __str__(self):
    1357          return str(self.data)
    1358  
    1359      def __repr__(self):
    1360          return repr(self.data)
    1361  
    1362      def __int__(self):
    1363          return int(self.data)
    1364  
    1365      def __float__(self):
    1366          return float(self.data)
    1367  
    1368      def __complex__(self):
    1369          return complex(self.data)
    1370  
    1371      def __hash__(self):
    1372          return hash(self.data)
    1373  
    1374      def __getnewargs__(self):
    1375          return (self.data[:],)
    1376  
    1377      def __eq__(self, string):
    1378          if isinstance(string, UserString):
    1379              return self.data == string.data
    1380          return self.data == string
    1381  
    1382      def __lt__(self, string):
    1383          if isinstance(string, UserString):
    1384              return self.data < string.data
    1385          return self.data < string
    1386  
    1387      def __le__(self, string):
    1388          if isinstance(string, UserString):
    1389              return self.data <= string.data
    1390          return self.data <= string
    1391  
    1392      def __gt__(self, string):
    1393          if isinstance(string, UserString):
    1394              return self.data > string.data
    1395          return self.data > string
    1396  
    1397      def __ge__(self, string):
    1398          if isinstance(string, UserString):
    1399              return self.data >= string.data
    1400          return self.data >= string
    1401  
    1402      def __contains__(self, char):
    1403          if isinstance(char, UserString):
    1404              char = char.data
    1405          return char in self.data
    1406  
    1407      def __len__(self):
    1408          return len(self.data)
    1409  
    1410      def __getitem__(self, index):
    1411          return self.__class__(self.data[index])
    1412  
    1413      def __add__(self, other):
    1414          if isinstance(other, UserString):
    1415              return self.__class__(self.data + other.data)
    1416          elif isinstance(other, str):
    1417              return self.__class__(self.data + other)
    1418          return self.__class__(self.data + str(other))
    1419  
    1420      def __radd__(self, other):
    1421          if isinstance(other, str):
    1422              return self.__class__(other + self.data)
    1423          return self.__class__(str(other) + self.data)
    1424  
    1425      def __mul__(self, n):
    1426          return self.__class__(self.data * n)
    1427  
    1428      __rmul__ = __mul__
    1429  
    1430      def __mod__(self, args):
    1431          return self.__class__(self.data % args)
    1432  
    1433      def __rmod__(self, template):
    1434          return self.__class__(str(template) % self)
    1435  
    1436      # the following methods are defined in alphabetical order:
    1437      def capitalize(self):
    1438          return self.__class__(self.data.capitalize())
    1439  
    1440      def casefold(self):
    1441          return self.__class__(self.data.casefold())
    1442  
    1443      def center(self, width, *args):
    1444          return self.__class__(self.data.center(width, *args))
    1445  
    1446      def count(self, sub, start=0, end=_sys.maxsize):
    1447          if isinstance(sub, UserString):
    1448              sub = sub.data
    1449          return self.data.count(sub, start, end)
    1450  
    1451      def removeprefix(self, prefix, /):
    1452          if isinstance(prefix, UserString):
    1453              prefix = prefix.data
    1454          return self.__class__(self.data.removeprefix(prefix))
    1455  
    1456      def removesuffix(self, suffix, /):
    1457          if isinstance(suffix, UserString):
    1458              suffix = suffix.data
    1459          return self.__class__(self.data.removesuffix(suffix))
    1460  
    1461      def encode(self, encoding='utf-8', errors='strict'):
    1462          encoding = 'utf-8' if encoding is None else encoding
    1463          errors = 'strict' if errors is None else errors
    1464          return self.data.encode(encoding, errors)
    1465  
    1466      def endswith(self, suffix, start=0, end=_sys.maxsize):
    1467          return self.data.endswith(suffix, start, end)
    1468  
    1469      def expandtabs(self, tabsize=8):
    1470          return self.__class__(self.data.expandtabs(tabsize))
    1471  
    1472      def find(self, sub, start=0, end=_sys.maxsize):
    1473          if isinstance(sub, UserString):
    1474              sub = sub.data
    1475          return self.data.find(sub, start, end)
    1476  
    1477      def format(self, /, *args, **kwds):
    1478          return self.data.format(*args, **kwds)
    1479  
    1480      def format_map(self, mapping):
    1481          return self.data.format_map(mapping)
    1482  
    1483      def index(self, sub, start=0, end=_sys.maxsize):
    1484          return self.data.index(sub, start, end)
    1485  
    1486      def isalpha(self):
    1487          return self.data.isalpha()
    1488  
    1489      def isalnum(self):
    1490          return self.data.isalnum()
    1491  
    1492      def isascii(self):
    1493          return self.data.isascii()
    1494  
    1495      def isdecimal(self):
    1496          return self.data.isdecimal()
    1497  
    1498      def isdigit(self):
    1499          return self.data.isdigit()
    1500  
    1501      def isidentifier(self):
    1502          return self.data.isidentifier()
    1503  
    1504      def islower(self):
    1505          return self.data.islower()
    1506  
    1507      def isnumeric(self):
    1508          return self.data.isnumeric()
    1509  
    1510      def isprintable(self):
    1511          return self.data.isprintable()
    1512  
    1513      def isspace(self):
    1514          return self.data.isspace()
    1515  
    1516      def istitle(self):
    1517          return self.data.istitle()
    1518  
    1519      def isupper(self):
    1520          return self.data.isupper()
    1521  
    1522      def join(self, seq):
    1523          return self.data.join(seq)
    1524  
    1525      def ljust(self, width, *args):
    1526          return self.__class__(self.data.ljust(width, *args))
    1527  
    1528      def lower(self):
    1529          return self.__class__(self.data.lower())
    1530  
    1531      def lstrip(self, chars=None):
    1532          return self.__class__(self.data.lstrip(chars))
    1533  
    1534      maketrans = str.maketrans
    1535  
    1536      def partition(self, sep):
    1537          return self.data.partition(sep)
    1538  
    1539      def replace(self, old, new, maxsplit=-1):
    1540          if isinstance(old, UserString):
    1541              old = old.data
    1542          if isinstance(new, UserString):
    1543              new = new.data
    1544          return self.__class__(self.data.replace(old, new, maxsplit))
    1545  
    1546      def rfind(self, sub, start=0, end=_sys.maxsize):
    1547          if isinstance(sub, UserString):
    1548              sub = sub.data
    1549          return self.data.rfind(sub, start, end)
    1550  
    1551      def rindex(self, sub, start=0, end=_sys.maxsize):
    1552          return self.data.rindex(sub, start, end)
    1553  
    1554      def rjust(self, width, *args):
    1555          return self.__class__(self.data.rjust(width, *args))
    1556  
    1557      def rpartition(self, sep):
    1558          return self.data.rpartition(sep)
    1559  
    1560      def rstrip(self, chars=None):
    1561          return self.__class__(self.data.rstrip(chars))
    1562  
    1563      def split(self, sep=None, maxsplit=-1):
    1564          return self.data.split(sep, maxsplit)
    1565  
    1566      def rsplit(self, sep=None, maxsplit=-1):
    1567          return self.data.rsplit(sep, maxsplit)
    1568  
    1569      def splitlines(self, keepends=False):
    1570          return self.data.splitlines(keepends)
    1571  
    1572      def startswith(self, prefix, start=0, end=_sys.maxsize):
    1573          return self.data.startswith(prefix, start, end)
    1574  
    1575      def strip(self, chars=None):
    1576          return self.__class__(self.data.strip(chars))
    1577  
    1578      def swapcase(self):
    1579          return self.__class__(self.data.swapcase())
    1580  
    1581      def title(self):
    1582          return self.__class__(self.data.title())
    1583  
    1584      def translate(self, *args):
    1585          return self.__class__(self.data.translate(*args))
    1586  
    1587      def upper(self):
    1588          return self.__class__(self.data.upper())
    1589  
    1590      def zfill(self, width):
    1591          return self.__class__(self.data.zfill(width))