docstr: Finalizes options.
docstr_tok: ["Finalizes","options","."]
code: def finalize_options(self):  # noqa: C901
      """Finalizes options."""
      # This method (and its helpers, like 'finalize_unix()',
      # 'finalize_other()', and 'select_scheme()') is where the default
      # installation directories for modules, extension modules, and
      # anything else we care to install from a Python module
      # distribution.  Thus, this code makes a pretty important policy
      # statement about how third-party stuff is added to a Python
      # installation!  Note that the actual work of installation is done
      # by the relatively simple 'install_*' commands; they just take
      # their orders from the installation directory options determined
      # here.
  
      # Check for errors/inconsistencies in the options; first, stuff
      # that's wrong on any platform.
  
      if (self.prefix or self.exec_prefix or self.home) and (
          self.install_base or self.install_platbase
      ):
          raise DistutilsOptionError(
              "must supply either prefix/exec-prefix/home or "
              + "install-base/install-platbase -- not both"
          )
  
      if self.home and (self.prefix or self.exec_prefix):
          raise DistutilsOptionError(
              "must supply either home or prefix/exec-prefix -- not both"
          )
  
      if self.user and (
          self.prefix
          or self.exec_prefix
          or self.home
          or self.install_base
          or self.install_platbase
      ):
          raise DistutilsOptionError(
              "can't combine user with prefix, "
              "exec_prefix/home, or install_(plat)base"
          )
  
      # Next, stuff that's wrong (or dubious) only on certain platforms.
      if os.name != "posix":
          if self.exec_prefix:
              self.warn("exec-prefix option ignored on this platform")
              self.exec_prefix = None
  
      # Now the interesting logic -- so interesting that we farm it out
      # to other methods.  The goal of these methods is to set the final
      # values for the install_{lib,scripts,data,...}  options, using as
      # input a heady brew of prefix, exec_prefix, home, install_base,
      # install_platbase, user-supplied versions of
      # install_{purelib,platlib,lib,scripts,data,...}, and the
      # install schemes.  Phew!
  
      self.dump_dirs("pre-finalize_{unix,other}")
  
      if os.name == "posix":
          self.finalize_unix()
      else:
          self.finalize_other()
  
      self.dump_dirs("post-finalize_{unix,other}()")
  
      # Expand configuration variables, tilde, etc. in self.install_base
      # and self.install_platbase -- that way, we can use $base or
      # $platbase in the other installation directories and not worry
      # about needing recursive variable expansion (shudder).
  
      py_version = sys.version.split()[0]
      (prefix, exec_prefix) = get_config_vars("prefix", "exec_prefix")
      try:
          abiflags = sys.abiflags
      except AttributeError:
          # sys.abiflags may not be defined on all platforms.
          abiflags = ""
      local_vars = {
          "dist_name": self.distribution.get_name(),
          "dist_version": self.distribution.get_version(),
          "dist_fullname": self.distribution.get_fullname(),
          "py_version": py_version,
          "py_version_short": "%d.%d" % sys.version_info[:2],
          "py_version_nodot": "%d%d" % sys.version_info[:2],
          "sys_prefix": prefix,
          "prefix": prefix,
          "sys_exec_prefix": exec_prefix,
          "exec_prefix": exec_prefix,
          "abiflags": abiflags,
          "platlibdir": getattr(sys, "platlibdir", "lib"),
          "implementation_lower": _get_implementation().lower(),
          "implementation": _get_implementation(),
      }
  
      # vars for compatibility on older Pythons
      compat_vars = dict(
          # Python 3.9 and earlier
          py_version_nodot_plat=getattr(sys, "winver", "").replace(
              ".", ""
          ),
      )
  
      if HAS_USER_SITE:
          local_vars["userbase"] = self.install_userbase
          local_vars["usersite"] = self.install_usersite
  
      self.config_vars = _collections.DictStack(
          [
              fw.vars(),
              compat_vars,
              sysconfig.get_config_vars(),
              local_vars,
          ]
      )
  
      self.expand_basedirs()
  
      self.dump_dirs("post-expand_basedirs()")
  
      # Now define config vars for the base directories so we can expand
      # everything else.
      local_vars["base"] = self.install_base
      local_vars["platbase"] = self.install_platbase
  
      if DEBUG:
          from pprint import pprint
  
          print("config vars:")
          pprint(dict(self.config_vars))
  
      # Expand "~" and configuration variables in the installation
      # directories.
      self.expand_dirs()
  
      self.dump_dirs("post-expand_dirs()")
  
      # Create directories in the home dir:
      if self.user:
          self.create_home_path()
  
      # Pick the actual directory to install all modules to: either
      # install_purelib or install_platlib, depending on whether this
      # module distribution is pure or not.  Of course, if the user
      # already specified install_lib, use their selection.
      if self.install_lib is None:
          if (
              self.distribution.has_ext_modules()
          ):  # has extensions: non-pure
              self.install_lib = self.install_platlib
          else:
              self.install_lib = self.install_purelib
  
      # Convert directories from Unix /-separated syntax to the local
      # convention.
      self.convert_paths(
          "lib",
          "purelib",
          "platlib",
          "scripts",
          "data",
          "headers",
          "userbase",
          "usersite",
      )
  
      # Deprecated
      # Well, we're not actually fully completely finalized yet: we still
      # have to deal with 'extra_path', which is the hack for allowing
      # non-packagized module distributions (hello, Numerical Python!) to
      # get their own directories.
      self.handle_extra_path()
      self.install_libbase = self.install_lib  # needed for .pth file
      self.install_lib = os.path.join(self.install_lib, self.extra_dirs)
  
      # If a new root directory was supplied, make all the installation
      # dirs relative to it.
      if self.root is not None:
          self.change_roots(
              "libbase",
              "lib",
              "purelib",
              "platlib",
              "scripts",
              "data",
              "headers",
          )
  
      self.dump_dirs("after prepending root")
  
      # Find out the build directories, ie. where to install from.
      self.set_undefined_options(
          "build",
          ("build_base", "build_base"),
          ("build_lib", "build_lib"),
      )
  
imports: import sys
  import os
  import contextlib
  import sysconfig
  import itertools
  from distutils._log import log
  from ..core import Command
  from ..debug import DEBUG
  from ..sysconfig import get_config_vars
  from ..file_util import write_file
  from ..util import convert_path, subst_vars, change_root
  from ..util import get_platform
  from ..errors import DistutilsOptionError, DistutilsPlatformError
  from .None import _framework_compat
  from ..None import _collections
  from site import USER_BASE
  from site import USER_SITE
label_desc: Use image node_id 2 for calling the install obj's underlying member method code with example usage: obj.finalize_options() without return types