docs: def factory(
              cls, file_id=None, path=None, url=None, blob=None, mime=None,
              prefer_local_download=True, prefer_str=False, create_instance=True
      ):
          """
          Creates a new InputFile subclass instance fitting the given parameters.
  
          :param prefer_local_download: If `True`, we download the file and send it to telegram. This is the default.
                                        If `False`, we send Telegram just the URL, and they'll try to download it.
          :type  prefer_local_download: bool
  
          :param prefer_str: Return just the `str` instead of a `InputFileUseFileID` or `InputFileUseUrl` object.
          :type  prefer_str: bool
  
          :param create_instance: If we should return a instance ready to use (default),
                                  or the building parts being a tuple of `(class, args_tuple, kwargs_dict)`.
                                  Setting this to `False` is probably only ever required for internal usage
                                  by the :class:`InputFile` constructor which uses this very factory.
          :type  create_instance: bool
  
  
          :returns: if `create_instance=True` it returns a instance of some InputFile subclass or a string,
                    if `create_instance=False` it returns a tuple of the needed class, args and kwargs needed
                    to create a instance.
          :rtype: InputFile|InputFileFromBlob|InputFileFromDisk|InputFileFromURL|str|tuple
          """
          if create_instance:
              clazz, args, kwargs = cls.factory(
                  file_id=file_id,
                  path=path,
                  url=url,
                  blob=blob,
                  mime=mime,
                  create_instance=False,
              )
              return clazz(*args, **kwargs)
          if file_id:
              if prefer_str:
                  assert_type_or_raise(file_id, str, parameter_name='file_id')
                  return str, (file_id,), dict()
              # end if
              return InputFileUseFileID, (file_id,), dict()
          if blob:
              name = "file"
              suffix = ".blob"
              if path:
                  name = os_path.basename(os_path.normpath(path))  # http://stackoverflow.com/a/3925147/3423324#last-part
                  name, suffix = os_path.splitext(name)  # http://stackoverflow.com/a/541394/3423324#extension
              elif url:
                  # http://stackoverflow.com/a/18727481/3423324#how-to-extract-a-filename-from-a-url
                  url = urlparse(url)
                  name = os_path.basename(url.path)
                  name, suffix = os_path.splitext(name)
              # end if
              if mime:
                  import mimetypes
                  suffix = mimetypes.guess_extension(mime)
                  suffix = '.jpg' if suffix == '.jpe' else suffix  # .jpe -> .jpg
              # end if
              if not suffix or not suffix.strip().lstrip("."):
                  logger.debug("suffix was empty. Using '.blob'")
                  suffix = ".blob"
              # end if
              name = "{filename}{suffix}".format(filename=name, suffix=suffix)
              return InputFileFromBlob, (blob,), dict(name=name, mime=mime)
          if path:
              return InputFileFromDisk, (path,), dict(mime=mime)
          if url:
              if prefer_local_download:
                  return InputFileFromURL, (url,), dict(mime=mime)
              # end if
              # else -> so we wanna let telegram handle it
              if prefer_str:
                  assert_type_or_raise(url, str, parameter_name='url')
                  return str, (url,), dict()
              # end if
              return InputFileUseUrl, (url,), dict()
  
          # end if
          raise ValueError('Could not find a matching subclass. You might need to do it manually instead.')