docs: def parse_url(url):
      """Parses the supplied Redis URL and returns a dict with the parsed/split data.
  
      For ambiguous URLs like redis://localhost and redis://my_socket_file this function will prioritize network URLs over
      socket URLs. redis://my_socket_file will be interpreted as a network URL, with the Redis server having a hostname of
      'my_socket_file'. Use the file:// or redis+socket:// (Celery compatibility) URL scheme to force socket URL
      interpretations over network URLs.
  
      Positional arguments:
      url -- URL to redis server. Examples are in this file's Redis class docstring under REDIS_URL.
  
      Returns:
      Dictionary with parsed data, compatible with StrictRedis.__init__() keyword arguments.
  
      Raises:
      ValueError -- if the supplies URL was malformed or invalid.
      """
      # Parse URL, make sure string is valid.
      try:
          split = urlsplit(url.rstrip('/'))
      except (AttributeError, TypeError) as e:
          raise ValueError('Malformed URL specified: {0}'.format(e))
      if split.scheme not in ['redis+socket', 'redis', 'file']:
          raise ValueError('Malformed URL specified.')
      scheme = split.scheme
      netloc = split.netloc
      hostname = split.hostname
      path = split.path
      password = split.password
      try:
          port = split.port
      except ValueError:
          port = None  # Stupid urlsplit bug on Windows.
  
      # urlsplit sucks on Windows, work around this.
      if os.name == 'nt' and not path and '\\' in netloc:
          if '@' in netloc:
              position = netloc.find('@') + 1
              path = netloc[position:]
              netloc = netloc[:position]
          else:
              path = netloc
              netloc = ''
  
      # Handle non-socket URLs.
      if scheme == 'redis' and netloc and not netloc.endswith('.') and not netloc.endswith('@'):
          result = dict(host=hostname)
          if password:
              result['password'] = password
          if port:
              result['port'] = port
          if path:
              if not path[1:].isdigit():
                  raise ValueError('Network URL path has non-digit characters: {0}'.format(path[1:]))
              result['db'] = int(path[1:])
          return result
  
      # Handle socket URLs.
      if port:
          raise ValueError('Socket URL looks like non-socket URL.')
      if not password:
          socket_path = '{0}{1}'.format(netloc, path)
      elif netloc.endswith('.'):
          socket_path = '{0}{1}'.format(netloc.split('@')[1], path)
      elif not path:
          socket_path = netloc.split('@')[1]
      else:
          socket_path = path
  
      # Catch bad paths.
      parent_dir = os.path.split(socket_path)[0]
      if parent_dir and not os.path.isdir(parent_dir):
          raise ValueError("Unix socket path's parent not a dir: {0}".format(parent_dir))
  
      # Finish up.
      result = dict(unix_socket_path=socket_path)
      if password:
          result['password'] = password
      return result