Bump up test.support to CPython 3.8.2

This commit is contained in:
CPython dev authored and Jeong YunWon committed 2020-04-07 14:36:41 +09:00
1 parent f5de59a4bd
commit 40451bba6b
2 files changed
+358 -71

No files matched your search

+357 -70
View File
@@ -6,15 +6,16 @@ if __name__ != 'test.support':
# import asyncio.events
import collections.abc
import contextlib
import datetime
import errno
# import faulthandler
import fnmatch
import functools
# import gc
import glob
import hashlib
import importlib
import importlib.util
import io
import locale
# import logging.handlers
# import nntplib
import os
@@ -68,6 +69,11 @@ try:
except ImportError:
resource = None
try:
import _hashlib
except ImportError:
_hashlib = None
__all__ = [
# globals
"PIPE_MAX_SIZE", "verbose", "max_memuse", "use_resources", "failfast",
@@ -85,15 +91,15 @@ __all__ = [
"create_empty_file", "can_symlink", "fs_is_case_insensitive",
# unittest
"is_resource_enabled", "requires", "requires_freebsd_version",
"requires_linux_version", "requires_mac_ver", "check_syntax_error",
"check_syntax_warning",
"requires_linux_version", "requires_mac_ver", "requires_hashdigest",
"check_syntax_error", "check_syntax_warning",
"TransientResource", "time_out", "socket_peer_reset", "ioerror_peer_reset",
"transient_internet", "BasicTestRunner", "run_unittest", "run_doctest",
"skip_unless_symlink", "requires_gzip", "requires_bz2", "requires_lzma",
"bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute",
"requires_IEEE_754", "skip_unless_xattr", "requires_zlib",
"anticipate_failure", "load_package_tests", "detect_api_mismatch",
"check__all__", "skip_unless_bind_unix_socket",
"check__all__", "skip_unless_bind_unix_socket", "skip_if_buggy_ucrt_strfptime",
"ignore_warnings",
# sys
"is_jython", "is_android", "check_impl_detail", "unix_shell",
@@ -113,6 +119,7 @@ __all__ = [
"run_with_locale", "swap_item",
"swap_attr", "Matcher", "set_memlimit", "SuppressCrashReport", "sortdict",
"run_with_tz", "PGO", "missing_compiler_executable", "fd_count",
"ALWAYS_EQ", "LARGEST", "SMALLEST"
]
class Error(Exception):
@@ -645,6 +652,36 @@ def requires_mac_ver(*min_version):
return decorator
def requires_hashdigest(digestname, openssl=None):
"""Decorator raising SkipTest if a hashing algorithm is not available
The hashing algorithm could be missing or blocked by a strict crypto
policy.
If 'openssl' is True, then the decorator checks that OpenSSL provides
the algorithm. Otherwise the check falls back to built-in
implementations.
ValueError: [digital envelope routines: EVP_DigestInit_ex] disabled for FIPS
ValueError: unsupported hash type md4
"""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
try:
if openssl and _hashlib is not None:
_hashlib.new(digestname)
else:
hashlib.new(digestname)
except ValueError:
raise unittest.SkipTest(
f"hash digest '{digestname}' is not available."
)
return func(*args, **kwargs)
return wrapper
return decorator
HOST = "localhost"
HOSTv4 = "127.0.0.1"
HOSTv6 = "::1"
@@ -757,22 +794,22 @@ def bind_unix_socket(sock, addr):
sock.close()
raise unittest.SkipTest('cannot bind AF_UNIX sockets')
# def _is_ipv6_enabled():
# """Check whether IPv6 is enabled on this host."""
# if socket.has_ipv6:
# sock = None
# try:
# sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
# sock.bind((HOSTv6, 0))
# return True
# except OSError:
# pass
# finally:
# if sock:
# sock.close()
# return False
def _is_ipv6_enabled():
"""Check whether IPv6 is enabled on this host."""
if socket.has_ipv6:
sock = None
try:
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
sock.bind((HOSTv6, 0))
return True
except OSError:
pass
finally:
if sock:
sock.close()
return False
# IPV6_ENABLED = _is_ipv6_enabled()
IPV6_ENABLED = _is_ipv6_enabled()
def system_must_validate_cert(f):
"""Skip the test on TLS certificate validation failures."""
@@ -896,25 +933,25 @@ if sys.platform == 'darwin':
TESTFN_UNICODE = unicodedata.normalize('NFD', TESTFN_UNICODE)
TESTFN_ENCODING = sys.getfilesystemencoding()
# # TESTFN_UNENCODABLE is a filename (str type) that should *not* be able to be
# # encoded by the filesystem encoding (in strict mode). It can be None if we
# # cannot generate such filename.
# TESTFN_UNENCODABLE = None
# if os.name == 'nt':
# # skip win32s (0) or Windows 9x/ME (1)
# if sys.getwindowsversion().platform >= 2:
# # Different kinds of characters from various languages to minimize the
# # probability that the whole name is encodable to MBCS (issue #9819)
# TESTFN_UNENCODABLE = TESTFN + "-\u5171\u0141\u2661\u0363\uDC80"
# try:
# TESTFN_UNENCODABLE.encode(TESTFN_ENCODING)
# except UnicodeEncodeError:
# pass
# else:
# print('WARNING: The filename %r CAN be encoded by the filesystem encoding (%s). '
# 'Unicode filename tests may not be effective'
# % (TESTFN_UNENCODABLE, TESTFN_ENCODING))
# TESTFN_UNENCODABLE = None
# TESTFN_UNENCODABLE is a filename (str type) that should *not* be able to be
# encoded by the filesystem encoding (in strict mode). It can be None if we
# cannot generate such filename.
TESTFN_UNENCODABLE = None
if os.name == 'nt':
# skip win32s (0) or Windows 9x/ME (1)
if sys.getwindowsversion().platform >= 2:
# Different kinds of characters from various languages to minimize the
# probability that the whole name is encodable to MBCS (issue #9819)
TESTFN_UNENCODABLE = TESTFN + "-\u5171\u0141\u2661\u0363\uDC80"
try:
TESTFN_UNENCODABLE.encode(TESTFN_ENCODING)
except UnicodeEncodeError:
pass
else:
print('WARNING: The filename %r CAN be encoded by the filesystem encoding (%s). '
'Unicode filename tests may not be effective'
% (TESTFN_UNENCODABLE, TESTFN_ENCODING))
TESTFN_UNENCODABLE = None
# # Mac OS X denies unencodable filenames (invalid utf-8)
# elif sys.platform != 'darwin':
# try:
@@ -929,35 +966,35 @@ TESTFN_ENCODING = sys.getfilesystemencoding()
# # the byte 0xff. Skip some unicode filename tests.
# pass
# # TESTFN_UNDECODABLE is a filename (bytes type) that should *not* be able to be
# # decoded from the filesystem encoding (in strict mode). It can be None if we
# # cannot generate such filename (ex: the latin1 encoding can decode any byte
# # sequence). On UNIX, TESTFN_UNDECODABLE can be decoded by os.fsdecode() thanks
# # to the surrogateescape error handler (PEP 383), but not from the filesystem
# # encoding in strict mode.
# TESTFN_UNDECODABLE = None
# for name in (
# # b'\xff' is not decodable by os.fsdecode() with code page 932. Windows
# # accepts it to create a file or a directory, or don't accept to enter to
# # such directory (when the bytes name is used). So test b'\xe7' first: it is
# # not decodable from cp932.
# b'\xe7w\xf0',
# # undecodable from ASCII, UTF-8
# b'\xff',
# # undecodable from iso8859-3, iso8859-6, iso8859-7, cp424, iso8859-8, cp856
# # and cp857
# b'\xae\xd5'
# # undecodable from UTF-8 (UNIX and Mac OS X)
# b'\xed\xb2\x80', b'\xed\xb4\x80',
# # undecodable from shift_jis, cp869, cp874, cp932, cp1250, cp1251, cp1252,
# # cp1253, cp1254, cp1255, cp1257, cp1258
# b'\x81\x98',
# ):
# try:
# name.decode(TESTFN_ENCODING)
# except UnicodeDecodeError:
# TESTFN_UNDECODABLE = os.fsencode(TESTFN) + name
# break
# TESTFN_UNDECODABLE is a filename (bytes type) that should *not* be able to be
# decoded from the filesystem encoding (in strict mode). It can be None if we
# cannot generate such filename (ex: the latin1 encoding can decode any byte
# sequence). On UNIX, TESTFN_UNDECODABLE can be decoded by os.fsdecode() thanks
# to the surrogateescape error handler (PEP 383), but not from the filesystem
# encoding in strict mode.
TESTFN_UNDECODABLE = None
for name in (
# b'\xff' is not decodable by os.fsdecode() with code page 932. Windows
# accepts it to create a file or a directory, or don't accept to enter to
# such directory (when the bytes name is used). So test b'\xe7' first: it is
# not decodable from cp932.
b'\xe7w\xf0',
# undecodable from ASCII, UTF-8
b'\xff',
# undecodable from iso8859-3, iso8859-6, iso8859-7, cp424, iso8859-8, cp856
# and cp857
b'\xae\xd5'
# undecodable from UTF-8 (UNIX and Mac OS X)
b'\xed\xb2\x80', b'\xed\xb4\x80',
# undecodable from shift_jis, cp869, cp874, cp932, cp1250, cp1251, cp1252,
# cp1253, cp1254, cp1255, cp1257, cp1258
b'\x81\x98',
):
try:
name.decode(TESTFN_ENCODING)
except UnicodeDecodeError:
TESTFN_UNDECODABLE = os.fsencode(TESTFN) + name
break
if FS_NONASCII:
TESTFN_NONASCII = TESTFN + '-' + FS_NONASCII
@@ -971,6 +1008,10 @@ SAVEDCWD = os.getcwd()
# useful for PGO
PGO = False
# Set by libregrtest/main.py if we are running the extended (time consuming)
# PGO task. If this is True, PGO is also True.
PGO_EXTENDED = False
@contextlib.contextmanager
def temp_dir(path=None, quiet=False):
"""Return a context manager that creates a temporary directory.
@@ -1025,7 +1066,7 @@ def change_cwd(path, quiet=False):
"""
saved_dir = os.getcwd()
try:
os.chdir(path)
os.chdir(os.path.realpath(path))
except OSError as exc:
if not quiet:
raise
@@ -1490,6 +1531,11 @@ def get_socket_conn_refused_errs():
# bpo-31910: socket.create_connection() fails randomly
# with EADDRNOTAVAIL on Travis CI
errors.append(errno.EADDRNOTAVAIL)
if hasattr(errno, 'EHOSTUNREACH'):
# bpo-37583: The destination host cannot be reached
errors.append(errno.EHOSTUNREACH)
if not IPV6_ENABLED:
errors.append(errno.EAFNOSUPPORT)
return errors
@@ -2500,6 +2546,105 @@ def skip_unless_symlink(test):
msg = "Requires functional symlink implementation"
return test if ok else unittest.skip(msg)(test)
_buggy_ucrt = None
def skip_if_buggy_ucrt_strfptime(test):
"""
Skip decorator for tests that use buggy strptime/strftime
If the UCRT bugs are present time.localtime().tm_zone will be
an empty string, otherwise we assume the UCRT bugs are fixed
See bpo-37552 [Windows] strptime/strftime return invalid
results with UCRT version 17763.615
"""
global _buggy_ucrt
if _buggy_ucrt is None:
if(sys.platform == 'win32' and
locale.getdefaultlocale()[1] == 'cp65001' and
time.localtime().tm_zone == ''):
_buggy_ucrt = True
else:
_buggy_ucrt = False
return unittest.skip("buggy MSVC UCRT strptime/strftime")(test) if _buggy_ucrt else test
class PythonSymlink:
"""Creates a symlink for the current Python executable"""
def __init__(self, link=None):
self.link = link or os.path.abspath(TESTFN)
self._linked = []
self.real = os.path.realpath(sys.executable)
self._also_link = []
self._env = None
self._platform_specific()
def _platform_specific(self):
pass
if sys.platform == "win32":
def _platform_specific(self):
import _winapi
if os.path.lexists(self.real) and not os.path.exists(self.real):
# App symlink appears to not exist, but we want the
# real executable here anyway
self.real = _winapi.GetModuleFileName(0)
dll = _winapi.GetModuleFileName(sys.dllhandle)
src_dir = os.path.dirname(dll)
dest_dir = os.path.dirname(self.link)
self._also_link.append((
dll,
os.path.join(dest_dir, os.path.basename(dll))
))
for runtime in glob.glob(os.path.join(src_dir, "vcruntime*.dll")):
self._also_link.append((
runtime,
os.path.join(dest_dir, os.path.basename(runtime))
))
self._env = {k.upper(): os.getenv(k) for k in os.environ}
self._env["PYTHONHOME"] = os.path.dirname(self.real)
if sysconfig.is_python_build(True):
self._env["PYTHONPATH"] = os.path.dirname(os.__file__)
def __enter__(self):
os.symlink(self.real, self.link)
self._linked.append(self.link)
for real, link in self._also_link:
os.symlink(real, link)
self._linked.append(link)
return self
def __exit__(self, exc_type, exc_value, exc_tb):
for link in self._linked:
try:
os.remove(link)
except IOError as ex:
if verbose:
print("failed to clean up {}: {}".format(link, ex))
def _call(self, python, args, env, returncode):
cmd = [python, *args]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, env=env)
r = p.communicate()
if p.returncode != returncode:
if verbose:
print(repr(r[0]))
print(repr(r[1]), file=sys.stderr)
raise RuntimeError(
'unexpected return code: {0} (0x{0:08X})'.format(p.returncode))
return r
def call_real(self, *args, returncode=0):
return self._call(self.real, args, None, returncode)
def call_link(self, *args, returncode=0):
return self._call(self.link, args, self._env, returncode)
_can_xattr = None
def can_xattr():
global _can_xattr
@@ -2537,6 +2682,12 @@ def skip_unless_xattr(test):
msg = "no non-broken extended attribute support"
return test if ok else unittest.skip(msg)(test)
def skip_if_pgo_task(test):
"""Skip decorator for tests not run in (non-extended) PGO task"""
ok = not PGO or PGO_EXTENDED
msg = "Not run for (non-extended) PGO task"
return test if ok else unittest.skip(msg)(test)
_bind_nix_socket_error = None
def skip_unless_bind_unix_socket(test):
"""Decorator for tests requiring a functional bind() for unix sockets."""
@@ -2877,7 +3028,7 @@ def fd_count():
if sys.platform.startswith(('linux', 'freebsd')):
try:
names = os.listdir("/proc/self/fd")
# Substract one because listdir() opens internally a file
# Subtract one because listdir() internally opens a file
# descriptor to list the content of the /proc/self/fd/ directory.
return len(names) - 1
except FileNotFoundError:
@@ -2992,6 +3143,41 @@ class FakePath:
return self.path
class _ALWAYS_EQ:
"""
Object that is equal to anything.
"""
def __eq__(self, other):
return True
def __ne__(self, other):
return False
ALWAYS_EQ = _ALWAYS_EQ()
@functools.total_ordering
class _LARGEST:
"""
Object that is greater than anything (except itself).
"""
def __eq__(self, other):
return isinstance(other, _LARGEST)
def __lt__(self, other):
return False
LARGEST = _LARGEST()
@functools.total_ordering
class _SMALLEST:
"""
Object that is less than anything (except itself).
"""
def __eq__(self, other):
return isinstance(other, _SMALLEST)
def __gt__(self, other):
return False
SMALLEST = _SMALLEST()
def maybe_get_event_loop_policy():
"""Return the global event loop policy if one is set, else return None."""
return asyncio.events._event_loop_policy
@@ -3036,3 +3222,104 @@ def collision_stats(nbins, nballs):
collisions = k - occupied
var = dn*(dn-1)*((dn-2)/dn)**k + meanempty * (1 - meanempty)
return float(collisions), float(var.sqrt())
class catch_unraisable_exception:
"""
Context manager catching unraisable exception using sys.unraisablehook.
Storing the exception value (cm.unraisable.exc_value) creates a reference
cycle. The reference cycle is broken explicitly when the context manager
exits.
Storing the object (cm.unraisable.object) can resurrect it if it is set to
an object which is being finalized. Exiting the context manager clears the
stored object.
Usage:
with support.catch_unraisable_exception() as cm:
# code creating an "unraisable exception"
...
# check the unraisable exception: use cm.unraisable
...
# cm.unraisable attribute no longer exists at this point
# (to break a reference cycle)
"""
def __init__(self):
self.unraisable = None
self._old_hook = None
def _hook(self, unraisable):
# Storing unraisable.object can resurrect an object which is being
# finalized. Storing unraisable.exc_value creates a reference cycle.
self.unraisable = unraisable
def __enter__(self):
self._old_hook = sys.unraisablehook
sys.unraisablehook = self._hook
return self
def __exit__(self, *exc_info):
sys.unraisablehook = self._old_hook
del self.unraisable
class catch_threading_exception:
"""
Context manager catching threading.Thread exception using
threading.excepthook.
Attributes set when an exception is catched:
* exc_type
* exc_value
* exc_traceback
* thread
See threading.excepthook() documentation for these attributes.
These attributes are deleted at the context manager exit.
Usage:
with support.catch_threading_exception() as cm:
# code spawning a thread which raises an exception
...
# check the thread exception, use cm attributes:
# exc_type, exc_value, exc_traceback, thread
...
# exc_type, exc_value, exc_traceback, thread attributes of cm no longer
# exists at this point
# (to avoid reference cycles)
"""
def __init__(self):
self.exc_type = None
self.exc_value = None
self.exc_traceback = None
self.thread = None
self._old_hook = None
def _hook(self, args):
self.exc_type = args.exc_type
self.exc_value = args.exc_value
self.exc_traceback = args.exc_traceback
self.thread = args.thread
def __enter__(self):
self._old_hook = threading.excepthook
threading.excepthook = self._hook
return self
def __exit__(self, *exc_info):
threading.excepthook = self._old_hook
del self.exc_type
del self.exc_value
del self.exc_traceback
del self.thread
+1 -1
View File
@@ -59,7 +59,7 @@ class RegressionTestResult(unittest.TextTestResult):
e.set('result', args.pop('result', 'completed'))
if self.__start_time:
# e.set('time', f'{time.perf_counter() - self.__start_time:0.6f}')
e.set('time', f'{time.time() - self.__start_time}')
e.set('time', f'{time.time() - self.__start_time:0.6f}')
if capture:
if self._stdout_buffer is not None: