Back to index

python3.2  3.2.2
Public Member Functions | Public Attributes | Static Public Attributes
distutils.command.build_py.build_py Class Reference
Inheritance diagram for distutils.command.build_py.build_py:
Inheritance graph
[legend]
Collaboration diagram for distutils.command.build_py.build_py:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def initialize_options
def finalize_options
def run
def get_data_files
def find_data_files
def build_package_data
def get_package_dir
def check_package
def check_module
def find_package_modules
def find_modules
def find_all_modules
def get_source_files
def get_module_outfile
def get_outputs
def build_module
def build_modules
def build_packages
def byte_compile

Public Attributes

 build_lib
 py_modules
 package
 package_data
 package_dir
 compile
 optimize
 force
 packages
 data_files

Static Public Attributes

string description = "\"build\" pure Python modules (copy to build directory)"
list user_options
list boolean_options = ['compile', 'force']
dictionary negative_opt = {'no-compile' : 'compile'}

Detailed Description

Definition at line 14 of file build_py.py.


Member Function Documentation

def distutils.command.build_py.build_py.build_module (   self,
  module,
  module_file,
  package 
)

Reimplemented in distutils.command.build_py.build_py_2to3.

Definition at line 326 of file build_py.py.

00326 
00327     def build_module(self, module, module_file, package):
00328         if isinstance(package, str):
00329             package = package.split('.')
00330         elif not isinstance(package, (list, tuple)):
00331             raise TypeError(
00332                   "'package' must be a string (dot-separated), list, or tuple")
00333 
00334         # Now put the module source file into the "build" area -- this is
00335         # easy, we just copy it somewhere under self.build_lib (the build
00336         # directory for Python source).
00337         outfile = self.get_module_outfile(self.build_lib, package, module)
00338         dir = os.path.dirname(outfile)
00339         self.mkpath(dir)
00340         return self.copy_file(module_file, outfile, preserve_mode=0)

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 341 of file build_py.py.

00341 
00342     def build_modules(self):
00343         modules = self.find_modules()
00344         for (package, module, module_file) in modules:
00345             # Now "build" the module -- ie. copy the source file to
00346             # self.build_lib (the build directory for Python source).
00347             # (Actually, it gets copied to the directory for this package
00348             # under self.build_lib.)
00349             self.build_module(module, module_file, package)

Here is the call graph for this function:

Here is the caller graph for this function:

Copy data files into build directory

Definition at line 132 of file build_py.py.

00132 
00133     def build_package_data(self):
00134         """Copy data files into build directory"""
00135         lastdir = None
00136         for package, src_dir, build_dir, filenames in self.data_files:
00137             for filename in filenames:
00138                 target = os.path.join(build_dir, filename)
00139                 self.mkpath(os.path.dirname(target))
00140                 self.copy_file(os.path.join(src_dir, filename), target,
00141                                preserve_mode=False)

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 350 of file build_py.py.

00350 
00351     def build_packages(self):
00352         for package in self.packages:
00353             # Get list of (package, module, module_file) tuples based on
00354             # scanning the package directory.  'package' is only included
00355             # in the tuple so that 'find_modules()' and
00356             # 'find_package_tuples()' have a consistent interface; it's
00357             # ignored here (apart from a sanity check).  Also, 'module' is
00358             # the *unqualified* module name (ie. no dots, no package -- we
00359             # already know its package!), and 'module_file' is the path to
00360             # the .py file, relative to the current directory
00361             # (ie. including 'package_dir').
00362             package_dir = self.get_package_dir(package)
00363             modules = self.find_package_modules(package, package_dir)
00364 
00365             # Now loop over the modules we found, "building" each one (just
00366             # copy it to self.build_lib).
00367             for (package_, module, module_file) in modules:
00368                 assert package == package_
00369                 self.build_module(module, module_file, package)

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 370 of file build_py.py.

00370 
00371     def byte_compile(self, files):
00372         if sys.dont_write_bytecode:
00373             self.warn('byte-compiling is disabled, skipping.')
00374             return
00375 
00376         from distutils.util import byte_compile
00377         prefix = self.build_lib
00378         if prefix[-1] != os.sep:
00379             prefix = prefix + os.sep
00380 
00381         # XXX this code is essentially the same as the 'byte_compile()
00382         # method of the "install_lib" command, except for the determination
00383         # of the 'prefix' string.  Hmmm.
00384         if self.compile:
00385             byte_compile(files, optimize=0,
00386                          force=self.force, prefix=prefix, dry_run=self.dry_run)
00387         if self.optimize > 0:
00388             byte_compile(files, optimize=self.optimize,
00389                          force=self.force, prefix=prefix, dry_run=self.dry_run)

Here is the call graph for this function:

Here is the caller graph for this function:

def distutils.command.build_py.build_py.check_module (   self,
  module,
  module_file 
)

Definition at line 208 of file build_py.py.

00208 
00209     def check_module(self, module, module_file):
00210         if not os.path.isfile(module_file):
00211             log.warn("file %s (for module %s) not found", module_file, module)
00212             return False
00213         else:
00214             return True

Here is the caller graph for this function:

def distutils.command.build_py.build_py.check_package (   self,
  package,
  package_dir 
)

Definition at line 181 of file build_py.py.

00181 
00182     def check_package(self, package, package_dir):
00183         # Empty dir name means current directory, which we can probably
00184         # assume exists.  Also, os.path.exists and isdir don't know about
00185         # my "empty string means current dir" convention, so we have to
00186         # circumvent them.
00187         if package_dir != "":
00188             if not os.path.exists(package_dir):
00189                 raise DistutilsFileError(
00190                       "package directory '%s' does not exist" % package_dir)
00191             if not os.path.isdir(package_dir):
00192                 raise DistutilsFileError(
00193                        "supposed package directory '%s' exists, "
00194                        "but is not a directory" % package_dir)
00195 
00196         # Require __init__.py for all but the "root package"
00197         if package:
00198             init_py = os.path.join(package_dir, "__init__.py")
00199             if os.path.isfile(init_py):
00200                 return init_py
00201             else:
00202                 log.warn(("package init file '%s' not found " +
00203                           "(or not a regular file)"), init_py)
00204 
00205         # Either not in a package at all (__init__.py not expected), or
00206         # __init__.py doesn't exist -- so don't return the filename.
00207         return None

Here is the caller graph for this function:

Definition at line 41 of file build_py.py.

00041 
00042     def finalize_options(self):
00043         self.set_undefined_options('build',
00044                                    ('build_lib', 'build_lib'),
00045                                    ('force', 'force'))
00046 
00047         # Get the distribution options that are aliases for build_py
00048         # options -- list of packages and list of modules.
00049         self.packages = self.distribution.packages
00050         self.py_modules = self.distribution.py_modules
00051         self.package_data = self.distribution.package_data
00052         self.package_dir = {}
00053         if self.distribution.package_dir:
00054             for name, path in self.distribution.package_dir.items():
00055                 self.package_dir[name] = convert_path(path)
00056         self.data_files = self.get_data_files()
00057 
00058         # Ick, copied straight from install_lib.py (fancy_getopt needs a
00059         # type system!  Hell, *everything* needs a type system!!!)
00060         if not isinstance(self.optimize, int):
00061             try:
00062                 self.optimize = int(self.optimize)
00063                 assert 0 <= self.optimize <= 2
00064             except (ValueError, AssertionError):
00065                 raise DistutilsOptionError("optimize must be 0, 1, or 2")

Here is the call graph for this function:

Here is the caller graph for this function:

Compute the list of all modules that will be built, whether
they are specified one-module-at-a-time ('self.py_modules') or
by whole packages ('self.packages').  Return a list of tuples
(package, module, module_file), just like 'find_modules()' and
'find_package_modules()' do.

Definition at line 282 of file build_py.py.

00282 
00283     def find_all_modules(self):
00284         """Compute the list of all modules that will be built, whether
00285         they are specified one-module-at-a-time ('self.py_modules') or
00286         by whole packages ('self.packages').  Return a list of tuples
00287         (package, module, module_file), just like 'find_modules()' and
00288         'find_package_modules()' do."""
00289         modules = []
00290         if self.py_modules:
00291             modules.extend(self.find_modules())
00292         if self.packages:
00293             for package in self.packages:
00294                 package_dir = self.get_package_dir(package)
00295                 m = self.find_package_modules(package, package_dir)
00296                 modules.extend(m)
00297         return modules

Here is the call graph for this function:

Here is the caller graph for this function:

def distutils.command.build_py.build_py.find_data_files (   self,
  package,
  src_dir 
)
Return filenames for package's data files in 'src_dir'

Definition at line 120 of file build_py.py.

00120 
00121     def find_data_files(self, package, src_dir):
00122         """Return filenames for package's data files in 'src_dir'"""
00123         globs = (self.package_data.get('', [])
00124                  + self.package_data.get(package, []))
00125         files = []
00126         for pattern in globs:
00127             # Each pattern has to be converted to a platform-specific path
00128             filelist = glob(os.path.join(src_dir, convert_path(pattern)))
00129             # Files that match more than one pattern are only added once
00130             files.extend([fn for fn in filelist if fn not in files])
00131         return files

Here is the call graph for this function:

Here is the caller graph for this function:

Finds individually-specified Python modules, ie. those listed by
module name in 'self.py_modules'.  Returns a list of tuples (package,
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.

Definition at line 230 of file build_py.py.

00230 
00231     def find_modules(self):
00232         """Finds individually-specified Python modules, ie. those listed by
00233         module name in 'self.py_modules'.  Returns a list of tuples (package,
00234         module_base, filename): 'package' is a tuple of the path through
00235         package-space to the module; 'module_base' is the bare (no
00236         packages, no dots) module name, and 'filename' is the path to the
00237         ".py" file (relative to the distribution root) that implements the
00238         module.
00239         """
00240         # Map package names to tuples of useful info about the package:
00241         #    (package_dir, checked)
00242         # package_dir - the directory where we'll find source files for
00243         #   this package
00244         # checked - true if we have checked that the package directory
00245         #   is valid (exists, contains __init__.py, ... ?)
00246         packages = {}
00247 
00248         # List of (package, module, filename) tuples to return
00249         modules = []
00250 
00251         # We treat modules-in-packages almost the same as toplevel modules,
00252         # just the "package" for a toplevel is empty (either an empty
00253         # string or empty list, depending on context).  Differences:
00254         #   - don't check for __init__.py in directory for empty package
00255         for module in self.py_modules:
00256             path = module.split('.')
00257             package = '.'.join(path[0:-1])
00258             module_base = path[-1]
00259 
00260             try:
00261                 (package_dir, checked) = packages[package]
00262             except KeyError:
00263                 package_dir = self.get_package_dir(package)
00264                 checked = 0
00265 
00266             if not checked:
00267                 init_py = self.check_package(package, package_dir)
00268                 packages[package] = (package_dir, 1)
00269                 if init_py:
00270                     modules.append((package, "__init__", init_py))
00271 
00272             # XXX perhaps we should also check for just .pyc files
00273             # (so greedy closed-source bastards can distribute Python
00274             # modules too)
00275             module_file = os.path.join(package_dir, module_base + ".py")
00276             if not self.check_module(module, module_file):
00277                 continue
00278 
00279             modules.append((package, module_base, module_file))
00280 
00281         return modules

Here is the call graph for this function:

Here is the caller graph for this function:

def distutils.command.build_py.build_py.find_package_modules (   self,
  package,
  package_dir 
)

Definition at line 215 of file build_py.py.

00215 
00216     def find_package_modules(self, package, package_dir):
00217         self.check_package(package, package_dir)
00218         module_files = glob(os.path.join(package_dir, "*.py"))
00219         modules = []
00220         setup_script = os.path.abspath(self.distribution.script_name)
00221 
00222         for f in module_files:
00223             abs_f = os.path.abspath(f)
00224             if abs_f != setup_script:
00225                 module = os.path.splitext(os.path.basename(f))[0]
00226                 modules.append((package, module, f))
00227             else:
00228                 self.debug_print("excluding %s" % setup_script)
00229         return modules

Here is the call graph for this function:

Here is the caller graph for this function:

Generate list of '(package,src_dir,build_dir,filenames)' tuples

Definition at line 96 of file build_py.py.

00096 
00097     def get_data_files(self):
00098         """Generate list of '(package,src_dir,build_dir,filenames)' tuples"""
00099         data = []
00100         if not self.packages:
00101             return data
00102         for package in self.packages:
00103             # Locate package source directory
00104             src_dir = self.get_package_dir(package)
00105 
00106             # Compute package build directory
00107             build_dir = os.path.join(*([self.build_lib] + package.split('.')))
00108 
00109             # Length of path to strip from found files
00110             plen = 0
00111             if src_dir:
00112                 plen = len(src_dir)+1
00113 
00114             # Strip directory from globbed filenames
00115             filenames = [
00116                 file[plen:] for file in self.find_data_files(package, src_dir)
00117                 ]
00118             data.append((package, src_dir, build_dir, filenames))
00119         return data

Here is the call graph for this function:

def distutils.command.build_py.build_py.get_module_outfile (   self,
  build_dir,
  package,
  module 
)

Definition at line 301 of file build_py.py.

00301 
00302     def get_module_outfile(self, build_dir, package, module):
00303         outfile_path = [build_dir] + list(package) + [module + ".py"]
00304         return os.path.join(*outfile_path)

Here is the caller graph for this function:

def distutils.command.build_py.build_py.get_outputs (   self,
  include_bytecode = 1 
)

Definition at line 305 of file build_py.py.

00305 
00306     def get_outputs(self, include_bytecode=1):
00307         modules = self.find_all_modules()
00308         outputs = []
00309         for (package, module, module_file) in modules:
00310             package = package.split('.')
00311             filename = self.get_module_outfile(self.build_lib, package, module)
00312             outputs.append(filename)
00313             if include_bytecode:
00314                 if self.compile:
00315                     outputs.append(filename + "c")
00316                 if self.optimize > 0:
00317                     outputs.append(filename + "o")
00318 
00319         outputs += [
00320             os.path.join(build_dir, filename)
00321             for package, src_dir, build_dir, filenames in self.data_files
00322             for filename in filenames
00323             ]
00324 
00325         return outputs

Here is the call graph for this function:

Here is the caller graph for this function:

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).

Definition at line 142 of file build_py.py.

00142 
00143     def get_package_dir(self, package):
00144         """Return the directory, relative to the top of the source
00145            distribution, where package 'package' should be found
00146            (at least according to the 'package_dir' option, if any)."""
00147         path = package.split('.')
00148 
00149         if not self.package_dir:
00150             if path:
00151                 return os.path.join(*path)
00152             else:
00153                 return ''
00154         else:
00155             tail = []
00156             while path:
00157                 try:
00158                     pdir = self.package_dir['.'.join(path)]
00159                 except KeyError:
00160                     tail.insert(0, path[-1])
00161                     del path[-1]
00162                 else:
00163                     tail.insert(0, pdir)
00164                     return os.path.join(*tail)
00165             else:
00166                 # Oops, got all the way through 'path' without finding a
00167                 # match in package_dir.  If package_dir defines a directory
00168                 # for the root (nameless) package, then fallback on it;
00169                 # otherwise, we might as well have not consulted
00170                 # package_dir at all, as we just use the directory implied
00171                 # by 'tail' (which should be the same as the original value
00172                 # of 'path' at this point).
00173                 pdir = self.package_dir.get('')
00174                 if pdir is not None:
00175                     tail.insert(0, pdir)
00176 
00177                 if tail:
00178                     return os.path.join(*tail)
00179                 else:
00180                     return ''

Here is the caller graph for this function:

Definition at line 298 of file build_py.py.

00298 
00299     def get_source_files(self):
00300         return [module[-1] for module in self.find_all_modules()]

Here is the call graph for this function:

Definition at line 31 of file build_py.py.

00031 
00032     def initialize_options(self):
00033         self.build_lib = None
00034         self.py_modules = None
00035         self.package = None
00036         self.package_data = None
00037         self.package_dir = None
00038         self.compile = 0
00039         self.optimize = 0
00040         self.force = None

Reimplemented in distutils.command.build_py.build_py_2to3.

Definition at line 66 of file build_py.py.

00066 
00067     def run(self):
00068         # XXX copy_file by default preserves atime and mtime.  IMHO this is
00069         # the right thing to do, but perhaps it should be an option -- in
00070         # particular, a site administrator might want installed files to
00071         # reflect the time of installation rather than the last
00072         # modification time before the installed release.
00073 
00074         # XXX copy_file by default preserves mode, which appears to be the
00075         # wrong thing to do: if a file is read-only in the working
00076         # directory, we want it to be installed read/write so that the next
00077         # installation of the same module distribution can overwrite it
00078         # without problems.  (This might be a Unix-specific issue.)  Thus
00079         # we turn off 'preserve_mode' when copying to the build directory,
00080         # since the build directory is supposed to be exactly what the
00081         # installation will look like (ie. we preserve mode when
00082         # installing).
00083 
00084         # Two options control which modules will be installed: 'packages'
00085         # and 'py_modules'.  The former lets us work with whole packages, not
00086         # specifying individual modules at all; the latter is for
00087         # specifying modules one-at-a-time.
00088 
00089         if self.py_modules:
00090             self.build_modules()
00091         if self.packages:
00092             self.build_packages()
00093             self.build_package_data()
00094 
00095         self.byte_compile(self.get_outputs(include_bytecode=0))

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 28 of file build_py.py.

Definition at line 32 of file build_py.py.

Definition at line 37 of file build_py.py.

Definition at line 55 of file build_py.py.

string distutils.command.build_py.build_py.description = "\"build\" pure Python modules (copy to build directory)" [static]

Definition at line 16 of file build_py.py.

Definition at line 39 of file build_py.py.

Definition at line 29 of file build_py.py.

Definition at line 38 of file build_py.py.

Definition at line 34 of file build_py.py.

Definition at line 35 of file build_py.py.

Definition at line 36 of file build_py.py.

Definition at line 48 of file build_py.py.

Definition at line 33 of file build_py.py.

Initial value:
[
        ('build-lib=', 'd', "directory to \"build\" (copy) to"),
        ('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]"),
        ('force', 'f', "forcibly build everything (ignore file timestamps)"),
        ]

Definition at line 18 of file build_py.py.


The documentation for this class was generated from the following file: