[Python-checkins] cpython (merge 3.4 -> default): Closes #22002: Merge with 3.4

zach.ware python-checkins at python.org
Wed Jul 23 19:07:14 CEST 2014


http://hg.python.org/cpython/rev/6298895a52de
changeset:   91784:6298895a52de
parent:      91782:2df1bf279bdf
parent:      91783:4f9f7e0fe1fd
user:        Zachary Ware <zachary.ware at gmail.com>
date:        Wed Jul 23 12:06:47 2014 -0500
summary:
  Closes #22002: Merge with 3.4

files:
  Doc/library/test.rst                          |  17 ++++-
  Lib/test/support/__init__.py                  |  21 +++++-
  Lib/test/test_asyncio/__init__.py             |  25 +------
  Lib/test/test_asyncio/__main__.py             |   7 +-
  Lib/test/test_email/__init__.py               |  23 +-----
  Lib/test/test_email/__main__.py               |   5 +-
  Lib/test/test_importlib/__init__.py           |  34 +---------
  Lib/test/test_importlib/__main__.py           |  11 +--
  Lib/test/test_importlib/builtin/__init__.py   |  13 +--
  Lib/test/test_importlib/builtin/__main__.py   |   4 +
  Lib/test/test_importlib/extension/__init__.py |  16 +---
  Lib/test/test_importlib/extension/__main__.py |   4 +
  Lib/test/test_importlib/frozen/__init__.py    |  16 +---
  Lib/test/test_importlib/frozen/__main__.py    |   4 +
  Lib/test/test_importlib/import_/__init__.py   |  16 +---
  Lib/test/test_importlib/import_/__main__.py   |   4 +
  Lib/test/test_importlib/source/__init__.py    |  16 +---
  Lib/test/test_importlib/source/__main__.py    |   4 +
  Lib/test/test_json/__init__.py                |  19 +----
  Lib/test/test_tools/__init__.py               |  10 +--
  Misc/NEWS                                     |   4 +
  21 files changed, 104 insertions(+), 169 deletions(-)


diff --git a/Doc/library/test.rst b/Doc/library/test.rst
--- a/Doc/library/test.rst
+++ b/Doc/library/test.rst
@@ -461,7 +461,7 @@
 .. function:: make_bad_fd()
 
    Create an invalid file descriptor by opening and closing a temporary file,
-   and returning its descripor.
+   and returning its descriptor.
 
 
 .. function:: import_module(name, deprecated=False)
@@ -554,6 +554,21 @@
    run simultaneously, which is a problem for buildbots.
 
 
+.. function:: load_package_tests(pkg_dir, loader, standard_tests, pattern)
+
+   Generic implementation of the :mod:`unittest` ``load_tests`` protocol for
+   use in test packages.  *pkg_dir* is the root directory of the package;
+   *loader*, *standard_tests*, and *pattern* are the arguments expected by
+   ``load_tests``.  In simple cases, the test package's ``__init__.py``
+   can be the following::
+
+      import os
+      from test.support import load_package_tests
+
+      def load_tests(*args):
+          return load_package_tests(os.path.dirname(__file__), *args)
+
+
 The :mod:`test.support` module defines the following classes:
 
 .. class:: TransientResource(exc, **kwargs)
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -85,7 +85,7 @@
     "skip_unless_symlink", "requires_gzip", "requires_bz2", "requires_lzma",
     "bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute",
     "requires_IEEE_754", "skip_unless_xattr", "requires_zlib",
-    "anticipate_failure",
+    "anticipate_failure", "load_package_tests",
     # sys
     "is_jython", "check_impl_detail",
     # network
@@ -188,6 +188,25 @@
         return unittest.expectedFailure
     return lambda f: f
 
+def load_package_tests(pkg_dir, loader, standard_tests, pattern):
+    """Generic load_tests implementation for simple test packages.
+
+    Most packages can implement load_tests using this function as follows:
+
+       def load_tests(*args):
+           return load_package_tests(os.path.dirname(__file__), *args)
+    """
+    if pattern is None:
+        pattern = "test*"
+    top_dir = os.path.dirname(              # Lib
+                  os.path.dirname(              # test
+                      os.path.dirname(__file__)))   # support
+    package_tests = loader.discover(start_dir=pkg_dir,
+                                    top_level_dir=top_dir,
+                                    pattern=pattern)
+    standard_tests.addTests(package_tests)
+    return standard_tests
+
 
 def import_fresh_module(name, fresh=(), blocked=(), deprecated=False):
     """Import and return a module, deliberately bypassing sys.modules.
diff --git a/Lib/test/test_asyncio/__init__.py b/Lib/test/test_asyncio/__init__.py
--- a/Lib/test/test_asyncio/__init__.py
+++ b/Lib/test/test_asyncio/__init__.py
@@ -1,29 +1,10 @@
 import os
-import sys
-import unittest
-from test.support import run_unittest, import_module
+from test.support import load_package_tests, import_module
 
 # Skip tests if we don't have threading.
 import_module('threading')
 # Skip tests if we don't have concurrent.futures.
 import_module('concurrent.futures')
 
-
-def suite():
-    tests = unittest.TestSuite()
-    loader = unittest.TestLoader()
-    for fn in os.listdir(os.path.dirname(__file__)):
-        if fn.startswith("test") and fn.endswith(".py"):
-            mod_name = 'test.test_asyncio.' + fn[:-3]
-            try:
-                __import__(mod_name)
-            except unittest.SkipTest:
-                pass
-            else:
-                mod = sys.modules[mod_name]
-                tests.addTests(loader.loadTestsFromModule(mod))
-    return tests
-
-
-def test_main():
-    run_unittest(suite())
+def load_tests(*args):
+    return load_package_tests(os.path.dirname(__file__), *args)
diff --git a/Lib/test/test_asyncio/__main__.py b/Lib/test/test_asyncio/__main__.py
--- a/Lib/test/test_asyncio/__main__.py
+++ b/Lib/test/test_asyncio/__main__.py
@@ -1,5 +1,4 @@
-from . import test_main
+from . import load_tests
+import unittest
 
-
-if __name__ == '__main__':
-    test_main()
+unittest.main()
diff --git a/Lib/test/test_email/__init__.py b/Lib/test/test_email/__init__.py
--- a/Lib/test/test_email/__init__.py
+++ b/Lib/test/test_email/__init__.py
@@ -1,31 +1,16 @@
 import os
 import sys
 import unittest
-import test.support
 import collections
 import email
 from email.message import Message
 from email._policybase import compat32
+from test.support import load_package_tests
 from test.test_email import __file__ as landmark
 
-# Run all tests in package for '-m unittest test.test_email'
-def load_tests(loader, standard_tests, pattern):
-    this_dir = os.path.dirname(__file__)
-    if pattern is None:
-        pattern = "test*"
-    package_tests = loader.discover(start_dir=this_dir, pattern=pattern)
-    standard_tests.addTests(package_tests)
-    return standard_tests
-
-
-# used by regrtest and __main__.
-def test_main():
-    here = os.path.dirname(__file__)
-    # Unittest mucks with the path, so we have to save and restore
-    # it to keep regrtest happy.
-    savepath = sys.path[:]
-    test.support._run_suite(unittest.defaultTestLoader.discover(here))
-    sys.path[:] = savepath
+# Load all tests in package
+def load_tests(*args):
+    return load_package_tests(os.path.dirname(__file__), *args)
 
 
 # helper code used by a number of test modules.
diff --git a/Lib/test/test_email/__main__.py b/Lib/test/test_email/__main__.py
--- a/Lib/test/test_email/__main__.py
+++ b/Lib/test/test_email/__main__.py
@@ -1,3 +1,4 @@
-from test.test_email import test_main
+from test.test_email import load_tests
+import unittest
 
-test_main()
+unittest.main()
diff --git a/Lib/test/test_importlib/__init__.py b/Lib/test/test_importlib/__init__.py
--- a/Lib/test/test_importlib/__init__.py
+++ b/Lib/test/test_importlib/__init__.py
@@ -1,33 +1,5 @@
 import os
-import sys
-from test import support
-import unittest
+from test.support import load_package_tests
 
-def test_suite(package=__package__, directory=os.path.dirname(__file__)):
-    suite = unittest.TestSuite()
-    for name in os.listdir(directory):
-        if name.startswith(('.', '__')):
-            continue
-        path = os.path.join(directory, name)
-        if (os.path.isfile(path) and name.startswith('test_') and
-                name.endswith('.py')):
-            submodule_name = os.path.splitext(name)[0]
-            module_name = "{0}.{1}".format(package, submodule_name)
-            __import__(module_name, level=0)
-            module_tests = unittest.findTestCases(sys.modules[module_name])
-            suite.addTest(module_tests)
-        elif os.path.isdir(path):
-            package_name = "{0}.{1}".format(package, name)
-            __import__(package_name, level=0)
-            package_tests = getattr(sys.modules[package_name], 'test_suite')()
-            suite.addTest(package_tests)
-        else:
-            continue
-    return suite
-
-
-def test_main():
-    start_dir = os.path.dirname(__file__)
-    top_dir = os.path.dirname(os.path.dirname(start_dir))
-    test_loader = unittest.TestLoader()
-    support.run_unittest(test_loader.discover(start_dir, top_level_dir=top_dir))
+def load_tests(*args):
+    return load_package_tests(os.path.dirname(__file__), *args)
diff --git a/Lib/test/test_importlib/__main__.py b/Lib/test/test_importlib/__main__.py
--- a/Lib/test/test_importlib/__main__.py
+++ b/Lib/test/test_importlib/__main__.py
@@ -1,9 +1,4 @@
-"""Run importlib's test suite.
+from . import load_tests
+import unittest
 
-Specifying the ``--builtin`` flag will run tests, where applicable, with
-builtins.__import__ instead of importlib.__import__.
-
-"""
-if __name__ == '__main__':
-    from . import test_main
-    test_main()
+unittest.main()
diff --git a/Lib/test/test_importlib/builtin/__init__.py b/Lib/test/test_importlib/builtin/__init__.py
--- a/Lib/test/test_importlib/builtin/__init__.py
+++ b/Lib/test/test_importlib/builtin/__init__.py
@@ -1,12 +1,5 @@
-from .. import test_suite
 import os
+from test.support import load_package_tests
 
-
-def test_suite():
-    directory = os.path.dirname(__file__)
-    return test_suite('importlib.test.builtin', directory)
-
-
-if __name__ == '__main__':
-    from test.support import run_unittest
-    run_unittest(test_suite())
+def load_tests(*args):
+    return load_package_tests(os.path.dirname(__file__), *args)
diff --git a/Lib/test/test_importlib/builtin/__main__.py b/Lib/test/test_importlib/builtin/__main__.py
new file mode 100644
--- /dev/null
+++ b/Lib/test/test_importlib/builtin/__main__.py
@@ -0,0 +1,4 @@
+from . import load_tests
+import unittest
+
+unittest.main()
diff --git a/Lib/test/test_importlib/extension/__init__.py b/Lib/test/test_importlib/extension/__init__.py
--- a/Lib/test/test_importlib/extension/__init__.py
+++ b/Lib/test/test_importlib/extension/__init__.py
@@ -1,13 +1,5 @@
-from .. import test_suite
-import os.path
-import unittest
+import os
+from test.support import load_package_tests
 
-
-def test_suite():
-    directory = os.path.dirname(__file__)
-    return test_suite('importlib.test.extension', directory)
-
-
-if __name__ == '__main__':
-    from test.support import run_unittest
-    run_unittest(test_suite())
+def load_tests(*args):
+    return load_package_tests(os.path.dirname(__file__), *args)
diff --git a/Lib/test/test_importlib/extension/__main__.py b/Lib/test/test_importlib/extension/__main__.py
new file mode 100644
--- /dev/null
+++ b/Lib/test/test_importlib/extension/__main__.py
@@ -0,0 +1,4 @@
+from . import load_tests
+import unittest
+
+unittest.main()
diff --git a/Lib/test/test_importlib/frozen/__init__.py b/Lib/test/test_importlib/frozen/__init__.py
--- a/Lib/test/test_importlib/frozen/__init__.py
+++ b/Lib/test/test_importlib/frozen/__init__.py
@@ -1,13 +1,5 @@
-from .. import test_suite
-import os.path
-import unittest
+import os
+from test.support import load_package_tests
 
-
-def test_suite():
-    directory = os.path.dirname(__file__)
-    return test_suite('importlib.test.frozen', directory)
-
-
-if __name__ == '__main__':
-    from test.support import run_unittest
-    run_unittest(test_suite())
+def load_tests(*args):
+    return load_package_tests(os.path.dirname(__file__), *args)
diff --git a/Lib/test/test_importlib/frozen/__main__.py b/Lib/test/test_importlib/frozen/__main__.py
new file mode 100644
--- /dev/null
+++ b/Lib/test/test_importlib/frozen/__main__.py
@@ -0,0 +1,4 @@
+from . import load_tests
+import unittest
+
+unittest.main()
diff --git a/Lib/test/test_importlib/import_/__init__.py b/Lib/test/test_importlib/import_/__init__.py
--- a/Lib/test/test_importlib/import_/__init__.py
+++ b/Lib/test/test_importlib/import_/__init__.py
@@ -1,13 +1,5 @@
-from .. import test_suite
-import os.path
-import unittest
+import os
+from test.support import load_package_tests
 
-
-def test_suite():
-    directory = os.path.dirname(__file__)
-    return test_suite('importlib.test.import_', directory)
-
-
-if __name__ == '__main__':
-    from test.support import run_unittest
-    run_unittest(test_suite())
+def load_tests(*args):
+    return load_package_tests(os.path.dirname(__file__), *args)
diff --git a/Lib/test/test_importlib/import_/__main__.py b/Lib/test/test_importlib/import_/__main__.py
new file mode 100644
--- /dev/null
+++ b/Lib/test/test_importlib/import_/__main__.py
@@ -0,0 +1,4 @@
+from . import load_tests
+import unittest
+
+unittest.main()
diff --git a/Lib/test/test_importlib/source/__init__.py b/Lib/test/test_importlib/source/__init__.py
--- a/Lib/test/test_importlib/source/__init__.py
+++ b/Lib/test/test_importlib/source/__init__.py
@@ -1,13 +1,5 @@
-from .. import test_suite
-import os.path
-import unittest
+import os
+from test.support import load_package_tests
 
-
-def test_suite():
-    directory = os.path.dirname(__file__)
-    return test.test_suite('importlib.test.source', directory)
-
-
-if __name__ == '__main__':
-    from test.support import run_unittest
-    run_unittest(test_suite())
+def load_tests(*args):
+    return load_package_tests(os.path.dirname(__file__), *args)
diff --git a/Lib/test/test_importlib/source/__main__.py b/Lib/test/test_importlib/source/__main__.py
new file mode 100644
--- /dev/null
+++ b/Lib/test/test_importlib/source/__main__.py
@@ -0,0 +1,4 @@
+from . import load_tests
+import unittest
+
+unittest.main()
diff --git a/Lib/test/test_json/__init__.py b/Lib/test/test_json/__init__.py
--- a/Lib/test/test_json/__init__.py
+++ b/Lib/test/test_json/__init__.py
@@ -42,23 +42,12 @@
                          '_json')
 
 
-here = os.path.dirname(__file__)
-
-def load_tests(*args):
-    suite = additional_tests()
-    loader = unittest.TestLoader()
-    for fn in os.listdir(here):
-        if fn.startswith("test") and fn.endswith(".py"):
-            modname = "test.test_json." + fn[:-3]
-            __import__(modname)
-            module = sys.modules[modname]
-            suite.addTests(loader.loadTestsFromModule(module))
-    return suite
-
-def additional_tests():
+def load_tests(loader, _, pattern):
     suite = unittest.TestSuite()
     for mod in (json, json.encoder, json.decoder):
         suite.addTest(doctest.DocTestSuite(mod))
     suite.addTest(TestPyTest('test_pyjson'))
     suite.addTest(TestCTest('test_cjson'))
-    return suite
+
+    pkg_dir = os.path.dirname(__file__)
+    return support.load_package_tests(pkg_dir, loader, suite, pattern)
diff --git a/Lib/test/test_tools/__init__.py b/Lib/test/test_tools/__init__.py
--- a/Lib/test/test_tools/__init__.py
+++ b/Lib/test/test_tools/__init__.py
@@ -21,11 +21,5 @@
     with support.DirsOnSysPath(scriptsdir):
         return importlib.import_module(toolname)
 
-def load_tests(loader, standard_tests, pattern):
-    this_dir = os.path.dirname(__file__)
-    if pattern is None:
-        pattern = "test*"
-    with support.DirsOnSysPath():
-        package_tests = loader.discover(start_dir=this_dir, pattern=pattern)
-    standard_tests.addTests(package_tests)
-    return standard_tests
+def load_tests(*args):
+    return support.load_package_tests(os.path.dirname(__file__), *args)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -716,6 +716,10 @@
 Tests
 -----
 
+- Issue #22002: Added ``load_package_tests`` function to test.support and used
+  it to implement/augment test discovery in test_asyncio, test_email,
+  test_importlib, test_json, and test_tools.
+
 - Issue #21976: Fix test_ssl to accept LibreSSL version strings.  Thanks
   to William Orr.
 

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


More information about the Python-checkins mailing list