code: def run(self):
      # work out the version
      if self.version is None:
          write(
              "  Getting download page to work out current SQLite version"
          )
          page = self.download(
              "https://sqlite.org/download.html",
              text=True,
              checksum=False,
          )
          match = re.search(
              r"sqlite-amalgamation-3([0-9][0-9])([0-9][0-9])([0-9][0-9])\.zip",
              page,
          )
          if match:
              self.version = "3.%d.%d.%d" % tuple(
                  [int(match.group(n)) for n in range(1, 4)]
              )
              if self.version.endswith(".0"):
                  self.version = self.version[: -len(".0")]
          else:
              write(
                  "Unable to determine current SQLite version.  Use --version=VERSION",
                  sys.stderr,
              )
              write(
                  "to set version - eg setup.py fetch --version=3.6.18",
                  sys.stderr,
              )
              sys.exit(17)
          write("    Version is " + self.version)
      # now get each selected component
      downloaded = 0
  
      if not self.version.startswith("fossil"):
          v = [int(x) for x in self.version.split(".")]
          if len(v) < 4:
              v.append(0)
          self.webversion = "%d%02d%02d%02d" % tuple(v)
  
      ## The amalgamation
      if self.sqlite:
          if self.version.startswith("fossil"):
              write("  Getting code from fossil")
          else:
              write("  Getting the SQLite amalgamation")
  
          if self.version.startswith("fossil"):
              if self.version == "fossil":
                  uuid = "trunk"
              else:
                  showmsg = False
                  if not self.version.startswith("fossil-"):
                      showmsg = True
                  else:
                      uuid = self.version.split("-", 1)[1]
                      if not uuid:
                          showmsg = True
                  if showmsg:
                      write(
                          "Use fossil-HASH to identify a particular commit",
                          sys.stderr,
                      )
                      write("eg  fossil-3a82c8e6", sys.stderr)
                      sys.exit(18)
  
              AURL = (
                  "https://sqlite.org/src/zip/sqlite3.zip?uuid=" + uuid
              )
              checksum = False
          else:
              if sys.platform == "win32":
                  AURL = (
                      "https://sqlite.org/sqlite-amalgamation-%s.zip"
                      % (self.webversion,)
                  )
              else:
                  AURL = (
                      "https://sqlite.org/sqlite-autoconf-%s.tar.gz"
                      % (self.webversion,)
                  )
              checksum = True
  
          AURL = fixup_download_url(AURL)
  
          data = self.download(AURL, checksum=checksum)
  
          if AURL.endswith(".zip"):
              zip = zipfile.ZipFile(data, "r")
              for name in "sqlite3.c", "sqlite3.h", "sqlite3ext.h":
                  write("Extracting", name)
                  f = [n for n in zip.namelist() if n.endswith(name)]
                  if len(f) != 1:
                      raise Exception(
                          "Can't find %s in zip.  Candidates are %s"
                          % (name, f)
                      )
                  # Work around SQLite 3.7.13 bug where a symbol was
                  # declared SQLITE_API and extern
                  data = zip.read(f[0])
                  if name == "sqlite3.c":
                      data = data.decode("utf8")
                      data = data.replace(
                          "SQLITE_API extern", "SQLITE_API"
                      )
                      data = data.encode("utf8")
                  open(name, "wb").write(data)
              zip.close()
          else:
              # we need to run configure to get various -DHAVE_foo flags on non-windows platforms
              # delete existing sqlite3 directory if it exists, but save sqlite3config.h if it exists
              sqlite3config_h = None
              if os.path.exists("sqlite3/sqlite3config.h"):
                  sqlite3config_h = read_whole_file(
                      "sqlite3/sqlite3config.h", "rb"
                  )
              if os.path.exists("sqlite3"):
                  for dirpath, dirnames, filenames in os.walk(
                      "sqlite3", topdown=False
                  ):
                      for file in filenames:
                          os.remove(os.path.join(dirpath, file))
                      for dir in dirnames:
                          os.rmdir(os.path.join(dirpath, dir))
                  os.rmdir("sqlite3")
              if self.version.startswith("fossil"):
                  zip = zipfile.ZipFile(data, "r")
                  for name in zip.namelist():
                      # extract
                      if name.endswith("/"):
                          os.mkdir(name)
                      else:
                          open(name, "wb").write(zip.read(name))
                  zip.close()
              else:
                  # if you get an exception here it is likely that you don't have the python zlib module
                  import zlib
  
                  tar = tarfile.open(
                      "nonexistentname to keep old python happy",
                      "r",
                      data,
                  )
                  configmember = None
                  for member in tar.getmembers():
                      tar.extract(member)
                      # find first file named configure
                      if not configmember and member.name.endswith(
                          "/configure"
                      ):
                          configmember = member
                  tar.close()
                  # the directory name has changed a bit with each release so try to work out what it is
                  if not configmember:
                      write(
                          "Unable to determine directory it extracted to.",
                          dest=sys.stderr,
                      )
                      sys.exit(19)
                  dirname = configmember.name.split("/")[0]
                  os.rename(dirname, "sqlite3")
              os.chdir("sqlite3")
              if self.version.startswith("fossil"):
                  write("    Building amalgamation from fossil")
                  res = os.system(
                      "make TOP=. -f Makefile.linux-gcc sqlite3.c && cp src/sqlite3ext.h ."
                  )
                  defs = []
                  if sqlite3config_h:
                      open("sqlite3config.h", "wb").write(
                          sqlite3config_h
                      )
              else:
                  write(
                      "    Running configure to work out SQLite compilation flags"
                  )
                  res = os.system("./configure >/dev/null")
                  defline = None
                  for line in read_whole_file("Makefile", "rtU").split(
                      "\n"
                  ):
                      if line.startswith("DEFS = "):
                          defline = line
                          break
                  if not defline:
                      write(
                          "Unable to determine compile flags.  Create sqlite3/sqlite3config.h to manually set.",
                          sys.stderr,
                      )
                      sys.exit(18)
                  defs = []
                  for part in shlex.split(defline):
                      if part.startswith("-DHAVE"):
                          part = part[2:]
                          if "=" in part:
                              part = part.split("=", 1)
                          else:
                              part = (part,)
                          defs.append(part)
              if res != 0:
                  raise ValueError("Command execution failed")
              if defs:
                  op = open("sqlite3config.h", "wt")
                  op.write(
                      """
  /* This file was generated by parsing how configure altered the Makefile
     which isn't used when building python extensions.  It is specific to the
     machine and developer components on which it was run. */
     \n"""
                  )
  
                  for define in defs:
                      op.write("#define %s %s\n" % tuple(define))
                  op.close()
              os.chdir("..")
          downloaded += 1
  
      if not downloaded:
          write("You didn't specify any components to fetch.  Use")
          write("   setup.py fetch --help")
          write("for a list and details")
          raise ValueError("No components downloaded")
  
imports: import os
  import sys
  import shlex
  import glob
  import re
  import time
  import zipfile
  import tarfile
  from distutils.command import build_ext, build, sdist
label_desc: Use image node_id 3 for calling the fetch obj's underlying member method code with example usage: obj.run() without return types