install.py 26.8 KB
Newer Older
1 2 3 4
"""distutils.command.install

Implements the Distutils 'install' command."""

5
__revision__ = "$Id$"
6

7 8 9
import sys
import os

10
from sysconfig import get_config_vars, get_paths, get_path, get_config_var
11

12
from distutils import log
13 14
from distutils.core import Command
from distutils.debug import DEBUG
15
from distutils.errors import DistutilsPlatformError
16
from distutils.file_util import write_file
17
from distutils.util import convert_path, change_root, get_platform
18
from distutils.errors import DistutilsOptionError
19

20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
# kept for backward compat, will be removed in 3.2
if sys.version < "2.2":
    WINDOWS_SCHEME = {
        'purelib': '$base',
        'platlib': '$base',
        'headers': '$base/Include/$dist_name',
        'scripts': '$base/Scripts',
        'data'   : '$base',
    }
else:
    WINDOWS_SCHEME = {
        'purelib': '$base/Lib/site-packages',
        'platlib': '$base/Lib/site-packages',
        'headers': '$base/Include/$dist_name',
        'scripts': '$base/Scripts',
        'data'   : '$base',
    }

INSTALL_SCHEMES = {
    'unix_prefix': {
        'purelib': '$base/lib/python$py_version_short/site-packages',
        'platlib': '$platbase/lib/python$py_version_short/site-packages',
        'headers': '$base/include/python$py_version_short/$dist_name',
        'scripts': '$base/bin',
        'data'   : '$base',
        },
    'unix_home': {
        'purelib': '$base/lib/python',
        'platlib': '$base/lib/python',
        'headers': '$base/include/python/$dist_name',
        'scripts': '$base/bin',
        'data'   : '$base',
        },
    'unix_user': {
        'purelib': '$usersite',
        'platlib': '$usersite',
        'headers': '$userbase/include/python$py_version_short/$dist_name',
        'scripts': '$userbase/bin',
        'data'   : '$userbase',
        },
    'nt': WINDOWS_SCHEME,
    'nt_user': {
        'purelib': '$usersite',
        'platlib': '$usersite',
        'headers': '$userbase/Python$py_version_nodot/Include/$dist_name',
        'scripts': '$userbase/Scripts',
        'data'   : '$userbase',
        },
    'os2': {
        'purelib': '$base/Lib/site-packages',
        'platlib': '$base/Lib/site-packages',
        'headers': '$base/Include/$dist_name',
        'scripts': '$base/Scripts',
        'data'   : '$base',
        },
    'os2_home': {
        'purelib': '$usersite',
        'platlib': '$usersite',
        'headers': '$userbase/include/python$py_version_short/$dist_name',
        'scripts': '$userbase/bin',
        'data'   : '$userbase',
        },
    }

SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data')
# end of backward compat

87 88 89 90 91 92 93 94
def _subst_vars(s, local_vars):
    try:
        return s.format(**local_vars)
    except KeyError:
        try:
            return s.format(**os.environ)
        except KeyError as var:
            raise AttributeError('{%s}' % var)
95

96
class install(Command):
97

98 99
    description = "install everything from build directory"

100
    user_options = [
101 102 103
        # Select installation scheme and set base director(y|ies)
        ('prefix=', None,
         "installation prefix"),
104
        ('exec-prefix=', None,
105 106 107 108 109 110 111 112 113 114
         "(Unix only) prefix for platform-specific files"),
        ('home=', None,
         "(Unix only) home directory to install under"),

        # Or, just set the base director(y|ies)
        ('install-base=', None,
         "base installation directory (instead of --prefix or --home)"),
        ('install-platbase=', None,
         "base installation directory for platform-specific files " +
         "(instead of --exec-prefix or --home)"),
115 116
        ('root=', None,
         "install everything relative to this alternate root directory"),
117 118 119 120

        # Or, explicitly set the installation scheme
        ('install-purelib=', None,
         "installation directory for pure Python module distributions"),
121
        ('install-platlib=', None,
122 123 124 125 126
         "installation directory for non-pure module distributions"),
        ('install-lib=', None,
         "installation directory for all module distributions " +
         "(overrides --install-purelib and --install-platlib)"),

127 128
        ('install-headers=', None,
         "installation directory for C/C++ headers"),
129 130 131 132
        ('install-scripts=', None,
         "installation directory for Python scripts"),
        ('install-data=', None,
         "installation directory for data files"),
133

134 135 136 137 138 139 140 141
        # Byte-compilation options -- see install_lib.py for details, as
        # these are duplicated from there (but only install_lib does
        # anything with them).
        ('compile', 'c', "compile .py to .pyc [default]"),
        ('no-compile', None, "don't compile .py files"),
        ('optimize=', 'O',
         "also compile with optimization: -O1 for \"python -O\", "
         "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
Fred Drake's avatar
Fred Drake committed
142

143 144 145
        # Miscellaneous control options
        ('force', 'f',
         "force installation (overwrite any existing files)"),
146 147 148
        ('skip-build', None,
         "skip rebuilding everything (for testing/debugging)"),

149
        # Where to install documentation (eventually!)
150 151 152 153
        #('doc-format=', None, "format of documentation to generate"),
        #('install-man=', None, "directory for Unix man pages"),
        #('install-html=', None, "directory for HTML documentation"),
        #('install-info=', None, "directory for GNU info files"),
154

155 156
        ('record=', None,
         "filename in which to record list of installed files"),
157
        ]
158

159 160
    boolean_options = ['compile', 'force', 'skip-build']

161 162 163 164
    user_options.append(('user', None,
                        "install in user site-package '%s'" % \
                            get_path('purelib', '%s_user' % os.name)))
    boolean_options.append('user')
165
    negative_opt = {'no-compile' : 'compile'}
166

167

168
    def initialize_options(self):
169
        """Initializes options."""
170 171
        # High-level options: these select both an installation base
        # and scheme.
172 173
        self.prefix = None
        self.exec_prefix = None
174
        self.home = None
175
        self.user = 0
176

177 178 179
        # These select only the installation base; it's up to the user to
        # specify the installation scheme (currently, that means supplying
        # the --install-{platlib,purelib,scripts,data} options).
180 181
        self.install_base = None
        self.install_platbase = None
182
        self.root = None
183

184 185 186 187 188 189
        # These options are the actual installation directories; if not
        # supplied by the user, they are filled in using the installation
        # scheme implied by prefix/exec-prefix/home and the contents of
        # that installation scheme.
        self.install_purelib = None     # for pure module distributions
        self.install_platlib = None     # non-pure (dists w/ extensions)
190
        self.install_headers = None     # for C/C++ headers
191
        self.install_lib = None         # set to either purelib or platlib
192 193
        self.install_scripts = None
        self.install_data = None
194 195
        self.install_userbase = get_config_var('userbase')
        self.install_usersite = get_path('purelib', '%s_user' % os.name)
196

197
        self.compile = None
198 199
        self.optimize = None

200 201
        # These two are for putting non-packagized distributions into their
        # own directory and creating a .pth file if it makes sense.
202 203 204 205 206 207
        # 'extra_path' comes from the setup file; 'install_path_file' can
        # be turned off if it makes no sense to install a .pth file.  (But
        # better to install it uselessly than to guess wrong and not
        # install it when it's necessary and would be used!)  Currently,
        # 'install_path_file' is always true unless some outsider meddles
        # with it.
208
        self.extra_path = None
209 210 211 212
        self.install_path_file = 1

        # 'force' forces installation, even if target files are not
        # out-of-date.  'skip_build' skips running the "build" command,
213
        # handy if you know it's not necessary.  'warn_dir' (which is *not*
214 215 216
        # a user option, it's just there so the bdist_* commands can turn
        # it off) determines whether we warn about installing to a
        # directory not in sys.path.
217
        self.force = 0
218
        self.skip_build = 0
219
        self.warn_dir = 1
220

221 222 223 224 225 226 227 228 229
        # These are only here as a conduit from the 'build' command to the
        # 'install_*' commands that do the real work.  ('build_base' isn't
        # actually used anywhere, but it might be useful in future.)  They
        # are not user options, because if the user told the install
        # command where the build directory is, that wouldn't affect the
        # build command.
        self.build_base = None
        self.build_lib = None

230 231
        # Not defined yet because we don't know anything about
        # documentation yet.
232 233 234
        #self.install_man = None
        #self.install_html = None
        #self.install_info = None
235

236
        self.record = None
237

238 239 240 241 242 243 244

    # -- Option finalizing methods -------------------------------------
    # (This is rather more involved than for most commands,
    # because this is where the policy for installing third-
    # party Python modules on various platforms given a wide
    # array of user input is decided.  Yes, it's quite complex!)

245
    def finalize_options(self):
246
        """Finalizes options."""
247 248 249 250 251 252 253 254 255 256
        # This method (and its pliant slaves, 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.
257

258 259
        # Check for errors/inconsistencies in the options; first, stuff
        # that's wrong on any platform.
260 261 262

        if ((self.prefix or self.exec_prefix or self.home) and
            (self.install_base or self.install_platbase)):
263 264
            raise DistutilsOptionError(
                   "must supply either prefix/exec-prefix/home or " +
265 266
                   "install-base/install-platbase -- not both")

267
        if self.home and (self.prefix or self.exec_prefix):
268 269
            raise DistutilsOptionError(
                  "must supply either home or prefix/exec-prefix -- not both")
270

271 272 273 274 275
        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 with prefix/"
                                       "exec_prefix/home or install_(plat)base")

276
        # Next, stuff that's wrong (or dubious) only on certain platforms.
277
        if os.name != "posix":
278
            if self.exec_prefix:
279
                self.warn("exec-prefix option ignored on this platform")
280 281 282 283 284 285 286 287 288
                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_SCHEME dictionary above.  Phew!
289

290
        self.dump_dirs("pre-finalize_{unix,other}")
291

292
        if os.name == 'posix':
293
            self.finalize_unix()
294
        else:
295
            self.finalize_other()
296

297
        self.dump_dirs("post-finalize_{unix,other}()")
298 299 300 301 302 303

        # 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).

304
        py_version = sys.version.split()[0]
305 306
        prefix, exec_prefix, srcdir, projectbase = get_config_vars('prefix', 'exec_prefix',
                                                      'srcdir', 'projectbase')
307

308 309 310 311 312
        self.config_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': py_version[0:3],
313
                            'py_version_nodot': py_version[0] + py_version[2],
314 315 316 317
                            'sys_prefix': prefix,
                            'prefix': prefix,
                            'sys_exec_prefix': exec_prefix,
                            'exec_prefix': exec_prefix,
318
                            'srcdir': srcdir,
319
                            'projectbase': projectbase,
320
                           }
321

322 323
        self.config_vars['userbase'] = self.install_userbase
        self.config_vars['usersite'] = self.install_usersite
324
        self.expand_basedirs()
325

326
        self.dump_dirs("post-expand_basedirs()")
327 328 329 330 331 332

        # Now define config vars for the base directories so we can expand
        # everything else.
        self.config_vars['base'] = self.install_base
        self.config_vars['platbase'] = self.install_platbase

333 334
        if DEBUG:
            from pprint import pprint
335
            print("config vars:")
336
            pprint(self.config_vars)
337

338 339
        # Expand "~" and configuration variables in the installation
        # directories.
340
        self.expand_dirs()
341

342
        self.dump_dirs("post-expand_dirs()")
343

344 345 346 347
        # Create directories in the home dir:
        if self.user:
            self.create_home_path()

348 349 350 351 352 353 354 355 356
        # 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.ext_modules: # has extensions: non-pure
                self.install_lib = self.install_platlib
            else:
                self.install_lib = self.install_purelib
Fred Drake's avatar
Fred Drake committed
357

358 359 360 361

        # Convert directories from Unix /-separated syntax to the local
        # convention.
        self.convert_paths('lib', 'purelib', 'platlib',
362 363
                           'scripts', 'data', 'headers',
                           'userbase', 'usersite')
364

365 366 367 368
        # 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.
369
        self.handle_extra_path()
370
        self.install_libbase = self.install_lib # needed for .pth file
371
        self.install_lib = os.path.join(self.install_lib, self.extra_dirs)
372

373 374 375
        # If a new root directory was supplied, make all the installation
        # dirs relative to it.
        if self.root is not None:
376 377
            self.change_roots('libbase', 'lib', 'purelib', 'platlib',
                              'scripts', 'data', 'headers')
378

379
        self.dump_dirs("after prepending root")
380

381
        # Find out the build directories, ie. where to install from.
382 383 384
        self.set_undefined_options('build',
                                   ('build_base', 'build_base'),
                                   ('build_lib', 'build_lib'))
385 386 387

        # Punt on doc directories for now -- after all, we're punting on
        # documentation completely!
388

389
    def dump_dirs(self, msg):
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
        """Dumps the list of user options."""
        if not DEBUG:
            return
        from distutils.fancy_getopt import longopt_xlate
        log.debug(msg + ":")
        for opt in self.user_options:
            opt_name = opt[0]
            if opt_name[-1] == "=":
                opt_name = opt_name[0:-1]
            if opt_name in self.negative_opt:
                opt_name = self.negative_opt[opt_name]
                opt_name = opt_name.translate(longopt_xlate)
                val = not getattr(self, opt_name)
            else:
                opt_name = opt_name.translate(longopt_xlate)
                val = getattr(self, opt_name)
            log.debug("  %s: %s" % (opt_name, val))
407

408
    def finalize_unix(self):
409
        """Finalizes options for posix platforms."""
410 411 412 413
        if self.install_base is not None or self.install_platbase is not None:
            if ((self.install_lib is None and
                 self.install_purelib is None and
                 self.install_platlib is None) or
414
                self.install_headers is None or
415 416
                self.install_scripts is None or
                self.install_data is None):
417 418
                raise DistutilsOptionError(
                      "install-base or install-platbase supplied, but "
419
                      "installation scheme is incomplete")
420 421
            return

422 423 424 425 426
        if self.user:
            if self.install_userbase is None:
                raise DistutilsPlatformError(
                    "User base directory is not specified")
            self.install_base = self.install_platbase = self.install_userbase
427
            self.select_scheme("posix_user")
428
        elif self.home is not None:
429
            self.install_base = self.install_platbase = self.home
430
            self.select_scheme("posix_home")
431
        else:
432 433
            if self.prefix is None:
                if self.exec_prefix is not None:
434 435
                    raise DistutilsOptionError(
                          "must not supply exec-prefix without prefix")
436

437 438
                self.prefix = os.path.normpath(sys.prefix)
                self.exec_prefix = os.path.normpath(sys.exec_prefix)
439 440 441 442 443 444 445

            else:
                if self.exec_prefix is None:
                    self.exec_prefix = self.prefix

            self.install_base = self.prefix
            self.install_platbase = self.exec_prefix
446
            self.select_scheme("posix_prefix")
447

448 449
    def finalize_other(self):
        """Finalizes options for non-posix platforms"""
450 451 452 453 454 455 456
        if self.user:
            if self.install_userbase is None:
                raise DistutilsPlatformError(
                    "User base directory is not specified")
            self.install_base = self.install_platbase = self.install_userbase
            self.select_scheme(os.name + "_user")
        elif self.home is not None:
457
            self.install_base = self.install_platbase = self.home
458
            self.select_scheme("posix_home")
459 460 461
        else:
            if self.prefix is None:
                self.prefix = os.path.normpath(sys.prefix)
462

463 464 465 466
            self.install_base = self.install_platbase = self.prefix
            try:
                self.select_scheme(os.name)
            except KeyError:
467 468
                raise DistutilsPlatformError(
                      "I don't know how to install stuff on '%s'" % os.name)
469

470
    def select_scheme(self, name):
471
        """Sets the install directories by applying the install schemes."""
472
        # it's the caller's problem if they supply a bad name!
473 474 475 476 477
        scheme = get_paths(name, expand=False)
        for key, value in scheme.items():
            if key == 'platinclude':
                key = 'headers'
                value = os.path.join(value, self.distribution.get_name())
478
            attrname = 'install_' + key
479 480 481
            if hasattr(self, attrname):
                if getattr(self, attrname) is None:
                    setattr(self, attrname, value)
482

483
    def _expand_attrs(self, attrs):
484
        for attr in attrs:
485
            val = getattr(self, attr)
486
            if val is not None:
487
                if os.name == 'posix' or os.name == 'nt':
488
                    val = os.path.expanduser(val)
489
                val = _subst_vars(val, self.config_vars)
490
                setattr(self, attr, val)
491

492
    def expand_basedirs(self):
493 494 495
        """Calls `os.path.expanduser` on install_base, install_platbase and
        root."""
        self._expand_attrs(['install_base', 'install_platbase', 'root'])
496

497
    def expand_dirs(self):
498 499 500 501
        """Calls `os.path.expanduser` on install dirs."""
        self._expand_attrs(['install_purelib', 'install_platlib',
                            'install_lib', 'install_headers',
                            'install_scripts', 'install_data',])
502

503
    def convert_paths(self, *names):
504
        """Call `convert_path` over `names`."""
505 506 507 508
        for name in names:
            attr = "install_" + name
            setattr(self, attr, convert_path(getattr(self, attr)))

509
    def handle_extra_path(self):
510
        """Set `path_file` and `extra_dirs` using `extra_path`."""
511 512 513 514
        if self.extra_path is None:
            self.extra_path = self.distribution.extra_path

        if self.extra_path is not None:
515
            if isinstance(self.extra_path, str):
516
                self.extra_path = self.extra_path.split(',')
517

518
            if len(self.extra_path) == 1:
519
                path_file = extra_dirs = self.extra_path[0]
520
            elif len(self.extra_path) == 2:
521
                path_file, extra_dirs = self.extra_path
522
            else:
523 524
                raise DistutilsOptionError(
                      "'extra_path' option must be a list, tuple, or "
525
                      "comma-separated string with 1 or 2 elements")
526

527 528
            # convert to local form in case Unix notation used (as it
            # should be in setup scripts)
529
            extra_dirs = convert_path(extra_dirs)
530 531 532 533
        else:
            path_file = None
            extra_dirs = ''

534 535
        # XXX should we warn if path_file and not extra_dirs? (in which
        # case the path file would be harmless but pointless)
536 537 538
        self.path_file = path_file
        self.extra_dirs = extra_dirs

539
    def change_roots(self, *names):
540
        """Change the install direcories pointed by name using root."""
541 542 543 544
        for name in names:
            attr = "install_" + name
            setattr(self, attr, change_root(self.root, getattr(self, attr)))

545
    def create_home_path(self):
546
        """Create directories under ~."""
547 548 549
        if not self.user:
            return
        home = convert_path(os.path.expanduser("~"))
550
        for name, path in self.config_vars.items():
551 552 553
            if path.startswith(home) and not os.path.isdir(path):
                self.debug_print("os.makedirs('%s', 0o700)" % path)
                os.makedirs(path, 0o700)
554

555 556
    # -- Command execution methods -------------------------------------

557
    def run(self):
558
        """Runs the command."""
559
        # Obviously have to build before we can install
560
        if not self.skip_build:
561
            self.run_command('build')
Christian Heimes's avatar
Christian Heimes committed
562 563 564 565 566 567 568 569
            # If we built for any other platform, we can't install.
            build_plat = self.distribution.get_command_obj('build').plat_name
            # check warn_dir - it is a clue that the 'install' is happening
            # internally, and not to sys.path, so we don't check the platform
            # matches what we are running.
            if self.warn_dir and build_plat != get_platform():
                raise DistutilsPlatformError("Can't install when "
                                             "cross-compiling")
570

571 572
        # Run all sub-commands (at least those that need to be run)
        for cmd_name in self.get_sub_commands():
573
            self.run_command(cmd_name)
574 575

        if self.path_file:
576
            self.create_path_file()
577

578 579 580
        # write list of installed files, if requested.
        if self.record:
            outputs = self.get_outputs()
581
            if self.root:               # strip any package prefix
582
                root_len = len(self.root)
583
                for counter in range(len(outputs)):
584 585
                    outputs[counter] = outputs[counter][root_len:]
            self.execute(write_file,
586 587 588
                         (self.record, outputs),
                         "writing list of installed files to '%s'" %
                         self.record)
589

590
        sys_path = map(os.path.normpath, sys.path)
Greg Ward's avatar
Greg Ward committed
591
        sys_path = map(os.path.normcase, sys_path)
592
        install_lib = os.path.normcase(os.path.normpath(self.install_lib))
593 594
        if (self.warn_dir and
            not (self.path_file and self.install_path_file) and
595
            install_lib not in sys_path):
596
            log.debug(("modules installed to '%s', which is not in "
597
                       "Python's module search path (sys.path) -- "
598 599
                       "you'll have to change the search path yourself"),
                       self.install_lib)
600

601
    def create_path_file(self):
602
        """Creates the .pth file"""
603 604
        filename = os.path.join(self.install_libbase,
                                self.path_file + ".pth")
605
        if self.install_path_file:
606 607 608
            self.execute(write_file,
                         (filename, [self.extra_dirs]),
                         "creating %s" % filename)
609 610
        else:
            self.warn("path file '%s' not created" % filename)
611

612

613
    # -- Reporting methods ---------------------------------------------
614

615
    def get_outputs(self):
616
        """Assembles the outputs of all the sub-commands."""
617
        outputs = []
618
        for cmd_name in self.get_sub_commands():
619
            cmd = self.get_finalized_command(cmd_name)
620 621 622 623 624
            # Add the contents of cmd.get_outputs(), ensuring
            # that outputs doesn't contain duplicate entries
            for filename in cmd.get_outputs():
                if filename not in outputs:
                    outputs.append(filename)
625

626 627 628
        if self.path_file and self.install_path_file:
            outputs.append(os.path.join(self.install_libbase,
                                        self.path_file + ".pth"))
Fred Drake's avatar
Fred Drake committed
629

630 631
        return outputs

632
    def get_inputs(self):
633
        """Returns the inputs of all the sub-commands"""
634 635
        # XXX gee, this looks familiar ;-(
        inputs = []
636
        for cmd_name in self.get_sub_commands():
637 638
            cmd = self.get_finalized_command(cmd_name)
            inputs.extend(cmd.get_inputs())
639 640 641

        return inputs

642 643
    # -- Predicates for sub-command list -------------------------------

644
    def has_lib(self):
645
        """Returns true if the current distribution has any Python
646 647 648 649
        modules to install."""
        return (self.distribution.has_pure_modules() or
                self.distribution.has_ext_modules())

650
    def has_headers(self):
651 652
        """Returns true if the current distribution has any headers to
        install."""
653 654
        return self.distribution.has_headers()

655
    def has_scripts(self):
656 657
        """Returns true if the current distribution has any scripts to.
        install."""
658 659
        return self.distribution.has_scripts()

660
    def has_data(self):
661 662
        """Returns true if the current distribution has any data to.
        install."""
663 664
        return self.distribution.has_data_files()

665 666 667 668 669 670
    # 'sub_commands': a list of commands this command might have to run to
    # get its work done.  See cmd.py for more info.
    sub_commands = [('install_lib',     has_lib),
                    ('install_headers', has_headers),
                    ('install_scripts', has_scripts),
                    ('install_data',    has_data),
671
                    ('install_egg_info', lambda self:True),
672
                   ]