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