mirror of
https://github.com/python/cpython.git
synced 2025-11-02 19:12:55 +00:00
- First, support.fixup_build_ext (already used to set proper library_dirs value under Unix shared builds) gains the ability to correctly set the debug attribute under Windows debug builds. - Second, the filename for the extension module gets a _d suffix under debug builds. - Third, the test code properly puts our customized build_ext object into an internal dictionary to make sure that the install command will later use our object instead of re-creating one. That’s the downside of using low-level APIs in our test code: we have to manually push knobs and turn handles that would otherwise be handled behind the scenes. Thanks to Nadeem for the testing.
250 lines
8.3 KiB
Python
250 lines
8.3 KiB
Python
"""Tests for distutils.command.install."""
|
|
|
|
import os
|
|
import sys
|
|
import unittest
|
|
import site
|
|
|
|
from test.support import captured_stdout, run_unittest
|
|
|
|
from distutils import sysconfig
|
|
from distutils.command.install import install
|
|
from distutils.command import install as install_module
|
|
from distutils.command.build_ext import build_ext
|
|
from distutils.command.install import INSTALL_SCHEMES
|
|
from distutils.core import Distribution
|
|
from distutils.errors import DistutilsOptionError
|
|
from distutils.extension import Extension
|
|
|
|
from distutils.tests import support
|
|
|
|
|
|
def _make_ext_name(modname):
|
|
if os.name == 'nt':
|
|
if sys.executable.endswith('_d.exe'):
|
|
modname += '_d'
|
|
return modname + sysconfig.get_config_var('SO')
|
|
|
|
|
|
class InstallTestCase(support.TempdirManager,
|
|
support.EnvironGuard,
|
|
support.LoggingSilencer,
|
|
unittest.TestCase):
|
|
|
|
def test_home_installation_scheme(self):
|
|
# This ensure two things:
|
|
# - that --home generates the desired set of directory names
|
|
# - test --home is supported on all platforms
|
|
builddir = self.mkdtemp()
|
|
destination = os.path.join(builddir, "installation")
|
|
|
|
dist = Distribution({"name": "foopkg"})
|
|
# script_name need not exist, it just need to be initialized
|
|
dist.script_name = os.path.join(builddir, "setup.py")
|
|
dist.command_obj["build"] = support.DummyCommand(
|
|
build_base=builddir,
|
|
build_lib=os.path.join(builddir, "lib"),
|
|
)
|
|
|
|
cmd = install(dist)
|
|
cmd.home = destination
|
|
cmd.ensure_finalized()
|
|
|
|
self.assertEqual(cmd.install_base, destination)
|
|
self.assertEqual(cmd.install_platbase, destination)
|
|
|
|
def check_path(got, expected):
|
|
got = os.path.normpath(got)
|
|
expected = os.path.normpath(expected)
|
|
self.assertEqual(got, expected)
|
|
|
|
libdir = os.path.join(destination, "lib", "python")
|
|
check_path(cmd.install_lib, libdir)
|
|
check_path(cmd.install_platlib, libdir)
|
|
check_path(cmd.install_purelib, libdir)
|
|
check_path(cmd.install_headers,
|
|
os.path.join(destination, "include", "python", "foopkg"))
|
|
check_path(cmd.install_scripts, os.path.join(destination, "bin"))
|
|
check_path(cmd.install_data, destination)
|
|
|
|
def test_user_site(self):
|
|
# site.USER_SITE was introduced in 2.6
|
|
if sys.version < '2.6':
|
|
return
|
|
|
|
# preparing the environment for the test
|
|
self.old_user_base = site.USER_BASE
|
|
self.old_user_site = site.USER_SITE
|
|
self.tmpdir = self.mkdtemp()
|
|
self.user_base = os.path.join(self.tmpdir, 'B')
|
|
self.user_site = os.path.join(self.tmpdir, 'S')
|
|
site.USER_BASE = self.user_base
|
|
site.USER_SITE = self.user_site
|
|
install_module.USER_BASE = self.user_base
|
|
install_module.USER_SITE = self.user_site
|
|
|
|
def _expanduser(path):
|
|
return self.tmpdir
|
|
self.old_expand = os.path.expanduser
|
|
os.path.expanduser = _expanduser
|
|
|
|
try:
|
|
# this is the actual test
|
|
self._test_user_site()
|
|
finally:
|
|
site.USER_BASE = self.old_user_base
|
|
site.USER_SITE = self.old_user_site
|
|
install_module.USER_BASE = self.old_user_base
|
|
install_module.USER_SITE = self.old_user_site
|
|
os.path.expanduser = self.old_expand
|
|
|
|
def _test_user_site(self):
|
|
for key in ('nt_user', 'unix_user', 'os2_home'):
|
|
self.assertTrue(key in INSTALL_SCHEMES)
|
|
|
|
dist = Distribution({'name': 'xx'})
|
|
cmd = install(dist)
|
|
|
|
# making sure the user option is there
|
|
options = [name for name, short, lable in
|
|
cmd.user_options]
|
|
self.assertTrue('user' in options)
|
|
|
|
# setting a value
|
|
cmd.user = 1
|
|
|
|
# user base and site shouldn't be created yet
|
|
self.assertTrue(not os.path.exists(self.user_base))
|
|
self.assertTrue(not os.path.exists(self.user_site))
|
|
|
|
# let's run finalize
|
|
cmd.ensure_finalized()
|
|
|
|
# now they should
|
|
self.assertTrue(os.path.exists(self.user_base))
|
|
self.assertTrue(os.path.exists(self.user_site))
|
|
|
|
self.assertTrue('userbase' in cmd.config_vars)
|
|
self.assertTrue('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.assertEqual(cmd.extra_path, ['path', 'dirs'])
|
|
self.assertEqual(cmd.extra_dirs, 'dirs')
|
|
self.assertEqual(cmd.path_file, 'path')
|
|
|
|
# one element
|
|
cmd.extra_path = ['path']
|
|
cmd.handle_extra_path()
|
|
self.assertEqual(cmd.extra_path, ['path'])
|
|
self.assertEqual(cmd.extra_dirs, 'path')
|
|
self.assertEqual(cmd.path_file, 'path')
|
|
|
|
# none
|
|
dist.extra_path = cmd.extra_path = None
|
|
cmd.handle_extra_path()
|
|
self.assertEqual(cmd.extra_path, None)
|
|
self.assertEqual(cmd.extra_dirs, '')
|
|
self.assertEqual(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()
|
|
project_dir, dist = self.create_dist(scripts=['hello'])
|
|
self.addCleanup(os.chdir, os.getcwd())
|
|
os.chdir(project_dir)
|
|
self.write_file('hello', "print('o hai')")
|
|
|
|
cmd = install(dist)
|
|
dist.command_obj['install'] = cmd
|
|
cmd.root = install_dir
|
|
cmd.record = os.path.join(project_dir, 'RECORD')
|
|
cmd.ensure_finalized()
|
|
cmd.run()
|
|
|
|
f = open(cmd.record)
|
|
try:
|
|
content = f.read()
|
|
finally:
|
|
f.close()
|
|
|
|
found = [os.path.basename(line) for line in content.splitlines()]
|
|
expected = ['hello',
|
|
'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]]
|
|
self.assertEqual(found, expected)
|
|
|
|
def test_record_extensions(self):
|
|
install_dir = self.mkdtemp()
|
|
project_dir, dist = self.create_dist(ext_modules=[
|
|
Extension('xx', ['xxmodule.c'])])
|
|
self.addCleanup(os.chdir, os.getcwd())
|
|
os.chdir(project_dir)
|
|
support.copy_xxmodule_c(project_dir)
|
|
|
|
buildextcmd = build_ext(dist)
|
|
support.fixup_build_ext(buildextcmd)
|
|
buildextcmd.ensure_finalized()
|
|
|
|
cmd = install(dist)
|
|
dist.command_obj['install'] = cmd
|
|
dist.command_obj['build_ext'] = buildextcmd
|
|
cmd.root = install_dir
|
|
cmd.record = os.path.join(project_dir, 'RECORD')
|
|
cmd.ensure_finalized()
|
|
cmd.run()
|
|
|
|
f = open(cmd.record)
|
|
try:
|
|
content = f.read()
|
|
finally:
|
|
f.close()
|
|
|
|
found = [os.path.basename(line) for line in content.splitlines()]
|
|
expected = [_make_ext_name('xx'),
|
|
'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]]
|
|
self.assertEqual(found, expected)
|
|
|
|
def test_debug_mode(self):
|
|
# this covers the code called when DEBUG is set
|
|
old_logs_len = len(self.logs)
|
|
install_module.DEBUG = True
|
|
try:
|
|
with captured_stdout():
|
|
self.test_record()
|
|
finally:
|
|
install_module.DEBUG = False
|
|
self.assertTrue(len(self.logs) > old_logs_len)
|
|
|
|
def test_suite():
|
|
return unittest.makeSuite(InstallTestCase)
|
|
|
|
if __name__ == "__main__":
|
|
run_unittest(test_suite())
|