From 434812d569eef54dd79936e581fc20df57671158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Thu, 16 Jun 2011 23:21:01 +0200 Subject: [PATCH 1/7] Clean up packaging.tests.test_mixin2to3 --- Lib/packaging/tests/test_mixin2to3.py | 77 +++++++++++++++------------ 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/Lib/packaging/tests/test_mixin2to3.py b/Lib/packaging/tests/test_mixin2to3.py index d7c83c2d6ae..926f754d01b 100644 --- a/Lib/packaging/tests/test_mixin2to3.py +++ b/Lib/packaging/tests/test_mixin2to3.py @@ -1,5 +1,5 @@ -"""Tests for packaging.command.build_py.""" import sys +import textwrap from packaging.tests import unittest, support from packaging.compat import Mixin2to3 @@ -12,60 +12,69 @@ class Mixin2to3TestCase(support.TempdirManager, @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher') def test_convert_code_only(self): # used to check if code gets converted properly. - code_content = "print 'test'\n" - code_handle = self.mktempfile() - code_name = code_handle.name + code = "print 'test'" - code_handle.write(code_content) - code_handle.flush() + with self.mktempfile() as fp: + fp.write(code) mixin2to3 = Mixin2to3() - mixin2to3._run_2to3([code_name]) - converted_code_content = "print('test')\n" - with open(code_name) as fp: - new_code_content = "".join(fp.readlines()) + mixin2to3._run_2to3([fp.name]) + expected = "print('test')" - self.assertEqual(new_code_content, converted_code_content) + with open(fp.name) as fp: + converted = fp.read() + + self.assertEqual(expected, converted) @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher') def test_doctests_only(self): # used to check if doctests gets converted properly. - doctest_content = '"""\n>>> print test\ntest\n"""\nprint test\n\n' - doctest_handle = self.mktempfile() - doctest_name = doctest_handle.name + doctest = textwrap.dedent('''\ + """Example docstring. - doctest_handle.write(doctest_content) - doctest_handle.flush() + >>> print test + test + + It works. + """''') + + with self.mktempfile() as fp: + fp.write(doctest) mixin2to3 = Mixin2to3() - mixin2to3._run_2to3([doctest_name]) + mixin2to3._run_2to3([fp.name]) + expected = textwrap.dedent('''\ + """Example docstring. - converted_doctest_content = ['"""', '>>> print(test)', 'test', '"""', - 'print(test)', '', '', ''] - converted_doctest_content = '\n'.join(converted_doctest_content) - with open(doctest_name) as fp: - new_doctest_content = "".join(fp.readlines()) + >>> print(test) + test - self.assertEqual(new_doctest_content, converted_doctest_content) + It works. + """\n''') + + with open(fp.name) as fp: + converted = fp.read() + + self.assertEqual(expected, converted) @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher') def test_additional_fixers(self): # used to check if use_2to3_fixers works - code_content = "type(x) is T" - code_handle = self.mktempfile() - code_name = code_handle.name + code = 'type(x) is not T' - code_handle.write(code_content) - code_handle.flush() + with self.mktempfile() as fp: + fp.write(code) mixin2to3 = Mixin2to3() - - mixin2to3._run_2to3(files=[code_name], doctests=[code_name], + mixin2to3._run_2to3(files=[fp.name], doctests=[fp.name], fixers=['packaging.tests.fixer']) - converted_code_content = "isinstance(x, T)" - with open(code_name) as fp: - new_code_content = "".join(fp.readlines()) - self.assertEqual(new_code_content, converted_code_content) + + expected = 'not isinstance(x, T)' + + with open(fp.name) as fp: + converted = fp.read() + + self.assertEqual(expected, converted) def test_suite(): From b6be20ca337348b7cf2b356f9354a4121627add0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Thu, 16 Jun 2011 23:34:55 +0200 Subject: [PATCH 2/7] Packaging: remove last mentions and uses of setup.py in the code. Now only the compatibility layer (in create, util and install) talk about setup.py. --- Lib/packaging/command/build_ext.py | 5 +---- Lib/packaging/compiler/msvc9compiler.py | 8 ++++---- Lib/packaging/compiler/msvccompiler.py | 3 +-- Lib/packaging/compiler/unixccompiler.py | 2 +- Lib/packaging/dist.py | 9 +++++---- Lib/packaging/tests/test_command_bdist_dumb.py | 16 ---------------- Lib/packaging/tests/test_dist.py | 4 +++- 7 files changed, 15 insertions(+), 32 deletions(-) diff --git a/Lib/packaging/command/build_ext.py b/Lib/packaging/command/build_ext.py index 403e5fd850a..c8203360857 100644 --- a/Lib/packaging/command/build_ext.py +++ b/Lib/packaging/command/build_ext.py @@ -38,7 +38,7 @@ class build_ext(Command): # XXX thoughts on how to deal with complex command-line options like # these, i.e. how to make it so fancy_getopt can suck them off the - # command line and make it look like setup.py defined the appropriate + # command line and turn them into the appropriate # lists of tuples of what-have-you. # - each command needs a callback to process its command-line options # - Command.__init__() needs access to its share of the whole @@ -287,9 +287,6 @@ class build_ext(Command): def run(self): from packaging.compiler import new_compiler - # 'self.extensions', as supplied by setup.py, is a list of - # Extension instances. See the documentation for Extension (in - # distutils.extension) for details. if not self.extensions: return diff --git a/Lib/packaging/compiler/msvc9compiler.py b/Lib/packaging/compiler/msvc9compiler.py index 43fc5fa2dba..6ca49c21b24 100644 --- a/Lib/packaging/compiler/msvc9compiler.py +++ b/Lib/packaging/compiler/msvc9compiler.py @@ -130,10 +130,10 @@ class MacroExpander: raise KeyError("sdkinstallrootv2.0") except KeyError: raise PackagingPlatformError( - """Python was built with Visual Studio 2008; -extensions must be built with a compiler than can generate compatible binaries. -Visual Studio 2008 was not found on this system. If you have Cygwin installed, -you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""") +"""Python was built with Visual Studio 2008; extensions must be built with a +compiler than can generate compatible binaries. Visual Studio 2008 was not +found on this system. If you have Cygwin installed, you can try compiling +with MingW32, by passing "-c mingw32" to pysetup.""") if version >= 9.0: self.set_macro("FrameworkVersion", self.vsbase, "clr version") diff --git a/Lib/packaging/compiler/msvccompiler.py b/Lib/packaging/compiler/msvccompiler.py index 97f76bb99f1..3d4ac3c60b1 100644 --- a/Lib/packaging/compiler/msvccompiler.py +++ b/Lib/packaging/compiler/msvccompiler.py @@ -134,8 +134,7 @@ class MacroExpander: """Python was built with Visual Studio 2003; extensions must be built with a compiler than can generate compatible binaries. Visual Studio 2003 was not found on this system. If you have Cygwin installed, you can try -compiling with MingW32, by passing "-c mingw32" to setup.py.""") -# XXX update this comment for setup.cfg +compiling with MingW32, by passing "-c mingw32" to pysetup.""") p = r"Software\Microsoft\NET Framework Setup\Product" for base in HKEYS: diff --git a/Lib/packaging/compiler/unixccompiler.py b/Lib/packaging/compiler/unixccompiler.py index 8c24c0f6e38..c857d03e09a 100644 --- a/Lib/packaging/compiler/unixccompiler.py +++ b/Lib/packaging/compiler/unixccompiler.py @@ -33,7 +33,7 @@ import sysconfig # we need some way for outsiders to feed preprocessor/compiler/linker # flags in to us -- eg. a sysadmin might want to mandate certain flags # via a site config file, or a user might want to set something for -# compiling this module distribution only via the setup.py command +# compiling this module distribution only via the pysetup command # line, whatever. As long as these options come from something on the # current system, they can be as system-dependent as they like, and we # should just happily stuff them into the preprocessor/compiler/linker diff --git a/Lib/packaging/dist.py b/Lib/packaging/dist.py index 5c390ce9d19..7b431acc8b6 100644 --- a/Lib/packaging/dist.py +++ b/Lib/packaging/dist.py @@ -47,7 +47,7 @@ class Distribution: # 'global_options' describes the command-line options that may be # supplied to the setup script prior to any actual commands. - # Eg. "./setup.py -n" or "./setup.py --dry-run" both take advantage of + # Eg. "pysetup -n" or "pysetup --dry-run" both take advantage of # these global options. This list should be kept to a bare minimum, # since every global option is also valid as a command option -- and we # don't want to pollute the commands with too many options that they @@ -63,14 +63,15 @@ class Distribution: common_usage = """\ Common commands: (see '--help-commands' for more) - setup.py build will build the package underneath 'build/' - setup.py install will install the package + pysetup run build will build the package underneath 'build/' + pysetup run install will install the package """ # options that are not propagated to the commands display_options = [ ('help-commands', None, "list all available commands"), + # XXX this is obsoleted by the pysetup metadata action ('name', None, "print package name"), ('version', 'V', @@ -360,7 +361,7 @@ Common commands: (see '--help-commands' for more) return # Handle the cases of --help as a "global" option, ie. - # "setup.py --help" and "setup.py --help command ...". For the + # "pysetup run --help" and "pysetup run --help command ...". For the # former, we show global options (--dry-run, etc.) # and display-only options (--name, --version, etc.); for the # latter, we omit the display-only options and show help for diff --git a/Lib/packaging/tests/test_command_bdist_dumb.py b/Lib/packaging/tests/test_command_bdist_dumb.py index b2357953a63..fd199ea932e 100644 --- a/Lib/packaging/tests/test_command_bdist_dumb.py +++ b/Lib/packaging/tests/test_command_bdist_dumb.py @@ -1,6 +1,5 @@ """Tests for distutils.command.bdist_dumb.""" -import sys import os from packaging.dist import Distribution @@ -9,15 +8,6 @@ from packaging.tests import unittest, support from packaging.tests.support import requires_zlib -SETUP_PY = """\ -from distutils.run import setup -import foo - -setup(name='foo', version='0.1', py_modules=['foo'], - url='xxx', author='xxx', author_email='xxx') -""" - - class BuildDumbTestCase(support.TempdirManager, support.LoggingCatcher, unittest.TestCase): @@ -25,12 +15,9 @@ class BuildDumbTestCase(support.TempdirManager, def setUp(self): super(BuildDumbTestCase, self).setUp() self.old_location = os.getcwd() - self.old_sys_argv = sys.argv, sys.argv[:] def tearDown(self): os.chdir(self.old_location) - sys.argv = self.old_sys_argv[0] - sys.argv[:] = self.old_sys_argv[1] super(BuildDumbTestCase, self).tearDown() @requires_zlib @@ -40,7 +27,6 @@ class BuildDumbTestCase(support.TempdirManager, tmp_dir = self.mkdtemp() pkg_dir = os.path.join(tmp_dir, 'foo') os.mkdir(pkg_dir) - self.write_file((pkg_dir, 'setup.py'), SETUP_PY) self.write_file((pkg_dir, 'foo.py'), '#') self.write_file((pkg_dir, 'MANIFEST.in'), 'include foo.py') self.write_file((pkg_dir, 'README'), '') @@ -50,8 +36,6 @@ class BuildDumbTestCase(support.TempdirManager, 'url': 'xxx', 'author': 'xxx', 'author_email': 'xxx'}) os.chdir(pkg_dir) - - sys.argv[:] = ['setup.py'] cmd = bdist_dumb(dist) # so the output is the same no matter diff --git a/Lib/packaging/tests/test_dist.py b/Lib/packaging/tests/test_dist.py index e1c5ff0a2d7..9ad7a0881d5 100644 --- a/Lib/packaging/tests/test_dist.py +++ b/Lib/packaging/tests/test_dist.py @@ -4,6 +4,7 @@ import io import sys import logging import textwrap +import sysconfig import packaging.dist from packaging.dist import Distribution @@ -396,7 +397,8 @@ class MetadataTestCase(support.TempdirManager, dist = Distribution() sys.argv = [] dist.help = True - dist.script_name = 'setup.py' + dist.script_name = os.path.join(sysconfig.get_path('scripts'), + 'pysetup') __, stdout = captured_stdout(dist.parse_command_line) output = [line for line in stdout.split('\n') if line.strip() != ''] From 6f67765389f63b49c094ee08017309bcb45d7ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Thu, 16 Jun 2011 23:43:15 +0200 Subject: [PATCH 3/7] Stop binding sys.path as default parameter value in packaging. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two public functions in database default to sys.path if the given *paths* argument is None; the private functions don’t have default values for their arguments anymore, which is fine as the public functions that call them pass their arguments down. Likewise in install, the functions will pass down their *paths* arguments down to database functions. A one-line unneeded function in install was removed instead of being changed, and the few remaining tests that used brute-force restoration of sys.path have been cleaned up to use sys.path.remove. --- Lib/packaging/database.py | 13 ++++++++----- Lib/packaging/install.py | 19 ++++++------------- Lib/packaging/tests/test_command_build_ext.py | 4 +--- Lib/packaging/tests/test_database.py | 11 +++++------ 4 files changed, 20 insertions(+), 27 deletions(-) diff --git a/Lib/packaging/database.py b/Lib/packaging/database.py index e3c57bacab1..67946a249b7 100644 --- a/Lib/packaging/database.py +++ b/Lib/packaging/database.py @@ -72,7 +72,7 @@ def clear_cache(): _cache_generated_egg = False -def _yield_distributions(include_dist, include_egg, paths=sys.path): +def _yield_distributions(include_dist, include_egg, paths): """ Yield .dist-info and .egg(-info) distributions, based on the arguments @@ -92,7 +92,7 @@ def _yield_distributions(include_dist, include_egg, paths=sys.path): yield EggInfoDistribution(dist_path) -def _generate_cache(use_egg_info=False, paths=sys.path): +def _generate_cache(use_egg_info, paths): global _cache_generated, _cache_generated_egg if _cache_generated_egg or (_cache_generated and not use_egg_info): @@ -472,7 +472,7 @@ def distinfo_dirname(name, version): return '-'.join([name, normalized_version]) + file_extension -def get_distributions(use_egg_info=False, paths=sys.path): +def get_distributions(use_egg_info=False, paths=None): """ Provides an iterator that looks for ``.dist-info`` directories in ``sys.path`` and returns :class:`Distribution` instances for each one of @@ -482,6 +482,9 @@ def get_distributions(use_egg_info=False, paths=sys.path): :rtype: iterator of :class:`Distribution` and :class:`EggInfoDistribution` instances """ + if paths is None: + paths = sys.path + if not _cache_enabled: for dist in _yield_distributions(True, use_egg_info, paths): yield dist @@ -513,7 +516,7 @@ def get_distribution(name, use_egg_info=False, paths=None): :rtype: :class:`Distribution` or :class:`EggInfoDistribution` or None """ - if paths == None: + if paths is None: paths = sys.path if not _cache_enabled: @@ -632,7 +635,7 @@ def get_file_users(path): def get_file_path(distribution_name, relative_path): """Return the path to a resource file.""" dist = get_distribution(distribution_name) - if dist != None: + if dist is not None: return dist.get_resource_path(relative_path) raise LookupError('no distribution named %r found' % distribution_name) diff --git a/Lib/packaging/install.py b/Lib/packaging/install.py index c5bda453074..551ece1ea48 100644 --- a/Lib/packaging/install.py +++ b/Lib/packaging/install.py @@ -54,10 +54,8 @@ def _move_files(files, destination): try: os.makedirs(os.path.dirname(new)) except OSError as e: - if e.errno == errno.EEXIST: - pass - else: - raise e + if e.errno != errno.EEXIST: + raise os.rename(old, new) yield old, new @@ -169,7 +167,7 @@ def _run_install_from_dir(source_dir): os.chdir(old_dir) -def install_dists(dists, path, paths=sys.path): +def install_dists(dists, path, paths=None): """Install all distributions provided in dists, with the given prefix. If an error occurs while installing one of the distributions, uninstall all @@ -196,13 +194,13 @@ def install_dists(dists, path, paths=sys.path): # reverting for installed_dist in installed_dists: logger.info('Reverting %s', installed_dist) - _remove_dist(installed_dist, paths) + remove(installed_dist.name, paths) raise e return installed_dists def install_from_infos(install_path=None, install=[], remove=[], conflicts=[], - paths=sys.path): + paths=None): """Install and remove the given distributions. The function signature is made to be compatible with the one of get_infos. @@ -383,11 +381,7 @@ def _update_infos(infos, new_infos): infos[key].extend(new_infos[key]) -def _remove_dist(dist, paths=sys.path): - remove(dist.name, paths) - - -def remove(project_name, paths=sys.path, auto_confirm=True): +def remove(project_name, paths=None, auto_confirm=True): """Removes a single project from the installation. Returns True on success @@ -539,7 +533,6 @@ def install(project): def _main(**attrs): if 'script_args' not in attrs: - import sys attrs['requirements'] = sys.argv[1] get_infos(**attrs) diff --git a/Lib/packaging/tests/test_command_build_ext.py b/Lib/packaging/tests/test_command_build_ext.py index 9729559865d..d8936d449ec 100644 --- a/Lib/packaging/tests/test_command_build_ext.py +++ b/Lib/packaging/tests/test_command_build_ext.py @@ -29,7 +29,6 @@ class BuildExtTestCase(support.TempdirManager, # Note that we're making changes to sys.path super(BuildExtTestCase, self).setUp() self.tmp_dir = self.mkdtemp() - self.sys_path = sys.path, sys.path[:] sys.path.append(self.tmp_dir) filename = _get_source_filename() if os.path.exists(filename): @@ -107,8 +106,7 @@ class BuildExtTestCase(support.TempdirManager, def tearDown(self): # Get everything back to normal unload('xx') - sys.path = self.sys_path[0] - sys.path[:] = self.sys_path[1] + sys.path.remove(self.tmp_dir) if sys.version > "2.6": site.USER_BASE = self.old_user_base build_ext.USER_BASE = self.old_user_base diff --git a/Lib/packaging/tests/test_database.py b/Lib/packaging/tests/test_database.py index e965c60773f..3eeda835702 100644 --- a/Lib/packaging/tests/test_database.py +++ b/Lib/packaging/tests/test_database.py @@ -259,12 +259,11 @@ class TestDatabase(support.LoggingCatcher, disable_cache() # Setup the path environment with our fake distributions current_path = os.path.abspath(os.path.dirname(__file__)) - self.sys_path = sys.path[:] self.fake_dists_path = os.path.join(current_path, 'fake_dists') sys.path.insert(0, self.fake_dists_path) def tearDown(self): - sys.path[:] = self.sys_path + sys.path.remove(self.fake_dists_path) enable_cache() super(TestDatabase, self).tearDown() @@ -488,20 +487,20 @@ class TestDatabase(support.LoggingCatcher, dists = [('choxie', '2.0.0.9'), ('grammar', '1.0a4'), ('towel-stuff', '0.1'), ('babar', '0.1')] - checkLists([], _yield_distributions(False, False)) + checkLists([], _yield_distributions(False, False, sys.path)) found = [(dist.name, dist.metadata['Version']) - for dist in _yield_distributions(False, True) + for dist in _yield_distributions(False, True, sys.path) if dist.path.startswith(self.fake_dists_path)] checkLists(eggs, found) found = [(dist.name, dist.metadata['Version']) - for dist in _yield_distributions(True, False) + for dist in _yield_distributions(True, False, sys.path) if dist.path.startswith(self.fake_dists_path)] checkLists(dists, found) found = [(dist.name, dist.metadata['Version']) - for dist in _yield_distributions(True, True) + for dist in _yield_distributions(True, True, sys.path) if dist.path.startswith(self.fake_dists_path)] checkLists(dists + eggs, found) From 3e85e5427410bce670d516cf662c12413e155c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Thu, 16 Jun 2011 23:50:17 +0200 Subject: [PATCH 4/7] Remove unused code in packaging.pypi.dist --- Lib/packaging/pypi/dist.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Lib/packaging/pypi/dist.py b/Lib/packaging/pypi/dist.py index d3824c22e82..dbf64592730 100644 --- a/Lib/packaging/pypi/dist.py +++ b/Lib/packaging/pypi/dist.py @@ -7,15 +7,13 @@ Release objects contain metadata-related information (see PEP 376); distribution objects contain download-related information. """ -import sys -import mimetypes import re +import hashlib import tempfile import urllib.request import urllib.parse import urllib.error import urllib.parse -import hashlib from shutil import unpack_archive from packaging.errors import IrrationalVersionError @@ -318,7 +316,6 @@ class DistInfo(IndexReference): path = tempfile.mkdtemp() filename = self.download(path) - content_type = mimetypes.guess_type(filename)[0] unpack_archive(filename, path) self._unpacked_dir = path From d2c7e3fe96b16122fe23e018f970c5518c6411b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Fri, 17 Jun 2011 13:24:33 +0200 Subject: [PATCH 5/7] =?UTF-8?q?Minor=20tweaks=20in=20packaging=E2=80=99s?= =?UTF-8?q?=20test=5Fdist.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use different Metadata objects to write and read a PKG-INFO (METADATA) file, to make sure the tested values come from the file - No need to restore methods on an instance after monkey-patching them: the methods are still the same on the class - Harmonize dedent calls --- Lib/packaging/tests/test_dist.py | 36 +++++++++++++------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/Lib/packaging/tests/test_dist.py b/Lib/packaging/tests/test_dist.py index 9ad7a0881d5..48335e77055 100644 --- a/Lib/packaging/tests/test_dist.py +++ b/Lib/packaging/tests/test_dist.py @@ -10,6 +10,7 @@ import packaging.dist from packaging.dist import Distribution from packaging.command import set_command from packaging.command.cmd import Command +from packaging.metadata import Metadata from packaging.errors import PackagingModuleError, PackagingOptionError from packaging.tests import TESTFN, captured_stdout from packaging.tests import support, unittest @@ -203,21 +204,21 @@ class DistributionTestCase(support.TempdirManager, config_file = os.path.join(temp_home, "config1.cfg") hooks_module = os.path.join(temp_home, pyname) - self.write_file(config_file, textwrap.dedent(''' + self.write_file(config_file, textwrap.dedent('''\ [test_dist] pre-hook.test = %(modname)s.log_pre_call post-hook.test = %(modname)s.log_post_call''' % {'modname': module_name})) - self.write_file(hooks_module, textwrap.dedent(''' - record = [] + self.write_file(hooks_module, textwrap.dedent('''\ + record = [] - def log_pre_call(cmd): - record.append('pre-%s' % cmd.get_command_name()) + def log_pre_call(cmd): + record.append('pre-%s' % cmd.get_command_name()) - def log_post_call(cmd): - record.append('post-%s' % cmd.get_command_name()) - ''')) + def log_post_call(cmd): + record.append('post-%s' % cmd.get_command_name()) + ''')) set_command('packaging.tests.test_dist.test_dist') d = create_distribution([config_file]) @@ -229,15 +230,9 @@ class DistributionTestCase(support.TempdirManager, self.addCleanup(unload, module_name) record = __import__(module_name).record - old_run = cmd.run - old_finalize = cmd.finalize_options cmd.run = lambda: record.append('run') cmd.finalize_options = lambda: record.append('finalize') - try: - d.run_command('test_dist') - finally: - cmd.run = old_run - cmd.finalize_options = old_finalize + d.run_command('test_dist') self.assertEqual(record, ['finalize', 'pre-test_dist', @@ -248,7 +243,7 @@ class DistributionTestCase(support.TempdirManager, temp_home = self.mkdtemp() config_file = os.path.join(temp_home, "config1.cfg") - self.write_file(config_file, textwrap.dedent(''' + self.write_file(config_file, textwrap.dedent('''\ [test_dist] pre-hook.test = nonexistent.dotted.name''')) @@ -263,7 +258,7 @@ class DistributionTestCase(support.TempdirManager, temp_home = self.mkdtemp() config_file = os.path.join(temp_home, "config1.cfg") - self.write_file(config_file, textwrap.dedent(''' + self.write_file(config_file, textwrap.dedent('''\ [test_dist] pre-hook.test = packaging.tests.test_dist.__doc__''')) @@ -429,14 +424,13 @@ class MetadataTestCase(support.TempdirManager, "requires_dist": ['foo']} dist = Distribution(attrs) - metadata = dist.metadata - - # write it then reloads it PKG_INFO = io.StringIO() - metadata.write_file(PKG_INFO) + dist.metadata.write_file(PKG_INFO) PKG_INFO.seek(0) + metadata = Metadata() metadata.read_file(PKG_INFO) + self.assertEqual(metadata['name'], "package") self.assertEqual(metadata['version'], "1.0") self.assertEqual(metadata['summary'], "xxx") From c06f46f74c4a5f3cc46aa3a6d1c9cc1cb187e4c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Fri, 17 Jun 2011 15:43:18 +0200 Subject: [PATCH 6/7] =?UTF-8?q?Packaging=20tests:=20don=E2=80=99t=20let=20?= =?UTF-8?q?an=20internal=20cache=20grow=20indefinitely.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Victor Stinner diagnosed on #12167 that some reference leaks came from util._path_created, a set used for caching; there are two tests that cause additions to this set, so now they clear it in tearDown, avoiding 17 refleaks. (My tests show that it’s necessary to clear the set in only one test, clearing it in both does not stop more refleaks, but there’s no harm in doing it.) --- Lib/packaging/tests/test_command_bdist_dumb.py | 2 ++ Lib/packaging/tests/test_uninstall.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Lib/packaging/tests/test_command_bdist_dumb.py b/Lib/packaging/tests/test_command_bdist_dumb.py index fd199ea932e..25f3276b0c8 100644 --- a/Lib/packaging/tests/test_command_bdist_dumb.py +++ b/Lib/packaging/tests/test_command_bdist_dumb.py @@ -1,6 +1,7 @@ """Tests for distutils.command.bdist_dumb.""" import os +import packaging.util from packaging.dist import Distribution from packaging.command.bdist_dumb import bdist_dumb @@ -18,6 +19,7 @@ class BuildDumbTestCase(support.TempdirManager, def tearDown(self): os.chdir(self.old_location) + packaging.util._path_created.clear() super(BuildDumbTestCase, self).tearDown() @requires_zlib diff --git a/Lib/packaging/tests/test_uninstall.py b/Lib/packaging/tests/test_uninstall.py index 00e97e4c700..0ef7f3be90b 100644 --- a/Lib/packaging/tests/test_uninstall.py +++ b/Lib/packaging/tests/test_uninstall.py @@ -3,6 +3,7 @@ import os import sys from io import StringIO import stat +import packaging.util from packaging.database import disable_cache, enable_cache from packaging.run import main @@ -43,6 +44,7 @@ class UninstallTestCase(support.TempdirManager, def tearDown(self): os.chdir(self.cwd) + packaging.util._path_created.clear() super(UninstallTestCase, self).tearDown() def run_setup(self, *args): From ed5d2f131083f16ab3d305ccc6f58c66f70f1f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Fri, 17 Jun 2011 15:47:41 +0200 Subject: [PATCH 7/7] Minor tweaks to packaging tests. - Move a tearDown method right after setUp - Use assertRaises instead of reinventing it - Skip a test instead of commenting it out, as a reminder --- Lib/packaging/tests/test_command_build_ext.py | 20 +++++------ Lib/packaging/tests/test_pypi_dist.py | 34 +++++++++---------- Lib/packaging/tests/test_util.py | 8 +---- 3 files changed, 28 insertions(+), 34 deletions(-) diff --git a/Lib/packaging/tests/test_command_build_ext.py b/Lib/packaging/tests/test_command_build_ext.py index d8936d449ec..930a38f4e82 100644 --- a/Lib/packaging/tests/test_command_build_ext.py +++ b/Lib/packaging/tests/test_command_build_ext.py @@ -37,6 +37,16 @@ class BuildExtTestCase(support.TempdirManager, site.USER_BASE = self.mkdtemp() build_ext.USER_BASE = site.USER_BASE + def tearDown(self): + # Get everything back to normal + unload('xx') + sys.path.remove(self.tmp_dir) + if sys.version > "2.6": + site.USER_BASE = self.old_user_base + build_ext.USER_BASE = self.old_user_base + + 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.so. This is because regrtest runs it @@ -103,16 +113,6 @@ class BuildExtTestCase(support.TempdirManager, self.assertTrue(isinstance(xx.Null(), xx.Null)) self.assertTrue(isinstance(xx.Str(), xx.Str)) - def tearDown(self): - # Get everything back to normal - unload('xx') - sys.path.remove(self.tmp_dir) - if sys.version > "2.6": - site.USER_BASE = self.old_user_base - build_ext.USER_BASE = self.old_user_base - - super(BuildExtTestCase, self).tearDown() - def test_solaris_enable_shared(self): dist = Distribution({'name': 'xx'}) cmd = build_ext(dist) diff --git a/Lib/packaging/tests/test_pypi_dist.py b/Lib/packaging/tests/test_pypi_dist.py index 0c88c9b6b96..ff9a16e27b8 100644 --- a/Lib/packaging/tests/test_pypi_dist.py +++ b/Lib/packaging/tests/test_pypi_dist.py @@ -239,7 +239,6 @@ class TestReleasesList(unittest.TestCase): def test_prefer_final(self): # Can order the distributions using prefer_final - fb10 = ReleaseInfo("FooBar", "1.0") # final distribution fb11a = ReleaseInfo("FooBar", "1.1a1") # alpha fb12a = ReleaseInfo("FooBar", "1.2a1") # alpha @@ -252,22 +251,23 @@ class TestReleasesList(unittest.TestCase): dists.sort_releases(prefer_final=False) self.assertEqual(fb12b, dists[0]) -# def test_prefer_source(self): -# # Ordering support prefer_source -# fb_source = Dist("FooBar", "1.0", type="source") -# fb_binary = Dist("FooBar", "1.0", type="binary") -# fb2_binary = Dist("FooBar", "2.0", type="binary") -# dists = ReleasesList([fb_binary, fb_source]) -# -# dists.sort_distributions(prefer_source=True) -# self.assertEqual(fb_source, dists[0]) -# -# dists.sort_distributions(prefer_source=False) -# self.assertEqual(fb_binary, dists[0]) -# -# dists.append(fb2_binary) -# dists.sort_distributions(prefer_source=True) -# self.assertEqual(fb2_binary, dists[0]) + @unittest.skip('method not implemented yet') + def test_prefer_source(self): + # Ordering supports prefer_source + fb_source = Dist("FooBar", "1.0", type="source") + fb_binary = Dist("FooBar", "1.0", type="binary") + fb2_binary = Dist("FooBar", "2.0", type="binary") + dists = ReleasesList([fb_binary, fb_source]) + + dists.sort_distributions(prefer_source=True) + self.assertEqual(fb_source, dists[0]) + + dists.sort_distributions(prefer_source=False) + self.assertEqual(fb_binary, dists[0]) + + dists.append(fb2_binary) + dists.sort_distributions(prefer_source=True) + self.assertEqual(fb2_binary, dists[0]) def test_get_last(self): dists = ReleasesList('Foo') diff --git a/Lib/packaging/tests/test_util.py b/Lib/packaging/tests/test_util.py index 9b6498b91e0..e3ccfd53203 100644 --- a/Lib/packaging/tests/test_util.py +++ b/Lib/packaging/tests/test_util.py @@ -700,14 +700,8 @@ class GlobTestCase(GlobTestCaseBase): '{a**a,babar}', '{bob,b**z}', ] - msg = "%r is not supposed to be a valid pattern" for pattern in invalids: - try: - iglob(pattern) - except ValueError: - continue - else: - self.fail(msg % pattern) + self.assertRaises(ValueError, iglob, pattern) class EggInfoToDistInfoTestCase(support.TempdirManager,