Home | History | Annotate | Download | only in command
      1 """distutils.command.install
      2 
      3 Implements the Distutils 'install' command."""
      4 
      5 import sys
      6 import os
      7 
      8 from distutils import log
      9 from distutils.core import Command
     10 from distutils.debug import DEBUG
     11 from distutils.sysconfig import get_config_vars
     12 from distutils.errors import DistutilsPlatformError
     13 from distutils.file_util import write_file
     14 from distutils.util import convert_path, subst_vars, change_root
     15 from distutils.util import get_platform
     16 from distutils.errors import DistutilsOptionError
     17 
     18 from site import USER_BASE
     19 from site import USER_SITE
     20 HAS_USER_SITE = True
     21 
     22 WINDOWS_SCHEME = {
     23     'purelib': '$base/Lib/site-packages',
     24     'platlib': '$base/Lib/site-packages',
     25     'headers': '$base/Include/$dist_name',
     26     'scripts': '$base/Scripts',
     27     'data'   : '$base',
     28 }
     29 
     30 INSTALL_SCHEMES = {
     31     'unix_prefix': {
     32         'purelib': '$base/lib/python$py_version_short/site-packages',
     33         'platlib': '$platbase/lib/python$py_version_short/site-packages',
     34         'headers': '$base/include/python$py_version_short$abiflags/$dist_name',
     35         'scripts': '$base/bin',
     36         'data'   : '$base',
     37         },
     38     'unix_home': {
     39         'purelib': '$base/lib/python',
     40         'platlib': '$base/lib/python',
     41         'headers': '$base/include/python/$dist_name',
     42         'scripts': '$base/bin',
     43         'data'   : '$base',
     44         },
     45     'nt': WINDOWS_SCHEME,
     46     }
     47 
     48 # user site schemes
     49 if HAS_USER_SITE:
     50     INSTALL_SCHEMES['nt_user'] = {
     51         'purelib': '$usersite',
     52         'platlib': '$usersite',
     53         'headers': '$userbase/Python$py_version_nodot/Include/$dist_name',
     54         'scripts': '$userbase/Python$py_version_nodot/Scripts',
     55         'data'   : '$userbase',
     56         }
     57 
     58     INSTALL_SCHEMES['unix_user'] = {
     59         'purelib': '$usersite',
     60         'platlib': '$usersite',
     61         'headers':
     62             '$userbase/include/python$py_version_short$abiflags/$dist_name',
     63         'scripts': '$userbase/bin',
     64         'data'   : '$userbase',
     65         }
     66 
     67 # The keys to an installation scheme; if any new types of files are to be
     68 # installed, be sure to add an entry to every installation scheme above,
     69 # and to SCHEME_KEYS here.
     70 SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data')
     71 
     72 
     73 class install(Command):
     74 
     75     description = "install everything from build directory"
     76 
     77     user_options = [
     78         # Select installation scheme and set base director(y|ies)
     79         ('prefix=', None,
     80          "installation prefix"),
     81         ('exec-prefix=', None,
     82          "(Unix only) prefix for platform-specific files"),
     83         ('home=', None,
     84          "(Unix only) home directory to install under"),
     85 
     86         # Or, just set the base director(y|ies)
     87         ('install-base=', None,
     88          "base installation directory (instead of --prefix or --home)"),
     89         ('install-platbase=', None,
     90          "base installation directory for platform-specific files " +
     91          "(instead of --exec-prefix or --home)"),
     92         ('root=', None,
     93          "install everything relative to this alternate root directory"),
     94 
     95         # Or, explicitly set the installation scheme
     96         ('install-purelib=', None,
     97          "installation directory for pure Python module distributions"),
     98         ('install-platlib=', None,
     99          "installation directory for non-pure module distributions"),
    100         ('install-lib=', None,
    101          "installation directory for all module distributions " +
    102          "(overrides --install-purelib and --install-platlib)"),
    103 
    104         ('install-headers=', None,
    105          "installation directory for C/C++ headers"),
    106         ('install-scripts=', None,
    107          "installation directory for Python scripts"),
    108         ('install-data=', None,
    109          "installation directory for data files"),
    110 
    111         # Byte-compilation options -- see install_lib.py for details, as
    112         # these are duplicated from there (but only install_lib does
    113         # anything with them).
    114         ('compile', 'c', "compile .py to .pyc [default]"),
    115         ('no-compile', None, "don't compile .py files"),
    116         ('optimize=', 'O',
    117          "also compile with optimization: -O1 for \"python -O\", "
    118          "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
    119 
    120         # Miscellaneous control options
    121         ('force', 'f',
    122          "force installation (overwrite any existing files)"),
    123         ('skip-build', None,
    124          "skip rebuilding everything (for testing/debugging)"),
    125 
    126         # Where to install documentation (eventually!)
    127         #('doc-format=', None, "format of documentation to generate"),
    128         #('install-man=', None, "directory for Unix man pages"),
    129         #('install-html=', None, "directory for HTML documentation"),
    130         #('install-info=', None, "directory for GNU info files"),
    131 
    132         ('record=', None,
    133          "filename in which to record list of installed files"),
    134         ]
    135 
    136     boolean_options = ['compile', 'force', 'skip-build']
    137 
    138     if HAS_USER_SITE:
    139         user_options.append(('user', None,
    140                              "install in user site-package '%s'" % USER_SITE))
    141         boolean_options.append('user')
    142 
    143     negative_opt = {'no-compile' : 'compile'}
    144 
    145 
    146     def initialize_options(self):
    147         """Initializes options."""
    148         # High-level options: these select both an installation base
    149         # and scheme.
    150         self.prefix = None
    151         self.exec_prefix = None
    152         self.home = None
    153         self.user = 0
    154 
    155         # These select only the installation base; it's up to the user to
    156         # specify the installation scheme (currently, that means supplying
    157         # the --install-{platlib,purelib,scripts,data} options).
    158         self.install_base = None
    159         self.install_platbase = None
    160         self.root = None
    161 
    162         # These options are the actual installation directories; if not
    163         # supplied by the user, they are filled in using the installation
    164         # scheme implied by prefix/exec-prefix/home and the contents of
    165         # that installation scheme.
    166         self.install_purelib = None     # for pure module distributions
    167         self.install_platlib = None     # non-pure (dists w/ extensions)
    168         self.install_headers = None     # for C/C++ headers
    169         self.install_lib = None         # set to either purelib or platlib
    170         self.install_scripts = None
    171         self.install_data = None
    172         self.install_userbase = USER_BASE
    173         self.install_usersite = USER_SITE
    174 
    175         self.compile = None
    176         self.optimize = None
    177 
    178         # Deprecated
    179         # These two are for putting non-packagized distributions into their
    180         # own directory and creating a .pth file if it makes sense.
    181         # 'extra_path' comes from the setup file; 'install_path_file' can
    182         # be turned off if it makes no sense to install a .pth file.  (But
    183         # better to install it uselessly than to guess wrong and not
    184         # install it when it's necessary and would be used!)  Currently,
    185         # 'install_path_file' is always true unless some outsider meddles
    186         # with it.
    187         self.extra_path = None
    188         self.install_path_file = 1
    189 
    190         # 'force' forces installation, even if target files are not
    191         # out-of-date.  'skip_build' skips running the "build" command,
    192         # handy if you know it's not necessary.  'warn_dir' (which is *not*
    193         # a user option, it's just there so the bdist_* commands can turn
    194         # it off) determines whether we warn about installing to a
    195         # directory not in sys.path.
    196         self.force = 0
    197         self.skip_build = 0
    198         self.warn_dir = 1
    199 
    200         # These are only here as a conduit from the 'build' command to the
    201         # 'install_*' commands that do the real work.  ('build_base' isn't
    202         # actually used anywhere, but it might be useful in future.)  They
    203         # are not user options, because if the user told the install
    204         # command where the build directory is, that wouldn't affect the
    205         # build command.
    206         self.build_base = None
    207         self.build_lib = None
    208 
    209         # Not defined yet because we don't know anything about
    210         # documentation yet.
    211         #self.install_man = None
    212         #self.install_html = None
    213         #self.install_info = None
    214 
    215         self.record = None
    216 
    217 
    218     # -- Option finalizing methods -------------------------------------
    219     # (This is rather more involved than for most commands,
    220     # because this is where the policy for installing third-
    221     # party Python modules on various platforms given a wide
    222     # array of user input is decided.  Yes, it's quite complex!)
    223 
    224     def finalize_options(self):
    225         """Finalizes options."""
    226         # This method (and its pliant slaves, like 'finalize_unix()',
    227         # 'finalize_other()', and 'select_scheme()') is where the default
    228         # installation directories for modules, extension modules, and
    229         # anything else we care to install from a Python module
    230         # distribution.  Thus, this code makes a pretty important policy
    231         # statement about how third-party stuff is added to a Python
    232         # installation!  Note that the actual work of installation is done
    233         # by the relatively simple 'install_*' commands; they just take
    234         # their orders from the installation directory options determined
    235         # here.
    236 
    237         # Check for errors/inconsistencies in the options; first, stuff
    238         # that's wrong on any platform.
    239 
    240         if ((self.prefix or self.exec_prefix or self.home) and
    241             (self.install_base or self.install_platbase)):
    242             raise DistutilsOptionError(
    243                    "must supply either prefix/exec-prefix/home or " +
    244                    "install-base/install-platbase -- not both")
    245 
    246         if self.home and (self.prefix or self.exec_prefix):
    247             raise DistutilsOptionError(
    248                   "must supply either home or prefix/exec-prefix -- not both")
    249 
    250         if self.user and (self.prefix or self.exec_prefix or self.home or
    251                 self.install_base or self.install_platbase):
    252             raise DistutilsOptionError("can't combine user with prefix, "
    253                                        "exec_prefix/home, or install_(plat)base")
    254 
    255         # Next, stuff that's wrong (or dubious) only on certain platforms.
    256         if os.name != "posix":
    257             if self.exec_prefix:
    258                 self.warn("exec-prefix option ignored on this platform")
    259                 self.exec_prefix = None
    260 
    261         # Now the interesting logic -- so interesting that we farm it out
    262         # to other methods.  The goal of these methods is to set the final
    263         # values for the install_{lib,scripts,data,...}  options, using as
    264         # input a heady brew of prefix, exec_prefix, home, install_base,
    265         # install_platbase, user-supplied versions of
    266         # install_{purelib,platlib,lib,scripts,data,...}, and the
    267         # INSTALL_SCHEME dictionary above.  Phew!
    268 
    269         self.dump_dirs("pre-finalize_{unix,other}")
    270 
    271         if os.name == 'posix':
    272             self.finalize_unix()
    273         else:
    274             self.finalize_other()
    275 
    276         self.dump_dirs("post-finalize_{unix,other}()")
    277 
    278         # Expand configuration variables, tilde, etc. in self.install_base
    279         # and self.install_platbase -- that way, we can use $base or
    280         # $platbase in the other installation directories and not worry
    281         # about needing recursive variable expansion (shudder).
    282 
    283         py_version = sys.version.split()[0]
    284         (prefix, exec_prefix) = get_config_vars('prefix', 'exec_prefix')
    285         try:
    286             abiflags = sys.abiflags
    287         except AttributeError:
    288             # sys.abiflags may not be defined on all platforms.
    289             abiflags = ''
    290         self.config_vars = {'dist_name': self.distribution.get_name(),
    291                             'dist_version': self.distribution.get_version(),
    292                             'dist_fullname': self.distribution.get_fullname(),
    293                             'py_version': py_version,
    294                             'py_version_short': '%d.%d' % sys.version_info[:2],
    295                             'py_version_nodot': '%d%d' % sys.version_info[:2],
    296                             'sys_prefix': prefix,
    297                             'prefix': prefix,
    298                             'sys_exec_prefix': exec_prefix,
    299                             'exec_prefix': exec_prefix,
    300                             'abiflags': abiflags,
    301                            }
    302 
    303         if HAS_USER_SITE:
    304             self.config_vars['userbase'] = self.install_userbase
    305             self.config_vars['usersite'] = self.install_usersite
    306 
    307         self.expand_basedirs()
    308 
    309         self.dump_dirs("post-expand_basedirs()")
    310 
    311         # Now define config vars for the base directories so we can expand
    312         # everything else.
    313         self.config_vars['base'] = self.install_base
    314         self.config_vars['platbase'] = self.install_platbase
    315 
    316         if DEBUG:
    317             from pprint import pprint
    318             print("config vars:")
    319             pprint(self.config_vars)
    320 
    321         # Expand "~" and configuration variables in the installation
    322         # directories.
    323         self.expand_dirs()
    324 
    325         self.dump_dirs("post-expand_dirs()")
    326 
    327         # Create directories in the home dir:
    328         if self.user:
    329             self.create_home_path()
    330 
    331         # Pick the actual directory to install all modules to: either
    332         # install_purelib or install_platlib, depending on whether this
    333         # module distribution is pure or not.  Of course, if the user
    334         # already specified install_lib, use their selection.
    335         if self.install_lib is None:
    336             if self.distribution.ext_modules: # has extensions: non-pure
    337                 self.install_lib = self.install_platlib
    338             else:
    339                 self.install_lib = self.install_purelib
    340 
    341 
    342         # Convert directories from Unix /-separated syntax to the local
    343         # convention.
    344         self.convert_paths('lib', 'purelib', 'platlib',
    345                            'scripts', 'data', 'headers',
    346                            'userbase', 'usersite')
    347 
    348         # Deprecated
    349         # Well, we're not actually fully completely finalized yet: we still
    350         # have to deal with 'extra_path', which is the hack for allowing
    351         # non-packagized module distributions (hello, Numerical Python!) to
    352         # get their own directories.
    353         self.handle_extra_path()
    354         self.install_libbase = self.install_lib # needed for .pth file
    355         self.install_lib = os.path.join(self.install_lib, self.extra_dirs)
    356 
    357         # If a new root directory was supplied, make all the installation
    358         # dirs relative to it.
    359         if self.root is not None:
    360             self.change_roots('libbase', 'lib', 'purelib', 'platlib',
    361                               'scripts', 'data', 'headers')
    362 
    363         self.dump_dirs("after prepending root")
    364 
    365         # Find out the build directories, ie. where to install from.
    366         self.set_undefined_options('build',
    367                                    ('build_base', 'build_base'),
    368                                    ('build_lib', 'build_lib'))
    369 
    370         # Punt on doc directories for now -- after all, we're punting on
    371         # documentation completely!
    372 
    373     def dump_dirs(self, msg):
    374         """Dumps the list of user options."""
    375         if not DEBUG:
    376             return
    377         from distutils.fancy_getopt import longopt_xlate
    378         log.debug(msg + ":")
    379         for opt in self.user_options:
    380             opt_name = opt[0]
    381             if opt_name[-1] == "=":
    382                 opt_name = opt_name[0:-1]
    383             if opt_name in self.negative_opt:
    384                 opt_name = self.negative_opt[opt_name]
    385                 opt_name = opt_name.translate(longopt_xlate)
    386                 val = not getattr(self, opt_name)
    387             else:
    388                 opt_name = opt_name.translate(longopt_xlate)
    389                 val = getattr(self, opt_name)
    390             log.debug("  %s: %s", opt_name, val)
    391 
    392     def finalize_unix(self):
    393         """Finalizes options for posix platforms."""
    394         if self.install_base is not None or self.install_platbase is not None:
    395             if ((self.install_lib is None and
    396                  self.install_purelib is None and
    397                  self.install_platlib is None) or
    398                 self.install_headers is None or
    399                 self.install_scripts is None or
    400                 self.install_data is None):
    401                 raise DistutilsOptionError(
    402                       "install-base or install-platbase supplied, but "
    403                       "installation scheme is incomplete")
    404             return
    405 
    406         if self.user:
    407             if self.install_userbase is None:
    408                 raise DistutilsPlatformError(
    409                     "User base directory is not specified")
    410             self.install_base = self.install_platbase = self.install_userbase
    411             self.select_scheme("unix_user")
    412         elif self.home is not None:
    413             self.install_base = self.install_platbase = self.home
    414             self.select_scheme("unix_home")
    415         else:
    416             if self.prefix is None:
    417                 if self.exec_prefix is not None:
    418                     raise DistutilsOptionError(
    419                           "must not supply exec-prefix without prefix")
    420 
    421                 self.prefix = os.path.normpath(sys.prefix)
    422                 self.exec_prefix = os.path.normpath(sys.exec_prefix)
    423 
    424             else:
    425                 if self.exec_prefix is None:
    426                     self.exec_prefix = self.prefix
    427 
    428             self.install_base = self.prefix
    429             self.install_platbase = self.exec_prefix
    430             self.select_scheme("unix_prefix")
    431 
    432     def finalize_other(self):
    433         """Finalizes options for non-posix platforms"""
    434         if self.user:
    435             if self.install_userbase is None:
    436                 raise DistutilsPlatformError(
    437                     "User base directory is not specified")
    438             self.install_base = self.install_platbase = self.install_userbase
    439             self.select_scheme(os.name + "_user")
    440         elif self.home is not None:
    441             self.install_base = self.install_platbase = self.home
    442             self.select_scheme("unix_home")
    443         else:
    444             if self.prefix is None:
    445                 self.prefix = os.path.normpath(sys.prefix)
    446 
    447             self.install_base = self.install_platbase = self.prefix
    448             try:
    449                 self.select_scheme(os.name)
    450             except KeyError:
    451                 raise DistutilsPlatformError(
    452                       "I don't know how to install stuff on '%s'" % os.name)
    453 
    454     def select_scheme(self, name):
    455         """Sets the install directories by applying the install schemes."""
    456         # it's the caller's problem if they supply a bad name!
    457         scheme = INSTALL_SCHEMES[name]
    458         for key in SCHEME_KEYS:
    459             attrname = 'install_' + key
    460             if getattr(self, attrname) is None:
    461                 setattr(self, attrname, scheme[key])
    462 
    463     def _expand_attrs(self, attrs):
    464         for attr in attrs:
    465             val = getattr(self, attr)
    466             if val is not None:
    467                 if os.name == 'posix' or os.name == 'nt':
    468                     val = os.path.expanduser(val)
    469                 val = subst_vars(val, self.config_vars)
    470                 setattr(self, attr, val)
    471 
    472     def expand_basedirs(self):
    473         """Calls `os.path.expanduser` on install_base, install_platbase and
    474         root."""
    475         self._expand_attrs(['install_base', 'install_platbase', 'root'])
    476 
    477     def expand_dirs(self):
    478         """Calls `os.path.expanduser` on install dirs."""
    479         self._expand_attrs(['install_purelib', 'install_platlib',
    480                             'install_lib', 'install_headers',
    481                             'install_scripts', 'install_data',])
    482 
    483     def convert_paths(self, *names):
    484         """Call `convert_path` over `names`."""
    485         for name in names:
    486             attr = "install_" + name
    487             setattr(self, attr, convert_path(getattr(self, attr)))
    488 
    489     def handle_extra_path(self):
    490         """Set `path_file` and `extra_dirs` using `extra_path`."""
    491         if self.extra_path is None:
    492             self.extra_path = self.distribution.extra_path
    493 
    494         if self.extra_path is not None:
    495             log.warn(
    496                 "Distribution option extra_path is deprecated. "
    497                 "See issue27919 for details."
    498             )
    499             if isinstance(self.extra_path, str):
    500                 self.extra_path = self.extra_path.split(',')
    501 
    502             if len(self.extra_path) == 1:
    503                 path_file = extra_dirs = self.extra_path[0]
    504             elif len(self.extra_path) == 2:
    505                 path_file, extra_dirs = self.extra_path
    506             else:
    507                 raise DistutilsOptionError(
    508                       "'extra_path' option must be a list, tuple, or "
    509                       "comma-separated string with 1 or 2 elements")
    510 
    511             # convert to local form in case Unix notation used (as it
    512             # should be in setup scripts)
    513             extra_dirs = convert_path(extra_dirs)
    514         else:
    515             path_file = None
    516             extra_dirs = ''
    517 
    518         # XXX should we warn if path_file and not extra_dirs? (in which
    519         # case the path file would be harmless but pointless)
    520         self.path_file = path_file
    521         self.extra_dirs = extra_dirs
    522 
    523     def change_roots(self, *names):
    524         """Change the install directories pointed by name using root."""
    525         for name in names:
    526             attr = "install_" + name
    527             setattr(self, attr, change_root(self.root, getattr(self, attr)))
    528 
    529     def create_home_path(self):
    530         """Create directories under ~."""
    531         if not self.user:
    532             return
    533         home = convert_path(os.path.expanduser("~"))
    534         for name, path in self.config_vars.items():
    535             if path.startswith(home) and not os.path.isdir(path):
    536                 self.debug_print("os.makedirs('%s', 0o700)" % path)
    537                 os.makedirs(path, 0o700)
    538 
    539     # -- Command execution methods -------------------------------------
    540 
    541     def run(self):
    542         """Runs the command."""
    543         # Obviously have to build before we can install
    544         if not self.skip_build:
    545             self.run_command('build')
    546             # If we built for any other platform, we can't install.
    547             build_plat = self.distribution.get_command_obj('build').plat_name
    548             # check warn_dir - it is a clue that the 'install' is happening
    549             # internally, and not to sys.path, so we don't check the platform
    550             # matches what we are running.
    551             if self.warn_dir and build_plat != get_platform():
    552                 raise DistutilsPlatformError("Can't install when "
    553                                              "cross-compiling")
    554 
    555         # Run all sub-commands (at least those that need to be run)
    556         for cmd_name in self.get_sub_commands():
    557             self.run_command(cmd_name)
    558 
    559         if self.path_file:
    560             self.create_path_file()
    561 
    562         # write list of installed files, if requested.
    563         if self.record:
    564             outputs = self.get_outputs()
    565             if self.root:               # strip any package prefix
    566                 root_len = len(self.root)
    567                 for counter in range(len(outputs)):
    568                     outputs[counter] = outputs[counter][root_len:]
    569             self.execute(write_file,
    570                          (self.record, outputs),
    571                          "writing list of installed files to '%s'" %
    572                          self.record)
    573 
    574         sys_path = map(os.path.normpath, sys.path)
    575         sys_path = map(os.path.normcase, sys_path)
    576         install_lib = os.path.normcase(os.path.normpath(self.install_lib))
    577         if (self.warn_dir and
    578             not (self.path_file and self.install_path_file) and
    579             install_lib not in sys_path):
    580             log.debug(("modules installed to '%s', which is not in "
    581                        "Python's module search path (sys.path) -- "
    582                        "you'll have to change the search path yourself"),
    583                        self.install_lib)
    584 
    585     def create_path_file(self):
    586         """Creates the .pth file"""
    587         filename = os.path.join(self.install_libbase,
    588                                 self.path_file + ".pth")
    589         if self.install_path_file:
    590             self.execute(write_file,
    591                          (filename, [self.extra_dirs]),
    592                          "creating %s" % filename)
    593         else:
    594             self.warn("path file '%s' not created" % filename)
    595 
    596 
    597     # -- Reporting methods ---------------------------------------------
    598 
    599     def get_outputs(self):
    600         """Assembles the outputs of all the sub-commands."""
    601         outputs = []
    602         for cmd_name in self.get_sub_commands():
    603             cmd = self.get_finalized_command(cmd_name)
    604             # Add the contents of cmd.get_outputs(), ensuring
    605             # that outputs doesn't contain duplicate entries
    606             for filename in cmd.get_outputs():
    607                 if filename not in outputs:
    608                     outputs.append(filename)
    609 
    610         if self.path_file and self.install_path_file:
    611             outputs.append(os.path.join(self.install_libbase,
    612                                         self.path_file + ".pth"))
    613 
    614         return outputs
    615 
    616     def get_inputs(self):
    617         """Returns the inputs of all the sub-commands"""
    618         # XXX gee, this looks familiar ;-(
    619         inputs = []
    620         for cmd_name in self.get_sub_commands():
    621             cmd = self.get_finalized_command(cmd_name)
    622             inputs.extend(cmd.get_inputs())
    623 
    624         return inputs
    625 
    626     # -- Predicates for sub-command list -------------------------------
    627 
    628     def has_lib(self):
    629         """Returns true if the current distribution has any Python
    630         modules to install."""
    631         return (self.distribution.has_pure_modules() or
    632                 self.distribution.has_ext_modules())
    633 
    634     def has_headers(self):
    635         """Returns true if the current distribution has any headers to
    636         install."""
    637         return self.distribution.has_headers()
    638 
    639     def has_scripts(self):
    640         """Returns true if the current distribution has any scripts to.
    641         install."""
    642         return self.distribution.has_scripts()
    643 
    644     def has_data(self):
    645         """Returns true if the current distribution has any data to.
    646         install."""
    647         return self.distribution.has_data_files()
    648 
    649     # 'sub_commands': a list of commands this command might have to run to
    650     # get its work done.  See cmd.py for more info.
    651     sub_commands = [('install_lib',     has_lib),
    652                     ('install_headers', has_headers),
    653                     ('install_scripts', has_scripts),
    654                     ('install_data',    has_data),
    655                     ('install_egg_info', lambda self:True),
    656                    ]
    657