[Python-checkins] cpython: Clean up mocking of stdout and stdin in packaging tests.

eric.araujo python-checkins at python.org
Mon Nov 7 18:11:41 CET 2011


http://hg.python.org/cpython/rev/547756d9a013
changeset:   73425:547756d9a013
user:        Éric Araujo <merwok at netwok.org>
date:        Sun Nov 06 11:32:47 2011 +0100
summary:
  Clean up mocking of stdout and stdin in packaging tests.

Running with regrtest does not show spurious output or unrestored
sys.std* objects; sometimes running with make test is different, I’ll
watch the buildbots.

In addition, update the create module to use logging.

files:
  Lib/packaging/create.py                       |  29 ++++----
  Lib/packaging/tests/support.py                |  18 +++++-
  Lib/packaging/tests/test_command_build_ext.py |  32 ++-------
  Lib/packaging/tests/test_command_build_py.py  |  26 ++-----
  Lib/packaging/tests/test_command_register.py  |  14 +----
  Lib/packaging/tests/test_config.py            |  13 +---
  Lib/packaging/tests/test_create.py            |  31 +++------
  Lib/packaging/tests/test_run.py               |   2 -
  Lib/packaging/tests/test_uninstall.py         |   5 -
  Lib/packaging/tests/test_util.py              |   4 +-
  10 files changed, 61 insertions(+), 113 deletions(-)


diff --git a/Lib/packaging/create.py b/Lib/packaging/create.py
--- a/Lib/packaging/create.py
+++ b/Lib/packaging/create.py
@@ -30,6 +30,7 @@
 from tokenize import detect_encoding
 from configparser import RawConfigParser
 
+from packaging import logger
 # importing this with an underscore as it should be replaced by the
 # dict form or another structures for all purposes
 from packaging._trove import all_classifiers as _CLASSIFIERS_LIST
@@ -124,7 +125,7 @@
         if answer and answer[0].lower() in ('y', 'n'):
             return answer[0].lower()
 
-        print('\nERROR: You must select "Y" or "N".\n')
+        logger.error('You must select "Y" or "N".')
 
 
 # XXX use util.ask
@@ -147,10 +148,7 @@
     helptext = helptext.strip("\n")
 
     while True:
-        sys.stdout.write(prompt)
-        sys.stdout.flush()
-
-        line = sys.stdin.readline().strip()
+        line = input(prompt).strip()
         if line == '?':
             print('=' * 70)
             print(helptext)
@@ -271,9 +269,10 @@
     def _write_cfg(self):
         if os.path.exists(_FILENAME):
             if os.path.exists('%s.old' % _FILENAME):
-                print("ERROR: %(name)s.old backup exists, please check that "
-                      "current %(name)s is correct and remove %(name)s.old" %
-                      {'name': _FILENAME})
+                message = ("ERROR: %(name)s.old backup exists, please check "
+                           "that current %(name)s is correct and remove "
+                           "%(name)s.old" % {'name': _FILENAME})
+                logger.error(message)
                 return
             shutil.move(_FILENAME, '%s.old' % _FILENAME)
 
@@ -320,7 +319,7 @@
             fp.write('\n')
 
         os.chmod(_FILENAME, 0o644)
-        print('Wrote "%s".' % _FILENAME)
+        logger.info('Wrote "%s".' % _FILENAME)
 
     def convert_py_to_cfg(self):
         """Generate a setup.cfg from an existing setup.py.
@@ -614,8 +613,8 @@
                         break
 
             if len(found_list) == 0:
-                print('ERROR: Could not find a matching license for "%s"' %
-                      license)
+                logger.error('Could not find a matching license for "%s"' %
+                             license)
                 continue
 
             question = 'Matching licenses:\n\n'
@@ -636,8 +635,8 @@
             try:
                 index = found_list[int(choice) - 1]
             except ValueError:
-                print("ERROR: Invalid selection, type a number from the list "
-                      "above.")
+                logger.error(
+                    "Invalid selection, type a number from the list above.")
 
             classifiers.add(_CLASSIFIERS_LIST[index])
 
@@ -660,8 +659,8 @@
                     classifiers.add(key)
                     return
                 except (IndexError, ValueError):
-                    print("ERROR: Invalid selection, type a single digit "
-                          "number.")
+                    logger.error(
+                        "Invalid selection, type a single digit number.")
 
 
 def main():
diff --git a/Lib/packaging/tests/support.py b/Lib/packaging/tests/support.py
--- a/Lib/packaging/tests/support.py
+++ b/Lib/packaging/tests/support.py
@@ -52,7 +52,7 @@
     # TestCase mixins
     'LoggingCatcher', 'TempdirManager', 'EnvironRestorer',
     # mocks
-    'DummyCommand', 'TestDistribution',
+    'DummyCommand', 'TestDistribution', 'Inputs',
     # misc. functions and decorators
     'fake_dec', 'create_distribution', 'use_command',
     'copy_xxmodule_c', 'fixup_build_ext',
@@ -274,6 +274,22 @@
         return self._config_files
 
 
+class Inputs:
+    """Fakes user inputs."""
+    # TODO document usage
+    # TODO use context manager or something for auto cleanup
+
+    def __init__(self, *answers):
+        self.answers = answers
+        self.index = 0
+
+    def __call__(self, prompt=''):
+        try:
+            return self.answers[self.index]
+        finally:
+            self.index += 1
+
+
 def create_distribution(configfiles=()):
     """Prepares a distribution with given config files parsed."""
     d = TestDistribution()
diff --git a/Lib/packaging/tests/test_command_build_ext.py b/Lib/packaging/tests/test_command_build_ext.py
--- a/Lib/packaging/tests/test_command_build_ext.py
+++ b/Lib/packaging/tests/test_command_build_ext.py
@@ -3,7 +3,6 @@
 import site
 import sysconfig
 import textwrap
-from io import StringIO
 from packaging.dist import Distribution
 from packaging.errors import (UnknownFileError, CompileError,
                               PackagingPlatformError)
@@ -11,7 +10,7 @@
 from packaging.compiler.extension import Extension
 
 from test.script_helper import assert_python_ok
-from packaging.tests import support, unittest, verbose
+from packaging.tests import support, unittest
 
 
 class BuildExtTestCase(support.TempdirManager,
@@ -37,18 +36,10 @@
         support.fixup_build_ext(cmd)
         cmd.build_lib = self.tmp_dir
         cmd.build_temp = self.tmp_dir
+        cmd.ensure_finalized()
+        cmd.run()
 
-        old_stdout = sys.stdout
-        if not verbose:
-            # silence compiler output
-            sys.stdout = StringIO()
-        try:
-            cmd.ensure_finalized()
-            cmd.run()
-        finally:
-            sys.stdout = old_stdout
-
-        code = """if 1:
+        code = textwrap.dedent("""\
             import sys
             sys.path.insert(0, %r)
 
@@ -63,7 +54,8 @@
             doc = 'This is a template module just for instruction.'
             assert xx.__doc__ == doc
             assert isinstance(xx.Null(), xx.Null)
-            assert isinstance(xx.Str(), xx.Str)"""
+            assert isinstance(xx.Str(), xx.Str)
+            """)
         code = code % self.tmp_dir
         assert_python_ok('-c', code)
 
@@ -388,16 +380,8 @@
         cmd.build_temp = self.tmp_dir
 
         try:
-            old_stdout = sys.stdout
-            if not verbose:
-                # silence compiler output
-                sys.stdout = StringIO()
-            try:
-                cmd.ensure_finalized()
-                cmd.run()
-            finally:
-                sys.stdout = old_stdout
-
+            cmd.ensure_finalized()
+            cmd.run()
         except CompileError:
             self.fail("Wrong deployment target during compilation")
 
diff --git a/Lib/packaging/tests/test_command_build_py.py b/Lib/packaging/tests/test_command_build_py.py
--- a/Lib/packaging/tests/test_command_build_py.py
+++ b/Lib/packaging/tests/test_command_build_py.py
@@ -67,8 +67,6 @@
 
     def test_empty_package_dir(self):
         # See SF 1668596/1720897.
-        cwd = os.getcwd()
-
         # create the distribution files.
         sources = self.mkdtemp()
         pkg = os.path.join(sources, 'pkg')
@@ -79,24 +77,16 @@
         open(os.path.join(testdir, "testfile"), "wb").close()
 
         os.chdir(sources)
-        old_stdout = sys.stdout
-        #sys.stdout = StringIO.StringIO()
+        dist = Distribution({"packages": ["pkg"],
+                             "package_dir": sources,
+                             "package_data": {"pkg": ["doc/*"]}})
+        dist.script_args = ["build"]
+        dist.parse_command_line()
 
         try:
-            dist = Distribution({"packages": ["pkg"],
-                                 "package_dir": sources,
-                                 "package_data": {"pkg": ["doc/*"]}})
-            dist.script_args = ["build"]
-            dist.parse_command_line()
-
-            try:
-                dist.run_commands()
-            except PackagingFileError:
-                self.fail("failed package_data test when package_dir is ''")
-        finally:
-            # Restore state.
-            os.chdir(cwd)
-            sys.stdout = old_stdout
+            dist.run_commands()
+        except PackagingFileError:
+            self.fail("failed package_data test when package_dir is ''")
 
     def test_byte_compile(self):
         project_dir, dist = self.create_dist(py_modules=['boiledeggs'])
diff --git a/Lib/packaging/tests/test_command_register.py b/Lib/packaging/tests/test_command_register.py
--- a/Lib/packaging/tests/test_command_register.py
+++ b/Lib/packaging/tests/test_command_register.py
@@ -12,6 +12,7 @@
     DOCUTILS_SUPPORT = False
 
 from packaging.tests import unittest, support
+from packaging.tests.support import Inputs
 from packaging.command import register as register_module
 from packaging.command.register import register
 from packaging.errors import PackagingSetupError
@@ -38,19 +39,6 @@
 """
 
 
-class Inputs:
-    """Fakes user inputs."""
-    def __init__(self, *answers):
-        self.answers = answers
-        self.index = 0
-
-    def __call__(self, prompt=''):
-        try:
-            return self.answers[self.index]
-        finally:
-            self.index += 1
-
-
 class FakeOpener:
     """Fakes a PyPI server"""
     def __init__(self):
diff --git a/Lib/packaging/tests/test_config.py b/Lib/packaging/tests/test_config.py
--- a/Lib/packaging/tests/test_config.py
+++ b/Lib/packaging/tests/test_config.py
@@ -1,7 +1,6 @@
 """Tests for packaging.config."""
 import os
 import sys
-from io import StringIO
 
 from packaging import command
 from packaging.dist import Distribution
@@ -210,21 +209,11 @@
 
     def setUp(self):
         super(ConfigTestCase, self).setUp()
-        self.addCleanup(setattr, sys, 'stdout', sys.stdout)
-        self.addCleanup(setattr, sys, 'stderr', sys.stderr)
-        sys.stdout = StringIO()
-        sys.stderr = StringIO()
-
-        self.addCleanup(os.chdir, os.getcwd())
         tempdir = self.mkdtemp()
         self.working_dir = os.getcwd()
         os.chdir(tempdir)
         self.tempdir = tempdir
 
-    def tearDown(self):
-        os.chdir(self.working_dir)
-        super(ConfigTestCase, self).tearDown()
-
     def write_setup(self, kwargs=None):
         opts = {'description-file': 'README', 'extra-files': '',
                 'setup-hooks': 'packaging.tests.test_config.version_hook'}
@@ -379,7 +368,7 @@
         self.assertIn('hooks', sys.modules)
 
     def test_missing_setup_hook_warns(self):
-        self.write_setup({'setup-hooks': 'this.does._not.exist'})
+        self.write_setup({'setup-hooks': 'does._not.exist'})
         self.write_file('README', 'yeah')
         self.get_dist()
         logs = self.get_logs()
diff --git a/Lib/packaging/tests/test_create.py b/Lib/packaging/tests/test_create.py
--- a/Lib/packaging/tests/test_create.py
+++ b/Lib/packaging/tests/test_create.py
@@ -2,15 +2,17 @@
 import os
 import sys
 import sysconfig
-from io import StringIO
 from textwrap import dedent
+from packaging import create
 from packaging.create import MainProgram, ask_yn, ask, main
 
 from packaging.tests import support, unittest
+from packaging.tests.support import Inputs
 
 
 class CreateTestCase(support.TempdirManager,
                      support.EnvironRestorer,
+                     support.LoggingCatcher,
                      unittest.TestCase):
 
     maxDiff = None
@@ -18,11 +20,6 @@
 
     def setUp(self):
         super(CreateTestCase, self).setUp()
-        self._stdin = sys.stdin  # TODO use Inputs
-        self._stdout = sys.stdout
-        sys.stdin = StringIO()
-        sys.stdout = StringIO()
-        self._cwd = os.getcwd()
         self.wdir = self.mkdtemp()
         os.chdir(self.wdir)
         # patch sysconfig
@@ -32,29 +29,24 @@
             'doc': sys.prefix + '/share/doc/pyxfoil', }
 
     def tearDown(self):
-        sys.stdin = self._stdin
-        sys.stdout = self._stdout
-        os.chdir(self._cwd)
         sysconfig.get_paths = self._old_get_paths
+        if hasattr(create, 'input'):
+            del create.input
         super(CreateTestCase, self).tearDown()
 
     def test_ask_yn(self):
-        sys.stdin.write('y\n')
-        sys.stdin.seek(0)
+        create.input = Inputs('y')
         self.assertEqual('y', ask_yn('is this a test'))
 
     def test_ask(self):
-        sys.stdin.write('a\n')
-        sys.stdin.write('b\n')
-        sys.stdin.seek(0)
+        create.input = Inputs('a', 'b')
         self.assertEqual('a', ask('is this a test'))
         self.assertEqual('b', ask(str(list(range(0, 70))), default='c',
                                   lengthy=True))
 
     def test_set_multi(self):
         mainprogram = MainProgram()
-        sys.stdin.write('aaaaa\n')
-        sys.stdin.seek(0)
+        create.input = Inputs('aaaaa')
         mainprogram.data['author'] = []
         mainprogram._set_multi('_set_multi test', 'author')
         self.assertEqual(['aaaaa'], mainprogram.data['author'])
@@ -130,8 +122,7 @@
               scripts=['my_script', 'bin/run'],
               )
         """), encoding='utf-8')
-        sys.stdin.write('y\n')
-        sys.stdin.seek(0)
+        create.input = Inputs('y')
         main()
 
         path = os.path.join(self.wdir, 'setup.cfg')
@@ -206,9 +197,7 @@
 barbar is now in the public domain,
 ho, baby!
                         '''))
-        sys.stdin.write('y\n')
-        sys.stdin.seek(0)
-        # FIXME Out of memory error.
+        create.input = Inputs('y')
         main()
 
         path = os.path.join(self.wdir, 'setup.cfg')
diff --git a/Lib/packaging/tests/test_run.py b/Lib/packaging/tests/test_run.py
--- a/Lib/packaging/tests/test_run.py
+++ b/Lib/packaging/tests/test_run.py
@@ -33,11 +33,9 @@
 
     def setUp(self):
         super(RunTestCase, self).setUp()
-        self.old_stdout = sys.stdout
         self.old_argv = sys.argv, sys.argv[:]
 
     def tearDown(self):
-        sys.stdout = self.old_stdout
         sys.argv = self.old_argv[0]
         sys.argv[:] = self.old_argv[1]
         super(RunTestCase, self).tearDown()
diff --git a/Lib/packaging/tests/test_uninstall.py b/Lib/packaging/tests/test_uninstall.py
--- a/Lib/packaging/tests/test_uninstall.py
+++ b/Lib/packaging/tests/test_uninstall.py
@@ -1,6 +1,5 @@
 """Tests for the packaging.uninstall module."""
 import os
-import sys
 import logging
 import packaging.util
 
@@ -31,16 +30,12 @@
 
     def setUp(self):
         super(UninstallTestCase, self).setUp()
-        self.addCleanup(setattr, sys, 'stdout', sys.stdout)
-        self.addCleanup(setattr, sys, 'stderr', sys.stderr)
-        self.addCleanup(os.chdir, os.getcwd())
         self.addCleanup(enable_cache)
         self.root_dir = self.mkdtemp()
         self.cwd = os.getcwd()
         disable_cache()
 
     def tearDown(self):
-        os.chdir(self.cwd)
         packaging.util._path_created.clear()
         super(UninstallTestCase, self).tearDown()
 
diff --git a/Lib/packaging/tests/test_util.py b/Lib/packaging/tests/test_util.py
--- a/Lib/packaging/tests/test_util.py
+++ b/Lib/packaging/tests/test_util.py
@@ -170,8 +170,8 @@
     def unmock_popen(self):
         util.find_executable = self.old_find_executable
         subprocess.Popen = self.old_popen
-        sys.old_stdout = self.old_stdout
-        sys.old_stderr = self.old_stderr
+        sys.stdout = self.old_stdout
+        sys.stderr = self.old_stderr
 
     def test_convert_path(self):
         # linux/mac

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list