~malept/ubuntu/lucid/python2.6/dev-dependency-fix

« back to all changes in this revision

Viewing changes to Lib/distutils/command/install_lib.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-02-13 12:51:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090213125100-uufgcb9yeqzujpqw
Tags: upstream-2.6.1
ImportĀ upstreamĀ versionĀ 2.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# This module should be kept compatible with Python 2.1.
 
2
 
 
3
__revision__ = "$Id: install_lib.py 61000 2008-02-23 17:40:11Z christian.heimes $"
 
4
 
 
5
import os
 
6
from types import IntType
 
7
from distutils.core import Command
 
8
from distutils.errors import DistutilsOptionError
 
9
 
 
10
 
 
11
# Extension for Python source files.
 
12
if hasattr(os, 'extsep'):
 
13
    PYTHON_SOURCE_EXTENSION = os.extsep + "py"
 
14
else:
 
15
    PYTHON_SOURCE_EXTENSION = ".py"
 
16
 
 
17
class install_lib (Command):
 
18
 
 
19
    description = "install all Python modules (extensions and pure Python)"
 
20
 
 
21
    # The byte-compilation options are a tad confusing.  Here are the
 
22
    # possible scenarios:
 
23
    #   1) no compilation at all (--no-compile --no-optimize)
 
24
    #   2) compile .pyc only (--compile --no-optimize; default)
 
25
    #   3) compile .pyc and "level 1" .pyo (--compile --optimize)
 
26
    #   4) compile "level 1" .pyo only (--no-compile --optimize)
 
27
    #   5) compile .pyc and "level 2" .pyo (--compile --optimize-more)
 
28
    #   6) compile "level 2" .pyo only (--no-compile --optimize-more)
 
29
    #
 
30
    # The UI for this is two option, 'compile' and 'optimize'.
 
31
    # 'compile' is strictly boolean, and only decides whether to
 
32
    # generate .pyc files.  'optimize' is three-way (0, 1, or 2), and
 
33
    # decides both whether to generate .pyo files and what level of
 
34
    # optimization to use.
 
35
 
 
36
    user_options = [
 
37
        ('install-dir=', 'd', "directory to install to"),
 
38
        ('build-dir=','b', "build directory (where to install from)"),
 
39
        ('force', 'f', "force installation (overwrite existing files)"),
 
40
        ('compile', 'c', "compile .py to .pyc [default]"),
 
41
        ('no-compile', None, "don't compile .py files"),
 
42
        ('optimize=', 'O',
 
43
         "also compile with optimization: -O1 for \"python -O\", "
 
44
         "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
 
45
        ('skip-build', None, "skip the build steps"),
 
46
        ]
 
47
 
 
48
    boolean_options = ['force', 'compile', 'skip-build']
 
49
    negative_opt = {'no-compile' : 'compile'}
 
50
 
 
51
 
 
52
    def initialize_options (self):
 
53
        # let the 'install' command dictate our installation directory
 
54
        self.install_dir = None
 
55
        self.build_dir = None
 
56
        self.force = 0
 
57
        self.compile = None
 
58
        self.optimize = None
 
59
        self.skip_build = None
 
60
 
 
61
    def finalize_options (self):
 
62
 
 
63
        # Get all the information we need to install pure Python modules
 
64
        # from the umbrella 'install' command -- build (source) directory,
 
65
        # install (target) directory, and whether to compile .py files.
 
66
        self.set_undefined_options('install',
 
67
                                   ('build_lib', 'build_dir'),
 
68
                                   ('install_lib', 'install_dir'),
 
69
                                   ('force', 'force'),
 
70
                                   ('compile', 'compile'),
 
71
                                   ('optimize', 'optimize'),
 
72
                                   ('skip_build', 'skip_build'),
 
73
                                  )
 
74
 
 
75
        if self.compile is None:
 
76
            self.compile = 1
 
77
        if self.optimize is None:
 
78
            self.optimize = 0
 
79
 
 
80
        if type(self.optimize) is not IntType:
 
81
            try:
 
82
                self.optimize = int(self.optimize)
 
83
                assert 0 <= self.optimize <= 2
 
84
            except (ValueError, AssertionError):
 
85
                raise DistutilsOptionError, "optimize must be 0, 1, or 2"
 
86
 
 
87
    def run (self):
 
88
 
 
89
        # Make sure we have built everything we need first
 
90
        self.build()
 
91
 
 
92
        # Install everything: simply dump the entire contents of the build
 
93
        # directory to the installation directory (that's the beauty of
 
94
        # having a build directory!)
 
95
        outfiles = self.install()
 
96
 
 
97
        # (Optionally) compile .py to .pyc
 
98
        if outfiles is not None and self.distribution.has_pure_modules():
 
99
            self.byte_compile(outfiles)
 
100
 
 
101
    # run ()
 
102
 
 
103
 
 
104
    # -- Top-level worker functions ------------------------------------
 
105
    # (called from 'run()')
 
106
 
 
107
    def build (self):
 
108
        if not self.skip_build:
 
109
            if self.distribution.has_pure_modules():
 
110
                self.run_command('build_py')
 
111
            if self.distribution.has_ext_modules():
 
112
                self.run_command('build_ext')
 
113
 
 
114
    def install (self):
 
115
        if os.path.isdir(self.build_dir):
 
116
            outfiles = self.copy_tree(self.build_dir, self.install_dir)
 
117
        else:
 
118
            self.warn("'%s' does not exist -- no Python modules to install" %
 
119
                      self.build_dir)
 
120
            return
 
121
        return outfiles
 
122
 
 
123
    def byte_compile (self, files):
 
124
        from distutils.util import byte_compile
 
125
 
 
126
        # Get the "--root" directory supplied to the "install" command,
 
127
        # and use it as a prefix to strip off the purported filename
 
128
        # encoded in bytecode files.  This is far from complete, but it
 
129
        # should at least generate usable bytecode in RPM distributions.
 
130
        install_root = self.get_finalized_command('install').root
 
131
 
 
132
        if self.compile:
 
133
            byte_compile(files, optimize=0,
 
134
                         force=self.force, prefix=install_root,
 
135
                         dry_run=self.dry_run)
 
136
        if self.optimize > 0:
 
137
            byte_compile(files, optimize=self.optimize,
 
138
                         force=self.force, prefix=install_root,
 
139
                         verbose=self.verbose, dry_run=self.dry_run)
 
140
 
 
141
 
 
142
    # -- Utility methods -----------------------------------------------
 
143
 
 
144
    def _mutate_outputs (self, has_any, build_cmd, cmd_option, output_dir):
 
145
 
 
146
        if not has_any:
 
147
            return []
 
148
 
 
149
        build_cmd = self.get_finalized_command(build_cmd)
 
150
        build_files = build_cmd.get_outputs()
 
151
        build_dir = getattr(build_cmd, cmd_option)
 
152
 
 
153
        prefix_len = len(build_dir) + len(os.sep)
 
154
        outputs = []
 
155
        for file in build_files:
 
156
            outputs.append(os.path.join(output_dir, file[prefix_len:]))
 
157
 
 
158
        return outputs
 
159
 
 
160
    # _mutate_outputs ()
 
161
 
 
162
    def _bytecode_filenames (self, py_filenames):
 
163
        bytecode_files = []
 
164
        for py_file in py_filenames:
 
165
            # Since build_py handles package data installation, the
 
166
            # list of outputs can contain more than just .py files.
 
167
            # Make sure we only report bytecode for the .py files.
 
168
            ext = os.path.splitext(os.path.normcase(py_file))[1]
 
169
            if ext != PYTHON_SOURCE_EXTENSION:
 
170
                continue
 
171
            if self.compile:
 
172
                bytecode_files.append(py_file + "c")
 
173
            if self.optimize > 0:
 
174
                bytecode_files.append(py_file + "o")
 
175
 
 
176
        return bytecode_files
 
177
 
 
178
 
 
179
    # -- External interface --------------------------------------------
 
180
    # (called by outsiders)
 
181
 
 
182
    def get_outputs (self):
 
183
        """Return the list of files that would be installed if this command
 
184
        were actually run.  Not affected by the "dry-run" flag or whether
 
185
        modules have actually been built yet.
 
186
        """
 
187
        pure_outputs = \
 
188
            self._mutate_outputs(self.distribution.has_pure_modules(),
 
189
                                 'build_py', 'build_lib',
 
190
                                 self.install_dir)
 
191
        if self.compile:
 
192
            bytecode_outputs = self._bytecode_filenames(pure_outputs)
 
193
        else:
 
194
            bytecode_outputs = []
 
195
 
 
196
        ext_outputs = \
 
197
            self._mutate_outputs(self.distribution.has_ext_modules(),
 
198
                                 'build_ext', 'build_lib',
 
199
                                 self.install_dir)
 
200
 
 
201
        return pure_outputs + bytecode_outputs + ext_outputs
 
202
 
 
203
    # get_outputs ()
 
204
 
 
205
    def get_inputs (self):
 
206
        """Get the list of files that are input to this command, ie. the
 
207
        files that get installed as they are named in the build tree.
 
208
        The files in this list correspond one-to-one to the output
 
209
        filenames returned by 'get_outputs()'.
 
210
        """
 
211
        inputs = []
 
212
 
 
213
        if self.distribution.has_pure_modules():
 
214
            build_py = self.get_finalized_command('build_py')
 
215
            inputs.extend(build_py.get_outputs())
 
216
 
 
217
        if self.distribution.has_ext_modules():
 
218
            build_ext = self.get_finalized_command('build_ext')
 
219
            inputs.extend(build_ext.get_outputs())
 
220
 
 
221
        return inputs
 
222
 
 
223
# class install_lib