[Python-checkins] cpython (merge 2.7 -> 2.7): Branch merge
eric.araujo
python-checkins at python.org
Fri Aug 26 16:37:41 CEST 2011
http://hg.python.org/cpython/rev/4493ac4c1287
changeset: 72094:4493ac4c1287
branch: 2.7
parent: 72076:498b03a55297
parent: 72093:993bccb490c7
user: Éric Araujo <merwok at netwok.org>
date: Fri Aug 26 16:32:36 2011 +0200
summary:
Branch merge
files:
Doc/ACKS.txt | 1 +
Doc/distutils/apiref.rst | 61 ++--
Lib/distutils/tests/support.py | 76 +++++
Lib/distutils/tests/test_build_ext.py | 104 +++----
Lib/distutils/tests/test_install.py | 195 +++++++++++++-
Lib/distutils/tests/test_sdist.py | 1 +
Lib/shutil.py | 3 +-
7 files changed, 351 insertions(+), 90 deletions(-)
diff --git a/Doc/ACKS.txt b/Doc/ACKS.txt
--- a/Doc/ACKS.txt
+++ b/Doc/ACKS.txt
@@ -183,6 +183,7 @@
* Joakim Sernbrant
* Justin Sheehy
* Charlie Shepherd
+ * Yue Shuaijie
* Michael Simcich
* Ionel Simionescu
* Michael Sloan
diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst
--- a/Doc/distutils/apiref.rst
+++ b/Doc/distutils/apiref.rst
@@ -31,8 +31,9 @@
+====================+================================+=============================================================+
| *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 @@
| | 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 @@
| | 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 @@
| *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 @@
+------------------------+--------------------------------+---------------------------+
| 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 @@
| | 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 @@
| | 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 @@
| | 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 @@
| | 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 @@
| | 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
diff --git a/Lib/distutils/tests/support.py b/Lib/distutils/tests/support.py
--- a/Lib/distutils/tests/support.py
+++ b/Lib/distutils/tests/support.py
@@ -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.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 @@
return func(*args, **kw)
return _capture_warnings
+
class LoggingSilencer(object):
def setUp(self):
@@ -49,6 +54,7 @@
def clear_logs(self):
self.logs = []
+
class TempdirManager(object):
"""Mix-in class that handles temporary directories for test cases.
@@ -105,6 +111,7 @@
return pkg_dir, dist
+
class DummyCommand:
"""Class to store options for retrieval via set_undefined_options()."""
@@ -115,6 +122,7 @@
def ensure_finalized(self):
pass
+
class EnvironGuard(object):
def setUp(self):
@@ -131,3 +139,71 @@
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)
diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py
--- a/Lib/distutils/tests/test_build_ext.py
+++ b/Lib/distutils/tests/test_build_ext.py
@@ -1,7 +1,5 @@
import sys
import os
-import tempfile
-import shutil
from StringIO import StringIO
import textwrap
@@ -19,76 +17,40 @@
# 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 @@
# 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 @@
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 @@
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 @@
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")
diff --git a/Lib/distutils/tests/test_install.py b/Lib/distutils/tests/test_install.py
--- a/Lib/distutils/tests/test_install.py
+++ b/Lib/distutils/tests/test_install.py
@@ -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 @@
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)
diff --git a/Lib/distutils/tests/test_sdist.py b/Lib/distutils/tests/test_sdist.py
--- a/Lib/distutils/tests/test_sdist.py
+++ b/Lib/distutils/tests/test_sdist.py
@@ -423,6 +423,7 @@
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'),
diff --git a/Lib/shutil.py b/Lib/shutil.py
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -25,7 +25,8 @@
__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
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list