[Python-checkins] cpython: Make sure packaging tests that register custom commands also clear them

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


http://hg.python.org/cpython/rev/7145ef38ca9d
changeset:   73422:7145ef38ca9d
user:        Éric Araujo <merwok at netwok.org>
date:        Sun Nov 06 07:01:18 2011 +0100
summary:
  Make sure packaging tests that register custom commands also clear them

files:
  Lib/packaging/tests/support.py     |  15 +++++++++-
  Lib/packaging/tests/test_config.py |  11 ++++--
  Lib/packaging/tests/test_dist.py   |  27 ++++++++---------
  Lib/test/regrtest.py               |  19 ++++++++++++-
  4 files changed, 52 insertions(+), 20 deletions(-)


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
@@ -41,6 +41,9 @@
 import sysconfig
 
 from packaging.dist import Distribution
+from packaging.util import resolve_name
+from packaging.command import set_command, _COMMANDS
+
 from packaging.tests import unittest
 from test.support import requires_zlib, unlink
 
@@ -51,7 +54,8 @@
     # mocks
     'DummyCommand', 'TestDistribution',
     # misc. functions and decorators
-    'fake_dec', 'create_distribution', 'copy_xxmodule_c', 'fixup_build_ext',
+    'fake_dec', 'create_distribution', 'use_command',
+    'copy_xxmodule_c', 'fixup_build_ext',
     # imported from this module for backport purposes
     'unittest', 'requires_zlib', 'skip_2to3_optimize', 'skip_unless_symlink',
 ]
@@ -280,6 +284,15 @@
     return d
 
 
+def use_command(testcase, fullname):
+    """Register command at *fullname* for the duration of a test."""
+    set_command(fullname)
+    # XXX maybe set_command should return the class object
+    name = resolve_name(fullname).get_command_name()
+    # XXX maybe we need a public API to remove commands
+    testcase.addCleanup(_COMMANDS.__delitem__, name)
+
+
 def fake_dec(*args, **kw):
     """Fake decorator"""
     def _wrap(func):
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
@@ -183,13 +183,14 @@
 
     def __init__(self, dist):
         self.distribution = dist
+        self._record = []
 
     @classmethod
     def get_command_name(cls):
         return 'foo'
 
     def run(self):
-        self.distribution.foo_was_here = True
+        self._record.append('foo has run')
 
     def nothing(self):
         pass
@@ -491,10 +492,12 @@
             self.write_file((pkg, '__init__.py'), '#')
 
         # try to run the install command to see if foo is called
+        self.addCleanup(command._COMMANDS.__delitem__, 'foo')
         dist = self.get_dist()
-        self.assertIn('foo', command.get_command_names())
-        self.assertEqual('FooBarBazTest',
-                         dist.get_command_obj('foo').__class__.__name__)
+        dist.run_command('install_dist')
+        cmd = dist.get_command_obj('foo')
+        self.assertEqual(cmd.__class__.__name__, 'FooBarBazTest')
+        self.assertEqual(cmd._record, ['foo has run'])
 
 
 def test_suite():
diff --git a/Lib/packaging/tests/test_dist.py b/Lib/packaging/tests/test_dist.py
--- a/Lib/packaging/tests/test_dist.py
+++ b/Lib/packaging/tests/test_dist.py
@@ -6,30 +6,32 @@
 import packaging.dist
 
 from packaging.dist import Distribution
-from packaging.command import set_command, _COMMANDS
 from packaging.command.cmd import Command
 from packaging.errors import PackagingModuleError, PackagingOptionError
 from packaging.tests import captured_stdout
 from packaging.tests import support, unittest
-from packaging.tests.support import create_distribution
+from packaging.tests.support import create_distribution, use_command
 from test.support import unload
 
 
 class test_dist(Command):
-    """Sample packaging extension command."""
+    """Custom command used for testing."""
 
     user_options = [
-        ("sample-option=", "S", "help text"),
+        ('sample-option=', 'S',
+         "help text"),
         ]
 
     def initialize_options(self):
         self.sample_option = None
+        self._record = []
 
     def finalize_options(self):
-        pass
+        if self.sample_option is None:
+            self.sample_option = 'default value'
 
     def run(self):
-        pass
+        self._record.append('test_dist has run')
 
 
 class DistributionTestCase(support.TempdirManager,
@@ -45,14 +47,10 @@
         # (defaulting to sys.argv)
         self.argv = sys.argv, sys.argv[:]
         del sys.argv[1:]
-        self._commands = _COMMANDS.copy()
 
     def tearDown(self):
         sys.argv = self.argv[0]
         sys.argv[:] = self.argv[1]
-        # XXX maybe we need a public API to remove commands
-        _COMMANDS.clear()
-        _COMMANDS.update(self._commands)
         super(DistributionTestCase, self).tearDown()
 
     @unittest.skip('needs to be updated')
@@ -181,7 +179,8 @@
         self.write_file((temp_home, "config2.cfg"),
                         '[test_dist]\npre-hook.b = type')
 
-        set_command('packaging.tests.test_dist.test_dist')
+        use_command(self, 'packaging.tests.test_dist.test_dist')
+
         dist = create_distribution(config_files)
         cmd = dist.get_command_obj("test_dist")
         self.assertEqual(cmd.pre_hook, {"a": 'type', "b": 'type'})
@@ -209,7 +208,7 @@
                 record.append('post-%s' % cmd.get_command_name())
             '''))
 
-        set_command('packaging.tests.test_dist.test_dist')
+        use_command(self, 'packaging.tests.test_dist.test_dist')
         d = create_distribution([config_file])
         cmd = d.get_command_obj("test_dist")
 
@@ -236,7 +235,7 @@
             [test_dist]
             pre-hook.test = nonexistent.dotted.name'''))
 
-        set_command('packaging.tests.test_dist.test_dist')
+        use_command(self, 'packaging.tests.test_dist.test_dist')
         d = create_distribution([config_file])
         cmd = d.get_command_obj("test_dist")
         cmd.ensure_finalized()
@@ -251,7 +250,7 @@
             [test_dist]
             pre-hook.test = packaging.tests.test_dist.__doc__'''))
 
-        set_command('packaging.tests.test_dist.test_dist')
+        use_command(self, 'packaging.tests.test_dist.test_dist')
         d = create_distribution([config_file])
         cmd = d.get_command_obj("test_dist")
         cmd.ensure_finalized()
diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py
--- a/Lib/test/regrtest.py
+++ b/Lib/test/regrtest.py
@@ -172,6 +172,7 @@
 import json
 import logging
 import os
+import packaging.command
 import packaging.database
 import platform
 import random
@@ -967,7 +968,7 @@
                  'sys.warnoptions', 'threading._dangling',
                  'multiprocessing.process._dangling',
                  'sysconfig._CONFIG_VARS', 'sysconfig._SCHEMES',
-                 'packaging.database_caches',
+                 'packaging.command._COMMANDS', 'packaging.database_caches',
                 )
 
     def get_sys_argv(self):
@@ -1055,6 +1056,22 @@
         # Can't easily revert the logging state
         pass
 
+    def get_packaging_command__COMMANDS(self):
+        # registry mapping command names to full dotted path or to the actual
+        # class (resolved on demand); this check only looks at the names, not
+        # the types of the values (IOW, if a value changes from a string
+        # (dotted path) to a class it's okay but if a key (i.e. command class)
+        # is added we complain)
+        id_ = id(packaging.command._COMMANDS)
+        keys = set(packaging.command._COMMANDS)
+        return id_, keys
+    def restore_packaging_command__COMMANDS(self, saved):
+        # if command._COMMANDS was bound to another dict obhect, we can't
+        # restore the previous object and contents, because the get_ method
+        # above does not return the dict object (to ignore changes in values)
+        for key in packaging.command._COMMANDS.keys() - saved[1]:
+            del packaging.command._COMMANDS[key]
+
     def get_packaging_database_caches(self):
         # caching system used by the PEP 376 implementation
         # we have one boolean and four dictionaries, initially empty

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


More information about the Python-checkins mailing list