code: def setup(**attrs):  # noqa: C901
      """The gateway to the Distutils: do everything your setup script needs
      to do, in a highly flexible and user-driven way.  Briefly: create a
      Distribution instance; find and parse config files; parse the command
      line; run each Distutils command found there, customized by the options
      supplied to 'setup()' (as keyword arguments), in config files, and on
      the command line.
  
      The Distribution instance might be an instance of a class supplied via
      the 'distclass' keyword argument to 'setup'; if no such class is
      supplied, then the Distribution class (in dist.py) is instantiated.
      All other arguments to 'setup' (except for 'cmdclass') are used to set
      attributes of the Distribution instance.
  
      The 'cmdclass' argument, if supplied, is a dictionary mapping command
      names to command classes.  Each command encountered on the command line
      will be turned into a command class, which is in turn instantiated; any
      class found in 'cmdclass' is used in place of the default, which is
      (for command 'foo_bar') class 'foo_bar' in module
      'distutils.command.foo_bar'.  The command class must provide a
      'user_options' attribute which is a list of option specifiers for
      'distutils.fancy_getopt'.  Any command-line options between the current
      and the next command are used to set attributes of the current command
      object.
  
      When the entire command-line has been successfully parsed, calls the
      'run()' method on each command object in turn.  This method will be
      driven entirely by the Distribution object (which each command object
      has a reference to, thanks to its constructor), and the
      command-specific options that became attributes of each command
      object.
      """
  
      global _setup_stop_after, _setup_distribution
  
      # Determine the distribution class -- either caller-supplied or
      # our Distribution (see below).
      klass = attrs.get("distclass")
      if klass:
          attrs.pop("distclass")
      else:
          klass = Distribution
  
      if "script_name" not in attrs:
          attrs["script_name"] = os.path.basename(sys.argv[0])
      if "script_args" not in attrs:
          attrs["script_args"] = sys.argv[1:]
  
      # Create the Distribution instance, using the remaining arguments
      # (ie. everything except distclass) to initialize it
      try:
          _setup_distribution = dist = klass(attrs)
      except DistutilsSetupError as msg:
          if "name" not in attrs:
              raise SystemExit("error in setup command: %s" % msg)
          else:
              raise SystemExit(
                  "error in {} setup command: {}".format(
                      attrs["name"], msg
                  )
              )
  
      if _setup_stop_after == "init":
          return dist
  
      # Find and parse the config file(s): they will override options from
      # the setup script, but be overridden by the command line.
      dist.parse_config_files()
  
      if DEBUG:
          print("options (after parsing config files):")
          dist.dump_option_dicts()
  
      if _setup_stop_after == "config":
          return dist
  
      # Parse the command line and override config files; any
      # command-line errors are the end user's fault, so turn them into
      # SystemExit to suppress tracebacks.
      try:
          ok = dist.parse_command_line()
      except DistutilsArgError as msg:
          raise SystemExit(
              gen_usage(dist.script_name) + "\nerror: %s" % msg
          )
  
      if DEBUG:
          print("options (after parsing command line):")
          dist.dump_option_dicts()
  
      if _setup_stop_after == "commandline":
          return dist
  
      # And finally, run all the commands found on the command line.
      if ok:
          return run_commands(dist)
  
      return dist
  
file_path: catboost/contrib/python/setuptools/py3/setuptools/_distutils/core.py
imports: import os
  import sys
  import tokenize
  from .debug import DEBUG
  from .errors import DistutilsSetupError, DistutilsError, CCompilerError, DistutilsArgError
  from .dist import Distribution
  from .cmd import Command
  from .config import PyPIRCCommand
  from .extension import Extension
label_desc: Use image node_id 2 for calling a global function with example usage: setup() and returns: dist, dist, dist, dist, run_commands