mirror of
https://github.com/python/cpython.git
synced 2025-07-31 23:23:11 +00:00
cleaned up distutils.command.build_py
This commit is contained in:
parent
65ec61ed06
commit
fe97ebbf62
1 changed files with 44 additions and 90 deletions
|
@ -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):
|
||||||
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):
|
||||||
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):
|
||||||
|
|
||||||
# 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):
|
||||||
|
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
# __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):
|
||||||
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):
|
||||||
".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):
|
||||||
|
return [module[-1] for module in self.find_all_modules()]
|
||||||
|
|
||||||
|
def get_module_outfile(self, build_dir, package, module):
|
||||||
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):
|
|
||||||
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 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):
|
||||||
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,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):
|
||||||
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
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue