| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | """distutils.command.build_py
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Implements the Distutils 'build_py' command."""
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-19 13:12:28 +00:00
										 |  |  | # This module should be kept compatible with Python 1.5.2. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-02 01:49:45 +00:00
										 |  |  | __revision__ = "$Id$" | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-12-12 17:03:59 +00:00
										 |  |  | import sys, string, os | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  | from types import * | 
					
						
							|  |  |  | from glob import glob | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | from distutils.core import Command | 
					
						
							|  |  |  | from distutils.errors import * | 
					
						
							| 
									
										
										
										
											2002-02-01 09:44:09 +00:00
										 |  |  | from distutils.util import convert_path | 
					
						
							| 
									
										
										
										
											2002-06-04 20:14:43 +00:00
										 |  |  | from distutils import log | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-18 00:13:53 +00:00
										 |  |  | class build_py (Command): | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-01-30 18:34:15 +00:00
										 |  |  |     description = "\"build\" pure Python modules (copy to build directory)" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-18 00:25:39 +00:00
										 |  |  |     user_options = [ | 
					
						
							| 
									
										
										
										
											2000-03-01 01:19:37 +00:00
										 |  |  |         ('build-lib=', 'd', "directory to \"build\" (copy) to"), | 
					
						
							| 
									
										
										
										
											2000-10-02 02:19:04 +00:00
										 |  |  |         ('compile', 'c', "compile .py to .pyc"), | 
					
						
							|  |  |  |         ('no-compile', None, "don't compile .py files [default]"), | 
					
						
							|  |  |  |         ('optimize=', 'O', | 
					
						
							|  |  |  |          "also compile with optimization: -O1 for \"python -O\", " | 
					
						
							|  |  |  |          "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), | 
					
						
							| 
									
										
										
										
											2000-09-06 02:06:27 +00:00
										 |  |  |         ('force', 'f', "forcibly build everything (ignore file timestamps)"), | 
					
						
							| 
									
										
										
										
											2000-02-18 00:25:39 +00:00
										 |  |  |         ] | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-10-02 02:19:04 +00:00
										 |  |  |     boolean_options = ['compile', 'force'] | 
					
						
							|  |  |  |     negative_opt = {'no-compile' : 'compile'} | 
					
						
							| 
									
										
										
										
											2000-09-25 01:41:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-18 00:35:22 +00:00
										 |  |  |     def initialize_options (self): | 
					
						
							| 
									
										
										
										
											2000-03-01 01:19:37 +00:00
										 |  |  |         self.build_lib = None | 
					
						
							| 
									
										
										
										
											2000-06-04 13:42:52 +00:00
										 |  |  |         self.py_modules = None | 
					
						
							| 
									
										
										
										
											1999-09-08 02:42:30 +00:00
										 |  |  |         self.package = None | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |         self.package_dir = None | 
					
						
							| 
									
										
										
										
											2000-10-02 02:19:04 +00:00
										 |  |  |         self.compile = 0 | 
					
						
							|  |  |  |         self.optimize = 0 | 
					
						
							| 
									
										
										
										
											2000-04-10 00:19:42 +00:00
										 |  |  |         self.force = None | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-18 00:35:22 +00:00
										 |  |  |     def finalize_options (self): | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |         self.set_undefined_options('build', | 
					
						
							|  |  |  |                                    ('build_lib', 'build_lib'), | 
					
						
							|  |  |  |                                    ('force', 'force')) | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Get the distribution options that are aliases for build_py | 
					
						
							|  |  |  |         # options -- list of packages and list of modules. | 
					
						
							|  |  |  |         self.packages = self.distribution.packages | 
					
						
							| 
									
										
										
										
											2000-06-04 13:42:52 +00:00
										 |  |  |         self.py_modules = self.distribution.py_modules | 
					
						
							| 
									
										
										
										
											2002-02-01 09:44:09 +00:00
										 |  |  |         self.package_dir = {} | 
					
						
							|  |  |  |         if self.distribution.package_dir: | 
					
						
							|  |  |  |             for name, path in self.distribution.package_dir.items(): | 
					
						
							|  |  |  |                 self.package_dir[name] = convert_path(path) | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-10-02 02:19:04 +00:00
										 |  |  |         # Ick, copied straight from install_lib.py (fancy_getopt needs a | 
					
						
							|  |  |  |         # type system!  Hell, *everything* needs a type system!!!) | 
					
						
							|  |  |  |         if type(self.optimize) is not IntType: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 self.optimize = int(self.optimize) | 
					
						
							|  |  |  |                 assert 0 <= self.optimize <= 2 | 
					
						
							|  |  |  |             except (ValueError, AssertionError): | 
					
						
							|  |  |  |                 raise DistutilsOptionError, "optimize must be 0, 1, or 2" | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def run (self): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-12-12 17:03:59 +00:00
										 |  |  |         # XXX copy_file by default preserves atime and mtime.  IMHO this is | 
					
						
							|  |  |  |         # the right thing to do, but perhaps it should be an option -- in | 
					
						
							|  |  |  |         # particular, a site administrator might want installed files to | 
					
						
							|  |  |  |         # reflect the time of installation rather than the last | 
					
						
							|  |  |  |         # modification time before the installed release. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # XXX copy_file by default preserves mode, which appears to be the | 
					
						
							|  |  |  |         # wrong thing to do: if a file is read-only in the working | 
					
						
							|  |  |  |         # directory, we want it to be installed read/write so that the next | 
					
						
							|  |  |  |         # installation of the same module distribution can overwrite it | 
					
						
							|  |  |  |         # without problems.  (This might be a Unix-specific issue.)  Thus | 
					
						
							|  |  |  |         # we turn off 'preserve_mode' when copying to the build directory, | 
					
						
							|  |  |  |         # since the build directory is supposed to be exactly what the | 
					
						
							|  |  |  |         # installation will look like (ie. we preserve mode when | 
					
						
							|  |  |  |         # installing). | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |         # Two options control which modules will be installed: 'packages' | 
					
						
							| 
									
										
										
										
											2000-06-04 13:42:52 +00:00
										 |  |  |         # and 'py_modules'.  The former lets us work with whole packages, not | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |         # specifying individual modules at all; the latter is for | 
					
						
							|  |  |  |         # specifying modules one-at-a-time.  Currently they are mutually | 
					
						
							|  |  |  |         # exclusive: you can define one or the other (or neither), but not | 
					
						
							|  |  |  |         # both.  It remains to be seen how limiting this is. | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |         # Dispose of the two "unusual" cases first: no pure Python modules | 
					
						
							|  |  |  |         # at all (no problem, just return silently), and over-specified | 
					
						
							| 
									
										
										
										
											2000-06-04 13:42:52 +00:00
										 |  |  |         # 'packages' and 'py_modules' options. | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-06-04 13:42:52 +00:00
										 |  |  |         if not self.py_modules and not self.packages: | 
					
						
							| 
									
										
										
										
											1999-08-29 18:19:01 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2000-06-04 13:42:52 +00:00
										 |  |  |         if self.py_modules and self.packages: | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |             raise DistutilsOptionError, \ | 
					
						
							| 
									
										
										
										
											2000-06-04 13:42:52 +00:00
										 |  |  |                   "build_py: supplying both 'packages' and 'py_modules' " + \ | 
					
						
							| 
									
										
										
										
											1999-12-12 17:03:59 +00:00
										 |  |  |                   "options is not allowed" | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-06-04 13:42:52 +00:00
										 |  |  |         # Now we're down to two cases: 'py_modules' only and 'packages' only. | 
					
						
							|  |  |  |         if self.py_modules: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |             self.build_modules() | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |             self.build_packages() | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-10-02 02:19:04 +00:00
										 |  |  |         self.byte_compile(self.get_outputs(include_bytecode=0)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |     # run () | 
					
						
							| 
									
										
										
										
											2001-12-06 21:01:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def get_package_dir (self, package): | 
					
						
							|  |  |  |         """Return the directory, relative to the top of the source
 | 
					
						
							|  |  |  |            distribution, where package 'package' should be found | 
					
						
							|  |  |  |            (at least according to the 'package_dir' option, if any)."""
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |         path = string.split(package, '.') | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if not self.package_dir: | 
					
						
							| 
									
										
										
										
											1999-12-03 16:18:56 +00:00
										 |  |  |             if path: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |                 return apply(os.path.join, path) | 
					
						
							| 
									
										
										
										
											1999-12-03 16:18:56 +00:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 return '' | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             tail = [] | 
					
						
							|  |  |  |             while path: | 
					
						
							|  |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |                     pdir = self.package_dir[string.join(path, '.')] | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |                 except KeyError: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |                     tail.insert(0, path[-1]) | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |                     del path[-1] | 
					
						
							|  |  |  |                 else: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |                     tail.insert(0, pdir) | 
					
						
							|  |  |  |                     return apply(os.path.join, tail) | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2000-05-26 00:44:06 +00:00
										 |  |  |                 # Oops, got all the way through 'path' without finding a | 
					
						
							|  |  |  |                 # match in package_dir.  If package_dir defines a directory | 
					
						
							|  |  |  |                 # for the root (nameless) package, then fallback on it; | 
					
						
							|  |  |  |                 # otherwise, we might as well have not consulted | 
					
						
							|  |  |  |                 # package_dir at all, as we just use the directory implied | 
					
						
							|  |  |  |                 # by 'tail' (which should be the same as the original value | 
					
						
							|  |  |  |                 # of 'path' at this point). | 
					
						
							|  |  |  |                 pdir = self.package_dir.get('') | 
					
						
							|  |  |  |                 if pdir is not None: | 
					
						
							|  |  |  |                     tail.insert(0, pdir) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-12-03 16:18:56 +00:00
										 |  |  |                 if tail: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |                     return apply(os.path.join, tail) | 
					
						
							| 
									
										
										
										
											1999-12-03 16:18:56 +00:00
										 |  |  |                 else: | 
					
						
							|  |  |  |                     return '' | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # get_package_dir () | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def check_package (self, package, package_dir): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Empty dir name means current directory, which we can probably | 
					
						
							|  |  |  |         # assume exists.  Also, os.path.exists and isdir don't know about | 
					
						
							|  |  |  |         # my "empty string means current dir" convention, so we have to | 
					
						
							|  |  |  |         # circumvent them. | 
					
						
							|  |  |  |         if package_dir != "": | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |             if not os.path.exists(package_dir): | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |                 raise DistutilsFileError, \ | 
					
						
							|  |  |  |                       "package directory '%s' does not exist" % package_dir | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |             if not os.path.isdir(package_dir): | 
					
						
							| 
									
										
										
										
											2000-03-03 03:00:27 +00:00
										 |  |  |                 raise DistutilsFileError, \ | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |                       ("supposed package directory '%s' exists, " + | 
					
						
							|  |  |  |                        "but is not a directory") % package_dir | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Require __init__.py for all but the "root package" | 
					
						
							| 
									
										
										
										
											1999-12-03 16:18:56 +00:00
										 |  |  |         if package: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |             init_py = os.path.join(package_dir, "__init__.py") | 
					
						
							|  |  |  |             if os.path.isfile(init_py): | 
					
						
							| 
									
										
										
										
											2000-05-26 00:44:06 +00:00
										 |  |  |                 return init_py | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2002-06-04 20:14:43 +00:00
										 |  |  |                 log.warn(("package init file '%s' not found " + | 
					
						
							|  |  |  |                           "(or not a regular file)"), init_py) | 
					
						
							| 
									
										
										
										
											2000-05-26 00:44:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Either not in a package at all (__init__.py not expected), or | 
					
						
							|  |  |  |         # __init__.py doesn't exist -- so don't return the filename. | 
					
						
							| 
									
										
										
										
											2002-06-04 21:00:20 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2001-12-06 21:01:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |     # check_package () | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def check_module (self, module, module_file): | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |         if not os.path.isfile(module_file): | 
					
						
							| 
									
										
										
										
											2002-06-04 20:14:43 +00:00
										 |  |  |             log.warn("file %s (for module %s) not found", module_file, module) | 
					
						
							| 
									
										
										
										
											2002-04-04 23:17:31 +00:00
										 |  |  |             return 0 | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2002-04-04 23:17:31 +00:00
										 |  |  |             return 1 | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # check_module () | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  |     def find_package_modules (self, package, package_dir): | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |         self.check_package(package, package_dir) | 
					
						
							|  |  |  |         module_files = glob(os.path.join(package_dir, "*.py")) | 
					
						
							| 
									
										
										
										
											2000-03-29 02:10:51 +00:00
										 |  |  |         modules = [] | 
					
						
							| 
									
										
										
										
											2000-08-29 01:15:18 +00:00
										 |  |  |         setup_script = os.path.abspath(self.distribution.script_name) | 
					
						
							| 
									
										
										
										
											1999-12-12 17:03:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |         for f in module_files: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |             abs_f = os.path.abspath(f) | 
					
						
							| 
									
										
										
										
											1999-12-12 17:03:59 +00:00
										 |  |  |             if abs_f != setup_script: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |                 module = os.path.splitext(os.path.basename(f))[0] | 
					
						
							|  |  |  |                 modules.append((package, module, f)) | 
					
						
							| 
									
										
										
										
											2000-08-29 01:15:18 +00:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 self.debug_print("excluding %s" % setup_script) | 
					
						
							| 
									
										
										
										
											2000-03-29 02:10:51 +00:00
										 |  |  |         return modules | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  |     def find_modules (self): | 
					
						
							| 
									
										
										
										
											2000-05-26 00:44:06 +00:00
										 |  |  |         """Finds individually-specified Python modules, ie. those listed by
 | 
					
						
							| 
									
										
										
										
											2000-06-04 13:42:52 +00:00
										 |  |  |         module name in 'self.py_modules'.  Returns a list of tuples (package, | 
					
						
							| 
									
										
										
										
											2000-05-26 00:44:06 +00:00
										 |  |  |         module_base, filename): 'package' is a tuple of the path through | 
					
						
							|  |  |  |         package-space to the module; 'module_base' is the bare (no | 
					
						
							|  |  |  |         packages, no dots) module name, and 'filename' is the path to the | 
					
						
							|  |  |  |         ".py" file (relative to the distribution root) that implements the | 
					
						
							|  |  |  |         module. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |         # Map package names to tuples of useful info about the package: | 
					
						
							|  |  |  |         #    (package_dir, checked) | 
					
						
							|  |  |  |         # package_dir - the directory where we'll find source files for | 
					
						
							|  |  |  |         #   this package | 
					
						
							|  |  |  |         # checked - true if we have checked that the package directory | 
					
						
							|  |  |  |         #   is valid (exists, contains __init__.py, ... ?) | 
					
						
							|  |  |  |         packages = {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-26 00:44:06 +00:00
										 |  |  |         # List of (package, module, filename) tuples to return | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  |         modules = [] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |         # We treat modules-in-packages almost the same as toplevel modules, | 
					
						
							|  |  |  |         # just the "package" for a toplevel is empty (either an empty | 
					
						
							|  |  |  |         # string or empty list, depending on context).  Differences: | 
					
						
							|  |  |  |         #   - don't check for __init__.py in directory for empty package | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-06-04 13:42:52 +00:00
										 |  |  |         for module in self.py_modules: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |             path = string.split(module, '.') | 
					
						
							| 
									
										
										
										
											2000-08-15 13:01:25 +00:00
										 |  |  |             package = string.join(path[0:-1], '.') | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  |             module_base = path[-1] | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 (package_dir, checked) = packages[package] | 
					
						
							|  |  |  |             except KeyError: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |                 package_dir = self.get_package_dir(package) | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |                 checked = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if not checked: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |                 init_py = self.check_package(package, package_dir) | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |                 packages[package] = (package_dir, 1) | 
					
						
							| 
									
										
										
										
											2000-05-26 00:44:06 +00:00
										 |  |  |                 if init_py: | 
					
						
							|  |  |  |                     modules.append((package, "__init__", init_py)) | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # XXX perhaps we should also check for just .pyc files | 
					
						
							|  |  |  |             # (so greedy closed-source bastards can distribute Python | 
					
						
							|  |  |  |             # modules too) | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |             module_file = os.path.join(package_dir, module_base + ".py") | 
					
						
							|  |  |  |             if not self.check_module(module, module_file): | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |             modules.append((package, module_base, module_file)) | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return modules | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # find_modules () | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-29 02:10:51 +00:00
										 |  |  |     def find_all_modules (self): | 
					
						
							|  |  |  |         """Compute the list of all modules that will be built, whether
 | 
					
						
							| 
									
										
										
										
											2000-06-04 13:42:52 +00:00
										 |  |  |         they are specified one-module-at-a-time ('self.py_modules') or | 
					
						
							| 
									
										
										
										
											2000-03-29 02:10:51 +00:00
										 |  |  |         by whole packages ('self.packages').  Return a list of tuples | 
					
						
							|  |  |  |         (package, module, module_file), just like 'find_modules()' and | 
					
						
							|  |  |  |         'find_package_modules()' do."""
 | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-06-04 13:42:52 +00:00
										 |  |  |         if self.py_modules: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |             modules = self.find_modules() | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             modules = [] | 
					
						
							|  |  |  |             for package in self.packages: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |                 package_dir = self.get_package_dir(package) | 
					
						
							|  |  |  |                 m = self.find_package_modules(package, package_dir) | 
					
						
							|  |  |  |                 modules.extend(m) | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-29 02:10:51 +00:00
										 |  |  |         return modules | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # find_all_modules () | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_source_files (self): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |         modules = self.find_all_modules() | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  |         filenames = [] | 
					
						
							|  |  |  |         for module in modules: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |             filenames.append(module[-1]) | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-29 02:10:51 +00:00
										 |  |  |         return filenames | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-29 02:10:51 +00:00
										 |  |  |     def get_module_outfile (self, build_dir, package, module): | 
					
						
							|  |  |  |         outfile_path = [build_dir] + list(package) + [module + ".py"] | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |         return apply(os.path.join, outfile_path) | 
					
						
							| 
									
										
										
										
											2000-03-29 02:10:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-10-02 02:19:04 +00:00
										 |  |  |     def get_outputs (self, include_bytecode=1): | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |         modules = self.find_all_modules() | 
					
						
							| 
									
										
										
										
											2000-03-29 02:10:51 +00:00
										 |  |  |         outputs = [] | 
					
						
							|  |  |  |         for (package, module, module_file) in modules: | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |             package = string.split(package, '.') | 
					
						
							| 
									
										
										
										
											2000-10-02 02:19:04 +00:00
										 |  |  |             filename = self.get_module_outfile(self.build_lib, package, module) | 
					
						
							|  |  |  |             outputs.append(filename) | 
					
						
							|  |  |  |             if include_bytecode: | 
					
						
							|  |  |  |                 if self.compile: | 
					
						
							|  |  |  |                     outputs.append(filename + "c") | 
					
						
							|  |  |  |                 if self.optimize > 0: | 
					
						
							|  |  |  |                     outputs.append(filename + "o") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-29 02:10:51 +00:00
										 |  |  |         return outputs | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-29 02:10:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def build_module (self, module, module_file, package): | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |         if type(package) is StringType: | 
					
						
							|  |  |  |             package = string.split(package, '.') | 
					
						
							|  |  |  |         elif type(package) not in (ListType, TupleType): | 
					
						
							| 
									
										
										
										
											1999-12-03 16:18:56 +00:00
										 |  |  |             raise TypeError, \ | 
					
						
							|  |  |  |                   "'package' must be a string (dot-separated), list, or tuple" | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Now put the module source file into the "build" area -- this is | 
					
						
							| 
									
										
										
										
											2000-03-01 01:19:37 +00:00
										 |  |  |         # easy, we just copy it somewhere under self.build_lib (the build | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  |         # directory for Python source). | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |         outfile = self.get_module_outfile(self.build_lib, package, module) | 
					
						
							|  |  |  |         dir = os.path.dirname(outfile) | 
					
						
							|  |  |  |         self.mkpath(dir) | 
					
						
							|  |  |  |         return self.copy_file(module_file, outfile, preserve_mode=0) | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def build_modules (self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         modules = self.find_modules() | 
					
						
							| 
									
										
										
										
											2000-03-29 02:10:51 +00:00
										 |  |  |         for (package, module, module_file) in modules: | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  |             # Now "build" the module -- ie. copy the source file to | 
					
						
							| 
									
										
										
										
											2000-03-01 01:19:37 +00:00
										 |  |  |             # self.build_lib (the build directory for Python source). | 
					
						
							| 
									
										
										
										
											1999-09-29 12:44:57 +00:00
										 |  |  |             # (Actually, it gets copied to the directory for this package | 
					
						
							| 
									
										
										
										
											2000-03-01 01:19:37 +00:00
										 |  |  |             # under self.build_lib.) | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |             self.build_module(module, module_file, package) | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # build_modules () | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def build_packages (self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for package in self.packages: | 
					
						
							| 
									
										
										
										
											2000-03-29 02:10:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # Get list of (package, module, module_file) tuples based on | 
					
						
							|  |  |  |             # scanning the package directory.  'package' is only included | 
					
						
							|  |  |  |             # in the tuple so that 'find_modules()' and | 
					
						
							|  |  |  |             # 'find_package_tuples()' have a consistent interface; it's | 
					
						
							|  |  |  |             # ignored here (apart from a sanity check).  Also, 'module' is | 
					
						
							|  |  |  |             # the *unqualified* module name (ie. no dots, no package -- we | 
					
						
							|  |  |  |             # already know its package!), and 'module_file' is the path to | 
					
						
							|  |  |  |             # the .py file, relative to the current directory | 
					
						
							|  |  |  |             # (ie. including 'package_dir'). | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |             package_dir = self.get_package_dir(package) | 
					
						
							|  |  |  |             modules = self.find_package_modules(package, package_dir) | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # Now loop over the modules we found, "building" each one (just | 
					
						
							| 
									
										
										
										
											2000-03-01 01:19:37 +00:00
										 |  |  |             # copy it to self.build_lib). | 
					
						
							| 
									
										
										
										
											2000-03-29 02:10:51 +00:00
										 |  |  |             for (package_, module, module_file) in modules: | 
					
						
							|  |  |  |                 assert package == package_ | 
					
						
							| 
									
										
										
										
											2000-09-30 18:27:54 +00:00
										 |  |  |                 self.build_module(module, module_file, package) | 
					
						
							| 
									
										
										
										
											1999-09-21 18:22:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # build_packages () | 
					
						
							| 
									
										
										
										
											2000-10-02 02:19:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def byte_compile (self, files): | 
					
						
							|  |  |  |         from distutils.util import byte_compile | 
					
						
							|  |  |  |         prefix = self.build_lib | 
					
						
							|  |  |  |         if prefix[-1] != os.sep: | 
					
						
							|  |  |  |             prefix = prefix + os.sep | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # XXX this code is essentially the same as the 'byte_compile() | 
					
						
							|  |  |  |         # method of the "install_lib" command, except for the determination | 
					
						
							|  |  |  |         # of the 'prefix' string.  Hmmm. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if self.compile: | 
					
						
							|  |  |  |             byte_compile(files, optimize=0, | 
					
						
							| 
									
										
										
										
											2002-06-04 20:14:43 +00:00
										 |  |  |                          force=self.force, prefix=prefix, dry_run=self.dry_run) | 
					
						
							| 
									
										
										
										
											2000-10-02 02:19:04 +00:00
										 |  |  |         if self.optimize > 0: | 
					
						
							|  |  |  |             byte_compile(files, optimize=self.optimize, | 
					
						
							| 
									
										
										
										
											2002-06-04 20:14:43 +00:00
										 |  |  |                          force=self.force, prefix=prefix, dry_run=self.dry_run) | 
					
						
							| 
									
										
										
										
											2000-10-02 02:19:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-25 01:10:04 +00:00
										 |  |  | # class build_py |