cleaned up distutils.command.build_py

This commit is contained in:
Tarek Ziadé 2009-07-03 09:01:07 +00:00
parent 65ec61ed06
commit fe97ebbf62

View file

@ -4,12 +4,11 @@ Implements the Distutils 'build_py' command."""
__revision__ = "$Id$" __revision__ = "$Id$"
import string, os import os
from types import *
from glob import glob from glob import glob
from distutils.core import Command from distutils.core import Command
from distutils.errors import * from distutils.errors import DistutilsOptionError, DistutilsFileError
from distutils.util import convert_path from distutils.util import convert_path
from distutils import log from distutils import log
@ -30,7 +29,6 @@ class build_py (Command):
boolean_options = ['compile', 'force'] boolean_options = ['compile', 'force']
negative_opt = {'no-compile' : 'compile'} negative_opt = {'no-compile' : 'compile'}
def initialize_options(self): def initialize_options(self):
self.build_lib = None self.build_lib = None
self.py_modules = None self.py_modules = None
@ -59,15 +57,14 @@ class build_py (Command):
# Ick, copied straight from install_lib.py (fancy_getopt needs a # Ick, copied straight from install_lib.py (fancy_getopt needs a
# type system! Hell, *everything* needs a type system!!!) # type system! Hell, *everything* needs a type system!!!)
if type(self.optimize) is not IntType: if not isinstance(self.optimize, int):
try: try:
self.optimize = int(self.optimize) self.optimize = int(self.optimize)
assert 0 <= self.optimize <= 2 assert 0 <= self.optimize <= 2
except (ValueError, AssertionError): except (ValueError, AssertionError):
raise DistutilsOptionError, "optimize must be 0, 1, or 2" raise DistutilsOptionError("optimize must be 0, 1, or 2")
def run(self): def run(self):
# XXX copy_file by default preserves atime and mtime. IMHO this is # 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 # the right thing to do, but perhaps it should be an option -- in
# particular, a site administrator might want installed files to # particular, a site administrator might want installed files to
@ -97,8 +94,6 @@ class build_py (Command):
self.byte_compile(self.get_outputs(include_bytecode=0)) self.byte_compile(self.get_outputs(include_bytecode=0))
# run ()
def get_data_files(self): def get_data_files(self):
"""Generate list of '(package,src_dir,build_dir,filenames)' tuples""" """Generate list of '(package,src_dir,build_dir,filenames)' tuples"""
data = [] data = []
@ -150,18 +145,18 @@ class build_py (Command):
distribution, where package 'package' should be found distribution, where package 'package' should be found
(at least according to the 'package_dir' option, if any).""" (at least according to the 'package_dir' option, if any)."""
path = string.split(package, '.') path = package.split('.')
if not self.package_dir: if not self.package_dir:
if path: if path:
return apply(os.path.join, path) return os.path.join(*path)
else: else:
return '' return ''
else: else:
tail = [] tail = []
while path: while path:
try: try:
pdir = self.package_dir[string.join(path, '.')] pdir = self.package_dir['.'.join(path)]
except KeyError: except KeyError:
tail.insert(0, path[-1]) tail.insert(0, path[-1])
del path[-1] del path[-1]
@ -181,27 +176,23 @@ class build_py (Command):
tail.insert(0, pdir) tail.insert(0, pdir)
if tail: if tail:
return apply(os.path.join, tail) return os.path.join(*tail)
else: else:
return '' return ''
# get_package_dir ()
def check_package(self, package, package_dir): def check_package(self, package, package_dir):
# Empty dir name means current directory, which we can probably # Empty dir name means current directory, which we can probably
# assume exists. Also, os.path.exists and isdir don't know about # assume exists. Also, os.path.exists and isdir don't know about
# my "empty string means current dir" convention, so we have to # my "empty string means current dir" convention, so we have to
# circumvent them. # circumvent them.
if package_dir != "": if package_dir != "":
if not os.path.exists(package_dir): if not os.path.exists(package_dir):
raise DistutilsFileError, \ raise DistutilsFileError(
"package directory '%s' does not exist" % package_dir "package directory '%s' does not exist" % package_dir)
if not os.path.isdir(package_dir): if not os.path.isdir(package_dir):
raise DistutilsFileError, \ raise DistutilsFileError(
("supposed package directory '%s' exists, " + "supposed package directory '%s' exists, "
"but is not a directory") % package_dir "but is not a directory" % package_dir)
# Require __init__.py for all but the "root package" # Require __init__.py for all but the "root package"
if package: if package:
@ -216,18 +207,12 @@ class build_py (Command):
# __init__.py doesn't exist -- so don't return the filename. # __init__.py doesn't exist -- so don't return the filename.
return None return None
# check_package ()
def check_module(self, module, module_file): def check_module(self, module, module_file):
if not os.path.isfile(module_file): if not os.path.isfile(module_file):
log.warn("file %s (for module %s) not found", module_file, module) log.warn("file %s (for module %s) not found", module_file, module)
return 0 return False
else: else:
return 1 return True
# check_module ()
def find_package_modules(self, package, package_dir): def find_package_modules(self, package, package_dir):
self.check_package(package, package_dir) self.check_package(package, package_dir)
@ -244,7 +229,6 @@ class build_py (Command):
self.debug_print("excluding %s" % setup_script) self.debug_print("excluding %s" % setup_script)
return modules return modules
def find_modules(self): def find_modules(self):
"""Finds individually-specified Python modules, ie. those listed by """Finds individually-specified Python modules, ie. those listed by
module name in 'self.py_modules'. Returns a list of tuples (package, module name in 'self.py_modules'. Returns a list of tuples (package,
@ -254,7 +238,6 @@ class build_py (Command):
".py" file (relative to the distribution root) that implements the ".py" file (relative to the distribution root) that implements the
module. module.
""" """
# Map package names to tuples of useful info about the package: # Map package names to tuples of useful info about the package:
# (package_dir, checked) # (package_dir, checked)
# package_dir - the directory where we'll find source files for # package_dir - the directory where we'll find source files for
@ -270,10 +253,9 @@ class build_py (Command):
# just the "package" for a toplevel is empty (either an empty # just the "package" for a toplevel is empty (either an empty
# string or empty list, depending on context). Differences: # string or empty list, depending on context). Differences:
# - don't check for __init__.py in directory for empty package # - don't check for __init__.py in directory for empty package
for module in self.py_modules: for module in self.py_modules:
path = string.split(module, '.') path = module.split('.')
package = string.join(path[0:-1], '.') package = '.'.join(path[0:-1])
module_base = path[-1] module_base = path[-1]
try: try:
@ -299,16 +281,12 @@ class build_py (Command):
return modules return modules
# find_modules ()
def find_all_modules(self): def find_all_modules(self):
"""Compute the list of all modules that will be built, whether """Compute the list of all modules that will be built, whether
they are specified one-module-at-a-time ('self.py_modules') or they are specified one-module-at-a-time ('self.py_modules') or
by whole packages ('self.packages'). Return a list of tuples by whole packages ('self.packages'). Return a list of tuples
(package, module, module_file), just like 'find_modules()' and (package, module, module_file), just like 'find_modules()' and
'find_package_modules()' do.""" 'find_package_modules()' do."""
modules = [] modules = []
if self.py_modules: if self.py_modules:
modules.extend(self.find_modules()) modules.extend(self.find_modules())
@ -317,32 +295,20 @@ class build_py (Command):
package_dir = self.get_package_dir(package) package_dir = self.get_package_dir(package)
m = self.find_package_modules(package, package_dir) m = self.find_package_modules(package, package_dir)
modules.extend(m) modules.extend(m)
return modules return modules
# find_all_modules ()
def get_source_files(self): def get_source_files(self):
return [module[-1] for module in self.find_all_modules()]
modules = self.find_all_modules()
filenames = []
for module in modules:
filenames.append(module[-1])
return filenames
def get_module_outfile(self, build_dir, package, module): def get_module_outfile(self, build_dir, package, module):
outfile_path = [build_dir] + list(package) + [module + ".py"] outfile_path = [build_dir] + list(package) + [module + ".py"]
return os.path.join(*outfile_path) return os.path.join(*outfile_path)
def get_outputs(self, include_bytecode=1): def get_outputs(self, include_bytecode=1):
modules = self.find_all_modules() modules = self.find_all_modules()
outputs = [] outputs = []
for (package, module, module_file) in modules: for (package, module, module_file) in modules:
package = string.split(package, '.') package = package.split('.')
filename = self.get_module_outfile(self.build_lib, package, module) filename = self.get_module_outfile(self.build_lib, package, module)
outputs.append(filename) outputs.append(filename)
if include_bytecode: if include_bytecode:
@ -359,13 +325,12 @@ class build_py (Command):
return outputs return outputs
def build_module(self, module, module_file, package): def build_module(self, module, module_file, package):
if type(package) is StringType: if isinstance(package, str):
package = string.split(package, '.') package = package.split('.')
elif type(package) not in (ListType, TupleType): elif not isinstance(package, (list, tuple)):
raise TypeError, \ raise TypeError(
"'package' must be a string (dot-separated), list, or tuple" "'package' must be a string (dot-separated), list, or tuple")
# Now put the module source file into the "build" area -- this is # Now put the module source file into the "build" area -- this is
# easy, we just copy it somewhere under self.build_lib (the build # easy, we just copy it somewhere under self.build_lib (the build
@ -375,9 +340,7 @@ class build_py (Command):
self.mkpath(dir) self.mkpath(dir)
return self.copy_file(module_file, outfile, preserve_mode=0) return self.copy_file(module_file, outfile, preserve_mode=0)
def build_modules(self): def build_modules(self):
modules = self.find_modules() modules = self.find_modules()
for (package, module, module_file) in modules: for (package, module, module_file) in modules:
@ -387,11 +350,7 @@ class build_py (Command):
# under self.build_lib.) # under self.build_lib.)
self.build_module(module, module_file, package) self.build_module(module, module_file, package)
# build_modules ()
def build_packages(self): def build_packages(self):
for package in self.packages: for package in self.packages:
# Get list of (package, module, module_file) tuples based on # Get list of (package, module, module_file) tuples based on
@ -412,9 +371,6 @@ class build_py (Command):
assert package == package_ assert package == package_
self.build_module(module, module_file, package) self.build_module(module, module_file, package)
# build_packages ()
def byte_compile(self, files): def byte_compile(self, files):
from distutils.util import byte_compile from distutils.util import byte_compile
prefix = self.build_lib prefix = self.build_lib
@ -431,5 +387,3 @@ class build_py (Command):
if self.optimize > 0: if self.optimize > 0:
byte_compile(files, optimize=self.optimize, byte_compile(files, optimize=self.optimize,
force=self.force, prefix=prefix, dry_run=self.dry_run) force=self.force, prefix=prefix, dry_run=self.dry_run)
# class build_py