build_py.py (9682B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\distutils\command\build_py.py 2 __revision__ = '$Id: build_py.py 82110 2010-06-20 13:38:51Z kristjan.jonsson $' 3 import os 4 import sys 5 from glob import glob 6 from distutils.core import Command 7 from distutils.errors import DistutilsOptionError, DistutilsFileError 8 from distutils.util import convert_path 9 from distutils import log 10 11 class build_py(Command): 12 description = '"build" pure Python modules (copy to build directory)' 13 user_options = [('build-lib=', 'd', 'directory to "build" (copy) to'), 14 ('compile', 'c', 'compile .py to .pyc'), 15 ('no-compile', None, "don't compile .py files [default]"), 16 ('optimize=', 'O', 'also compile with optimization: -O1 for "python -O", -O2 for "python -OO", and -O0 to disable [default: -O0]'), 17 ('force', 'f', 'forcibly build everything (ignore file timestamps)')] 18 boolean_options = ['compile', 'force'] 19 negative_opt = {'no-compile': 'compile'} 20 21 def initialize_options(self): 22 self.build_lib = None 23 self.py_modules = None 24 self.package = None 25 self.package_data = None 26 self.package_dir = None 27 self.compile = 0 28 self.optimize = 0 29 self.force = None 30 31 def finalize_options(self): 32 self.set_undefined_options('build', ('build_lib', 'build_lib'), ('force', 'force')) 33 self.packages = self.distribution.packages 34 self.py_modules = self.distribution.py_modules 35 self.package_data = self.distribution.package_data 36 self.package_dir = {} 37 if self.distribution.package_dir: 38 for name, path in self.distribution.package_dir.items(): 39 self.package_dir[name] = convert_path(path) 40 41 self.data_files = self.get_data_files() 42 if not isinstance(self.optimize, int): 43 try: 44 self.optimize = int(self.optimize) 45 except (ValueError, AssertionError): 46 raise DistutilsOptionError('optimize must be 0, 1, or 2') 47 48 def run(self): 49 if self.py_modules: 50 self.build_modules() 51 if self.packages: 52 self.build_packages() 53 self.build_package_data() 54 self.byte_compile(self.get_outputs(include_bytecode=0)) 55 56 def get_data_files(self): 57 data = [] 58 if not self.packages: 59 return data 60 for package in self.packages: 61 src_dir = self.get_package_dir(package) 62 build_dir = os.path.join(*([self.build_lib] + package.split('.'))) 63 plen = 0 64 if src_dir: 65 plen = len(src_dir) + 1 66 filenames = [ file[plen:] for file in self.find_data_files(package, src_dir) ] 67 data.append((package, 68 src_dir, 69 build_dir, 70 filenames)) 71 72 return data 73 74 def find_data_files(self, package, src_dir): 75 globs = self.package_data.get('', []) + self.package_data.get(package, []) 76 files = [] 77 for pattern in globs: 78 filelist = glob(os.path.join(src_dir, convert_path(pattern))) 79 files.extend([ fn for fn in filelist if fn not in files ]) 80 81 return files 82 83 def build_package_data(self): 84 for package, src_dir, build_dir, filenames in self.data_files: 85 for filename in filenames: 86 target = os.path.join(build_dir, filename) 87 self.mkpath(os.path.dirname(target)) 88 self.copy_file(os.path.join(src_dir, filename), target, preserve_mode=False) 89 90 def get_package_dir(self, package): 91 path = package.split('.') 92 if not self.package_dir: 93 if path: 94 return os.path.join(*path) 95 else: 96 return '' 97 else: 98 tail = [] 99 while path: 100 try: 101 pdir = self.package_dir['.'.join(path)] 102 except KeyError: 103 tail.insert(0, path[-1]) 104 del path[-1] 105 else: 106 tail.insert(0, pdir) 107 return os.path.join(*tail) 108 109 else: 110 pdir = self.package_dir.get('') 111 if pdir is not None: 112 tail.insert(0, pdir) 113 if tail: 114 return os.path.join(*tail) 115 return '' 116 117 def check_package(self, package, package_dir): 118 if package_dir != '': 119 if not os.path.exists(package_dir): 120 raise DistutilsFileError("package directory '%s' does not exist" % package_dir) 121 if not os.path.isdir(package_dir): 122 raise DistutilsFileError("supposed package directory '%s' exists, but is not a directory" % package_dir) 123 if package: 124 init_py = os.path.join(package_dir, '__init__.py') 125 if os.path.isfile(init_py): 126 return init_py 127 log.warn("package init file '%s' not found " + '(or not a regular file)', init_py) 128 129 def check_module(self, module, module_file): 130 if not os.path.isfile(module_file): 131 log.warn('file %s (for module %s) not found', module_file, module) 132 return False 133 else: 134 return True 135 136 def find_package_modules(self, package, package_dir): 137 self.check_package(package, package_dir) 138 module_files = glob(os.path.join(package_dir, '*.py')) 139 modules = [] 140 setup_script = os.path.abspath(self.distribution.script_name) 141 for f in module_files: 142 abs_f = os.path.abspath(f) 143 if abs_f != setup_script: 144 module = os.path.splitext(os.path.basename(f))[0] 145 modules.append((package, module, f)) 146 else: 147 self.debug_print('excluding %s' % setup_script) 148 149 return modules 150 151 def find_modules(self): 152 packages = {} 153 modules = [] 154 for module in self.py_modules: 155 path = module.split('.') 156 package = '.'.join(path[0:-1]) 157 module_base = path[-1] 158 try: 159 package_dir, checked = packages[package] 160 except KeyError: 161 package_dir = self.get_package_dir(package) 162 checked = 0 163 164 if not checked: 165 init_py = self.check_package(package, package_dir) 166 packages[package] = (package_dir, 1) 167 if init_py: 168 modules.append((package, '__init__', init_py)) 169 module_file = os.path.join(package_dir, module_base + '.py') 170 if not self.check_module(module, module_file): 171 continue 172 modules.append((package, module_base, module_file)) 173 174 return modules 175 176 def find_all_modules(self): 177 modules = [] 178 if self.py_modules: 179 modules.extend(self.find_modules()) 180 if self.packages: 181 for package in self.packages: 182 package_dir = self.get_package_dir(package) 183 m = self.find_package_modules(package, package_dir) 184 modules.extend(m) 185 186 return modules 187 188 def get_source_files(self): 189 return [ module[-1] for module in self.find_all_modules() ] 190 191 def get_module_outfile(self, build_dir, package, module): 192 outfile_path = [build_dir] + list(package) + [module + '.py'] 193 return os.path.join(*outfile_path) 194 195 def get_outputs(self, include_bytecode = 1): 196 modules = self.find_all_modules() 197 outputs = [] 198 for package, module, module_file in modules: 199 package = package.split('.') 200 filename = self.get_module_outfile(self.build_lib, package, module) 201 outputs.append(filename) 202 if include_bytecode: 203 if self.compile: 204 outputs.append(filename + 'c') 205 if self.optimize > 0: 206 outputs.append(filename + 'o') 207 208 outputs += [ os.path.join(build_dir, filename) for package, src_dir, build_dir, filenames in self.data_files for filename in filenames ] 209 return outputs 210 211 def build_module(self, module, module_file, package): 212 if isinstance(package, str): 213 package = package.split('.') 214 elif not isinstance(package, (list, tuple)): 215 raise TypeError("'package' must be a string (dot-separated), list, or tuple") 216 outfile = self.get_module_outfile(self.build_lib, package, module) 217 dir = os.path.dirname(outfile) 218 self.mkpath(dir) 219 return self.copy_file(module_file, outfile, preserve_mode=0) 220 221 def build_modules(self): 222 modules = self.find_modules() 223 for package, module, module_file in modules: 224 self.build_module(module, module_file, package) 225 226 def build_packages(self): 227 for package in self.packages: 228 package_dir = self.get_package_dir(package) 229 modules = self.find_package_modules(package, package_dir) 230 for package_, module, module_file in modules: 231 self.build_module(module, module_file, package) 232 233 def byte_compile(self, files): 234 if sys.dont_write_bytecode: 235 self.warn('byte-compiling is disabled, skipping.') 236 return 237 from distutils.util import byte_compile 238 prefix = self.build_lib 239 if prefix[-1] != os.sep: 240 prefix = prefix + os.sep 241 if self.compile: 242 byte_compile(files, optimize=0, force=self.force, prefix=prefix, dry_run=self.dry_run) 243 if self.optimize > 0: 244 byte_compile(files, optimize=self.optimize, force=self.force, prefix=prefix, dry_run=self.dry_run)