33__revision__ = "$Id$"
44
55import sys , os , string
6+ from types import IntType
67from distutils .core import Command
8+ from distutils .errors import DistutilsOptionError
79from distutils .dir_util import copy_tree
8- from distutils .util import byte_compile
910
1011class install_lib (Command ):
1112
1213 description = "install all Python modules (extensions and pure Python)"
1314
15+ # The byte-compilation options are a tad confusing. Here are the
16+ # possible scenarios:
17+ # 1) no compilation at all (--no-compile --no-optimize)
18+ # 2) compile .pyc only (--compile --no-optimize; default)
19+ # 3) compile .pyc and "level 1" .pyo (--compile --optimize)
20+ # 4) compile "level 1" .pyo only (--no-compile --optimize)
21+ # 5) compile .pyc and "level 2" .pyo (--compile --optimize-more)
22+ # 6) compile "level 2" .pyo only (--no-compile --optimize-more)
23+ #
24+ # The UI for this is two option, 'compile' and 'optimize'.
25+ # 'compile' is strictly boolean, and only decides whether to
26+ # generate .pyc files. 'optimize' is three-way (0, 1, or 2), and
27+ # decides both whether to generate .pyo files and what level of
28+ # optimization to use.
29+
1430 user_options = [
1531 ('install-dir=' , 'd' , "directory to install to" ),
1632 ('build-dir=' ,'b' , "build directory (where to install from)" ),
1733 ('force' , 'f' , "force installation (overwrite existing files)" ),
18- ('compile' , 'c' , "compile .py to .pyc" ),
19- ('optimize' , 'o' , "compile .py to .pyo (optimized)" ),
34+ ('compile' , 'c' , "compile .py to .pyc [default]" ),
35+ ('no-compile' , None , "don't compile .py files" ),
36+ ('optimize=' , 'O' ,
37+ "also compile with optimization: -O1 for \" python -O\" , "
38+ "-O2 for \" python -OO\" , and -O0 to disable [default: -O0]" ),
2039 ('skip-build' , None , "skip the build steps" ),
2140 ]
2241
23- boolean_options = ['force' , 'compile' , 'optimize' , 'skip-build' ]
42+ boolean_options = ['force' , 'compile' , 'skip-build' ]
43+ negative_opt = {'no-compile' : 'compile' }
2444
2545
2646 def initialize_options (self ):
2747 # let the 'install' command dictate our installation directory
2848 self .install_dir = None
2949 self .build_dir = None
3050 self .force = 0
31- self .compile = 1
32- self .optimize = 1
51+ self .compile = None
52+ self .optimize = None
3353 self .skip_build = None
3454
3555 def finalize_options (self ):
@@ -41,11 +61,25 @@ def finalize_options (self):
4161 ('build_lib' , 'build_dir' ),
4262 ('install_lib' , 'install_dir' ),
4363 ('force' , 'force' ),
44- ('compile_py ' , 'compile' ),
45- ('optimize_py ' , 'optimize' ),
64+ ('compile ' , 'compile' ),
65+ ('optimize ' , 'optimize' ),
4666 ('skip_build' , 'skip_build' ),
4767 )
4868
69+ if self .compile is None :
70+ self .compile = 1
71+ if self .optimize is None :
72+ self .optimize = 0
73+
74+ print "install_lib: compile=%s, optimize=%s" % \
75+ (`self.compile` , `self.optimize` )
76+ if type (self .optimize ) is not IntType :
77+ try :
78+ self .optimize = int (self .optimize )
79+ assert 0 <= self .optimize <= 2
80+ except (ValueError , AssertionError ):
81+ raise DistutilsOptionError , "optimize must be 0, 1, or 2"
82+
4983 def run (self ):
5084
5185 # Make sure we have built everything we need first
@@ -58,7 +92,7 @@ def run (self):
5892
5993 # (Optionally) compile .py to .pyc
6094 if outfiles is not None and self .distribution .has_pure_modules ():
61- self .bytecompile (outfiles )
95+ self .byte_compile (outfiles )
6296
6397 # run ()
6498
@@ -82,10 +116,25 @@ def install (self):
82116 return
83117 return outfiles
84118
85- def bytecompile (self , files ):
86- byte_compile (files ,
87- force = self .force ,
88- verbose = self .verbose , dry_run = self .dry_run )
119+ def byte_compile (self , files ):
120+ from distutils .util import byte_compile
121+
122+ # Get the "--root" directory supplied to the "install" command,
123+ # and use it as a prefix to strip off the purported filename
124+ # encoded in bytecode files. This is far from complete, but it
125+ # should at least generate usable bytecode in RPM distributions.
126+ install_root = self .get_finalized_command ('install' ).root
127+
128+ if self .compile :
129+ byte_compile (files , optimize = 0 ,
130+ force = self .force ,
131+ prefix = install_root ,
132+ verbose = self .verbose , dry_run = self .dry_run )
133+ if self .optimize > 0 :
134+ byte_compile (files , optimize = self .optimize ,
135+ force = self .force ,
136+ prefix = install_root ,
137+ verbose = self .verbose , dry_run = self .dry_run )
89138
90139
91140 # -- Utility methods -----------------------------------------------
@@ -111,8 +160,10 @@ def _mutate_outputs (self, has_any, build_cmd, cmd_option, output_dir):
111160 def _bytecode_filenames (self , py_filenames ):
112161 bytecode_files = []
113162 for py_file in py_filenames :
114- bytecode = py_file + (__debug__ and "c" or "o" )
115- bytecode_files .append (bytecode )
163+ if self .compile :
164+ bytecode_files .append (py_file + "c" )
165+ if self .optmize > 0 :
166+ bytecode_files .append (py_file + "o" )
116167
117168 return bytecode_files
118169
0 commit comments