Commit 74ad50e5 authored by Tarek Ziadé's avatar Tarek Ziadé

Merged revisions 73197 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r73197 | tarek.ziade | 2009-06-04 09:31:52 +0200 (Thu, 04 Jun 2009) | 1 line

  improved test coverage for distutils.command.install and cleaned it up
........
parent 1352d8a6
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
Implements the Distutils 'install' command.""" Implements the Distutils 'install' command."""
from distutils import log
__revision__ = "$Id$" __revision__ = "$Id$"
import sys, os import sys
import os
from distutils import log
from distutils.core import Command from distutils.core import Command
from distutils.debug import DEBUG from distutils.debug import DEBUG
from distutils.sysconfig import get_config_vars from distutils.sysconfig import get_config_vars
...@@ -116,7 +117,7 @@ if HAS_USER_SITE: ...@@ -116,7 +117,7 @@ if HAS_USER_SITE:
SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data') SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data')
class install (Command): class install(Command):
description = "install everything from build directory" description = "install everything from build directory"
...@@ -190,7 +191,7 @@ class install (Command): ...@@ -190,7 +191,7 @@ class install (Command):
def initialize_options(self): def initialize_options(self):
"""Initializes options."""
# High-level options: these select both an installation base # High-level options: these select both an installation base
# and scheme. # and scheme.
self.prefix = None self.prefix = None
...@@ -267,7 +268,7 @@ class install (Command): ...@@ -267,7 +268,7 @@ class install (Command):
# array of user input is decided. Yes, it's quite complex!) # array of user input is decided. Yes, it's quite complex!)
def finalize_options(self): def finalize_options(self):
"""Finalizes options."""
# This method (and its pliant slaves, like 'finalize_unix()', # This method (and its pliant slaves, like 'finalize_unix()',
# 'finalize_other()', and 'select_scheme()') is where the default # 'finalize_other()', and 'select_scheme()') is where the default
# installation directories for modules, extension modules, and # installation directories for modules, extension modules, and
...@@ -408,25 +409,27 @@ class install (Command): ...@@ -408,25 +409,27 @@ class install (Command):
# Punt on doc directories for now -- after all, we're punting on # Punt on doc directories for now -- after all, we're punting on
# documentation completely! # documentation completely!
def dump_dirs(self, msg): def dump_dirs(self, msg):
if DEBUG: """Dumps the list of user options."""
from distutils.fancy_getopt import longopt_xlate if not DEBUG:
print(msg + ":") return
for opt in self.user_options: from distutils.fancy_getopt import longopt_xlate
opt_name = opt[0] log.debug(msg + ":")
if opt_name[-1] == "=": for opt in self.user_options:
opt_name = opt_name[0:-1] opt_name = opt[0]
if opt_name in self.negative_opt: if opt_name[-1] == "=":
opt_name = longopt_xlate(self.negative_opt[opt_name]) opt_name = opt_name[0:-1]
val = not getattr(self, opt_name) if opt_name in self.negative_opt:
else: opt_name = self.negative_opt[opt_name]
opt_name = longopt_xlate(opt_name) opt_name = opt_name.translate(longopt_xlate)
val = getattr(self, opt_name) val = not getattr(self, opt_name)
print(" %s: %s" % (opt_name, val)) else:
opt_name = opt_name.translate(longopt_xlate)
val = getattr(self, opt_name)
log.debug(" %s: %s" % (opt_name, val))
def finalize_unix(self): def finalize_unix(self):
"""Finalizes options for posix platforms."""
if self.install_base is not None or self.install_platbase is not None: if self.install_base is not None or self.install_platbase is not None:
if ((self.install_lib is None and if ((self.install_lib is None and
self.install_purelib is None and self.install_purelib is None and
...@@ -465,8 +468,8 @@ class install (Command): ...@@ -465,8 +468,8 @@ class install (Command):
self.install_platbase = self.exec_prefix self.install_platbase = self.exec_prefix
self.select_scheme("unix_prefix") self.select_scheme("unix_prefix")
def finalize_other(self):
def finalize_other(self): # Windows and Mac OS for now """Finalizes options for non-posix platforms"""
if self.user: if self.user:
if self.install_userbase is None: if self.install_userbase is None:
raise DistutilsPlatformError( raise DistutilsPlatformError(
...@@ -487,8 +490,8 @@ class install (Command): ...@@ -487,8 +490,8 @@ class install (Command):
raise DistutilsPlatformError( raise DistutilsPlatformError(
"I don't know how to install stuff on '%s'" % os.name) "I don't know how to install stuff on '%s'" % os.name)
def select_scheme(self, name): def select_scheme(self, name):
"""Sets the install directories by applying the install schemes."""
# it's the caller's problem if they supply a bad name! # it's the caller's problem if they supply a bad name!
scheme = INSTALL_SCHEMES[name] scheme = INSTALL_SCHEMES[name]
for key in SCHEME_KEYS: for key in SCHEME_KEYS:
...@@ -496,7 +499,6 @@ class install (Command): ...@@ -496,7 +499,6 @@ class install (Command):
if getattr(self, attrname) is None: if getattr(self, attrname) is None:
setattr(self, attrname, scheme[key]) setattr(self, attrname, scheme[key])
def _expand_attrs(self, attrs): def _expand_attrs(self, attrs):
for attr in attrs: for attr in attrs:
val = getattr(self, attr) val = getattr(self, attr)
...@@ -506,27 +508,25 @@ class install (Command): ...@@ -506,27 +508,25 @@ class install (Command):
val = subst_vars(val, self.config_vars) val = subst_vars(val, self.config_vars)
setattr(self, attr, val) setattr(self, attr, val)
def expand_basedirs(self): def expand_basedirs(self):
self._expand_attrs(['install_base', """Calls `os.path.expanduser` on install_base, install_platbase and
'install_platbase', root."""
'root']) self._expand_attrs(['install_base', 'install_platbase', 'root'])
def expand_dirs(self): def expand_dirs(self):
self._expand_attrs(['install_purelib', """Calls `os.path.expanduser` on install dirs."""
'install_platlib', self._expand_attrs(['install_purelib', 'install_platlib',
'install_lib', 'install_lib', 'install_headers',
'install_headers', 'install_scripts', 'install_data',])
'install_scripts',
'install_data',])
def convert_paths(self, *names): def convert_paths(self, *names):
"""Call `convert_path` over `names`."""
for name in names: for name in names:
attr = "install_" + name attr = "install_" + name
setattr(self, attr, convert_path(getattr(self, attr))) setattr(self, attr, convert_path(getattr(self, attr)))
def handle_extra_path(self): def handle_extra_path(self):
"""Set `path_file` and `extra_dirs` using `extra_path`."""
if self.extra_path is None: if self.extra_path is None:
self.extra_path = self.distribution.extra_path self.extra_path = self.distribution.extra_path
...@@ -537,7 +537,7 @@ class install (Command): ...@@ -537,7 +537,7 @@ class install (Command):
if len(self.extra_path) == 1: if len(self.extra_path) == 1:
path_file = extra_dirs = self.extra_path[0] path_file = extra_dirs = self.extra_path[0]
elif len(self.extra_path) == 2: elif len(self.extra_path) == 2:
(path_file, extra_dirs) = self.extra_path path_file, extra_dirs = self.extra_path
else: else:
raise DistutilsOptionError( raise DistutilsOptionError(
"'extra_path' option must be a list, tuple, or " "'extra_path' option must be a list, tuple, or "
...@@ -546,7 +546,6 @@ class install (Command): ...@@ -546,7 +546,6 @@ class install (Command):
# convert to local form in case Unix notation used (as it # convert to local form in case Unix notation used (as it
# should be in setup scripts) # should be in setup scripts)
extra_dirs = convert_path(extra_dirs) extra_dirs = convert_path(extra_dirs)
else: else:
path_file = None path_file = None
extra_dirs = '' extra_dirs = ''
...@@ -557,13 +556,13 @@ class install (Command): ...@@ -557,13 +556,13 @@ class install (Command):
self.extra_dirs = extra_dirs self.extra_dirs = extra_dirs
def change_roots(self, *names): def change_roots(self, *names):
"""Change the install direcories pointed by name using root."""
for name in names: for name in names:
attr = "install_" + name attr = "install_" + name
setattr(self, attr, change_root(self.root, getattr(self, attr))) setattr(self, attr, change_root(self.root, getattr(self, attr)))
def create_home_path(self): def create_home_path(self):
"""Create directories under ~ """Create directories under ~."""
"""
if not self.user: if not self.user:
return return
home = convert_path(os.path.expanduser("~")) home = convert_path(os.path.expanduser("~"))
...@@ -575,6 +574,7 @@ class install (Command): ...@@ -575,6 +574,7 @@ class install (Command):
# -- Command execution methods ------------------------------------- # -- Command execution methods -------------------------------------
def run(self): def run(self):
"""Runs the command."""
# Obviously have to build before we can install # Obviously have to build before we can install
if not self.skip_build: if not self.skip_build:
self.run_command('build') self.run_command('build')
...@@ -618,6 +618,7 @@ class install (Command): ...@@ -618,6 +618,7 @@ class install (Command):
self.install_lib) self.install_lib)
def create_path_file(self): def create_path_file(self):
"""Creates the .pth file"""
filename = os.path.join(self.install_libbase, filename = os.path.join(self.install_libbase,
self.path_file + ".pth") self.path_file + ".pth")
if self.install_path_file: if self.install_path_file:
...@@ -631,7 +632,7 @@ class install (Command): ...@@ -631,7 +632,7 @@ class install (Command):
# -- Reporting methods --------------------------------------------- # -- Reporting methods ---------------------------------------------
def get_outputs(self): def get_outputs(self):
# Assemble the outputs of all the sub-commands. """Assembles the outputs of all the sub-commands."""
outputs = [] outputs = []
for cmd_name in self.get_sub_commands(): for cmd_name in self.get_sub_commands():
cmd = self.get_finalized_command(cmd_name) cmd = self.get_finalized_command(cmd_name)
...@@ -648,6 +649,7 @@ class install (Command): ...@@ -648,6 +649,7 @@ class install (Command):
return outputs return outputs
def get_inputs(self): def get_inputs(self):
"""Returns the inputs of all the sub-commands"""
# XXX gee, this looks familiar ;-( # XXX gee, this looks familiar ;-(
inputs = [] inputs = []
for cmd_name in self.get_sub_commands(): for cmd_name in self.get_sub_commands():
...@@ -656,25 +658,29 @@ class install (Command): ...@@ -656,25 +658,29 @@ class install (Command):
return inputs return inputs
# -- Predicates for sub-command list ------------------------------- # -- Predicates for sub-command list -------------------------------
def has_lib(self): def has_lib(self):
"""Return true if the current distribution has any Python """Returns true if the current distribution has any Python
modules to install.""" modules to install."""
return (self.distribution.has_pure_modules() or return (self.distribution.has_pure_modules() or
self.distribution.has_ext_modules()) self.distribution.has_ext_modules())
def has_headers(self): def has_headers(self):
"""Returns true if the current distribution has any headers to
install."""
return self.distribution.has_headers() return self.distribution.has_headers()
def has_scripts(self): def has_scripts(self):
"""Returns true if the current distribution has any scripts to.
install."""
return self.distribution.has_scripts() return self.distribution.has_scripts()
def has_data(self): def has_data(self):
"""Returns true if the current distribution has any data to.
install."""
return self.distribution.has_data_files() return self.distribution.has_data_files()
# 'sub_commands': a list of commands this command might have to run to # 'sub_commands': a list of commands this command might have to run to
# get its work done. See cmd.py for more info. # get its work done. See cmd.py for more info.
sub_commands = [('install_lib', has_lib), sub_commands = [('install_lib', has_lib),
......
...@@ -10,11 +10,14 @@ from distutils.command.install import install ...@@ -10,11 +10,14 @@ from distutils.command.install import install
from distutils.command import install as install_module from distutils.command import install as install_module
from distutils.command.install import INSTALL_SCHEMES from distutils.command.install import INSTALL_SCHEMES
from distutils.core import Distribution from distutils.core import Distribution
from distutils.errors import DistutilsOptionError
from distutils.tests import support from distutils.tests import support
class InstallTestCase(support.TempdirManager, unittest.TestCase): class InstallTestCase(support.TempdirManager,
support.LoggingSilencer,
unittest.TestCase):
def test_home_installation_scheme(self): def test_home_installation_scheme(self):
# This ensure two things: # This ensure two things:
...@@ -112,6 +115,74 @@ class InstallTestCase(support.TempdirManager, unittest.TestCase): ...@@ -112,6 +115,74 @@ class InstallTestCase(support.TempdirManager, unittest.TestCase):
self.assert_('userbase' in cmd.config_vars) self.assert_('userbase' in cmd.config_vars)
self.assert_('usersite' in cmd.config_vars) self.assert_('usersite' in cmd.config_vars)
def test_handle_extra_path(self):
dist = Distribution({'name': 'xx', 'extra_path': 'path,dirs'})
cmd = install(dist)
# two elements
cmd.handle_extra_path()
self.assertEquals(cmd.extra_path, ['path', 'dirs'])
self.assertEquals(cmd.extra_dirs, 'dirs')
self.assertEquals(cmd.path_file, 'path')
# one element
cmd.extra_path = ['path']
cmd.handle_extra_path()
self.assertEquals(cmd.extra_path, ['path'])
self.assertEquals(cmd.extra_dirs, 'path')
self.assertEquals(cmd.path_file, 'path')
# none
dist.extra_path = cmd.extra_path = None
cmd.handle_extra_path()
self.assertEquals(cmd.extra_path, None)
self.assertEquals(cmd.extra_dirs, '')
self.assertEquals(cmd.path_file, None)
# three elements (no way !)
cmd.extra_path = 'path,dirs,again'
self.assertRaises(DistutilsOptionError, cmd.handle_extra_path)
def test_finalize_options(self):
dist = Distribution({'name': 'xx'})
cmd = install(dist)
# must supply either prefix/exec-prefix/home or
# install-base/install-platbase -- not both
cmd.prefix = 'prefix'
cmd.install_base = 'base'
self.assertRaises(DistutilsOptionError, cmd.finalize_options)
# must supply either home or prefix/exec-prefix -- not both
cmd.install_base = None
cmd.home = 'home'
self.assertRaises(DistutilsOptionError, cmd.finalize_options)
# can't combine user with with prefix/exec_prefix/home or
# install_(plat)base
cmd.prefix = None
cmd.user = 'user'
self.assertRaises(DistutilsOptionError, cmd.finalize_options)
def test_record(self):
install_dir = self.mkdtemp()
pkgdir, dist = self.create_dist()
dist = Distribution()
cmd = install(dist)
dist.command_obj['install'] = cmd
cmd.root = install_dir
cmd.record = os.path.join(pkgdir, 'RECORD')
cmd.ensure_finalized()
cmd.run()
# let's check the RECORD file was created with one
# line (the egg info file)
with open(cmd.record) as f:
self.assertEquals(len(f.readlines()), 1)
def test_suite(): def test_suite():
return unittest.makeSuite(InstallTestCase) return unittest.makeSuite(InstallTestCase)
......
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