diff --git a/Lib/packaging/command/bdist.py b/Lib/packaging/command/bdist.py --- a/Lib/packaging/command/bdist.py +++ b/Lib/packaging/command/bdist.py @@ -126,8 +126,8 @@ class bdist(Command): # Reinitialize and run each command. for i in range(len(self.formats)): cmd_name = commands[i] - sub_cmd = self.get_reinitialized_command(cmd_name) - sub_cmd.format = self.formats[i] + sub_cmd = self.get_reinitialized_command(cmd_name, + format=self.formats[i]) # passing the owner and group names for tar archiving if cmd_name == 'bdist_dumb': diff --git a/Lib/packaging/command/bdist_dumb.py b/Lib/packaging/command/bdist_dumb.py --- a/Lib/packaging/command/bdist_dumb.py +++ b/Lib/packaging/command/bdist_dumb.py @@ -80,11 +80,9 @@ class bdist_dumb(Command): if not self.skip_build: self.run_command('build') - install = self.get_reinitialized_command('install_dist', - reinit_subcommands=True) - install.root = self.bdist_dir - install.skip_build = self.skip_build - install.warn_dir = False + install = self.get_reinitialized_command( + 'install_dist', reinit_subcommands=True, + root=self.bdist_dir, skip_build=self.skip_build, warn_dir=False) logger.info("installing to %s", self.bdist_dir) self.run_command('install_dist') diff --git a/Lib/packaging/command/bdist_msi.py b/Lib/packaging/command/bdist_msi.py --- a/Lib/packaging/command/bdist_msi.py +++ b/Lib/packaging/command/bdist_msi.py @@ -183,16 +183,14 @@ class bdist_msi(Command): if not self.skip_build: self.run_command('build') - install = self.get_reinitialized_command('install_dist', - reinit_subcommands=True) - install.prefix = self.bdist_dir - install.skip_build = self.skip_build - install.warn_dir = False + install = self.get_reinitialized_command( + 'install_dist', reinit_subcommands=True, + prefix=self.bdist_dir, skip_build=self.skip_build, warn_dir=False) - install_lib = self.get_reinitialized_command('install_lib') - # we do not want to include pyc or pyo files - install_lib.compile = False - install_lib.optimize = 0 + install_lib = self.get_reinitialized_command( + 'install_lib', + # we do not want to include pyc or pyo files + compile=False, optimize=0) if self.distribution.has_ext_modules(): # If we are building an installer for a Python version other diff --git a/Lib/packaging/command/bdist_wininst.py b/Lib/packaging/command/bdist_wininst.py --- a/Lib/packaging/command/bdist_wininst.py +++ b/Lib/packaging/command/bdist_wininst.py @@ -115,17 +115,15 @@ class bdist_wininst(Command): if not self.skip_build: self.run_command('build') - install = self.get_reinitialized_command('install', - reinit_subcommands=True) - install.root = self.bdist_dir - install.skip_build = self.skip_build - install.warn_dir = False - install.plat_name = self.plat_name + install = self.get_reinitialized_command( + 'install_dist', reinit_subcommands=True, + root=self.bdist_dir, skip_build=self.skip_build, warn_dir=False, + plat_name=self.plat_name) - install_lib = self.get_reinitialized_command('install_lib') - # we do not want to include pyc or pyo files - install_lib.compile = False - install_lib.optimize = 0 + install_lib = self.get_reinitialized_command( + 'install_lib', + # we do not want to include pyc or pyo files + compile=False, optimize=0) if self.distribution.has_ext_modules(): # If we are building an installer for a Python version other diff --git a/Lib/packaging/command/cmd.py b/Lib/packaging/command/cmd.py --- a/Lib/packaging/command/cmd.py +++ b/Lib/packaging/command/cmd.py @@ -318,9 +318,10 @@ class Command: cmd_obj.ensure_finalized() return cmd_obj - def get_reinitialized_command(self, command, reinit_subcommands=False): + def get_reinitialized_command(self, command, reinit_subcommands=False, **kwargs): + """Wrapper around Distribution.get_reinitialized_command""" return self.distribution.get_reinitialized_command( - command, reinit_subcommands) + command, reinit_subcommands, **kwargs) def run_command(self, command): """Run some other command: uses the 'run_command()' method of diff --git a/Lib/packaging/command/test.py b/Lib/packaging/command/test.py --- a/Lib/packaging/command/test.py +++ b/Lib/packaging/command/test.py @@ -53,29 +53,24 @@ class test(Command): return None def run(self): - prev_syspath = sys.path[:] - try: - # build release - build = self.get_reinitialized_command('build') - self.run_command('build') - sys.path.insert(0, build.build_lib) + # build extension modules in place + build = self.get_reinitialized_command('build_ext', inplace=True) + self.run_command('build_ext') - # Temporary kludge until we remove the verbose arguments and use - # logging everywhere - logger = logging.getLogger('packaging') - verbose = logger.getEffectiveLevel() >= logging.DEBUG - verbosity = verbose + 1 + # Temporary kludge until we remove the verbose arguments and use + # logging everywhere + logger = logging.getLogger('packaging') + verbose = logger.getEffectiveLevel() >= logging.DEBUG + verbosity = verbose + 1 - # run the tests - if self.runner: - resolve_name(self.runner)() - elif self.suite: - runner = unittest.TextTestRunner(verbosity=verbosity) - runner.run(resolve_name(self.suite)()) - elif self.get_ut_with_discovery(): - ut = self.get_ut_with_discovery() - test_suite = ut.TestLoader().discover(os.curdir) - runner = ut.TextTestRunner(verbosity=verbosity) - runner.run(test_suite) - finally: - sys.path[:] = prev_syspath + # run the tests + if self.runner: + resolve_name(self.runner)() + elif self.suite: + runner = unittest.TextTestRunner(verbosity=verbosity) + runner.run(resolve_name(self.suite)()) + elif self.get_ut_with_discovery(): + ut = self.get_ut_with_discovery() + test_suite = ut.TestLoader().discover(os.curdir) + runner = ut.TextTestRunner(verbosity=verbosity) + runner.run(test_suite) diff --git a/Lib/packaging/dist.py b/Lib/packaging/dist.py --- a/Lib/packaging/dist.py +++ b/Lib/packaging/dist.py @@ -636,7 +636,8 @@ Common commands: (see '--help-commands' except ValueError as msg: raise PackagingOptionError(msg) - def get_reinitialized_command(self, command, reinit_subcommands=False): + def get_reinitialized_command(self, command, reinit_subcommands=False, + **kwargs): """Reinitializes a command to the state it was in when first returned by 'get_command_obj()': ie., initialized but not yet finalized. This provides the opportunity to sneak option @@ -653,6 +654,9 @@ Common commands: (see '--help-commands' reinitializes the sub-commands that actually matter, ie. those whose test predicates return true. + Keyword arguments will be used to set attributes on the command + object. + Returns the reinitialized command object. """ if not isinstance(command, Command): @@ -662,16 +666,21 @@ Common commands: (see '--help-commands' command_name = command.get_command_name() if not command.finalized: + for k, v in kwargs.items(): + setattr(command, k, v) return command command.initialize_options() self.have_run[command_name] = 0 command.finalized = False self._set_command_options(command) + for k, v in kwargs.items(): + setattr(command, k, v) if reinit_subcommands: for sub in command.get_sub_commands(): - self.get_reinitialized_command(sub, reinit_subcommands) + self.get_reinitialized_command(sub, reinit_subcommands, + **kwargs) return command diff --git a/Lib/packaging/tests/test_command_cmd.py b/Lib/packaging/tests/test_command_cmd.py --- a/Lib/packaging/tests/test_command_cmd.py +++ b/Lib/packaging/tests/test_command_cmd.py @@ -8,8 +8,23 @@ from packaging.tests import support, uni class MyCmd(Command): + + user_options = [ + ('test-option-1=', None, + "An option for testing defaults"), + ('test-option-2=', None, + "A second option for testing defaults"), + ] + def initialize_options(self): - pass + self.test_option_1 = None + self.test_option_2 = None + + def finalize_options(self): + if self.test_option_1 is None: + self.test_option_1 = 'default-1' + if self.test_option_2 is None: + self.test_option_2 = 'default-2' class CommandTestCase(support.LoggingCatcher, @@ -93,6 +108,27 @@ class CommandTestCase(support.LoggingCat cmd.option2 = 'xxx' self.assertRaises(PackagingOptionError, cmd.ensure_dirname, 'option2') + def test_get_reinitialized_command(self): + cmd = self.cmd + cmd.test_option_1 = 'Horse' + cmd.test_option_2 = 'Goat' + cmd.ensure_finalized() + cmd = cmd.get_reinitialized_command(cmd) + cmd.ensure_finalized() + self.assertEqual(cmd.test_option_1, 'default-1') + self.assertEqual(cmd.test_option_2, 'default-2') + + cmd = cmd.get_reinitialized_command(cmd, test_option_1='from-kwarg-1') + cmd.ensure_finalized() + self.assertEqual(cmd.test_option_1, 'from-kwarg-1') + self.assertEqual(cmd.test_option_2, 'default-2') + + cmd = cmd.get_reinitialized_command(cmd, test_option_2='from-kwarg-2') + cmd.test_option_1 = 'from-code-1' + cmd.ensure_finalized() + self.assertEqual(cmd.test_option_1, 'from-code-1') + self.assertEqual(cmd.test_option_2, 'from-kwarg-2') + def test_suite(): return unittest.makeSuite(CommandTestCase) diff --git a/Lib/packaging/tests/test_command_test.py b/Lib/packaging/tests/test_command_test.py --- a/Lib/packaging/tests/test_command_test.py +++ b/Lib/packaging/tests/test_command_test.py @@ -8,12 +8,11 @@ import packaging.database from os.path import join from operator import getitem, setitem, delitem -from packaging.command.build import build +from packaging.command.build_ext import build_ext from packaging.tests import unittest from packaging.tests.support import (TempdirManager, EnvironRestorer, LoggingCatcher) from packaging.command.test import test -from packaging.command import set_command from packaging.dist import Distribution @@ -28,19 +27,18 @@ AssertionError: horribly here = os.path.dirname(os.path.abspath(__file__)) -class MockBuildCmd(build): - build_lib = "mock build lib" - command_name = 'build' +class MockBuildExt(build_ext): + build_temp = 'mock build tmp' plat_name = 'whatever' def initialize_options(self): - pass + self._record = [] def finalize_options(self): pass def run(self): - self._record.append("build has run") + self._record.append('build_ext has run') class TestTest(TempdirManager, @@ -128,17 +126,15 @@ class TestTest(TempdirManager, cmd.run() self.assertEqual(record, ["suite", "run"]) - def test_builds_before_running_tests(self): - self.addCleanup(set_command, 'packaging.command.build.build') - set_command('packaging.tests.test_command_test.MockBuildCmd') - + def test_builds_ext_modules_before_running(self): dist = Distribution() - dist.get_command_obj('build')._record = record = [] + build_ext = MockBuildExt(dist) + dist.command_obj['build_ext'] = build_ext cmd = test(dist) cmd.runner = self.prepare_named_function(lambda: None) cmd.ensure_finalized() cmd.run() - self.assertEqual(['build has run'], record) + self.assertEqual(['build_ext has run'], build_ext._record) def _test_works_with_2to3(self): pass