1515import importlib
1616import re
1717
18- __all__ = ["Error" , "TestFailed" , "TestSkipped" , " ResourceDenied" , "import_module" ,
18+ __all__ = ["Error" , "TestFailed" , "ResourceDenied" , "import_module" ,
1919 "verbose" , "use_resources" , "max_memuse" , "record_original_stdout" ,
2020 "get_original_stdout" , "unload" , "unlink" , "rmtree" , "forget" ,
2121 "is_resource_enabled" , "requires" , "find_unused_port" , "bind_port" ,
2222 "fcmp" , "have_unicode" , "is_jython" , "TESTFN" , "HOST" , "FUZZ" ,
23- "findfile " , "verify " , "vereq " , "sortdict" , "check_syntax_error" ,
23+ "SAVEDCWD " , "temp_cwd " , "findfile " , "sortdict" , "check_syntax_error" ,
2424 "open_urlresource" , "check_warnings" , "check_py3k_warnings" ,
2525 "CleanImport" , "EnvironmentVarGuard" , "captured_output" ,
2626 "captured_stdout" , "TransientResource" , "transient_internet" ,
2727 "run_with_locale" , "set_memlimit" , "bigmemtest" , "bigaddrspacetest" ,
2828 "BasicTestRunner" , "run_unittest" , "run_doctest" , "threading_setup" ,
29- "import_fresh_module" , "threading_cleanup" , "reap_children" ]
29+ "threading_cleanup" , "reap_children" , "cpython_only" ,
30+ "check_impl_detail" , "get_attribute" , "py3k_bytes" ,
31+ "import_fresh_module" , "threading_cleanup" , "reap_children" ,
32+ "strip_python_stderr" ]
3033
3134class Error (Exception ):
3235 """Base class for regression test exceptions."""
3336
3437class TestFailed (Error ):
3538 """Test failed."""
3639
37- class TestSkipped (Error ):
38- """Test skipped.
39-
40- This can be raised to indicate that a test was deliberatly
41- skipped, but not because a feature wasn't available. For
42- example, if some resource can't be used, such as the network
43- appears to be unavailable, this should be raised instead of
44- TestFailed.
45- """
46-
47- class ResourceDenied (TestSkipped ):
40+ class ResourceDenied (unittest .SkipTest ):
4841 """Test skipped because it requested a disallowed resource.
4942
5043 This is raised when a test calls requires() for a resource that
@@ -68,18 +61,16 @@ def _ignore_deprecated_imports(ignore=True):
6861
6962
7063def import_module (name , deprecated = False ):
71- """Import the module to be tested, raising TestSkipped if it is not
72- available."""
73- with warnings . catch_warnings ():
74- if deprecated :
75- warnings . filterwarnings ( "ignore" , ".+ (module|package)" ,
76- DeprecationWarning )
64+ """Import and return the module to be tested, raising SkipTest if
65+ it is not available.
66+
67+ If deprecated is True, any module or package deprecation messages
68+ will be suppressed."""
69+ with _ignore_deprecated_imports ( deprecated ):
7770 try :
78- module = __import__ (name , level = 0 )
79- except ImportError :
80- raise TestSkipped ("No module named " + name )
81- else :
82- return module
71+ return importlib .import_module (name )
72+ except ImportError , msg :
73+ raise unittest .SkipTest (str (msg ))
8374
8475
8576def _save_and_remove_module (name , orig_modules ):
@@ -95,7 +86,6 @@ def _save_and_remove_module(name, orig_modules):
9586 orig_modules [modname ] = sys .modules [modname ]
9687 del sys .modules [modname ]
9788
98-
9989def _save_and_block_module (name , orig_modules ):
10090 """Helper function to save and block a module in sys.modules
10191
@@ -147,6 +137,17 @@ def import_fresh_module(name, fresh=(), blocked=(), deprecated=False):
147137 return fresh_module
148138
149139
140+ def get_attribute (obj , name ):
141+ """Get an attribute, raising SkipTest if AttributeError is raised."""
142+ try :
143+ attribute = getattr (obj , name )
144+ except AttributeError :
145+ raise unittest .SkipTest ("module %s has no attribute %s" % (
146+ obj .__name__ , name ))
147+ else :
148+ return attribute
149+
150+
150151verbose = 1 # Flag set to 0 by regrtest.py
151152use_resources = None # Flag set to [] by regrtest.py
152153junit_xml_dir = None # Option set by regrtest.py
@@ -438,12 +439,14 @@ def make_jar_classloader(jar):
438439 unlink (TESTFN )
439440del fp
440441
441- def findfile (file , here = __file__ ):
442+ def findfile (file , here = __file__ , subdir = None ):
442443 """Try to find a file on sys.path and the working directory. If it is not
443444 found the argument passed to the function is returned (this does not
444445 necessarily signal failure; could still be the legitimate path)."""
445446 if os .path .isabs (file ):
446447 return file
448+ if subdir is not None :
449+ file = os .path .join (subdir , file )
447450 path = sys .path
448451 path = [os .path .dirname (here )] + path
449452 for dn in path :
@@ -1066,6 +1069,23 @@ def threading_cleanup(num_active, num_limbo):
10661069 count += 1
10671070 time .sleep (0.1 )
10681071
1072+ def reap_threads (func ):
1073+ """Use this function when threads are being used. This will
1074+ ensure that the threads are cleaned up even when the test fails.
1075+ If threading is unavailable this function does nothing.
1076+ """
1077+ if not thread :
1078+ return func
1079+
1080+ @functools .wraps (func )
1081+ def decorator (* args ):
1082+ key = threading_setup ()
1083+ try :
1084+ return func (* args )
1085+ finally :
1086+ threading_cleanup (* key )
1087+ return decorator
1088+
10691089def reap_children ():
10701090 """Use this function at the end of test_main() whenever sub-processes
10711091 are started. This will help ensure that no extra children (zombies)
0 commit comments