docs: def natsort_key(val, key, string_func, bytes_func, num_func):
      """
      Key to sort strings and numbers naturally.
  
      It works by splitting the string into components of strings and numbers,
      and then converting the numbers into actual ints or floats.
  
      Parameters
      ----------
      val : str | unicode | bytes | int | float | iterable
      key : callable | None
          A key to apply to the *val* before any other operations are performed.
      string_func : callable
          If *val* (or the output of *key* if given) is of type *str*, this
          function will be applied to it. The function must return
          a tuple.
      bytes_func : callable
          If *val* (or the output of *key* if given) is of type *bytes*, this
          function will be applied to it. The function must return
          a tuple.
      num_func : callable
          If *val* (or the output of *key* if given) is not of type *bytes*,
          *str*, nor is iterable, this function will be applied to it.
          The function must return a tuple.
  
      Returns
      -------
      out : tuple
          The string split into its string and numeric components.
          It *always* starts with a string, and then alternates
          between numbers and strings (unless it was applied
          recursively, in which case it will return tuples of tuples,
          but the lowest-level tuples will then *always* start with
          a string etc.).
  
      See Also
      --------
      parse_string_factory
      parse_bytes_factory
      parse_number_factory
  
      """
  
      # Apply key if needed
      if key is not None:
          val = key(val)
  
      # Assume the input are strings, which is the most common case
      try:
          return string_func(val)
      except (TypeError, AttributeError):
  
          # If bytes type, use the bytes_func
          if type(val) in (bytes,):
              return bytes_func(val)
  
          # Otherwise, assume it is an iterable that must be parsed recursively.
          # Do not apply the key recursively.
          try:
              return tuple(
                  natsort_key(x, None, string_func, bytes_func, num_func) for x in val
              )
  
          # If that failed, it must be a number.
          except TypeError:
              return num_func(val)