github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-runtime-src/third_party/stdlib/test/test_support.py (about) 1 """Supporting definitions for the Python regression tests.""" 2 3 # if __name__ != 'test.test_support': 4 # raise ImportError('test_support must be imported from the test package') 5 6 import contextlib 7 # import errno 8 # import functools 9 # import gc 10 # import socket 11 import sys 12 import os 13 # import platform 14 # import shutil 15 import warnings 16 import unittest 17 # import importlib 18 import UserDict 19 # import re 20 # import time 21 # import struct 22 # import sysconfig 23 try: 24 import thread 25 except ImportError: 26 thread = None 27 28 __all__ = [ 29 "Error", "TestFailed", "have_unicode", "BasicTestRunner", "run_unittest", 30 "check_warnings", "check_py3k_warnings", "CleanImport", 31 "EnvironmentVarGuard" 32 ] 33 34 # __all__ = ["Error", "TestFailed", "ResourceDenied", "import_module", 35 # "verbose", "use_resources", "max_memuse", "record_original_stdout", 36 # "get_original_stdout", "unload", "unlink", "rmtree", "forget", 37 # "is_resource_enabled", "requires", "requires_mac_ver", 38 # "find_unused_port", "bind_port", 39 # "fcmp", "have_unicode", "is_jython", "TESTFN", "HOST", "FUZZ", 40 # "SAVEDCWD", "temp_cwd", "findfile", "sortdict", "check_syntax_error", 41 # "open_urlresource", "check_warnings", "check_py3k_warnings", 42 # "CleanImport", "EnvironmentVarGuard", "captured_output", 43 # "captured_stdout", "TransientResource", "transient_internet", 44 # "run_with_locale", "set_memlimit", "bigmemtest", "bigaddrspacetest", 45 # "BasicTestRunner", "run_unittest", "run_doctest", "threading_setup", 46 # "threading_cleanup", "reap_threads", "start_threads", "cpython_only", 47 # "check_impl_detail", "get_attribute", "py3k_bytes", 48 # "import_fresh_module", "threading_cleanup", "reap_children", 49 # "strip_python_stderr", "IPV6_ENABLED", "run_with_tz"] 50 51 class Error(Exception): 52 """Base class for regression test exceptions.""" 53 54 class TestFailed(Error): 55 """Test failed.""" 56 57 # class ResourceDenied(unittest.SkipTest): 58 # """Test skipped because it requested a disallowed resource. 59 60 # This is raised when a test calls requires() for a resource that 61 # has not been enabled. It is used to distinguish between expected 62 # and unexpected skips. 63 # """ 64 65 # @contextlib.contextmanager 66 # def _ignore_deprecated_imports(ignore=True): 67 # """Context manager to suppress package and module deprecation 68 # warnings when importing them. 69 70 # If ignore is False, this context manager has no effect.""" 71 # if ignore: 72 # with warnings.catch_warnings(): 73 # warnings.filterwarnings("ignore", ".+ (module|package)", 74 # DeprecationWarning) 75 # yield 76 # else: 77 # yield 78 79 80 # def import_module(name, deprecated=False): 81 # """Import and return the module to be tested, raising SkipTest if 82 # it is not available. 83 84 # If deprecated is True, any module or package deprecation messages 85 # will be suppressed.""" 86 # with _ignore_deprecated_imports(deprecated): 87 # try: 88 # return importlib.import_module(name) 89 # except ImportError, msg: 90 # raise unittest.SkipTest(str(msg)) 91 92 93 # def _save_and_remove_module(name, orig_modules): 94 # """Helper function to save and remove a module from sys.modules 95 96 # Raise ImportError if the module can't be imported.""" 97 # # try to import the module and raise an error if it can't be imported 98 # if name not in sys.modules: 99 # __import__(name) 100 # del sys.modules[name] 101 # for modname in list(sys.modules): 102 # if modname == name or modname.startswith(name + '.'): 103 # orig_modules[modname] = sys.modules[modname] 104 # del sys.modules[modname] 105 106 # def _save_and_block_module(name, orig_modules): 107 # """Helper function to save and block a module in sys.modules 108 109 # Return True if the module was in sys.modules, False otherwise.""" 110 # saved = True 111 # try: 112 # orig_modules[name] = sys.modules[name] 113 # except KeyError: 114 # saved = False 115 # sys.modules[name] = None 116 # return saved 117 118 119 # def import_fresh_module(name, fresh=(), blocked=(), deprecated=False): 120 # """Imports and returns a module, deliberately bypassing the sys.modules cache 121 # and importing a fresh copy of the module. Once the import is complete, 122 # the sys.modules cache is restored to its original state. 123 124 # Modules named in fresh are also imported anew if needed by the import. 125 # If one of these modules can't be imported, None is returned. 126 127 # Importing of modules named in blocked is prevented while the fresh import 128 # takes place. 129 130 # If deprecated is True, any module or package deprecation messages 131 # will be suppressed.""" 132 # # NOTE: test_heapq, test_json, and test_warnings include extra sanity 133 # # checks to make sure that this utility function is working as expected 134 # with _ignore_deprecated_imports(deprecated): 135 # # Keep track of modules saved for later restoration as well 136 # # as those which just need a blocking entry removed 137 # orig_modules = {} 138 # names_to_remove = [] 139 # _save_and_remove_module(name, orig_modules) 140 # try: 141 # for fresh_name in fresh: 142 # _save_and_remove_module(fresh_name, orig_modules) 143 # for blocked_name in blocked: 144 # if not _save_and_block_module(blocked_name, orig_modules): 145 # names_to_remove.append(blocked_name) 146 # fresh_module = importlib.import_module(name) 147 # except ImportError: 148 # fresh_module = None 149 # finally: 150 # for orig_name, module in orig_modules.items(): 151 # sys.modules[orig_name] = module 152 # for name_to_remove in names_to_remove: 153 # del sys.modules[name_to_remove] 154 # return fresh_module 155 156 157 # def get_attribute(obj, name): 158 # """Get an attribute, raising SkipTest if AttributeError is raised.""" 159 # try: 160 # attribute = getattr(obj, name) 161 # except AttributeError: 162 # raise unittest.SkipTest("module %s has no attribute %s" % ( 163 # obj.__name__, name)) 164 # else: 165 # return attribute 166 167 168 verbose = 1 # Flag set to 0 by regrtest.py 169 # use_resources = None # Flag set to [] by regrtest.py 170 # max_memuse = 0 # Disable bigmem tests (they will still be run with 171 # # small sizes, to make sure they work.) 172 # real_max_memuse = 0 173 174 # # _original_stdout is meant to hold stdout at the time regrtest began. 175 # # This may be "the real" stdout, or IDLE's emulation of stdout, or whatever. 176 # # The point is to have some flavor of stdout the user can actually see. 177 # _original_stdout = None 178 # def record_original_stdout(stdout): 179 # global _original_stdout 180 # _original_stdout = stdout 181 182 # def get_original_stdout(): 183 # return _original_stdout or sys.stdout 184 185 # def unload(name): 186 # try: 187 # del sys.modules[name] 188 # except KeyError: 189 # pass 190 191 if sys.platform.startswith("win"): 192 def _waitfor(func, pathname, waitall=False): 193 # Perform the operation 194 func(pathname) 195 # Now setup the wait loop 196 if waitall: 197 dirname = pathname 198 else: 199 dirname, name = os.path.split(pathname) 200 dirname = dirname or '.' 201 # Check for `pathname` to be removed from the filesystem. 202 # The exponential backoff of the timeout amounts to a total 203 # of ~1 second after which the deletion is probably an error 204 # anyway. 205 # Testing on a i7@4.3GHz shows that usually only 1 iteration is 206 # required when contention occurs. 207 timeout = 0.001 208 while timeout < 1.0: 209 # Note we are only testing for the existence of the file(s) in 210 # the contents of the directory regardless of any security or 211 # access rights. If we have made it this far, we have sufficient 212 # permissions to do that much using Python's equivalent of the 213 # Windows API FindFirstFile. 214 # Other Windows APIs can fail or give incorrect results when 215 # dealing with files that are pending deletion. 216 L = os.listdir(dirname) 217 if not (L if waitall else name in L): 218 return 219 # Increase the timeout and try again 220 time.sleep(timeout) 221 timeout *= 2 222 warnings.warn('tests may fail, delete still pending for ' + pathname, 223 RuntimeWarning, stacklevel=4) 224 225 def _unlink(filename): 226 _waitfor(os.unlink, filename) 227 228 def _rmdir(dirname): 229 _waitfor(os.rmdir, dirname) 230 231 def _rmtree(path): 232 def _rmtree_inner(path): 233 for name in os.listdir(path): 234 fullname = os.path.join(path, name) 235 if os.path.isdir(fullname): 236 _waitfor(_rmtree_inner, fullname, waitall=True) 237 os.rmdir(fullname) 238 else: 239 os.unlink(fullname) 240 _waitfor(_rmtree_inner, path, waitall=True) 241 _waitfor(os.rmdir, path) 242 else: 243 _unlink = os.unlink 244 _rmdir = os.rmdir 245 # _rmtree = shutil.rmtree 246 247 def unlink(filename): 248 try: 249 _unlink(filename) 250 except OSError: 251 pass 252 253 # def rmdir(dirname): 254 # try: 255 # _rmdir(dirname) 256 # except OSError as error: 257 # # The directory need not exist. 258 # if error.errno != errno.ENOENT: 259 # raise 260 261 # def rmtree(path): 262 # try: 263 # _rmtree(path) 264 # except OSError, e: 265 # # Unix returns ENOENT, Windows returns ESRCH. 266 # if e.errno not in (errno.ENOENT, errno.ESRCH): 267 # raise 268 269 # def forget(modname): 270 # '''"Forget" a module was ever imported by removing it from sys.modules and 271 # deleting any .pyc and .pyo files.''' 272 # unload(modname) 273 # for dirname in sys.path: 274 # unlink(os.path.join(dirname, modname + os.extsep + 'pyc')) 275 # # Deleting the .pyo file cannot be within the 'try' for the .pyc since 276 # # the chance exists that there is no .pyc (and thus the 'try' statement 277 # # is exited) but there is a .pyo file. 278 # unlink(os.path.join(dirname, modname + os.extsep + 'pyo')) 279 280 # # Check whether a gui is actually available 281 # def _is_gui_available(): 282 # if hasattr(_is_gui_available, 'result'): 283 # return _is_gui_available.result 284 # reason = None 285 # if sys.platform.startswith('win'): 286 # # if Python is running as a service (such as the buildbot service), 287 # # gui interaction may be disallowed 288 # import ctypes 289 # import ctypes.wintypes 290 # UOI_FLAGS = 1 291 # WSF_VISIBLE = 0x0001 292 # class USEROBJECTFLAGS(ctypes.Structure): 293 # _fields_ = [("fInherit", ctypes.wintypes.BOOL), 294 # ("fReserved", ctypes.wintypes.BOOL), 295 # ("dwFlags", ctypes.wintypes.DWORD)] 296 # dll = ctypes.windll.user32 297 # h = dll.GetProcessWindowStation() 298 # if not h: 299 # raise ctypes.WinError() 300 # uof = USEROBJECTFLAGS() 301 # needed = ctypes.wintypes.DWORD() 302 # res = dll.GetUserObjectInformationW(h, 303 # UOI_FLAGS, 304 # ctypes.byref(uof), 305 # ctypes.sizeof(uof), 306 # ctypes.byref(needed)) 307 # if not res: 308 # raise ctypes.WinError() 309 # if not bool(uof.dwFlags & WSF_VISIBLE): 310 # reason = "gui not available (WSF_VISIBLE flag not set)" 311 # elif sys.platform == 'darwin': 312 # # The Aqua Tk implementations on OS X can abort the process if 313 # # being called in an environment where a window server connection 314 # # cannot be made, for instance when invoked by a buildbot or ssh 315 # # process not running under the same user id as the current console 316 # # user. To avoid that, raise an exception if the window manager 317 # # connection is not available. 318 # from ctypes import cdll, c_int, pointer, Structure 319 # from ctypes.util import find_library 320 321 # app_services = cdll.LoadLibrary(find_library("ApplicationServices")) 322 323 # if app_services.CGMainDisplayID() == 0: 324 # reason = "gui tests cannot run without OS X window manager" 325 # else: 326 # class ProcessSerialNumber(Structure): 327 # _fields_ = [("highLongOfPSN", c_int), 328 # ("lowLongOfPSN", c_int)] 329 # psn = ProcessSerialNumber() 330 # psn_p = pointer(psn) 331 # if ( (app_services.GetCurrentProcess(psn_p) < 0) or 332 # (app_services.SetFrontProcess(psn_p) < 0) ): 333 # reason = "cannot run without OS X gui process" 334 335 # # check on every platform whether tkinter can actually do anything 336 # if not reason: 337 # try: 338 # from Tkinter import Tk 339 # root = Tk() 340 # root.update() 341 # root.destroy() 342 # except Exception as e: 343 # err_string = str(e) 344 # if len(err_string) > 50: 345 # err_string = err_string[:50] + ' [...]' 346 # reason = 'Tk unavailable due to {}: {}'.format(type(e).__name__, 347 # err_string) 348 349 # _is_gui_available.reason = reason 350 # _is_gui_available.result = not reason 351 352 # return _is_gui_available.result 353 354 # def is_resource_enabled(resource): 355 # """Test whether a resource is enabled. 356 357 # Known resources are set by regrtest.py. If not running under regrtest.py, 358 # all resources are assumed enabled unless use_resources has been set. 359 # """ 360 # return use_resources is None or resource in use_resources 361 362 # def requires(resource, msg=None): 363 # """Raise ResourceDenied if the specified resource is not available.""" 364 # if resource == 'gui' and not _is_gui_available(): 365 # raise ResourceDenied(_is_gui_available.reason) 366 # if not is_resource_enabled(resource): 367 # if msg is None: 368 # msg = "Use of the `%s' resource not enabled" % resource 369 # raise ResourceDenied(msg) 370 371 # def requires_mac_ver(*min_version): 372 # """Decorator raising SkipTest if the OS is Mac OS X and the OS X 373 # version if less than min_version. 374 375 # For example, @requires_mac_ver(10, 5) raises SkipTest if the OS X version 376 # is lesser than 10.5. 377 # """ 378 # def decorator(func): 379 # @functools.wraps(func) 380 # def wrapper(*args, **kw): 381 # if sys.platform == 'darwin': 382 # version_txt = platform.mac_ver()[0] 383 # try: 384 # version = tuple(map(int, version_txt.split('.'))) 385 # except ValueError: 386 # pass 387 # else: 388 # if version < min_version: 389 # min_version_txt = '.'.join(map(str, min_version)) 390 # raise unittest.SkipTest( 391 # "Mac OS X %s or higher required, not %s" 392 # % (min_version_txt, version_txt)) 393 # return func(*args, **kw) 394 # wrapper.min_version = min_version 395 # return wrapper 396 # return decorator 397 398 399 # # Don't use "localhost", since resolving it uses the DNS under recent 400 # # Windows versions (see issue #18792). 401 # HOST = "127.0.0.1" 402 # HOSTv6 = "::1" 403 404 405 # def find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM): 406 # """Returns an unused port that should be suitable for binding. This is 407 # achieved by creating a temporary socket with the same family and type as 408 # the 'sock' parameter (default is AF_INET, SOCK_STREAM), and binding it to 409 # the specified host address (defaults to 0.0.0.0) with the port set to 0, 410 # eliciting an unused ephemeral port from the OS. The temporary socket is 411 # then closed and deleted, and the ephemeral port is returned. 412 413 # Either this method or bind_port() should be used for any tests where a 414 # server socket needs to be bound to a particular port for the duration of 415 # the test. Which one to use depends on whether the calling code is creating 416 # a python socket, or if an unused port needs to be provided in a constructor 417 # or passed to an external program (i.e. the -accept argument to openssl's 418 # s_server mode). Always prefer bind_port() over find_unused_port() where 419 # possible. Hard coded ports should *NEVER* be used. As soon as a server 420 # socket is bound to a hard coded port, the ability to run multiple instances 421 # of the test simultaneously on the same host is compromised, which makes the 422 # test a ticking time bomb in a buildbot environment. On Unix buildbots, this 423 # may simply manifest as a failed test, which can be recovered from without 424 # intervention in most cases, but on Windows, the entire python process can 425 # completely and utterly wedge, requiring someone to log in to the buildbot 426 # and manually kill the affected process. 427 428 # (This is easy to reproduce on Windows, unfortunately, and can be traced to 429 # the SO_REUSEADDR socket option having different semantics on Windows versus 430 # Unix/Linux. On Unix, you can't have two AF_INET SOCK_STREAM sockets bind, 431 # listen and then accept connections on identical host/ports. An EADDRINUSE 432 # socket.error will be raised at some point (depending on the platform and 433 # the order bind and listen were called on each socket). 434 435 # However, on Windows, if SO_REUSEADDR is set on the sockets, no EADDRINUSE 436 # will ever be raised when attempting to bind two identical host/ports. When 437 # accept() is called on each socket, the second caller's process will steal 438 # the port from the first caller, leaving them both in an awkwardly wedged 439 # state where they'll no longer respond to any signals or graceful kills, and 440 # must be forcibly killed via OpenProcess()/TerminateProcess(). 441 442 # The solution on Windows is to use the SO_EXCLUSIVEADDRUSE socket option 443 # instead of SO_REUSEADDR, which effectively affords the same semantics as 444 # SO_REUSEADDR on Unix. Given the propensity of Unix developers in the Open 445 # Source world compared to Windows ones, this is a common mistake. A quick 446 # look over OpenSSL's 0.9.8g source shows that they use SO_REUSEADDR when 447 # openssl.exe is called with the 's_server' option, for example. See 448 # http://bugs.python.org/issue2550 for more info. The following site also 449 # has a very thorough description about the implications of both REUSEADDR 450 # and EXCLUSIVEADDRUSE on Windows: 451 # http://msdn2.microsoft.com/en-us/library/ms740621(VS.85).aspx) 452 453 # XXX: although this approach is a vast improvement on previous attempts to 454 # elicit unused ports, it rests heavily on the assumption that the ephemeral 455 # port returned to us by the OS won't immediately be dished back out to some 456 # other process when we close and delete our temporary socket but before our 457 # calling code has a chance to bind the returned port. We can deal with this 458 # issue if/when we come across it.""" 459 # tempsock = socket.socket(family, socktype) 460 # port = bind_port(tempsock) 461 # tempsock.close() 462 # del tempsock 463 # return port 464 465 # def bind_port(sock, host=HOST): 466 # """Bind the socket to a free port and return the port number. Relies on 467 # ephemeral ports in order to ensure we are using an unbound port. This is 468 # important as many tests may be running simultaneously, especially in a 469 # buildbot environment. This method raises an exception if the sock.family 470 # is AF_INET and sock.type is SOCK_STREAM, *and* the socket has SO_REUSEADDR 471 # or SO_REUSEPORT set on it. Tests should *never* set these socket options 472 # for TCP/IP sockets. The only case for setting these options is testing 473 # multicasting via multiple UDP sockets. 474 475 # Additionally, if the SO_EXCLUSIVEADDRUSE socket option is available (i.e. 476 # on Windows), it will be set on the socket. This will prevent anyone else 477 # from bind()'ing to our host/port for the duration of the test. 478 # """ 479 # if sock.family == socket.AF_INET and sock.type == socket.SOCK_STREAM: 480 # if hasattr(socket, 'SO_REUSEADDR'): 481 # if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) == 1: 482 # raise TestFailed("tests should never set the SO_REUSEADDR " \ 483 # "socket option on TCP/IP sockets!") 484 # if hasattr(socket, 'SO_REUSEPORT'): 485 # try: 486 # if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 1: 487 # raise TestFailed("tests should never set the SO_REUSEPORT " \ 488 # "socket option on TCP/IP sockets!") 489 # except EnvironmentError: 490 # # Python's socket module was compiled using modern headers 491 # # thus defining SO_REUSEPORT but this process is running 492 # # under an older kernel that does not support SO_REUSEPORT. 493 # pass 494 # if hasattr(socket, 'SO_EXCLUSIVEADDRUSE'): 495 # sock.setsockopt(socket.SOL_SOCKET, socket.SO_EXCLUSIVEADDRUSE, 1) 496 497 # sock.bind((host, 0)) 498 # port = sock.getsockname()[1] 499 # return port 500 501 # def _is_ipv6_enabled(): 502 # """Check whether IPv6 is enabled on this host.""" 503 # if socket.has_ipv6: 504 # sock = None 505 # try: 506 # sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) 507 # sock.bind((HOSTv6, 0)) 508 # return True 509 # except socket.error: 510 # pass 511 # finally: 512 # if sock: 513 # sock.close() 514 # return False 515 516 # IPV6_ENABLED = _is_ipv6_enabled() 517 518 # def system_must_validate_cert(f): 519 # """Skip the test on TLS certificate validation failures.""" 520 # @functools.wraps(f) 521 # def dec(*args, **kwargs): 522 # try: 523 # f(*args, **kwargs) 524 # except IOError as e: 525 # if "CERTIFICATE_VERIFY_FAILED" in str(e): 526 # raise unittest.SkipTest("system does not contain " 527 # "necessary certificates") 528 # raise 529 # return dec 530 531 # FUZZ = 1e-6 532 533 # def fcmp(x, y): # fuzzy comparison function 534 # if isinstance(x, float) or isinstance(y, float): 535 # try: 536 # fuzz = (abs(x) + abs(y)) * FUZZ 537 # if abs(x-y) <= fuzz: 538 # return 0 539 # except: 540 # pass 541 # elif type(x) == type(y) and isinstance(x, (tuple, list)): 542 # for i in range(min(len(x), len(y))): 543 # outcome = fcmp(x[i], y[i]) 544 # if outcome != 0: 545 # return outcome 546 # return (len(x) > len(y)) - (len(x) < len(y)) 547 # return (x > y) - (x < y) 548 549 550 # # A constant likely larger than the underlying OS pipe buffer size, to 551 # # make writes blocking. 552 # # Windows limit seems to be around 512 B, and many Unix kernels have a 553 # # 64 KiB pipe buffer size or 16 * PAGE_SIZE: take a few megs to be sure. 554 # # (see issue #17835 for a discussion of this number). 555 # PIPE_MAX_SIZE = 4 * 1024 * 1024 + 1 556 557 # # A constant likely larger than the underlying OS socket buffer size, to make 558 # # writes blocking. 559 # # The socket buffer sizes can usually be tuned system-wide (e.g. through sysctl 560 # # on Linux), or on a per-socket basis (SO_SNDBUF/SO_RCVBUF). See issue #18643 561 # # for a discussion of this number). 562 # SOCK_MAX_SIZE = 16 * 1024 * 1024 + 1 563 564 # is_jython = sys.platform.startswith('java') 565 566 try: 567 unicode 568 have_unicode = True 569 except NameError: 570 have_unicode = False 571 572 requires_unicode = unittest.skipUnless(have_unicode, 'no unicode support') 573 574 # def u(s): 575 # return unicode(s, 'unicode-escape') 576 577 # FS_NONASCII: non-ASCII Unicode character encodable by 578 # sys.getfilesystemencoding(), or None if there is no such character. 579 FS_NONASCII = None 580 # if have_unicode: 581 # for character in ( 582 # # First try printable and common characters to have a readable filename. 583 # # For each character, the encoding list are just example of encodings able 584 # # to encode the character (the list is not exhaustive). 585 586 # # U+00E6 (Latin Small Letter Ae): cp1252, iso-8859-1 587 # unichr(0x00E6), 588 # # U+0130 (Latin Capital Letter I With Dot Above): cp1254, iso8859_3 589 # unichr(0x0130), 590 # # U+0141 (Latin Capital Letter L With Stroke): cp1250, cp1257 591 # unichr(0x0141), 592 # # U+03C6 (Greek Small Letter Phi): cp1253 593 # unichr(0x03C6), 594 # # U+041A (Cyrillic Capital Letter Ka): cp1251 595 # unichr(0x041A), 596 # # U+05D0 (Hebrew Letter Alef): Encodable to cp424 597 # unichr(0x05D0), 598 # # U+060C (Arabic Comma): cp864, cp1006, iso8859_6, mac_arabic 599 # unichr(0x060C), 600 # # U+062A (Arabic Letter Teh): cp720 601 # unichr(0x062A), 602 # # U+0E01 (Thai Character Ko Kai): cp874 603 # unichr(0x0E01), 604 605 # # Then try more "special" characters. "special" because they may be 606 # # interpreted or displayed differently depending on the exact locale 607 # # encoding and the font. 608 609 # # U+00A0 (No-Break Space) 610 # unichr(0x00A0), 611 # # U+20AC (Euro Sign) 612 # unichr(0x20AC), 613 # ): 614 # try: 615 # character.encode(sys.getfilesystemencoding())\ 616 # .decode(sys.getfilesystemencoding()) 617 # except UnicodeError: 618 # pass 619 # else: 620 # FS_NONASCII = character 621 # break 622 623 # Filename used for testing 624 if os.name == 'java': 625 # Jython disallows @ in module names 626 TESTFN = '$test' 627 elif os.name == 'riscos': 628 TESTFN = 'testfile' 629 else: 630 TESTFN = '@test' 631 # # Unicode name only used if TEST_FN_ENCODING exists for the platform. 632 # if have_unicode: 633 # # Assuming sys.getfilesystemencoding()!=sys.getdefaultencoding() 634 # # TESTFN_UNICODE is a filename that can be encoded using the 635 # # file system encoding, but *not* with the default (ascii) encoding 636 # if isinstance('', unicode): 637 # # python -U 638 # # XXX perhaps unicode() should accept Unicode strings? 639 # TESTFN_UNICODE = "@test-\xe0\xf2" 640 # else: 641 # # 2 latin characters. 642 # TESTFN_UNICODE = unicode("@test-\xe0\xf2", "latin-1") 643 # TESTFN_ENCODING = sys.getfilesystemencoding() 644 # # TESTFN_UNENCODABLE is a filename that should *not* be 645 # # able to be encoded by *either* the default or filesystem encoding. 646 # # This test really only makes sense on Windows NT platforms 647 # # which have special Unicode support in posixmodule. 648 # if (not hasattr(sys, "getwindowsversion") or 649 # sys.getwindowsversion()[3] < 2): # 0=win32s or 1=9x/ME 650 # TESTFN_UNENCODABLE = None 651 # else: 652 # # Japanese characters (I think - from bug 846133) 653 # TESTFN_UNENCODABLE = eval('u"@test-\u5171\u6709\u3055\u308c\u308b"') 654 # try: 655 # # XXX - Note - should be using TESTFN_ENCODING here - but for 656 # # Windows, "mbcs" currently always operates as if in 657 # # errors=ignore' mode - hence we get '?' characters rather than 658 # # the exception. 'Latin1' operates as we expect - ie, fails. 659 # # See [ 850997 ] mbcs encoding ignores errors 660 # TESTFN_UNENCODABLE.encode("Latin1") 661 # except UnicodeEncodeError: 662 # pass 663 # else: 664 # print \ 665 # 'WARNING: The filename %r CAN be encoded by the filesystem. ' \ 666 # 'Unicode filename tests may not be effective' \ 667 # % TESTFN_UNENCODABLE 668 669 # Disambiguate TESTFN for parallel testing, while letting it remain a valid 670 # module name. 671 TESTFN = "%s_%s_tmp" % (TESTFN, os.getpid()) 672 673 # # Save the initial cwd 674 # SAVEDCWD = os.getcwd() 675 676 # @contextlib.contextmanager 677 # def change_cwd(path, quiet=False): 678 # """Return a context manager that changes the current working directory. 679 680 # Arguments: 681 682 # path: the directory to use as the temporary current working directory. 683 684 # quiet: if False (the default), the context manager raises an exception 685 # on error. Otherwise, it issues only a warning and keeps the current 686 # working directory the same. 687 688 # """ 689 # saved_dir = os.getcwd() 690 # try: 691 # os.chdir(path) 692 # except OSError: 693 # if not quiet: 694 # raise 695 # warnings.warn('tests may fail, unable to change CWD to: ' + path, 696 # RuntimeWarning, stacklevel=3) 697 # try: 698 # yield os.getcwd() 699 # finally: 700 # os.chdir(saved_dir) 701 702 703 # @contextlib.contextmanager 704 # def temp_cwd(name='tempcwd', quiet=False): 705 # """ 706 # Context manager that creates a temporary directory and set it as CWD. 707 708 # The new CWD is created in the current directory and it's named *name*. 709 # If *quiet* is False (default) and it's not possible to create or change 710 # the CWD, an error is raised. If it's True, only a warning is raised 711 # and the original CWD is used. 712 # """ 713 # if (have_unicode and isinstance(name, unicode) and 714 # not os.path.supports_unicode_filenames): 715 # try: 716 # name = name.encode(sys.getfilesystemencoding() or 'ascii') 717 # except UnicodeEncodeError: 718 # if not quiet: 719 # raise unittest.SkipTest('unable to encode the cwd name with ' 720 # 'the filesystem encoding.') 721 # saved_dir = os.getcwd() 722 # is_temporary = False 723 # try: 724 # os.mkdir(name) 725 # os.chdir(name) 726 # is_temporary = True 727 # except OSError: 728 # if not quiet: 729 # raise 730 # warnings.warn('tests may fail, unable to change the CWD to ' + name, 731 # RuntimeWarning, stacklevel=3) 732 # try: 733 # yield os.getcwd() 734 # finally: 735 # os.chdir(saved_dir) 736 # if is_temporary: 737 # rmtree(name) 738 739 740 # def findfile(file, here=__file__, subdir=None): 741 # """Try to find a file on sys.path and the working directory. If it is not 742 # found the argument passed to the function is returned (this does not 743 # necessarily signal failure; could still be the legitimate path).""" 744 # if os.path.isabs(file): 745 # return file 746 # if subdir is not None: 747 # file = os.path.join(subdir, file) 748 # path = sys.path 749 # path = [os.path.dirname(here)] + path 750 # for dn in path: 751 # fn = os.path.join(dn, file) 752 # if os.path.exists(fn): return fn 753 # return file 754 755 # def sortdict(dict): 756 # "Like repr(dict), but in sorted order." 757 # items = dict.items() 758 # items.sort() 759 # reprpairs = ["%r: %r" % pair for pair in items] 760 # withcommas = ", ".join(reprpairs) 761 # return "{%s}" % withcommas 762 763 # def make_bad_fd(): 764 # """ 765 # Create an invalid file descriptor by opening and closing a file and return 766 # its fd. 767 # """ 768 # file = open(TESTFN, "wb") 769 # try: 770 # return file.fileno() 771 # finally: 772 # file.close() 773 # unlink(TESTFN) 774 775 # def check_syntax_error(testcase, statement): 776 # testcase.assertRaises(SyntaxError, compile, statement, 777 # '<test string>', 'exec') 778 779 # def open_urlresource(url, check=None): 780 # import urlparse, urllib2 781 782 # filename = urlparse.urlparse(url)[2].split('/')[-1] # '/': it's URL! 783 784 # fn = os.path.join(os.path.dirname(__file__), "data", filename) 785 786 # def check_valid_file(fn): 787 # f = open(fn) 788 # if check is None: 789 # return f 790 # elif check(f): 791 # f.seek(0) 792 # return f 793 # f.close() 794 795 # if os.path.exists(fn): 796 # f = check_valid_file(fn) 797 # if f is not None: 798 # return f 799 # unlink(fn) 800 801 # # Verify the requirement before downloading the file 802 # requires('urlfetch') 803 804 # print >> get_original_stdout(), '\tfetching %s ...' % url 805 # f = urllib2.urlopen(url, timeout=15) 806 # try: 807 # with open(fn, "wb") as out: 808 # s = f.read() 809 # while s: 810 # out.write(s) 811 # s = f.read() 812 # finally: 813 # f.close() 814 815 # f = check_valid_file(fn) 816 # if f is not None: 817 # return f 818 # raise TestFailed('invalid resource "%s"' % fn) 819 820 821 class WarningsRecorder(object): 822 """Convenience wrapper for the warnings list returned on 823 entry to the warnings.catch_warnings() context manager. 824 """ 825 def __init__(self, warnings_list): 826 self._warnings = warnings_list 827 self._last = 0 828 829 def __getattr__(self, attr): 830 if len(self._warnings) > self._last: 831 return getattr(self._warnings[-1], attr) 832 elif attr in warnings.WarningMessage._WARNING_DETAILS: 833 return None 834 raise AttributeError("%r has no attribute %r" % (self, attr)) 835 836 @property 837 def warnings(self): 838 return self._warnings[self._last:] 839 840 def reset(self): 841 self._last = len(self._warnings) 842 843 844 def _filterwarnings(filters, quiet=False): 845 """Catch the warnings, then check if all the expected 846 warnings have been raised and re-raise unexpected warnings. 847 If 'quiet' is True, only re-raise the unexpected warnings. 848 """ 849 # Clear the warning registry of the calling module 850 # in order to re-raise the warnings. 851 # frame = sys._getframe(2) 852 # registry = frame.f_globals.get('__warningregistry__') 853 # if registry: 854 # registry.clear() 855 with warnings.catch_warnings(record=True) as w: 856 # Set filter "always" to record all warnings. Because 857 # test_warnings swap the module, we need to look up in 858 # the sys.modules dictionary. 859 sys.modules['warnings'].simplefilter("always") 860 yield WarningsRecorder(w) 861 # Filter the recorded warnings 862 reraise = [warning.message for warning in w] 863 missing = [] 864 for msg, cat in filters: 865 seen = False 866 for exc in reraise[:]: 867 message = str(exc) 868 # Filter out the matching messages 869 if (re.match(msg, message, re.I) and 870 issubclass(exc.__class__, cat)): 871 seen = True 872 reraise.remove(exc) 873 if not seen and not quiet: 874 # This filter caught nothing 875 missing.append((msg, cat.__name__)) 876 if reraise: 877 raise AssertionError("unhandled warning %r" % reraise[0]) 878 if missing: 879 raise AssertionError("filter (%r, %s) did not catch any warning" % 880 missing[0]) 881 882 883 @contextlib.contextmanager 884 def check_warnings(*filters, **kwargs): 885 """Context manager to silence warnings. 886 887 Accept 2-tuples as positional arguments: 888 ("message regexp", WarningCategory) 889 890 Optional argument: 891 - if 'quiet' is True, it does not fail if a filter catches nothing 892 (default True without argument, 893 default False if some filters are defined) 894 895 Without argument, it defaults to: 896 check_warnings(("", Warning), quiet=True) 897 """ 898 quiet = kwargs.get('quiet') 899 if not filters: 900 filters = (("", Warning),) 901 # Preserve backward compatibility 902 if quiet is None: 903 quiet = True 904 return _filterwarnings(filters, quiet) 905 906 907 @contextlib.contextmanager 908 def check_py3k_warnings(*filters, **kwargs): 909 """Context manager to silence py3k warnings. 910 911 Accept 2-tuples as positional arguments: 912 ("message regexp", WarningCategory) 913 914 Optional argument: 915 - if 'quiet' is True, it does not fail if a filter catches nothing 916 (default False) 917 918 Without argument, it defaults to: 919 check_py3k_warnings(("", DeprecationWarning), quiet=False) 920 """ 921 if sys.py3kwarning: 922 if not filters: 923 filters = (("", DeprecationWarning),) 924 else: 925 # It should not raise any py3k warning 926 filters = () 927 return _filterwarnings(filters, kwargs.get('quiet')) 928 929 930 class CleanImport(object): 931 """Context manager to force import to return a new module reference. 932 933 This is useful for testing module-level behaviours, such as 934 the emission of a DeprecationWarning on import. 935 936 Use like this: 937 938 with CleanImport("foo"): 939 importlib.import_module("foo") # new reference 940 """ 941 942 def __init__(self, *module_names): 943 self.original_modules = sys.modules.copy() 944 for module_name in module_names: 945 if module_name in sys.modules: 946 module = sys.modules[module_name] 947 # It is possible that module_name is just an alias for 948 # another module (e.g. stub for modules renamed in 3.x). 949 # In that case, we also need delete the real module to clear 950 # the import cache. 951 if module.__name__ != module_name: 952 del sys.modules[module.__name__] 953 del sys.modules[module_name] 954 955 def __enter__(self): 956 return self 957 958 def __exit__(self, *ignore_exc): 959 sys.modules.update(self.original_modules) 960 961 962 class EnvironmentVarGuard(UserDict.DictMixin): 963 964 """Class to help protect the environment variable properly. Can be used as 965 a context manager.""" 966 967 def __init__(self): 968 self._environ = os.environ 969 self._changed = {} 970 971 def __getitem__(self, envvar): 972 return self._environ[envvar] 973 974 def __setitem__(self, envvar, value): 975 # Remember the initial value on the first access 976 if envvar not in self._changed: 977 self._changed[envvar] = self._environ.get(envvar) 978 self._environ[envvar] = value 979 980 def __delitem__(self, envvar): 981 # Remember the initial value on the first access 982 if envvar not in self._changed: 983 self._changed[envvar] = self._environ.get(envvar) 984 if envvar in self._environ: 985 del self._environ[envvar] 986 987 def keys(self): 988 return self._environ.keys() 989 990 def set(self, envvar, value): 991 self[envvar] = value 992 993 def unset(self, envvar): 994 del self[envvar] 995 996 def __enter__(self): 997 return self 998 999 def __exit__(self, *ignore_exc): 1000 for (k, v) in self._changed.items(): 1001 if v is None: 1002 if k in self._environ: 1003 del self._environ[k] 1004 else: 1005 self._environ[k] = v 1006 os.environ = self._environ 1007 1008 1009 # class DirsOnSysPath(object): 1010 # """Context manager to temporarily add directories to sys.path. 1011 1012 # This makes a copy of sys.path, appends any directories given 1013 # as positional arguments, then reverts sys.path to the copied 1014 # settings when the context ends. 1015 1016 # Note that *all* sys.path modifications in the body of the 1017 # context manager, including replacement of the object, 1018 # will be reverted at the end of the block. 1019 # """ 1020 1021 # def __init__(self, *paths): 1022 # self.original_value = sys.path[:] 1023 # self.original_object = sys.path 1024 # sys.path.extend(paths) 1025 1026 # def __enter__(self): 1027 # return self 1028 1029 # def __exit__(self, *ignore_exc): 1030 # sys.path = self.original_object 1031 # sys.path[:] = self.original_value 1032 1033 1034 # class TransientResource(object): 1035 1036 # """Raise ResourceDenied if an exception is raised while the context manager 1037 # is in effect that matches the specified exception and attributes.""" 1038 1039 # def __init__(self, exc, **kwargs): 1040 # self.exc = exc 1041 # self.attrs = kwargs 1042 1043 # def __enter__(self): 1044 # return self 1045 1046 # def __exit__(self, type_=None, value=None, traceback=None): 1047 # """If type_ is a subclass of self.exc and value has attributes matching 1048 # self.attrs, raise ResourceDenied. Otherwise let the exception 1049 # propagate (if any).""" 1050 # if type_ is not None and issubclass(self.exc, type_): 1051 # for attr, attr_value in self.attrs.iteritems(): 1052 # if not hasattr(value, attr): 1053 # break 1054 # if getattr(value, attr) != attr_value: 1055 # break 1056 # else: 1057 # raise ResourceDenied("an optional resource is not available") 1058 1059 1060 # @contextlib.contextmanager 1061 # def transient_internet(resource_name, timeout=30.0, errnos=()): 1062 # """Return a context manager that raises ResourceDenied when various issues 1063 # with the Internet connection manifest themselves as exceptions.""" 1064 # default_errnos = [ 1065 # ('ECONNREFUSED', 111), 1066 # ('ECONNRESET', 104), 1067 # ('EHOSTUNREACH', 113), 1068 # ('ENETUNREACH', 101), 1069 # ('ETIMEDOUT', 110), 1070 # ] 1071 # default_gai_errnos = [ 1072 # ('EAI_AGAIN', -3), 1073 # ('EAI_FAIL', -4), 1074 # ('EAI_NONAME', -2), 1075 # ('EAI_NODATA', -5), 1076 # # Windows defines EAI_NODATA as 11001 but idiotic getaddrinfo() 1077 # # implementation actually returns WSANO_DATA i.e. 11004. 1078 # ('WSANO_DATA', 11004), 1079 # ] 1080 1081 # denied = ResourceDenied("Resource '%s' is not available" % resource_name) 1082 # captured_errnos = errnos 1083 # gai_errnos = [] 1084 # if not captured_errnos: 1085 # captured_errnos = [getattr(errno, name, num) 1086 # for (name, num) in default_errnos] 1087 # gai_errnos = [getattr(socket, name, num) 1088 # for (name, num) in default_gai_errnos] 1089 1090 # def filter_error(err): 1091 # n = getattr(err, 'errno', None) 1092 # if (isinstance(err, socket.timeout) or 1093 # (isinstance(err, socket.gaierror) and n in gai_errnos) or 1094 # n in captured_errnos): 1095 # if not verbose: 1096 # sys.stderr.write(denied.args[0] + "\n") 1097 # raise denied 1098 1099 # old_timeout = socket.getdefaulttimeout() 1100 # try: 1101 # if timeout is not None: 1102 # socket.setdefaulttimeout(timeout) 1103 # yield 1104 # except IOError as err: 1105 # # urllib can wrap original socket errors multiple times (!), we must 1106 # # unwrap to get at the original error. 1107 # while True: 1108 # a = err.args 1109 # if len(a) >= 1 and isinstance(a[0], IOError): 1110 # err = a[0] 1111 # # The error can also be wrapped as args[1]: 1112 # # except socket.error as msg: 1113 # # raise IOError('socket error', msg).with_traceback(sys.exc_info()[2]) 1114 # elif len(a) >= 2 and isinstance(a[1], IOError): 1115 # err = a[1] 1116 # else: 1117 # break 1118 # filter_error(err) 1119 # raise 1120 # # XXX should we catch generic exceptions and look for their 1121 # # __cause__ or __context__? 1122 # finally: 1123 # socket.setdefaulttimeout(old_timeout) 1124 1125 1126 # @contextlib.contextmanager 1127 # def captured_output(stream_name): 1128 # """Return a context manager used by captured_stdout and captured_stdin 1129 # that temporarily replaces the sys stream *stream_name* with a StringIO.""" 1130 # import StringIO 1131 # orig_stdout = getattr(sys, stream_name) 1132 # setattr(sys, stream_name, StringIO.StringIO()) 1133 # try: 1134 # yield getattr(sys, stream_name) 1135 # finally: 1136 # setattr(sys, stream_name, orig_stdout) 1137 1138 # def captured_stdout(): 1139 # """Capture the output of sys.stdout: 1140 1141 # with captured_stdout() as s: 1142 # print "hello" 1143 # self.assertEqual(s.getvalue(), "hello") 1144 # """ 1145 # return captured_output("stdout") 1146 1147 # def captured_stderr(): 1148 # return captured_output("stderr") 1149 1150 # def captured_stdin(): 1151 # return captured_output("stdin") 1152 1153 # def gc_collect(): 1154 # """Force as many objects as possible to be collected. 1155 1156 # In non-CPython implementations of Python, this is needed because timely 1157 # deallocation is not guaranteed by the garbage collector. (Even in CPython 1158 # this can be the case in case of reference cycles.) This means that __del__ 1159 # methods may be called later than expected and weakrefs may remain alive for 1160 # longer than expected. This function tries its best to force all garbage 1161 # objects to disappear. 1162 # """ 1163 # gc.collect() 1164 # if is_jython: 1165 # time.sleep(0.1) 1166 # gc.collect() 1167 # gc.collect() 1168 1169 1170 # _header = '2P' 1171 # if hasattr(sys, "gettotalrefcount"): 1172 # _header = '2P' + _header 1173 # _vheader = _header + 'P' 1174 1175 # def calcobjsize(fmt): 1176 # return struct.calcsize(_header + fmt + '0P') 1177 1178 # def calcvobjsize(fmt): 1179 # return struct.calcsize(_vheader + fmt + '0P') 1180 1181 1182 # _TPFLAGS_HAVE_GC = 1<<14 1183 # _TPFLAGS_HEAPTYPE = 1<<9 1184 1185 # def check_sizeof(test, o, size): 1186 # import _testcapi 1187 # result = sys.getsizeof(o) 1188 # # add GC header size 1189 # if ((type(o) == type) and (o.__flags__ & _TPFLAGS_HEAPTYPE) or\ 1190 # ((type(o) != type) and (type(o).__flags__ & _TPFLAGS_HAVE_GC))): 1191 # size += _testcapi.SIZEOF_PYGC_HEAD 1192 # msg = 'wrong size for %s: got %d, expected %d' \ 1193 # % (type(o), result, size) 1194 # test.assertEqual(result, size, msg) 1195 1196 1197 # #======================================================================= 1198 # # Decorator for running a function in a different locale, correctly resetting 1199 # # it afterwards. 1200 1201 # def run_with_locale(catstr, *locales): 1202 # def decorator(func): 1203 # def inner(*args, **kwds): 1204 # try: 1205 # import locale 1206 # category = getattr(locale, catstr) 1207 # orig_locale = locale.setlocale(category) 1208 # except AttributeError: 1209 # # if the test author gives us an invalid category string 1210 # raise 1211 # except: 1212 # # cannot retrieve original locale, so do nothing 1213 # locale = orig_locale = None 1214 # else: 1215 # for loc in locales: 1216 # try: 1217 # locale.setlocale(category, loc) 1218 # break 1219 # except: 1220 # pass 1221 1222 # # now run the function, resetting the locale on exceptions 1223 # try: 1224 # return func(*args, **kwds) 1225 # finally: 1226 # if locale and orig_locale: 1227 # locale.setlocale(category, orig_locale) 1228 # inner.func_name = func.func_name 1229 # inner.__doc__ = func.__doc__ 1230 # return inner 1231 # return decorator 1232 1233 # #======================================================================= 1234 # # Decorator for running a function in a specific timezone, correctly 1235 # # resetting it afterwards. 1236 1237 # def run_with_tz(tz): 1238 # def decorator(func): 1239 # def inner(*args, **kwds): 1240 # try: 1241 # tzset = time.tzset 1242 # except AttributeError: 1243 # raise unittest.SkipTest("tzset required") 1244 # if 'TZ' in os.environ: 1245 # orig_tz = os.environ['TZ'] 1246 # else: 1247 # orig_tz = None 1248 # os.environ['TZ'] = tz 1249 # tzset() 1250 1251 # # now run the function, resetting the tz on exceptions 1252 # try: 1253 # return func(*args, **kwds) 1254 # finally: 1255 # if orig_tz is None: 1256 # del os.environ['TZ'] 1257 # else: 1258 # os.environ['TZ'] = orig_tz 1259 # time.tzset() 1260 1261 # inner.__name__ = func.__name__ 1262 # inner.__doc__ = func.__doc__ 1263 # return inner 1264 # return decorator 1265 1266 # #======================================================================= 1267 # # Big-memory-test support. Separate from 'resources' because memory use should be configurable. 1268 1269 # # Some handy shorthands. Note that these are used for byte-limits as well 1270 # # as size-limits, in the various bigmem tests 1271 # _1M = 1024*1024 1272 # _1G = 1024 * _1M 1273 # _2G = 2 * _1G 1274 # _4G = 4 * _1G 1275 1276 MAX_Py_ssize_t = sys.maxsize 1277 1278 # def set_memlimit(limit): 1279 # global max_memuse 1280 # global real_max_memuse 1281 # sizes = { 1282 # 'k': 1024, 1283 # 'm': _1M, 1284 # 'g': _1G, 1285 # 't': 1024*_1G, 1286 # } 1287 # m = re.match(r'(\d+(\.\d+)?) (K|M|G|T)b?$', limit, 1288 # re.IGNORECASE | re.VERBOSE) 1289 # if m is None: 1290 # raise ValueError('Invalid memory limit %r' % (limit,)) 1291 # memlimit = int(float(m.group(1)) * sizes[m.group(3).lower()]) 1292 # real_max_memuse = memlimit 1293 # if memlimit > MAX_Py_ssize_t: 1294 # memlimit = MAX_Py_ssize_t 1295 # if memlimit < _2G - 1: 1296 # raise ValueError('Memory limit %r too low to be useful' % (limit,)) 1297 # max_memuse = memlimit 1298 1299 # def bigmemtest(minsize, memuse, overhead=5*_1M): 1300 # """Decorator for bigmem tests. 1301 1302 # 'minsize' is the minimum useful size for the test (in arbitrary, 1303 # test-interpreted units.) 'memuse' is the number of 'bytes per size' for 1304 # the test, or a good estimate of it. 'overhead' specifies fixed overhead, 1305 # independent of the testsize, and defaults to 5Mb. 1306 1307 # The decorator tries to guess a good value for 'size' and passes it to 1308 # the decorated test function. If minsize * memuse is more than the 1309 # allowed memory use (as defined by max_memuse), the test is skipped. 1310 # Otherwise, minsize is adjusted upward to use up to max_memuse. 1311 # """ 1312 # def decorator(f): 1313 # def wrapper(self): 1314 # if not max_memuse: 1315 # # If max_memuse is 0 (the default), 1316 # # we still want to run the tests with size set to a few kb, 1317 # # to make sure they work. We still want to avoid using 1318 # # too much memory, though, but we do that noisily. 1319 # maxsize = 5147 1320 # self.assertFalse(maxsize * memuse + overhead > 20 * _1M) 1321 # else: 1322 # maxsize = int((max_memuse - overhead) / memuse) 1323 # if maxsize < minsize: 1324 # # Really ought to print 'test skipped' or something 1325 # if verbose: 1326 # sys.stderr.write("Skipping %s because of memory " 1327 # "constraint\n" % (f.__name__,)) 1328 # return 1329 # # Try to keep some breathing room in memory use 1330 # maxsize = max(maxsize - 50 * _1M, minsize) 1331 # return f(self, maxsize) 1332 # wrapper.minsize = minsize 1333 # wrapper.memuse = memuse 1334 # wrapper.overhead = overhead 1335 # return wrapper 1336 # return decorator 1337 1338 # def precisionbigmemtest(size, memuse, overhead=5*_1M, dry_run=True): 1339 # def decorator(f): 1340 # def wrapper(self): 1341 # if not real_max_memuse: 1342 # maxsize = 5147 1343 # else: 1344 # maxsize = size 1345 1346 # if ((real_max_memuse or not dry_run) 1347 # and real_max_memuse < maxsize * memuse): 1348 # if verbose: 1349 # sys.stderr.write("Skipping %s because of memory " 1350 # "constraint\n" % (f.__name__,)) 1351 # return 1352 1353 # return f(self, maxsize) 1354 # wrapper.size = size 1355 # wrapper.memuse = memuse 1356 # wrapper.overhead = overhead 1357 # return wrapper 1358 # return decorator 1359 1360 # def bigaddrspacetest(f): 1361 # """Decorator for tests that fill the address space.""" 1362 # def wrapper(self): 1363 # if max_memuse < MAX_Py_ssize_t: 1364 # if verbose: 1365 # sys.stderr.write("Skipping %s because of memory " 1366 # "constraint\n" % (f.__name__,)) 1367 # else: 1368 # return f(self) 1369 # return wrapper 1370 1371 #======================================================================= 1372 # unittest integration. 1373 1374 class BasicTestRunner(object): 1375 def run(self, test): 1376 result = unittest.TestResult() 1377 test(result) 1378 return result 1379 1380 def _id(obj): 1381 return obj 1382 1383 # def requires_resource(resource): 1384 # if resource == 'gui' and not _is_gui_available(): 1385 # return unittest.skip(_is_gui_available.reason) 1386 # if is_resource_enabled(resource): 1387 # return _id 1388 # else: 1389 # return unittest.skip("resource {0!r} is not enabled".format(resource)) 1390 1391 def cpython_only(test): 1392 return lambda *arg, **kw: None 1393 1394 # def cpython_only(test): 1395 # """ 1396 # Decorator for tests only applicable on CPython. 1397 # """ 1398 # return impl_detail(cpython=True)(test) 1399 1400 # def impl_detail(msg=None, **guards): 1401 # if check_impl_detail(**guards): 1402 # return _id 1403 # if msg is None: 1404 # guardnames, default = _parse_guards(guards) 1405 # if default: 1406 # msg = "implementation detail not available on {0}" 1407 # else: 1408 # msg = "implementation detail specific to {0}" 1409 # guardnames = sorted(guardnames.keys()) 1410 # msg = msg.format(' or '.join(guardnames)) 1411 # return unittest.skip(msg) 1412 1413 # def _parse_guards(guards): 1414 # # Returns a tuple ({platform_name: run_me}, default_value) 1415 # if not guards: 1416 # return ({'cpython': True}, False) 1417 # is_true = guards.values()[0] 1418 # assert guards.values() == [is_true] * len(guards) # all True or all False 1419 # return (guards, not is_true) 1420 1421 # # Use the following check to guard CPython's implementation-specific tests -- 1422 # # or to run them only on the implementation(s) guarded by the arguments. 1423 # def check_impl_detail(**guards): 1424 # """This function returns True or False depending on the host platform. 1425 # Examples: 1426 # if check_impl_detail(): # only on CPython (default) 1427 # if check_impl_detail(jython=True): # only on Jython 1428 # if check_impl_detail(cpython=False): # everywhere except on CPython 1429 # """ 1430 # guards, default = _parse_guards(guards) 1431 # return guards.get(platform.python_implementation().lower(), default) 1432 1433 1434 1435 def _run_suite(suite): 1436 """Run tests from a unittest.TestSuite-derived class.""" 1437 if verbose: 1438 runner = unittest.TextTestRunner(sys.stdout, verbosity=2) 1439 else: 1440 runner = BasicTestRunner() 1441 1442 result = runner.run(suite) 1443 if not result.wasSuccessful(): 1444 if len(result.errors) == 1 and not result.failures: 1445 err = result.errors[0][1] 1446 elif len(result.failures) == 1 and not result.errors: 1447 err = result.failures[0][1] 1448 else: 1449 err = "multiple errors occurred" 1450 if not verbose: 1451 err += "; run in verbose mode for details" 1452 raise TestFailed(err) 1453 1454 1455 def run_unittest(*classes): 1456 """Run tests from unittest.TestCase-derived classes.""" 1457 valid_types = (unittest.TestSuite, unittest.TestCase) 1458 suite = unittest.TestSuite() 1459 for cls in classes: 1460 if isinstance(cls, str): 1461 if cls in sys.modules: 1462 suite.addTest(unittest.findTestCases(sys.modules[cls])) 1463 else: 1464 raise ValueError("str arguments must be keys in sys.modules") 1465 elif isinstance(cls, valid_types): 1466 suite.addTest(cls) 1467 else: 1468 suite.addTest(unittest.makeSuite(cls)) 1469 _run_suite(suite) 1470 1471 # #======================================================================= 1472 # # Check for the presence of docstrings. 1473 1474 # HAVE_DOCSTRINGS = (check_impl_detail(cpython=False) or 1475 # sys.platform == 'win32' or 1476 # sysconfig.get_config_var('WITH_DOC_STRINGS')) 1477 1478 # requires_docstrings = unittest.skipUnless(HAVE_DOCSTRINGS, 1479 # "test requires docstrings") 1480 1481 1482 # #======================================================================= 1483 # # doctest driver. 1484 1485 # def run_doctest(module, verbosity=None): 1486 # """Run doctest on the given module. Return (#failures, #tests). 1487 1488 # If optional argument verbosity is not specified (or is None), pass 1489 # test_support's belief about verbosity on to doctest. Else doctest's 1490 # usual behavior is used (it searches sys.argv for -v). 1491 # """ 1492 1493 # import doctest 1494 1495 # if verbosity is None: 1496 # verbosity = verbose 1497 # else: 1498 # verbosity = None 1499 1500 # # Direct doctest output (normally just errors) to real stdout; doctest 1501 # # output shouldn't be compared by regrtest. 1502 # save_stdout = sys.stdout 1503 # sys.stdout = get_original_stdout() 1504 # try: 1505 # f, t = doctest.testmod(module, verbose=verbosity) 1506 # if f: 1507 # raise TestFailed("%d of %d doctests failed" % (f, t)) 1508 # finally: 1509 # sys.stdout = save_stdout 1510 # if verbose: 1511 # print 'doctest (%s) ... %d tests with zero failures' % (module.__name__, t) 1512 # return f, t 1513 1514 #======================================================================= 1515 # Threading support to prevent reporting refleaks when running regrtest.py -R 1516 1517 # NOTE: we use thread._count() rather than threading.enumerate() (or the 1518 # moral equivalent thereof) because a threading.Thread object is still alive 1519 # until its __bootstrap() method has returned, even after it has been 1520 # unregistered from the threading module. 1521 # thread._count(), on the other hand, only gets decremented *after* the 1522 # __bootstrap() method has returned, which gives us reliable reference counts 1523 # at the end of a test run. 1524 1525 def threading_setup(): 1526 if thread: 1527 return (thread._count(),) 1528 else: 1529 return (1,) 1530 1531 def threading_cleanup(nb_threads): 1532 if not thread: 1533 return 1534 1535 _MAX_COUNT = 10 1536 for count in range(_MAX_COUNT): 1537 n = thread._count() 1538 if n == nb_threads: 1539 break 1540 time.sleep(0.1) 1541 # XXX print a warning in case of failure? 1542 1543 # def reap_threads(func): 1544 # """Use this function when threads are being used. This will 1545 # ensure that the threads are cleaned up even when the test fails. 1546 # If threading is unavailable this function does nothing. 1547 # """ 1548 # if not thread: 1549 # return func 1550 1551 # @functools.wraps(func) 1552 # def decorator(*args): 1553 # key = threading_setup() 1554 # try: 1555 # return func(*args) 1556 # finally: 1557 # threading_cleanup(*key) 1558 # return decorator 1559 1560 def reap_children(): 1561 """Use this function at the end of test_main() whenever sub-processes 1562 are started. This will help ensure that no extra children (zombies) 1563 stick around to hog resources and create problems when looking 1564 for refleaks. 1565 """ 1566 1567 # Reap all our dead child processes so we don't leave zombies around. 1568 # These hog resources and might be causing some of the buildbots to die. 1569 if hasattr(os, 'waitpid'): 1570 any_process = -1 1571 while True: 1572 try: 1573 # This will raise an exception on Windows. That's ok. 1574 pid, status = os.waitpid(any_process, os.WNOHANG) 1575 if pid == 0: 1576 break 1577 except: 1578 break 1579 1580 # @contextlib.contextmanager 1581 # def start_threads(threads, unlock=None): 1582 # threads = list(threads) 1583 # started = [] 1584 # try: 1585 # try: 1586 # for t in threads: 1587 # t.start() 1588 # started.append(t) 1589 # except: 1590 # if verbose: 1591 # print("Can't start %d threads, only %d threads started" % 1592 # (len(threads), len(started))) 1593 # raise 1594 # yield 1595 # finally: 1596 # if unlock: 1597 # unlock() 1598 # endtime = starttime = time.time() 1599 # for timeout in range(1, 16): 1600 # endtime += 60 1601 # for t in started: 1602 # t.join(max(endtime - time.time(), 0.01)) 1603 # started = [t for t in started if t.isAlive()] 1604 # if not started: 1605 # break 1606 # if verbose: 1607 # print('Unable to join %d threads during a period of ' 1608 # '%d minutes' % (len(started), timeout)) 1609 # started = [t for t in started if t.isAlive()] 1610 # if started: 1611 # raise AssertionError('Unable to join %d threads' % len(started)) 1612 1613 # @contextlib.contextmanager 1614 # def swap_attr(obj, attr, new_val): 1615 # """Temporary swap out an attribute with a new object. 1616 1617 # Usage: 1618 # with swap_attr(obj, "attr", 5): 1619 # ... 1620 1621 # This will set obj.attr to 5 for the duration of the with: block, 1622 # restoring the old value at the end of the block. If `attr` doesn't 1623 # exist on `obj`, it will be created and then deleted at the end of the 1624 # block. 1625 # """ 1626 # if hasattr(obj, attr): 1627 # real_val = getattr(obj, attr) 1628 # setattr(obj, attr, new_val) 1629 # try: 1630 # yield 1631 # finally: 1632 # setattr(obj, attr, real_val) 1633 # else: 1634 # setattr(obj, attr, new_val) 1635 # try: 1636 # yield 1637 # finally: 1638 # delattr(obj, attr) 1639 1640 # def py3k_bytes(b): 1641 # """Emulate the py3k bytes() constructor. 1642 1643 # NOTE: This is only a best effort function. 1644 # """ 1645 # try: 1646 # # memoryview? 1647 # return b.tobytes() 1648 # except AttributeError: 1649 # try: 1650 # # iterable of ints? 1651 # return b"".join(chr(x) for x in b) 1652 # except TypeError: 1653 # return bytes(b) 1654 1655 # def args_from_interpreter_flags(): 1656 # """Return a list of command-line arguments reproducing the current 1657 # settings in sys.flags.""" 1658 # import subprocess 1659 # return subprocess._args_from_interpreter_flags() 1660 1661 # def strip_python_stderr(stderr): 1662 # """Strip the stderr of a Python process from potential debug output 1663 # emitted by the interpreter. 1664 1665 # This will typically be run on the result of the communicate() method 1666 # of a subprocess.Popen object. 1667 # """ 1668 # stderr = re.sub(br"\[\d+ refs\]\r?\n?$", b"", stderr).strip() 1669 # return stderr 1670 1671 1672 # def check_free_after_iterating(test, iter, cls, args=()): 1673 # class A(cls): 1674 # def __del__(self): 1675 # done[0] = True 1676 # try: 1677 # next(it) 1678 # except StopIteration: 1679 # pass 1680 1681 # done = [False] 1682 # it = iter(A(*args)) 1683 # # Issue 26494: Shouldn't crash 1684 # test.assertRaises(StopIteration, next, it) 1685 # # The sequence should be deallocated just after the end of iterating 1686 # gc_collect() 1687 # test.assertTrue(done[0])