1import errno 2import importlib 3import io 4import os 5import shutil 6import socket 7import stat 8import subprocess 9import sys 10import tempfile 11import textwrap 12import time 13import unittest 14import warnings 15 16from test import support 17from test.support import import_helper 18from test.support import os_helper 19from test.support import script_helper 20from test.support import socket_helper 21from test.support import warnings_helper 22 23TESTFN = os_helper.TESTFN 24 25 26class TestSupport(unittest.TestCase): 27 @classmethod 28 def setUpClass(cls): 29 orig_filter_len = len(warnings.filters) 30 cls._warnings_helper_token = support.ignore_deprecations_from( 31 "test.support.warnings_helper", like=".*used in test_support.*" 32 ) 33 cls._test_support_token = support.ignore_deprecations_from( 34 "test.test_support", like=".*You should NOT be seeing this.*" 35 ) 36 assert len(warnings.filters) == orig_filter_len + 2 37 38 @classmethod 39 def tearDownClass(cls): 40 orig_filter_len = len(warnings.filters) 41 support.clear_ignored_deprecations( 42 cls._warnings_helper_token, 43 cls._test_support_token, 44 ) 45 assert len(warnings.filters) == orig_filter_len - 2 46 47 def test_ignored_deprecations_are_silent(self): 48 """Test support.ignore_deprecations_from() silences warnings""" 49 with warnings.catch_warnings(record=True) as warning_objs: 50 warnings_helper._warn_about_deprecation() 51 warnings.warn("You should NOT be seeing this.", DeprecationWarning) 52 messages = [str(w.message) for w in warning_objs] 53 self.assertEqual(len(messages), 0, messages) 54 55 def test_import_module(self): 56 import_helper.import_module("ftplib") 57 self.assertRaises(unittest.SkipTest, 58 import_helper.import_module, "foo") 59 60 def test_import_fresh_module(self): 61 import_helper.import_fresh_module("ftplib") 62 63 def test_get_attribute(self): 64 self.assertEqual(support.get_attribute(self, "test_get_attribute"), 65 self.test_get_attribute) 66 self.assertRaises(unittest.SkipTest, support.get_attribute, self, "foo") 67 68 @unittest.skip("failing buildbots") 69 def test_get_original_stdout(self): 70 self.assertEqual(support.get_original_stdout(), sys.stdout) 71 72 def test_unload(self): 73 import sched 74 self.assertIn("sched", sys.modules) 75 import_helper.unload("sched") 76 self.assertNotIn("sched", sys.modules) 77 78 def test_unlink(self): 79 with open(TESTFN, "w", encoding="utf-8") as f: 80 pass 81 os_helper.unlink(TESTFN) 82 self.assertFalse(os.path.exists(TESTFN)) 83 os_helper.unlink(TESTFN) 84 85 def test_rmtree(self): 86 dirpath = os_helper.TESTFN + 'd' 87 subdirpath = os.path.join(dirpath, 'subdir') 88 os.mkdir(dirpath) 89 os.mkdir(subdirpath) 90 os_helper.rmtree(dirpath) 91 self.assertFalse(os.path.exists(dirpath)) 92 with support.swap_attr(support, 'verbose', 0): 93 os_helper.rmtree(dirpath) 94 95 os.mkdir(dirpath) 96 os.mkdir(subdirpath) 97 os.chmod(dirpath, stat.S_IRUSR|stat.S_IXUSR) 98 with support.swap_attr(support, 'verbose', 0): 99 os_helper.rmtree(dirpath) 100 self.assertFalse(os.path.exists(dirpath)) 101 102 os.mkdir(dirpath) 103 os.mkdir(subdirpath) 104 os.chmod(dirpath, 0) 105 with support.swap_attr(support, 'verbose', 0): 106 os_helper.rmtree(dirpath) 107 self.assertFalse(os.path.exists(dirpath)) 108 109 def test_forget(self): 110 mod_filename = TESTFN + '.py' 111 with open(mod_filename, 'w', encoding="utf-8") as f: 112 print('foo = 1', file=f) 113 sys.path.insert(0, os.curdir) 114 importlib.invalidate_caches() 115 try: 116 mod = __import__(TESTFN) 117 self.assertIn(TESTFN, sys.modules) 118 119 import_helper.forget(TESTFN) 120 self.assertNotIn(TESTFN, sys.modules) 121 finally: 122 del sys.path[0] 123 os_helper.unlink(mod_filename) 124 os_helper.rmtree('__pycache__') 125 126 def test_HOST(self): 127 s = socket.create_server((socket_helper.HOST, 0)) 128 s.close() 129 130 def test_find_unused_port(self): 131 port = socket_helper.find_unused_port() 132 s = socket.create_server((socket_helper.HOST, port)) 133 s.close() 134 135 def test_bind_port(self): 136 s = socket.socket() 137 socket_helper.bind_port(s) 138 s.listen() 139 s.close() 140 141 # Tests for temp_dir() 142 143 def test_temp_dir(self): 144 """Test that temp_dir() creates and destroys its directory.""" 145 parent_dir = tempfile.mkdtemp() 146 parent_dir = os.path.realpath(parent_dir) 147 148 try: 149 path = os.path.join(parent_dir, 'temp') 150 self.assertFalse(os.path.isdir(path)) 151 with os_helper.temp_dir(path) as temp_path: 152 self.assertEqual(temp_path, path) 153 self.assertTrue(os.path.isdir(path)) 154 self.assertFalse(os.path.isdir(path)) 155 finally: 156 os_helper.rmtree(parent_dir) 157 158 def test_temp_dir__path_none(self): 159 """Test passing no path.""" 160 with os_helper.temp_dir() as temp_path: 161 self.assertTrue(os.path.isdir(temp_path)) 162 self.assertFalse(os.path.isdir(temp_path)) 163 164 def test_temp_dir__existing_dir__quiet_default(self): 165 """Test passing a directory that already exists.""" 166 def call_temp_dir(path): 167 with os_helper.temp_dir(path) as temp_path: 168 raise Exception("should not get here") 169 170 path = tempfile.mkdtemp() 171 path = os.path.realpath(path) 172 try: 173 self.assertTrue(os.path.isdir(path)) 174 self.assertRaises(FileExistsError, call_temp_dir, path) 175 # Make sure temp_dir did not delete the original directory. 176 self.assertTrue(os.path.isdir(path)) 177 finally: 178 shutil.rmtree(path) 179 180 def test_temp_dir__existing_dir__quiet_true(self): 181 """Test passing a directory that already exists with quiet=True.""" 182 path = tempfile.mkdtemp() 183 path = os.path.realpath(path) 184 185 try: 186 with warnings_helper.check_warnings() as recorder: 187 with os_helper.temp_dir(path, quiet=True) as temp_path: 188 self.assertEqual(path, temp_path) 189 warnings = [str(w.message) for w in recorder.warnings] 190 # Make sure temp_dir did not delete the original directory. 191 self.assertTrue(os.path.isdir(path)) 192 finally: 193 shutil.rmtree(path) 194 195 self.assertEqual(len(warnings), 1, warnings) 196 warn = warnings[0] 197 self.assertTrue(warn.startswith(f'tests may fail, unable to create ' 198 f'temporary directory {path!r}: '), 199 warn) 200 201 @unittest.skipUnless(hasattr(os, "fork"), "test requires os.fork") 202 def test_temp_dir__forked_child(self): 203 """Test that a forked child process does not remove the directory.""" 204 # See bpo-30028 for details. 205 # Run the test as an external script, because it uses fork. 206 script_helper.assert_python_ok("-c", textwrap.dedent(""" 207 import os 208 from test import support 209 from test.support import os_helper 210 with os_helper.temp_cwd() as temp_path: 211 pid = os.fork() 212 if pid != 0: 213 # parent process 214 215 # wait for the child to terminate 216 support.wait_process(pid, exitcode=0) 217 218 # Make sure that temp_path is still present. When the child 219 # process leaves the 'temp_cwd'-context, the __exit__()- 220 # method of the context must not remove the temporary 221 # directory. 222 if not os.path.isdir(temp_path): 223 raise AssertionError("Child removed temp_path.") 224 """)) 225 226 # Tests for change_cwd() 227 228 def test_change_cwd(self): 229 original_cwd = os.getcwd() 230 231 with os_helper.temp_dir() as temp_path: 232 with os_helper.change_cwd(temp_path) as new_cwd: 233 self.assertEqual(new_cwd, temp_path) 234 self.assertEqual(os.getcwd(), new_cwd) 235 236 self.assertEqual(os.getcwd(), original_cwd) 237 238 def test_change_cwd__non_existent_dir(self): 239 """Test passing a non-existent directory.""" 240 original_cwd = os.getcwd() 241 242 def call_change_cwd(path): 243 with os_helper.change_cwd(path) as new_cwd: 244 raise Exception("should not get here") 245 246 with os_helper.temp_dir() as parent_dir: 247 non_existent_dir = os.path.join(parent_dir, 'does_not_exist') 248 self.assertRaises(FileNotFoundError, call_change_cwd, 249 non_existent_dir) 250 251 self.assertEqual(os.getcwd(), original_cwd) 252 253 def test_change_cwd__non_existent_dir__quiet_true(self): 254 """Test passing a non-existent directory with quiet=True.""" 255 original_cwd = os.getcwd() 256 257 with os_helper.temp_dir() as parent_dir: 258 bad_dir = os.path.join(parent_dir, 'does_not_exist') 259 with warnings_helper.check_warnings() as recorder: 260 with os_helper.change_cwd(bad_dir, quiet=True) as new_cwd: 261 self.assertEqual(new_cwd, original_cwd) 262 self.assertEqual(os.getcwd(), new_cwd) 263 warnings = [str(w.message) for w in recorder.warnings] 264 265 self.assertEqual(len(warnings), 1, warnings) 266 warn = warnings[0] 267 self.assertTrue(warn.startswith(f'tests may fail, unable to change ' 268 f'the current working directory ' 269 f'to {bad_dir!r}: '), 270 warn) 271 272 # Tests for change_cwd() 273 274 def test_change_cwd__chdir_warning(self): 275 """Check the warning message when os.chdir() fails.""" 276 path = TESTFN + '_does_not_exist' 277 with warnings_helper.check_warnings() as recorder: 278 with os_helper.change_cwd(path=path, quiet=True): 279 pass 280 messages = [str(w.message) for w in recorder.warnings] 281 282 self.assertEqual(len(messages), 1, messages) 283 msg = messages[0] 284 self.assertTrue(msg.startswith(f'tests may fail, unable to change ' 285 f'the current working directory ' 286 f'to {path!r}: '), 287 msg) 288 289 # Tests for temp_cwd() 290 291 def test_temp_cwd(self): 292 here = os.getcwd() 293 with os_helper.temp_cwd(name=TESTFN): 294 self.assertEqual(os.path.basename(os.getcwd()), TESTFN) 295 self.assertFalse(os.path.exists(TESTFN)) 296 self.assertEqual(os.getcwd(), here) 297 298 299 def test_temp_cwd__name_none(self): 300 """Test passing None to temp_cwd().""" 301 original_cwd = os.getcwd() 302 with os_helper.temp_cwd(name=None) as new_cwd: 303 self.assertNotEqual(new_cwd, original_cwd) 304 self.assertTrue(os.path.isdir(new_cwd)) 305 self.assertEqual(os.getcwd(), new_cwd) 306 self.assertEqual(os.getcwd(), original_cwd) 307 308 def test_sortdict(self): 309 self.assertEqual(support.sortdict({3:3, 2:2, 1:1}), "{1: 1, 2: 2, 3: 3}") 310 311 def test_make_bad_fd(self): 312 fd = os_helper.make_bad_fd() 313 with self.assertRaises(OSError) as cm: 314 os.write(fd, b"foo") 315 self.assertEqual(cm.exception.errno, errno.EBADF) 316 317 def test_check_syntax_error(self): 318 support.check_syntax_error(self, "def class", lineno=1, offset=5) 319 with self.assertRaises(AssertionError): 320 support.check_syntax_error(self, "x=1") 321 322 def test_CleanImport(self): 323 import importlib 324 with import_helper.CleanImport("pprint"): 325 importlib.import_module("pprint") 326 327 def test_DirsOnSysPath(self): 328 with import_helper.DirsOnSysPath('foo', 'bar'): 329 self.assertIn("foo", sys.path) 330 self.assertIn("bar", sys.path) 331 self.assertNotIn("foo", sys.path) 332 self.assertNotIn("bar", sys.path) 333 334 def test_captured_stdout(self): 335 with support.captured_stdout() as stdout: 336 print("hello") 337 self.assertEqual(stdout.getvalue(), "hello\n") 338 339 def test_captured_stderr(self): 340 with support.captured_stderr() as stderr: 341 print("hello", file=sys.stderr) 342 self.assertEqual(stderr.getvalue(), "hello\n") 343 344 def test_captured_stdin(self): 345 with support.captured_stdin() as stdin: 346 stdin.write('hello\n') 347 stdin.seek(0) 348 # call test code that consumes from sys.stdin 349 captured = input() 350 self.assertEqual(captured, "hello") 351 352 def test_gc_collect(self): 353 support.gc_collect() 354 355 def test_python_is_optimized(self): 356 self.assertIsInstance(support.python_is_optimized(), bool) 357 358 def test_swap_attr(self): 359 class Obj: 360 pass 361 obj = Obj() 362 obj.x = 1 363 with support.swap_attr(obj, "x", 5) as x: 364 self.assertEqual(obj.x, 5) 365 self.assertEqual(x, 1) 366 self.assertEqual(obj.x, 1) 367 with support.swap_attr(obj, "y", 5) as y: 368 self.assertEqual(obj.y, 5) 369 self.assertIsNone(y) 370 self.assertFalse(hasattr(obj, 'y')) 371 with support.swap_attr(obj, "y", 5): 372 del obj.y 373 self.assertFalse(hasattr(obj, 'y')) 374 375 def test_swap_item(self): 376 D = {"x":1} 377 with support.swap_item(D, "x", 5) as x: 378 self.assertEqual(D["x"], 5) 379 self.assertEqual(x, 1) 380 self.assertEqual(D["x"], 1) 381 with support.swap_item(D, "y", 5) as y: 382 self.assertEqual(D["y"], 5) 383 self.assertIsNone(y) 384 self.assertNotIn("y", D) 385 with support.swap_item(D, "y", 5): 386 del D["y"] 387 self.assertNotIn("y", D) 388 389 class RefClass: 390 attribute1 = None 391 attribute2 = None 392 _hidden_attribute1 = None 393 __magic_1__ = None 394 395 class OtherClass: 396 attribute2 = None 397 attribute3 = None 398 __magic_1__ = None 399 __magic_2__ = None 400 401 def test_detect_api_mismatch(self): 402 missing_items = support.detect_api_mismatch(self.RefClass, 403 self.OtherClass) 404 self.assertEqual({'attribute1'}, missing_items) 405 406 missing_items = support.detect_api_mismatch(self.OtherClass, 407 self.RefClass) 408 self.assertEqual({'attribute3', '__magic_2__'}, missing_items) 409 410 def test_detect_api_mismatch__ignore(self): 411 ignore = ['attribute1', 'attribute3', '__magic_2__', 'not_in_either'] 412 413 missing_items = support.detect_api_mismatch( 414 self.RefClass, self.OtherClass, ignore=ignore) 415 self.assertEqual(set(), missing_items) 416 417 missing_items = support.detect_api_mismatch( 418 self.OtherClass, self.RefClass, ignore=ignore) 419 self.assertEqual(set(), missing_items) 420 421 def test_check__all__(self): 422 extra = {'tempdir'} 423 not_exported = {'template'} 424 support.check__all__(self, 425 tempfile, 426 extra=extra, 427 not_exported=not_exported) 428 429 extra = {'TextTestResult', 'installHandler'} 430 not_exported = {'load_tests', "TestProgram", "BaseTestSuite"} 431 432 support.check__all__(self, 433 unittest, 434 ("unittest.result", "unittest.case", 435 "unittest.suite", "unittest.loader", 436 "unittest.main", "unittest.runner", 437 "unittest.signals", "unittest.async_case"), 438 extra=extra, 439 not_exported=not_exported) 440 441 self.assertRaises(AssertionError, support.check__all__, self, unittest) 442 443 @unittest.skipUnless(hasattr(os, 'waitpid') and hasattr(os, 'WNOHANG'), 444 'need os.waitpid() and os.WNOHANG') 445 def test_reap_children(self): 446 # Make sure that there is no other pending child process 447 support.reap_children() 448 449 # Create a child process 450 pid = os.fork() 451 if pid == 0: 452 # child process: do nothing, just exit 453 os._exit(0) 454 455 t0 = time.monotonic() 456 deadline = time.monotonic() + support.SHORT_TIMEOUT 457 458 was_altered = support.environment_altered 459 try: 460 support.environment_altered = False 461 stderr = io.StringIO() 462 463 while True: 464 if time.monotonic() > deadline: 465 self.fail("timeout") 466 467 old_stderr = sys.__stderr__ 468 try: 469 sys.__stderr__ = stderr 470 support.reap_children() 471 finally: 472 sys.__stderr__ = old_stderr 473 474 # Use environment_altered to check if reap_children() found 475 # the child process 476 if support.environment_altered: 477 break 478 479 # loop until the child process completed 480 time.sleep(0.100) 481 482 msg = "Warning -- reap_children() reaped child process %s" % pid 483 self.assertIn(msg, stderr.getvalue()) 484 self.assertTrue(support.environment_altered) 485 finally: 486 support.environment_altered = was_altered 487 488 # Just in case, check again that there is no other 489 # pending child process 490 support.reap_children() 491 492 def check_options(self, args, func, expected=None): 493 code = f'from test.support import {func}; print(repr({func}()))' 494 cmd = [sys.executable, *args, '-c', code] 495 env = {key: value for key, value in os.environ.items() 496 if not key.startswith('PYTHON')} 497 proc = subprocess.run(cmd, 498 stdout=subprocess.PIPE, 499 stderr=subprocess.DEVNULL, 500 universal_newlines=True, 501 env=env) 502 if expected is None: 503 expected = args 504 self.assertEqual(proc.stdout.rstrip(), repr(expected)) 505 self.assertEqual(proc.returncode, 0) 506 507 def test_args_from_interpreter_flags(self): 508 # Test test.support.args_from_interpreter_flags() 509 for opts in ( 510 # no option 511 [], 512 # single option 513 ['-B'], 514 ['-s'], 515 ['-S'], 516 ['-E'], 517 ['-v'], 518 ['-b'], 519 ['-q'], 520 ['-I'], 521 # same option multiple times 522 ['-bb'], 523 ['-vvv'], 524 # -W options 525 ['-Wignore'], 526 # -X options 527 ['-X', 'dev'], 528 ['-Wignore', '-X', 'dev'], 529 ['-X', 'faulthandler'], 530 ['-X', 'importtime'], 531 ['-X', 'showrefcount'], 532 ['-X', 'tracemalloc'], 533 ['-X', 'tracemalloc=3'], 534 ): 535 with self.subTest(opts=opts): 536 self.check_options(opts, 'args_from_interpreter_flags') 537 538 self.check_options(['-I', '-E', '-s'], 'args_from_interpreter_flags', 539 ['-I']) 540 541 def test_optim_args_from_interpreter_flags(self): 542 # Test test.support.optim_args_from_interpreter_flags() 543 for opts in ( 544 # no option 545 [], 546 ['-O'], 547 ['-OO'], 548 ['-OOOO'], 549 ): 550 with self.subTest(opts=opts): 551 self.check_options(opts, 'optim_args_from_interpreter_flags') 552 553 def test_match_test(self): 554 class Test: 555 def __init__(self, test_id): 556 self.test_id = test_id 557 558 def id(self): 559 return self.test_id 560 561 test_access = Test('test.test_os.FileTests.test_access') 562 test_chdir = Test('test.test_os.Win32ErrorTests.test_chdir') 563 564 # Test acceptance 565 with support.swap_attr(support, '_match_test_func', None): 566 # match all 567 support.set_match_tests([]) 568 self.assertTrue(support.match_test(test_access)) 569 self.assertTrue(support.match_test(test_chdir)) 570 571 # match all using None 572 support.set_match_tests(None, None) 573 self.assertTrue(support.match_test(test_access)) 574 self.assertTrue(support.match_test(test_chdir)) 575 576 # match the full test identifier 577 support.set_match_tests([test_access.id()], None) 578 self.assertTrue(support.match_test(test_access)) 579 self.assertFalse(support.match_test(test_chdir)) 580 581 # match the module name 582 support.set_match_tests(['test_os'], None) 583 self.assertTrue(support.match_test(test_access)) 584 self.assertTrue(support.match_test(test_chdir)) 585 586 # Test '*' pattern 587 support.set_match_tests(['test_*'], None) 588 self.assertTrue(support.match_test(test_access)) 589 self.assertTrue(support.match_test(test_chdir)) 590 591 # Test case sensitivity 592 support.set_match_tests(['filetests'], None) 593 self.assertFalse(support.match_test(test_access)) 594 support.set_match_tests(['FileTests'], None) 595 self.assertTrue(support.match_test(test_access)) 596 597 # Test pattern containing '.' and a '*' metacharacter 598 support.set_match_tests(['*test_os.*.test_*'], None) 599 self.assertTrue(support.match_test(test_access)) 600 self.assertTrue(support.match_test(test_chdir)) 601 602 # Multiple patterns 603 support.set_match_tests([test_access.id(), test_chdir.id()], None) 604 self.assertTrue(support.match_test(test_access)) 605 self.assertTrue(support.match_test(test_chdir)) 606 607 support.set_match_tests(['test_access', 'DONTMATCH'], None) 608 self.assertTrue(support.match_test(test_access)) 609 self.assertFalse(support.match_test(test_chdir)) 610 611 # Test rejection 612 with support.swap_attr(support, '_match_test_func', None): 613 # match all 614 support.set_match_tests(ignore_patterns=[]) 615 self.assertTrue(support.match_test(test_access)) 616 self.assertTrue(support.match_test(test_chdir)) 617 618 # match all using None 619 support.set_match_tests(None, None) 620 self.assertTrue(support.match_test(test_access)) 621 self.assertTrue(support.match_test(test_chdir)) 622 623 # match the full test identifier 624 support.set_match_tests(None, [test_access.id()]) 625 self.assertFalse(support.match_test(test_access)) 626 self.assertTrue(support.match_test(test_chdir)) 627 628 # match the module name 629 support.set_match_tests(None, ['test_os']) 630 self.assertFalse(support.match_test(test_access)) 631 self.assertFalse(support.match_test(test_chdir)) 632 633 # Test '*' pattern 634 support.set_match_tests(None, ['test_*']) 635 self.assertFalse(support.match_test(test_access)) 636 self.assertFalse(support.match_test(test_chdir)) 637 638 # Test case sensitivity 639 support.set_match_tests(None, ['filetests']) 640 self.assertTrue(support.match_test(test_access)) 641 support.set_match_tests(None, ['FileTests']) 642 self.assertFalse(support.match_test(test_access)) 643 644 # Test pattern containing '.' and a '*' metacharacter 645 support.set_match_tests(None, ['*test_os.*.test_*']) 646 self.assertFalse(support.match_test(test_access)) 647 self.assertFalse(support.match_test(test_chdir)) 648 649 # Multiple patterns 650 support.set_match_tests(None, [test_access.id(), test_chdir.id()]) 651 self.assertFalse(support.match_test(test_access)) 652 self.assertFalse(support.match_test(test_chdir)) 653 654 support.set_match_tests(None, ['test_access', 'DONTMATCH']) 655 self.assertFalse(support.match_test(test_access)) 656 self.assertTrue(support.match_test(test_chdir)) 657 658 def test_fd_count(self): 659 # We cannot test the absolute value of fd_count(): on old Linux 660 # kernel or glibc versions, os.urandom() keeps a FD open on 661 # /dev/urandom device and Python has 4 FD opens instead of 3. 662 start = os_helper.fd_count() 663 fd = os.open(__file__, os.O_RDONLY) 664 try: 665 more = os_helper.fd_count() 666 finally: 667 os.close(fd) 668 self.assertEqual(more - start, 1) 669 670 def check_print_warning(self, msg, expected): 671 stderr = io.StringIO() 672 673 old_stderr = sys.__stderr__ 674 try: 675 sys.__stderr__ = stderr 676 support.print_warning(msg) 677 finally: 678 sys.__stderr__ = old_stderr 679 680 self.assertEqual(stderr.getvalue(), expected) 681 682 def test_print_warning(self): 683 self.check_print_warning("msg", 684 "Warning -- msg\n") 685 self.check_print_warning("a\nb", 686 'Warning -- a\nWarning -- b\n') 687 688 # XXX -follows a list of untested API 689 # make_legacy_pyc 690 # is_resource_enabled 691 # requires 692 # fcmp 693 # umaks 694 # findfile 695 # check_warnings 696 # EnvironmentVarGuard 697 # transient_internet 698 # run_with_locale 699 # set_memlimit 700 # bigmemtest 701 # precisionbigmemtest 702 # bigaddrspacetest 703 # requires_resource 704 # run_doctest 705 # threading_cleanup 706 # reap_threads 707 # can_symlink 708 # skip_unless_symlink 709 # SuppressCrashReport 710 711 712if __name__ == '__main__': 713 unittest.main() 714