class_docstr: ImageResource handling utility.
  
  Represents a request for reading or saving an image resource. This
  object wraps information to that request and acts as an interface
  for the plugins to several resources; it allows the user to read
  from filenames, files, http, zipfiles, raw bytes, etc., but offer
  a simple interface to the plugins via ``get_file()`` and
  ``get_local_filename()``.
  
  For each read/write operation a single Request instance is used and passed
  to the can_read/can_write method of a format, and subsequently to
  the Reader/Writer class. This allows rudimentary passing of
  information between different formats and between a format and
  associated reader/writer.
  
  Parameters
  ----------
  uri : {str, bytes, file}
      The resource to load the image from.
  mode : str
      The first character is "r" or "w", indicating a read or write
      request. The second character is used to indicate the kind of data:
      "i" for an image, "I" for multiple images, "v" for a volume,
      "V" for multiple volumes, "?" for don't care.
class_docstr_tok: ["ImageResource","handling","utility",".","Represents","a","request","for","reading","or","saving","an","image","resource",".","This","object","wraps","information","to","that","request","and","acts","as","an","interface","for","the","plugins","to","several","resources",";","it","allows","the","user","to","read","from","filenames",",","files",",","http",",","zipfiles",",","raw","bytes",",","etc.",",","but","offer","a","simple","interface","to","the","plugins","via","``","get_file","(",")","``","and","``","get_local_filename","(",")","``",".","For","each","read\/write","operation","a","single","Request","instance","is","used","and","passed","to","the","can_read\/can_write","method","of","a","format",",","and","subsequently","to","the","Reader\/Writer","class",".","This","allows","rudimentary","passing","of","information","between","different","formats","and","between","a","format","and","associated","reader\/writer",".","Parameters","--","--","--","--","--","uri",":","{","str",",","bytes",",","file","}","The","resource","to","load","the","image","from",".","mode",":","str","The","first","character","is","``","r","''","or","``","w","''",",","indicating","a","read","or","write","request",".","The","second","character","is","used","to","indicate","the","kind","of","data",":","``","i","''","for","an","image",",","``","I","''","for","multiple","images",",","``","v","''","for","a","volume",",","``","V","''","for","multiple","volumes",",","``","?","''","for","do","n't","care","."]
docstr: Try to figure our what we were given
docstr_tok: ["Try","to","figure","our","what","we","were","given"]
code: def _parse_uri(self, uri):
      """Try to figure our what we were given"""
      is_read_request = self.mode.io_mode is IOMode.read
      is_write_request = self.mode.io_mode is IOMode.write
  
      if isinstance(uri, str):
          # Explicit
          if uri.startswith("imageio:"):
              if is_write_request:
                  raise RuntimeError(
                      "Cannot write to the standard images."
                  )
              fn = uri.split(":", 1)[-1].lower()
              fn, _, zip_part = fn.partition(".zip/")
              if zip_part:
                  fn += ".zip"
              if fn not in EXAMPLE_IMAGES:
                  raise ValueError("Unknown standard image %r." % fn)
              self._uri_type = URI_FILENAME
              self._filename = get_remote_file(
                  "images/" + fn, auto=True
              )
              if zip_part:
                  self._filename += "/" + zip_part
          elif uri.startswith("http://") or uri.startswith("https://"):
              self._uri_type = URI_HTTP
              self._filename = uri
          elif uri.startswith("ftp://") or uri.startswith("ftps://"):
              self._uri_type = URI_FTP
              self._filename = uri
          elif uri.startswith("file://"):
              self._uri_type = URI_FILENAME
              self._filename = uri[7:]
          elif uri.startswith(SPECIAL_READ_URIS) and is_read_request:
              self._uri_type = URI_BYTES
              self._filename = uri
          elif uri.startswith(RETURN_BYTES) and is_write_request:
              self._uri_type = URI_BYTES
              self._filename = uri
          else:
              self._uri_type = URI_FILENAME
              self._filename = uri
  
      elif isinstance(uri, memoryview) and is_read_request:
          self._uri_type = URI_BYTES
          self._filename = "<bytes>"
          self._bytes = uri.tobytes()
      elif isinstance(uri, bytes) and is_read_request:
          self._uri_type = URI_BYTES
          self._filename = "<bytes>"
          self._bytes = uri
      elif isinstance(uri, Path):
          self._uri_type = URI_FILENAME
          self._filename = str(uri)
      # Files
      elif is_read_request:
          if hasattr(uri, "read") and hasattr(uri, "close"):
              self._uri_type = URI_FILE
              self._filename = "<file>"
              self._file = uri  # Data must be read from here
      elif is_write_request:
          if hasattr(uri, "write") and hasattr(uri, "close"):
              self._uri_type = URI_FILE
              self._filename = "<file>"
              self._file = uri  # Data must be written here
  
      # Expand user dir
      if self._uri_type == URI_FILENAME and self._filename.startswith(
          "~"
      ):
          self._filename = os.path.expanduser(self._filename)
  
      # Check if a zipfile
      if self._uri_type == URI_FILENAME:
          # Search for zip extension followed by a path separator
          for needle in [".zip/", ".zip\\"]:
              zip_i = self._filename.lower().find(needle)
              if zip_i > 0:
                  zip_i += 4
                  zip_path = self._filename[:zip_i]
                  if os.path.isdir(zip_path):
                      pass  # is an existing dir (see #548)
                  elif is_write_request or os.path.isfile(zip_path):
                      self._uri_type = URI_ZIPPED
                      self._filename_zip = (
                          zip_path,
                          self._filename[zip_i:].lstrip("/\\"),
                      )
                      break
  
      # Check if we could read it
      if self._uri_type is None:
          uri_r = repr(uri)
          if len(uri_r) > 60:
              uri_r = uri_r[:57] + "..."
          raise IOError("Cannot understand given URI: %s." % uri_r)
  
      # Check if this is supported
      noWriting = [URI_HTTP, URI_FTP]
      if is_write_request and self._uri_type in noWriting:
          raise IOError("imageio does not support writing to http/ftp.")
  
      # Deprecated way to load standard images, give a sensible error message
      if is_read_request and self._uri_type in [
          URI_FILENAME,
          URI_ZIPPED,
      ]:
          fn = self._filename
          if self._filename_zip:
              fn = self._filename_zip[0]
          if (not os.path.exists(fn)) and (fn in EXAMPLE_IMAGES):
              raise IOError(
                  "No such file: %r. This file looks like one of "
                  "the standard images, but from imageio 2.1, "
                  "standard images have to be specified using "
                  '"imageio:%s".' % (fn, fn)
              )
  
      # Make filename absolute
      if self._uri_type in [URI_FILENAME, URI_ZIPPED]:
          if self._filename_zip:
              self._filename_zip = (
                  os.path.abspath(self._filename_zip[0]),
                  self._filename_zip[1],
              )
          else:
              self._filename = os.path.abspath(self._filename)
  
      # Check whether file name is valid
      if self._uri_type in [URI_FILENAME, URI_ZIPPED]:
          fn = self._filename
          if self._filename_zip:
              fn = self._filename_zip[0]
          if is_read_request:
              # Reading: check that the file exists (but is allowed a dir)
              if not os.path.exists(fn):
                  raise FileNotFoundError("No such file: '%s'" % fn)
          else:
              # Writing: check that the directory to write to does exist
              dn = os.path.dirname(fn)
              if not os.path.exists(dn):
                  raise FileNotFoundError(
                      "The directory %r does not exist" % dn
                  )
  
imports: import os
  from io import BytesIO
  import zipfile
  import tempfile
  import shutil
  import enum
  import warnings
  from ..core import urlopen, get_remote_file
  from pathlib import Path
  from urllib.parse import urlparse
  from typing import Optional
label_desc: Use image node_id 2 for calling the Request obj's underlying member method code with example usage: obj._parse_uri(uri) without return types