mirror of https://github.com/python/cpython
Branch merge
This commit is contained in:
commit
1bd3b9cea0
|
@ -183,6 +183,7 @@ docs@python.org), and we'll be glad to correct the problem.
|
|||
* Joakim Sernbrant
|
||||
* Justin Sheehy
|
||||
* Charlie Shepherd
|
||||
* Yue Shuaijie
|
||||
* Michael Simcich
|
||||
* Ionel Simionescu
|
||||
* Michael Sloan
|
||||
|
|
|
@ -31,8 +31,9 @@ setup script). Indirectly provides the :class:`distutils.dist.Distribution` and
|
|||
+====================+================================+=============================================================+
|
||||
| *name* | The name of the package | a string |
|
||||
+--------------------+--------------------------------+-------------------------------------------------------------+
|
||||
| *version* | The version number of the | See :mod:`distutils.version` |
|
||||
| | package | |
|
||||
| *version* | The version number of the | a string |
|
||||
| | package; see | |
|
||||
| | :mod:`distutils.version` | |
|
||||
+--------------------+--------------------------------+-------------------------------------------------------------+
|
||||
| *description* | A single line describing the | a string |
|
||||
| | package | |
|
||||
|
@ -49,14 +50,14 @@ setup script). Indirectly provides the :class:`distutils.dist.Distribution` and
|
|||
| | maintainer, if different from | |
|
||||
| | the author | |
|
||||
+--------------------+--------------------------------+-------------------------------------------------------------+
|
||||
| *maintainer_email* | The email address of the | |
|
||||
| *maintainer_email* | The email address of the | a string |
|
||||
| | current maintainer, if | |
|
||||
| | different from the author | |
|
||||
+--------------------+--------------------------------+-------------------------------------------------------------+
|
||||
| *url* | A URL for the package | a URL |
|
||||
| *url* | A URL for the package | a string |
|
||||
| | (homepage) | |
|
||||
+--------------------+--------------------------------+-------------------------------------------------------------+
|
||||
| *download_url* | A URL to download the package | a URL |
|
||||
| *download_url* | A URL to download the package | a string |
|
||||
+--------------------+--------------------------------+-------------------------------------------------------------+
|
||||
| *packages* | A list of Python packages that | a list of strings |
|
||||
| | distutils will manipulate | |
|
||||
|
@ -68,14 +69,13 @@ setup script). Indirectly provides the :class:`distutils.dist.Distribution` and
|
|||
| | files to be built and | |
|
||||
| | installed | |
|
||||
+--------------------+--------------------------------+-------------------------------------------------------------+
|
||||
| *ext_modules* | A list of Python extensions to | A list of instances of |
|
||||
| *ext_modules* | A list of Python extensions to | a list of instances of |
|
||||
| | be built | :class:`distutils.core.Extension` |
|
||||
+--------------------+--------------------------------+-------------------------------------------------------------+
|
||||
| *classifiers* | A list of categories for the | The list of available |
|
||||
| | package | categorizations is available on `PyPI |
|
||||
| | | <http://pypi.python.org/pypi?:action=list_classifiers>`_. |
|
||||
| *classifiers* | A list of categories for the | a list of strings; valid classifiers are listed on `PyPI |
|
||||
| | package | <http://pypi.python.org/pypi?:action=list_classifiers>`_. |
|
||||
+--------------------+--------------------------------+-------------------------------------------------------------+
|
||||
| *distclass* | the :class:`Distribution` | A subclass of |
|
||||
| *distclass* | the :class:`Distribution` | a subclass of |
|
||||
| | class to use | :class:`distutils.core.Distribution` |
|
||||
+--------------------+--------------------------------+-------------------------------------------------------------+
|
||||
| *script_name* | The name of the setup.py | a string |
|
||||
|
@ -85,15 +85,15 @@ setup script). Indirectly provides the :class:`distutils.dist.Distribution` and
|
|||
| *script_args* | Arguments to supply to the | a list of strings |
|
||||
| | setup script | |
|
||||
+--------------------+--------------------------------+-------------------------------------------------------------+
|
||||
| *options* | default options for the setup | a string |
|
||||
| *options* | default options for the setup | a dictionary |
|
||||
| | script | |
|
||||
+--------------------+--------------------------------+-------------------------------------------------------------+
|
||||
| *license* | The license for the package | a string |
|
||||
+--------------------+--------------------------------+-------------------------------------------------------------+
|
||||
| *keywords* | Descriptive meta-data, see | |
|
||||
| *keywords* | Descriptive meta-data, see | a list of strings or a comma-separated string |
|
||||
| | :pep:`314` | |
|
||||
+--------------------+--------------------------------+-------------------------------------------------------------+
|
||||
| *platforms* | | |
|
||||
| *platforms* | | a list of strings or a comma-separated string |
|
||||
+--------------------+--------------------------------+-------------------------------------------------------------+
|
||||
| *cmdclass* | A mapping of command names to | a dictionary |
|
||||
| | :class:`Command` subclasses | |
|
||||
|
@ -165,13 +165,13 @@ the full reference.
|
|||
+------------------------+--------------------------------+---------------------------+
|
||||
| argument name | value | type |
|
||||
+========================+================================+===========================+
|
||||
| *name* | the full name of the | string |
|
||||
| *name* | the full name of the | a string |
|
||||
| | extension, including any | |
|
||||
| | packages --- ie. *not* a | |
|
||||
| | filename or pathname, but | |
|
||||
| | Python dotted name | |
|
||||
+------------------------+--------------------------------+---------------------------+
|
||||
| *sources* | list of source filenames, | string |
|
||||
| *sources* | list of source filenames, | a list of strings |
|
||||
| | relative to the distribution | |
|
||||
| | root (where the setup script | |
|
||||
| | lives), in Unix form (slash- | |
|
||||
|
@ -184,12 +184,12 @@ the full reference.
|
|||
| | as source for a Python | |
|
||||
| | extension. | |
|
||||
+------------------------+--------------------------------+---------------------------+
|
||||
| *include_dirs* | list of directories to search | string |
|
||||
| *include_dirs* | list of directories to search | a list of strings |
|
||||
| | for C/C++ header files (in | |
|
||||
| | Unix form for portability) | |
|
||||
+------------------------+--------------------------------+---------------------------+
|
||||
| *define_macros* | list of macros to define; each | (string, string) tuple or |
|
||||
| | macro is defined using a | (name, ``None``) |
|
||||
| *define_macros* | list of macros to define; each | a list of tuples |
|
||||
| | macro is defined using a | |
|
||||
| | 2-tuple ``(name, value)``, | |
|
||||
| | where *value* is | |
|
||||
| | either the string to define it | |
|
||||
|
@ -200,31 +200,31 @@ the full reference.
|
|||
| | on Unix C compiler command | |
|
||||
| | line) | |
|
||||
+------------------------+--------------------------------+---------------------------+
|
||||
| *undef_macros* | list of macros to undefine | string |
|
||||
| *undef_macros* | list of macros to undefine | a list of strings |
|
||||
| | explicitly | |
|
||||
+------------------------+--------------------------------+---------------------------+
|
||||
| *library_dirs* | list of directories to search | string |
|
||||
| *library_dirs* | list of directories to search | a list of strings |
|
||||
| | for C/C++ libraries at link | |
|
||||
| | time | |
|
||||
+------------------------+--------------------------------+---------------------------+
|
||||
| *libraries* | list of library names (not | string |
|
||||
| *libraries* | list of library names (not | a list of strings |
|
||||
| | filenames or paths) to link | |
|
||||
| | against | |
|
||||
+------------------------+--------------------------------+---------------------------+
|
||||
| *runtime_library_dirs* | list of directories to search | string |
|
||||
| *runtime_library_dirs* | list of directories to search | a list of strings |
|
||||
| | for C/C++ libraries at run | |
|
||||
| | time (for shared extensions, | |
|
||||
| | this is when the extension is | |
|
||||
| | loaded) | |
|
||||
+------------------------+--------------------------------+---------------------------+
|
||||
| *extra_objects* | list of extra files to link | string |
|
||||
| *extra_objects* | list of extra files to link | a list of strings |
|
||||
| | with (eg. object files not | |
|
||||
| | implied by 'sources', static | |
|
||||
| | library that must be | |
|
||||
| | explicitly specified, binary | |
|
||||
| | resource files, etc.) | |
|
||||
+------------------------+--------------------------------+---------------------------+
|
||||
| *extra_compile_args* | any extra platform- and | string |
|
||||
| *extra_compile_args* | any extra platform- and | a list of strings |
|
||||
| | compiler-specific information | |
|
||||
| | to use when compiling the | |
|
||||
| | source files in 'sources'. For | |
|
||||
|
@ -235,7 +235,7 @@ the full reference.
|
|||
| | for other platforms it could | |
|
||||
| | be anything. | |
|
||||
+------------------------+--------------------------------+---------------------------+
|
||||
| *extra_link_args* | any extra platform- and | string |
|
||||
| *extra_link_args* | any extra platform- and | a list of strings |
|
||||
| | compiler-specific information | |
|
||||
| | to use when linking object | |
|
||||
| | files together to create the | |
|
||||
|
@ -244,7 +244,7 @@ the full reference.
|
|||
| | Similar interpretation as for | |
|
||||
| | 'extra_compile_args'. | |
|
||||
+------------------------+--------------------------------+---------------------------+
|
||||
| *export_symbols* | list of symbols to be exported | string |
|
||||
| *export_symbols* | list of symbols to be exported | a list of strings |
|
||||
| | from a shared extension. Not | |
|
||||
| | used on all platforms, and not | |
|
||||
| | generally necessary for Python | |
|
||||
|
@ -252,15 +252,20 @@ the full reference.
|
|||
| | export exactly one symbol: | |
|
||||
| | ``init`` + extension_name. | |
|
||||
+------------------------+--------------------------------+---------------------------+
|
||||
| *depends* | list of files that the | string |
|
||||
| *depends* | list of files that the | a list of strings |
|
||||
| | extension depends on | |
|
||||
+------------------------+--------------------------------+---------------------------+
|
||||
| *language* | extension language (i.e. | string |
|
||||
| *language* | extension language (i.e. | a string |
|
||||
| | ``'c'``, ``'c++'``, | |
|
||||
| | ``'objc'``). Will be detected | |
|
||||
| | from the source extensions if | |
|
||||
| | not provided. | |
|
||||
+------------------------+--------------------------------+---------------------------+
|
||||
| *optional* | specifies that a build failure | a boolean |
|
||||
| | in the extension should not | |
|
||||
| | abort the build process, but | |
|
||||
| | simply skip the extension. | |
|
||||
+------------------------+--------------------------------+---------------------------+
|
||||
|
||||
|
||||
.. class:: Distribution
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
"""Support code for distutils test cases."""
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
import sysconfig
|
||||
from copy import deepcopy
|
||||
import warnings
|
||||
|
||||
|
@ -9,6 +12,7 @@ from distutils import log
|
|||
from distutils.log import DEBUG, INFO, WARN, ERROR, FATAL
|
||||
from distutils.core import Distribution
|
||||
|
||||
|
||||
def capture_warnings(func):
|
||||
def _capture_warnings(*args, **kw):
|
||||
with warnings.catch_warnings():
|
||||
|
@ -16,6 +20,7 @@ def capture_warnings(func):
|
|||
return func(*args, **kw)
|
||||
return _capture_warnings
|
||||
|
||||
|
||||
class LoggingSilencer(object):
|
||||
|
||||
def setUp(self):
|
||||
|
@ -49,6 +54,7 @@ class LoggingSilencer(object):
|
|||
def clear_logs(self):
|
||||
self.logs = []
|
||||
|
||||
|
||||
class TempdirManager(object):
|
||||
"""Mix-in class that handles temporary directories for test cases.
|
||||
|
||||
|
@ -105,6 +111,7 @@ class TempdirManager(object):
|
|||
|
||||
return pkg_dir, dist
|
||||
|
||||
|
||||
class DummyCommand:
|
||||
"""Class to store options for retrieval via set_undefined_options()."""
|
||||
|
||||
|
@ -115,6 +122,7 @@ class DummyCommand:
|
|||
def ensure_finalized(self):
|
||||
pass
|
||||
|
||||
|
||||
class EnvironGuard(object):
|
||||
|
||||
def setUp(self):
|
||||
|
@ -131,3 +139,71 @@ class EnvironGuard(object):
|
|||
del os.environ[key]
|
||||
|
||||
super(EnvironGuard, self).tearDown()
|
||||
|
||||
|
||||
def copy_xxmodule_c(directory):
|
||||
"""Helper for tests that need the xxmodule.c source file.
|
||||
|
||||
Example use:
|
||||
|
||||
def test_compile(self):
|
||||
copy_xxmodule_c(self.tmpdir)
|
||||
self.assertIn('xxmodule.c', os.listdir(self.tmpdir))
|
||||
|
||||
If the source file can be found, it will be copied to *directory*. If not,
|
||||
the test will be skipped. Errors during copy are not caught.
|
||||
"""
|
||||
filename = _get_xxmodule_path()
|
||||
if filename is None:
|
||||
raise unittest.SkipTest('cannot find xxmodule.c (test must run in '
|
||||
'the python build dir)')
|
||||
shutil.copy(filename, directory)
|
||||
|
||||
|
||||
def _get_xxmodule_path():
|
||||
srcdir = sysconfig.get_config_var('srcdir')
|
||||
candidates = [
|
||||
# use installed copy if available
|
||||
os.path.join(os.path.dirname(__file__), 'xxmodule.c'),
|
||||
# otherwise try using copy from build directory
|
||||
os.path.join(srcdir, 'Modules', 'xxmodule.c'),
|
||||
# srcdir mysteriously can be $srcdir/Lib/distutils/tests when
|
||||
# this file is run from its parent directory, so walk up the
|
||||
# tree to find the real srcdir
|
||||
os.path.join(srcdir, '..', '..', '..', 'Modules', 'xxmodule.c'),
|
||||
]
|
||||
for path in candidates:
|
||||
if os.path.exists(path):
|
||||
return path
|
||||
|
||||
|
||||
def fixup_build_ext(cmd):
|
||||
"""Function needed to make build_ext tests pass.
|
||||
|
||||
When Python was build with --enable-shared on Unix, -L. is not good
|
||||
enough to find the libpython<blah>.so. This is because regrtest runs
|
||||
it under a tempdir, not in the top level where the .so lives. By the
|
||||
time we've gotten here, Python's already been chdir'd to the tempdir.
|
||||
|
||||
When Python was built with in debug mode on Windows, build_ext commands
|
||||
need their debug attribute set, and it is not done automatically for
|
||||
some reason.
|
||||
|
||||
This function handles both of these things. Example use:
|
||||
|
||||
cmd = build_ext(dist)
|
||||
support.fixup_build_ext(cmd)
|
||||
cmd.ensure_finalized()
|
||||
"""
|
||||
if os.name == 'nt':
|
||||
cmd.debug = sys.executable.endswith('_d.exe')
|
||||
elif sysconfig.get_config_var('Py_ENABLE_SHARED'):
|
||||
# To further add to the shared builds fun on Unix, we can't just add
|
||||
# library_dirs to the Extension() instance because that doesn't get
|
||||
# plumbed through to the final compiler command.
|
||||
runshared = sysconfig.get_config_var('RUNSHARED')
|
||||
if runshared is None:
|
||||
cmd.library_dirs = ['.']
|
||||
else:
|
||||
name, equals, value = runshared.partition('=')
|
||||
cmd.library_dirs = value.split(os.pathsep)
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import sys
|
||||
import os
|
||||
import tempfile
|
||||
import shutil
|
||||
from StringIO import StringIO
|
||||
import textwrap
|
||||
|
||||
|
@ -19,76 +17,40 @@ from test import test_support
|
|||
# Don't load the xx module more than once.
|
||||
ALREADY_TESTED = False
|
||||
|
||||
def _get_source_filename():
|
||||
# use installed copy if available
|
||||
tests_f = os.path.join(os.path.dirname(__file__), 'xxmodule.c')
|
||||
if os.path.exists(tests_f):
|
||||
return tests_f
|
||||
# otherwise try using copy from build directory
|
||||
srcdir = sysconfig.get_config_var('srcdir')
|
||||
if srcdir is None:
|
||||
return os.path.join(sysconfig.project_base, 'Modules', 'xxmodule.c')
|
||||
return os.path.join(srcdir, 'Modules', 'xxmodule.c')
|
||||
|
||||
_XX_MODULE_PATH = _get_source_filename()
|
||||
|
||||
class BuildExtTestCase(support.TempdirManager,
|
||||
support.LoggingSilencer,
|
||||
unittest.TestCase):
|
||||
def setUp(self):
|
||||
# Create a simple test environment
|
||||
# Note that we're making changes to sys.path
|
||||
super(BuildExtTestCase, self).setUp()
|
||||
self.tmp_dir = tempfile.mkdtemp(prefix="pythontest_")
|
||||
if os.path.exists(_XX_MODULE_PATH):
|
||||
self.sys_path = sys.path[:]
|
||||
sys.path.append(self.tmp_dir)
|
||||
shutil.copy(_XX_MODULE_PATH, self.tmp_dir)
|
||||
self.tmp_dir = self.mkdtemp()
|
||||
self.xx_created = False
|
||||
sys.path.append(self.tmp_dir)
|
||||
self.addCleanup(sys.path.remove, self.tmp_dir)
|
||||
if sys.version > "2.6":
|
||||
import site
|
||||
self.old_user_base = site.USER_BASE
|
||||
site.USER_BASE = self.mkdtemp()
|
||||
from distutils.command import build_ext
|
||||
build_ext.USER_BASE = site.USER_BASE
|
||||
|
||||
def tearDown(self):
|
||||
# Get everything back to normal
|
||||
if os.path.exists(_XX_MODULE_PATH):
|
||||
if self.xx_created:
|
||||
test_support.unload('xx')
|
||||
sys.path[:] = self.sys_path
|
||||
# XXX on Windows the test leaves a directory
|
||||
# with xx module in TEMP
|
||||
shutil.rmtree(self.tmp_dir, os.name == 'nt' or
|
||||
sys.platform == 'cygwin')
|
||||
super(BuildExtTestCase, self).tearDown()
|
||||
|
||||
def _fixup_command(self, cmd):
|
||||
# When Python was build with --enable-shared, -L. is not good enough
|
||||
# to find the libpython<blah>.so. This is because regrtest runs it
|
||||
# under a tempdir, not in the top level where the .so lives. By the
|
||||
# time we've gotten here, Python's already been chdir'd to the
|
||||
# tempdir.
|
||||
#
|
||||
# To further add to the fun, we can't just add library_dirs to the
|
||||
# Extension() instance because that doesn't get plumbed through to the
|
||||
# final compiler command.
|
||||
if (sysconfig.get_config_var('Py_ENABLE_SHARED') and
|
||||
not sys.platform.startswith('win')):
|
||||
runshared = sysconfig.get_config_var('RUNSHARED')
|
||||
if runshared is None:
|
||||
cmd.library_dirs = ['.']
|
||||
else:
|
||||
name, equals, value = runshared.partition('=')
|
||||
cmd.library_dirs = value.split(os.pathsep)
|
||||
|
||||
@unittest.skipIf(not os.path.exists(_XX_MODULE_PATH),
|
||||
'xxmodule.c not found')
|
||||
def test_build_ext(self):
|
||||
global ALREADY_TESTED
|
||||
support.copy_xxmodule_c(self.tmp_dir)
|
||||
self.xx_created = True
|
||||
xx_c = os.path.join(self.tmp_dir, 'xxmodule.c')
|
||||
xx_ext = Extension('xx', [xx_c])
|
||||
dist = Distribution({'name': 'xx', 'ext_modules': [xx_ext]})
|
||||
dist.package_dir = self.tmp_dir
|
||||
cmd = build_ext(dist)
|
||||
self._fixup_command(cmd)
|
||||
if os.name == "nt":
|
||||
# On Windows, we must build a debug version iff running
|
||||
# a debug build of Python
|
||||
cmd.debug = sys.executable.endswith("_d.exe")
|
||||
support.fixup_build_ext(cmd)
|
||||
cmd.build_lib = self.tmp_dir
|
||||
cmd.build_temp = self.tmp_dir
|
||||
|
||||
|
@ -141,6 +103,36 @@ class BuildExtTestCase(support.TempdirManager,
|
|||
# make sure we get some library dirs under solaris
|
||||
self.assertTrue(len(cmd.library_dirs) > 0)
|
||||
|
||||
def test_user_site(self):
|
||||
# site.USER_SITE was introduced in 2.6
|
||||
if sys.version < '2.6':
|
||||
return
|
||||
|
||||
import site
|
||||
dist = Distribution({'name': 'xx'})
|
||||
cmd = build_ext(dist)
|
||||
|
||||
# making sure the user option is there
|
||||
options = [name for name, short, label in
|
||||
cmd.user_options]
|
||||
self.assertIn('user', options)
|
||||
|
||||
# setting a value
|
||||
cmd.user = 1
|
||||
|
||||
# setting user based lib and include
|
||||
lib = os.path.join(site.USER_BASE, 'lib')
|
||||
incl = os.path.join(site.USER_BASE, 'include')
|
||||
os.mkdir(lib)
|
||||
os.mkdir(incl)
|
||||
|
||||
cmd.ensure_finalized()
|
||||
|
||||
# see if include_dirs and library_dirs were set
|
||||
self.assertIn(lib, cmd.library_dirs)
|
||||
self.assertIn(lib, cmd.rpath)
|
||||
self.assertIn(incl, cmd.include_dirs)
|
||||
|
||||
def test_finalize_options(self):
|
||||
# Make sure Python's include directories (for Python.h, pyconfig.h,
|
||||
# etc.) are in the include search path.
|
||||
|
@ -149,7 +141,6 @@ class BuildExtTestCase(support.TempdirManager,
|
|||
cmd = build_ext(dist)
|
||||
cmd.finalize_options()
|
||||
|
||||
from distutils import sysconfig
|
||||
py_include = sysconfig.get_python_inc()
|
||||
self.assertTrue(py_include in cmd.include_dirs)
|
||||
|
||||
|
@ -277,13 +268,10 @@ class BuildExtTestCase(support.TempdirManager,
|
|||
dist = Distribution({'name': 'xx',
|
||||
'ext_modules': [ext]})
|
||||
cmd = build_ext(dist)
|
||||
self._fixup_command(cmd)
|
||||
support.fixup_build_ext(cmd)
|
||||
cmd.ensure_finalized()
|
||||
self.assertEqual(len(cmd.get_outputs()), 1)
|
||||
|
||||
if os.name == "nt":
|
||||
cmd.debug = sys.executable.endswith("_d.exe")
|
||||
|
||||
cmd.build_lib = os.path.join(self.tmp_dir, 'build')
|
||||
cmd.build_temp = os.path.join(self.tmp_dir, 'tempt')
|
||||
|
||||
|
@ -509,10 +497,8 @@ class BuildExtTestCase(support.TempdirManager,
|
|||
cmd.build_temp = self.tmp_dir
|
||||
|
||||
try:
|
||||
old_stdout = sys.stdout
|
||||
cmd.ensure_finalized()
|
||||
cmd.run()
|
||||
|
||||
except CompileError:
|
||||
self.fail("Wrong deployment target during compilation")
|
||||
|
||||
|
|
|
@ -1,17 +1,33 @@
|
|||
"""Tests for distutils.command.install."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
import site
|
||||
|
||||
from test.test_support import run_unittest
|
||||
from test.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
|
||||
|
||||
|
||||
class InstallTestCase(support.TempdirManager, unittest.TestCase):
|
||||
def _make_ext_name(modname):
|
||||
if os.name == 'nt' and sys.executable.endswith('_d.exe'):
|
||||
modname += '_d'
|
||||
return modname + sysconfig.get_config_var('SO')
|
||||
|
||||
|
||||
class InstallTestCase(support.TempdirManager,
|
||||
support.LoggingSilencer,
|
||||
unittest.TestCase):
|
||||
|
||||
def test_home_installation_scheme(self):
|
||||
# This ensure two things:
|
||||
|
@ -49,6 +65,181 @@ class InstallTestCase(support.TempdirManager, unittest.TestCase):
|
|||
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)
|
||||
|
|
|
@ -423,6 +423,7 @@ class SDistTestCase(PyPIRCCommandTestCase):
|
|||
def test_manual_manifest(self):
|
||||
# check that a MANIFEST without a marker is left alone
|
||||
dist, cmd = self.get_cmd()
|
||||
cmd.formats = ['gztar']
|
||||
cmd.ensure_finalized()
|
||||
self.write_file((self.tmp_dir, cmd.manifest), 'README.manual')
|
||||
self.write_file((self.tmp_dir, 'README.manual'),
|
||||
|
|
|
@ -25,7 +25,8 @@ except ImportError:
|
|||
__all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2",
|
||||
"copytree", "move", "rmtree", "Error", "SpecialFileError",
|
||||
"ExecError", "make_archive", "get_archive_formats",
|
||||
"register_archive_format", "unregister_archive_format"]
|
||||
"register_archive_format", "unregister_archive_format",
|
||||
"ignore_patterns"]
|
||||
|
||||
class Error(EnvironmentError):
|
||||
pass
|
||||
|
|
Loading…
Reference in New Issue