Commit a09e1355 authored by Tarek Ziadé's avatar Tarek Ziadé

cleaned up distutils.command.build_py

parent 08842023
...@@ -4,16 +4,15 @@ Implements the Distutils 'build_py' command.""" ...@@ -4,16 +4,15 @@ 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
class build_py (Command): class build_py(Command):
description = "\"build\" pure Python modules (copy to build directory)" description = "\"build\" pure Python modules (copy to build directory)"
...@@ -30,8 +29,7 @@ class build_py (Command): ...@@ -30,8 +29,7 @@ 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
self.package = None self.package = None
...@@ -41,7 +39,7 @@ class build_py (Command): ...@@ -41,7 +39,7 @@ class build_py (Command):
self.optimize = 0 self.optimize = 0
self.force = None self.force = None
def finalize_options (self): def finalize_options(self):
self.set_undefined_options('build', self.set_undefined_options('build',
('build_lib', 'build_lib'), ('build_lib', 'build_lib'),
('force', 'force')) ('force', 'force'))
...@@ -59,15 +57,14 @@ class build_py (Command): ...@@ -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,9 +94,7 @@ class build_py (Command): ...@@ -97,9 +94,7 @@ 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 = []
if not self.packages: if not self.packages:
...@@ -123,7 +118,7 @@ class build_py (Command): ...@@ -123,7 +118,7 @@ class build_py (Command):
data.append((package, src_dir, build_dir, filenames)) data.append((package, src_dir, build_dir, filenames))
return data return data
def find_data_files (self, package, src_dir): def find_data_files(self, package, src_dir):
"""Return filenames for package's data files in 'src_dir'""" """Return filenames for package's data files in 'src_dir'"""
globs = (self.package_data.get('', []) globs = (self.package_data.get('', [])
+ self.package_data.get(package, [])) + self.package_data.get(package, []))
...@@ -135,7 +130,7 @@ class build_py (Command): ...@@ -135,7 +130,7 @@ class build_py (Command):
files.extend([fn for fn in filelist if fn not in files]) files.extend([fn for fn in filelist if fn not in files])
return files return files
def build_package_data (self): def build_package_data(self):
"""Copy data files into build directory""" """Copy data files into build directory"""
lastdir = None lastdir = None
for package, src_dir, build_dir, filenames in self.data_files: for package, src_dir, build_dir, filenames in self.data_files:
...@@ -145,23 +140,23 @@ class build_py (Command): ...@@ -145,23 +140,23 @@ class build_py (Command):
self.copy_file(os.path.join(src_dir, filename), target, self.copy_file(os.path.join(src_dir, filename), target,
preserve_mode=False) preserve_mode=False)
def get_package_dir (self, package): def get_package_dir(self, package):
"""Return the directory, relative to the top of the source """Return the directory, relative to the top of the source
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): ...@@ -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,20 +207,14 @@ class build_py (Command): ...@@ -216,20 +207,14 @@ 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)
module_files = glob(os.path.join(package_dir, "*.py")) module_files = glob(os.path.join(package_dir, "*.py"))
modules = [] modules = []
...@@ -244,8 +229,7 @@ class build_py (Command): ...@@ -244,8 +229,7 @@ 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,
module_base, filename): 'package' is a tuple of the path through module_base, filename): 'package' is a tuple of the path through
...@@ -254,7 +238,6 @@ class build_py (Command): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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):
return [module[-1] for module in self.find_all_modules()]
def get_source_files (self):
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): ...@@ -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 isinstance(package, str):
if type(package) is StringType: package = package.split('.')
package = string.split(package, '.') elif not isinstance(package, (list, tuple)):
elif type(package) not in (ListType, TupleType): 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): ...@@ -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): ...@@ -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,10 +371,7 @@ class build_py (Command): ...@@ -412,10 +371,7 @@ 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
if prefix[-1] != os.sep: if prefix[-1] != os.sep:
...@@ -431,5 +387,3 @@ class build_py (Command): ...@@ -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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment