diff --git a/etc/gdbinit b/etc/gdbinit index aa5636d4ef5..14e9c83122d 100644 --- a/etc/gdbinit +++ b/etc/gdbinit @@ -1,6 +1,6 @@ python import sys -sys.path.insert(0, sys.path[0] + '/../../gcc-11.3.0/python') +sys.path.insert(0, sys.path[0] + '/../../gcc-13.2.0/python') from libstdcxx.v6.printers import register_libstdcxx_printers register_libstdcxx_printers (None) end \ No newline at end of file diff --git a/mingw32/bin/libpython3.11.dll b/mingw32/bin/libpython3.11.dll index 082af455cb0..d608ab1c2a7 100644 Binary files a/mingw32/bin/libpython3.11.dll and b/mingw32/bin/libpython3.11.dll differ diff --git a/mingw32/bin/libpython3.dll b/mingw32/bin/libpython3.dll index 4b63ee07b23..e22ed6a1736 100644 Binary files a/mingw32/bin/libpython3.dll and b/mingw32/bin/libpython3.dll differ diff --git a/mingw32/bin/python.exe b/mingw32/bin/python.exe index e4a0958227a..af124cc4469 100644 Binary files a/mingw32/bin/python.exe and b/mingw32/bin/python.exe differ diff --git a/mingw32/bin/python3.11.exe b/mingw32/bin/python3.11.exe index e4a0958227a..af124cc4469 100644 Binary files a/mingw32/bin/python3.11.exe and b/mingw32/bin/python3.11.exe differ diff --git a/mingw32/bin/python3.exe b/mingw32/bin/python3.exe index e4a0958227a..af124cc4469 100644 Binary files a/mingw32/bin/python3.exe and b/mingw32/bin/python3.exe differ diff --git a/mingw32/bin/python3w.exe b/mingw32/bin/python3w.exe index fdfb27faafd..f2d5b8d804e 100644 Binary files a/mingw32/bin/python3w.exe and b/mingw32/bin/python3w.exe differ diff --git a/mingw32/bin/pythonw.exe b/mingw32/bin/pythonw.exe index fdfb27faafd..f2d5b8d804e 100644 Binary files a/mingw32/bin/pythonw.exe and b/mingw32/bin/pythonw.exe differ diff --git a/mingw32/include/python3.11/internal/pycore_pystate.h b/mingw32/include/python3.11/internal/pycore_pystate.h index cb8f115768a..7c5aba12d52 100644 --- a/mingw32/include/python3.11/internal/pycore_pystate.h +++ b/mingw32/include/python3.11/internal/pycore_pystate.h @@ -61,6 +61,12 @@ _Py_ThreadCanHandlePendingCalls(void) } +#ifndef NDEBUG +extern int _PyThreadState_CheckConsistency(PyThreadState *tstate); +#endif + +int _PyThreadState_MustExit(PyThreadState *tstate); + /* Variable and macro for in-line access to current thread and interpreter state */ diff --git a/mingw32/include/python3.11/patchlevel.h b/mingw32/include/python3.11/patchlevel.h index 7023a3f6c36..70d71c11377 100644 --- a/mingw32/include/python3.11/patchlevel.h +++ b/mingw32/include/python3.11/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 11 -#define PY_MICRO_VERSION 5 +#define PY_MICRO_VERSION 6 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.11.5" +#define PY_VERSION "3.11.6" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/mingw32/include/python3.11/pyport.h b/mingw32/include/python3.11/pyport.h index b816c90e038..9bbdbc92fdf 100644 --- a/mingw32/include/python3.11/pyport.h +++ b/mingw32/include/python3.11/pyport.h @@ -454,11 +454,6 @@ Please be conservative with adding new ones, document them and enclose them in platform-specific #ifdefs. **************************************************************************/ -#ifdef SOLARIS -/* Unchecked */ -extern int gethostname(char *, int); -#endif - #ifdef HAVE__GETPTY #include /* we need to import mode_t */ extern char * _getpty(int *, int, mode_t, int); diff --git a/mingw32/lib/python3.11/Tools/scripts/freeze_modules.py b/mingw32/lib/python3.11/Tools/scripts/freeze_modules.py index dd208c78471..0e41d96d462 100644 --- a/mingw32/lib/python3.11/Tools/scripts/freeze_modules.py +++ b/mingw32/lib/python3.11/Tools/scripts/freeze_modules.py @@ -581,7 +581,7 @@ def regen_makefile(modules): pyfiles = [] frozenfiles = [] rules = [''] - deepfreezerules = ["Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS)", + deepfreezerules = ["$(DEEPFREEZE_C): $(DEEPFREEZE_DEPS)", "\t$(PYTHON_FOR_FREEZE) $(srcdir)/Tools/scripts/deepfreeze.py \\"] for src in _iter_sources(modules): frozen_header = relpath_for_posix_display(src.frozenfile, ROOT_DIR) diff --git a/mingw32/lib/python3.11/Tools/scripts/patchcheck.py b/mingw32/lib/python3.11/Tools/scripts/patchcheck.py index a324eafc52b..c2dceea2a2c 100644 --- a/mingw32/lib/python3.11/Tools/scripts/patchcheck.py +++ b/mingw32/lib/python3.11/Tools/scripts/patchcheck.py @@ -11,6 +11,13 @@ import untabify +def get_python_source_dir(): + src_dir = sysconfig.get_config_var('abs_srcdir') + if not src_dir: + src_dir = sysconfig.get_config_var('srcdir') + return os.path.abspath(src_dir) + + # Excluded directories which are copies of external libraries: # don't check their coding style EXCLUDE_DIRS = [os.path.join('Modules', '_ctypes', 'libffi_osx'), @@ -18,7 +25,7 @@ os.path.join('Modules', '_decimal', 'libmpdec'), os.path.join('Modules', 'expat'), os.path.join('Modules', 'zlib')] -SRCDIR = sysconfig.get_config_var('srcdir') +SRCDIR = get_python_source_dir() def n_files_str(count): diff --git a/mingw32/lib/python3.11/Tools/scripts/verify_ensurepip_wheels.py b/mingw32/lib/python3.11/Tools/scripts/verify_ensurepip_wheels.py index 044d1fd6b3c..434a0b4c538 100644 --- a/mingw32/lib/python3.11/Tools/scripts/verify_ensurepip_wheels.py +++ b/mingw32/lib/python3.11/Tools/scripts/verify_ensurepip_wheels.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python3 +#!/usr/bin/env python3 """ Compare checksums for wheels in :mod:`ensurepip` against the Cheeseshop. @@ -35,11 +35,17 @@ def print_error(file_path: str, message: str) -> None: def verify_wheel(package_name: str) -> bool: # Find the package on disk - package_path = next(WHEEL_DIR.glob(f"{package_name}*.whl"), None) - if not package_path: - print_error("", f"Could not find a {package_name} wheel on disk.") + package_paths = list(WHEEL_DIR.glob(f"{package_name}*.whl")) + if len(package_paths) != 1: + if package_paths: + for p in package_paths: + print_error(p, f"Found more than one wheel for package {package_name}.") + else: + print_error("", f"Could not find a {package_name} wheel on disk.") return False + package_path = package_paths[0] + print(f"Verifying checksum for {package_path}.") # Find the version of the package used by ensurepip diff --git a/mingw32/lib/python3.11/_sysconfigdata__win32_.py b/mingw32/lib/python3.11/_sysconfigdata__win32_.py index 23c58b2b769..6b63ef956d7 100644 --- a/mingw32/lib/python3.11/_sysconfigdata__win32_.py +++ b/mingw32/lib/python3.11/_sysconfigdata__win32_.py @@ -47,7 +47,7 @@ '-fvisibility=hidden -D_WIN32_WINNT=0x0602 ' '-DPY3_DLLNAME=\'L"libpython3.11.dll"\' ' '-DMS_DLL_ID=\'"3.11-32"\'', - 'CONFIGURE_CPPFLAGS': '-I../Python-3.11.5/PC -D__USE_MINGW_ANSI_STDIO=1 -I.', + 'CONFIGURE_CPPFLAGS': '-I../Python-3.11.6/PC -D__USE_MINGW_ANSI_STDIO=1 -I.', 'CONFIGURE_LDFLAGS': '-pipe -Wl,--no-seh -Wl,--large-address-aware ' '-Wl,--large-address-aware', 'CONFIGURE_LDFLAGS_NODIST': '-fno-semantic-interposition', @@ -75,15 +75,16 @@ 'COVERAGE_REPORT_OPTIONS': '--rc lcov_branch_coverage=1 --branch-coverage ' '--title "CPython 3.11 LCOV report [commit $(shell ' ')]"', - 'CPPFLAGS': '-IObjects -IInclude -IPython -I. -I../Python-3.11.5/Include ' - '-I../Python-3.11.5/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' + 'CPPFLAGS': '-IObjects -IInclude -IPython -I. -I../Python-3.11.6/Include ' + '-I../Python-3.11.6/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' '-D__USE_MINGW_ANSI_STDIO=1', 'CXX': 'g++', 'DECIMAL_CFLAGS': '-DCONFIG_32=1 -DANSI=1', 'DECIMAL_LDFLAGS': '-lmpdec', - 'DEEPFREEZE_DEPS': '../Python-3.11.5/Tools/scripts/deepfreeze.py ' + 'DEEPFREEZE_C': 'Python/deepfreeze/deepfreeze.c', + 'DEEPFREEZE_DEPS': '../Python-3.11.6/Tools/scripts/deepfreeze.py ' '_bootstrap_python ' - '../Python-3.11.5/Programs/_freeze_module.py \\', + '../Python-3.11.6/Programs/_freeze_module.py \\', 'DEEPFREEZE_OBJS': 'Python/deepfreeze/deepfreeze.o', 'DESTDIR': '', 'DESTDIRFINAL': '/', @@ -123,11 +124,11 @@ 'FILEMODE': 644, 'FLOAT_WORDS_BIGENDIAN': 0, 'FREEZE_MODULE': './_bootstrap_python ' - '../Python-3.11.5/Programs/_freeze_module.py', + '../Python-3.11.6/Programs/_freeze_module.py', 'FREEZE_MODULE_BOOTSTRAP': './Programs/_freeze_module', 'FREEZE_MODULE_BOOTSTRAP_DEPS': 'Programs/_freeze_module', 'FREEZE_MODULE_DEPS': '_bootstrap_python ' - '../Python-3.11.5/Programs/_freeze_module.py', + '../Python-3.11.6/Programs/_freeze_module.py', 'FROZEN_FILES_IN': '\\', 'FROZEN_FILES_OUT': '\\', 'GETPGRP_HAVE_ARG': 0, @@ -653,9 +654,9 @@ '-fvisibility=hidden -D_WIN32_WINNT=0x0602 ' '-DPY3_DLLNAME=\'L"libpython3.11.dll"\' ' '-DMS_DLL_ID=\'"3.11-32"\' -fprofile-use ' - '-fprofile-correction -I../Python-3.11.5/Include/internal ' + '-fprofile-correction -I../Python-3.11.6/Include/internal ' '-IObjects -IInclude -IPython -I. ' - '-I../Python-3.11.5/Include -I../Python-3.11.5/PC ' + '-I../Python-3.11.6/Include -I../Python-3.11.6/PC ' '-D__USE_MINGW_ANSI_STDIO=1 -I. -D__USE_MINGW_ANSI_STDIO=1', 'LIBEXPAT_HEADERS': '\\', 'LIBEXPAT_OBJS': '\\', @@ -672,9 +673,9 @@ '-D_WIN32_WINNT=0x0602 ' '-DPY3_DLLNAME=\'L"libpython3.11.dll"\' ' '-DMS_DLL_ID=\'"3.11-32"\' -fprofile-use ' - '-fprofile-correction -I../Python-3.11.5/Include/internal ' + '-fprofile-correction -I../Python-3.11.6/Include/internal ' '-IObjects -IInclude -IPython -I. ' - '-I../Python-3.11.5/Include -I../Python-3.11.5/PC ' + '-I../Python-3.11.6/Include -I../Python-3.11.6/PC ' '-D__USE_MINGW_ANSI_STDIO=1 -I. -D__USE_MINGW_ANSI_STDIO=1', 'LIBMPDEC_HEADERS': '\\', 'LIBMPDEC_OBJS': '\\', @@ -707,7 +708,7 @@ 'MAINCC': 'gcc', 'MAJOR_IN_MKDEV': 0, 'MAJOR_IN_SYSMACROS': 0, - 'MAKESETUP': '../Python-3.11.5/Modules/makesetup', + 'MAKESETUP': '../Python-3.11.6/Modules/makesetup', 'MANDIR': '/mingw32/share/man', 'MKDIR_P': '/usr/bin/mkdir -p', 'MODBUILT_NAMES': 'atexit faulthandler nt _signal _tracemalloc _codecs ' @@ -738,7 +739,7 @@ 'MODULE_BINASCII_CFLAGS': '-DUSE_ZLIB_CRC32', 'MODULE_BINASCII_LDFLAGS': '-lz', 'MODULE_BINASCII_STATE': 'yes', - 'MODULE_CMATH_DEPS': '../Python-3.11.5/Modules/_math.h', + 'MODULE_CMATH_DEPS': '../Python-3.11.6/Modules/_math.h', 'MODULE_CMATH_LDFLAGS': '-lm', 'MODULE_CMATH_STATE': 'yes', 'MODULE_ERRNO_LDFLAGS': '', @@ -746,7 +747,7 @@ 'MODULE_FCNTL_STATE': 'missing', 'MODULE_GRP_STATE': 'missing', 'MODULE_ITERTOOLS_LDFLAGS': '', - 'MODULE_MATH_DEPS': '../Python-3.11.5/Modules/_math.h', + 'MODULE_MATH_DEPS': '../Python-3.11.6/Modules/_math.h', 'MODULE_MATH_LDFLAGS': '-lm', 'MODULE_MATH_STATE': 'yes', 'MODULE_MMAP_STATE': 'yes', @@ -767,8 +768,8 @@ 'MODULE_TERMIOS_STATE': 'missing', 'MODULE_TIME_LDFLAGS': '', 'MODULE_TIME_STATE': 'yes', - 'MODULE_UNICODEDATA_DEPS': '../Python-3.11.5/Modules/unicodedata_db.h ' - '../Python-3.11.5/Modules/unicodename_db.h', + 'MODULE_UNICODEDATA_DEPS': '../Python-3.11.6/Modules/unicodedata_db.h ' + '../Python-3.11.6/Modules/unicodename_db.h', 'MODULE_UNICODEDATA_STATE': 'yes', 'MODULE_WINREG_LDFLAGS': '', 'MODULE_WINSOUND_LDFLAGS': '-lwinmm', @@ -783,22 +784,22 @@ 'MODULE__ASYNCIO_STATE': 'yes', 'MODULE__BISECT_STATE': 'yes', 'MODULE__BLAKE2_CFLAGS': '', - 'MODULE__BLAKE2_DEPS': '../Python-3.11.5/Modules/_blake2/impl/blake2-config.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2-impl.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2b-load-sse2.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2b-load-sse41.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2b-ref.c ' - '../Python-3.11.5/Modules/_blake2/impl/blake2b-round.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2b.c ' - '../Python-3.11.5/Modules/_blake2/impl/blake2s-load-sse2.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2s-load-sse41.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2s-load-xop.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2s-ref.c ' - '../Python-3.11.5/Modules/_blake2/impl/blake2s-round.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2s.c ' - '../Python-3.11.5/Modules/_blake2/blake2module.h ' - '../Python-3.11.5/Modules/hashlib.h', + 'MODULE__BLAKE2_DEPS': '../Python-3.11.6/Modules/_blake2/impl/blake2-config.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2-impl.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2b-load-sse2.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2b-load-sse41.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2b-ref.c ' + '../Python-3.11.6/Modules/_blake2/impl/blake2b-round.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2b.c ' + '../Python-3.11.6/Modules/_blake2/impl/blake2s-load-sse2.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2s-load-sse41.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2s-load-xop.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2s-ref.c ' + '../Python-3.11.6/Modules/_blake2/impl/blake2s-round.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2s.c ' + '../Python-3.11.6/Modules/_blake2/blake2module.h ' + '../Python-3.11.6/Modules/hashlib.h', 'MODULE__BLAKE2_LDFLAGS': '', 'MODULE__BLAKE2_STATE': 'yes', 'MODULE__BZ2_CFLAGS': '', @@ -815,27 +816,27 @@ 'MODULE__CONTEXTVARS_STATE': 'yes', 'MODULE__CRYPT_STATE': 'missing', 'MODULE__CSV_STATE': 'yes', - 'MODULE__CTYPES_DEPS': '../Python-3.11.5/Modules/_ctypes/ctypes.h', + 'MODULE__CTYPES_DEPS': '../Python-3.11.6/Modules/_ctypes/ctypes.h', 'MODULE__CTYPES_TEST_LDFLAGS': '-lm', 'MODULE__CTYPES_TEST_STATE': 'yes', 'MODULE__DATETIME_LDFLAGS': '-lm', 'MODULE__DATETIME_STATE': 'yes', 'MODULE__DECIMAL_CFLAGS': '-DCONFIG_32=1 -DANSI=1', - 'MODULE__DECIMAL_DEPS': '../Python-3.11.5/Modules/_decimal/docstrings.h', + 'MODULE__DECIMAL_DEPS': '../Python-3.11.6/Modules/_decimal/docstrings.h', 'MODULE__DECIMAL_LDFLAGS': '-lmpdec', 'MODULE__DECIMAL_STATE': 'yes', 'MODULE__ELEMENTTREE_CFLAGS': '', - 'MODULE__ELEMENTTREE_DEPS': '../Python-3.11.5/Modules/pyexpat.c', + 'MODULE__ELEMENTTREE_DEPS': '../Python-3.11.6/Modules/pyexpat.c', 'MODULE__ELEMENTTREE_STATE': 'yes', 'MODULE__FUNCTOOLS_LDFLAGS': '', 'MODULE__GDBM_STATE': 'missing', 'MODULE__HASHLIB_CFLAGS': '', - 'MODULE__HASHLIB_DEPS': '../Python-3.11.5/Modules/hashlib.h', + 'MODULE__HASHLIB_DEPS': '../Python-3.11.6/Modules/hashlib.h', 'MODULE__HASHLIB_LDFLAGS': '-lcrypto', 'MODULE__HASHLIB_STATE': 'yes', 'MODULE__HEAPQ_STATE': 'yes', - 'MODULE__IO_CFLAGS': '-I../Python-3.11.5/Modules/_io', - 'MODULE__IO_DEPS': '../Python-3.11.5/Modules/_io/_iomodule.h', + 'MODULE__IO_CFLAGS': '-I../Python-3.11.6/Modules/_io', + 'MODULE__IO_DEPS': '../Python-3.11.6/Modules/_io/_iomodule.h', 'MODULE__IO_LDFLAGS': '', 'MODULE__IO_STATE': 'yes', 'MODULE__JSON_STATE': 'yes', @@ -844,12 +845,12 @@ 'MODULE__LZMA_CFLAGS': '', 'MODULE__LZMA_LDFLAGS': '-llzma', 'MODULE__LZMA_STATE': 'yes', - 'MODULE__MD5_DEPS': '../Python-3.11.5/Modules/hashlib.h', + 'MODULE__MD5_DEPS': '../Python-3.11.6/Modules/hashlib.h', 'MODULE__MD5_STATE': 'yes', 'MODULE__MSI_LDFLAGS': '-lmsi -lcabinet -lrpcrt4', 'MODULE__MSI_STATE': 'yes', 'MODULE__MULTIBYTECODEC_STATE': 'yes', - 'MODULE__MULTIPROCESSING_CFLAGS': '-I../Python-3.11.5/Modules/_multiprocessing', + 'MODULE__MULTIPROCESSING_CFLAGS': '-I../Python-3.11.6/Modules/_multiprocessing', 'MODULE__MULTIPROCESSING_STATE': 'yes', 'MODULE__OPCODE_STATE': 'yes', 'MODULE__OPERATOR_LDFLAGS': '', @@ -861,42 +862,42 @@ 'MODULE__QUEUE_STATE': 'yes', 'MODULE__RANDOM_STATE': 'yes', 'MODULE__SCPROXY_STATE': 'n/a', - 'MODULE__SHA1_DEPS': '../Python-3.11.5/Modules/hashlib.h', + 'MODULE__SHA1_DEPS': '../Python-3.11.6/Modules/hashlib.h', 'MODULE__SHA1_STATE': 'yes', - 'MODULE__SHA256_DEPS': '../Python-3.11.5/Modules/hashlib.h', + 'MODULE__SHA256_DEPS': '../Python-3.11.6/Modules/hashlib.h', 'MODULE__SHA256_STATE': 'yes', - 'MODULE__SHA3_DEPS': '../Python-3.11.5/Modules/_sha3/sha3.c ' - '../Python-3.11.5/Modules/_sha3/sha3.h ' - '../Python-3.11.5/Modules/hashlib.h', + 'MODULE__SHA3_DEPS': '../Python-3.11.6/Modules/_sha3/sha3.c ' + '../Python-3.11.6/Modules/_sha3/sha3.h ' + '../Python-3.11.6/Modules/hashlib.h', 'MODULE__SHA3_STATE': 'yes', - 'MODULE__SHA512_DEPS': '../Python-3.11.5/Modules/hashlib.h', + 'MODULE__SHA512_DEPS': '../Python-3.11.6/Modules/hashlib.h', 'MODULE__SHA512_STATE': 'yes', - 'MODULE__SOCKET_DEPS': '../Python-3.11.5/Modules/socketmodule.h ' - '../Python-3.11.5/Modules/addrinfo.h ' - '../Python-3.11.5/Modules/getaddrinfo.c ' - '../Python-3.11.5/Modules/getnameinfo.c', + 'MODULE__SOCKET_DEPS': '../Python-3.11.6/Modules/socketmodule.h ' + '../Python-3.11.6/Modules/addrinfo.h ' + '../Python-3.11.6/Modules/getaddrinfo.c ' + '../Python-3.11.6/Modules/getnameinfo.c', 'MODULE__SOCKET_LDFLAGS': '', 'MODULE__SOCKET_STATE': 'yes', - 'MODULE__SQLITE3_CFLAGS': '-I../Python-3.11.5/Modules/_sqlite', - 'MODULE__SQLITE3_DEPS': '../Python-3.11.5/Modules/_sqlite/connection.h ' - '../Python-3.11.5/Modules/_sqlite/cursor.h ' - '../Python-3.11.5/Modules/_sqlite/microprotocols.h ' - '../Python-3.11.5/Modules/_sqlite/module.h ' - '../Python-3.11.5/Modules/_sqlite/prepare_protocol.h ' - '../Python-3.11.5/Modules/_sqlite/row.h ' - '../Python-3.11.5/Modules/_sqlite/util.h', + 'MODULE__SQLITE3_CFLAGS': '-I../Python-3.11.6/Modules/_sqlite', + 'MODULE__SQLITE3_DEPS': '../Python-3.11.6/Modules/_sqlite/connection.h ' + '../Python-3.11.6/Modules/_sqlite/cursor.h ' + '../Python-3.11.6/Modules/_sqlite/microprotocols.h ' + '../Python-3.11.6/Modules/_sqlite/module.h ' + '../Python-3.11.6/Modules/_sqlite/prepare_protocol.h ' + '../Python-3.11.6/Modules/_sqlite/row.h ' + '../Python-3.11.6/Modules/_sqlite/util.h', 'MODULE__SQLITE3_LDFLAGS': '-lsqlite3', 'MODULE__SQLITE3_STATE': 'yes', 'MODULE__SRE_LDFLAGS': '', 'MODULE__SSL_CFLAGS': '', - 'MODULE__SSL_DEPS': '../Python-3.11.5/Modules/_ssl.h ' - '../Python-3.11.5/Modules/_ssl/cert.c ' - '../Python-3.11.5/Modules/_ssl/debughelpers.c ' - '../Python-3.11.5/Modules/_ssl/misc.c ' - '../Python-3.11.5/Modules/_ssl_data.h ' - '../Python-3.11.5/Modules/_ssl_data_111.h ' - '../Python-3.11.5/Modules/_ssl_data_300.h ' - '../Python-3.11.5/Modules/socketmodule.h', + 'MODULE__SSL_DEPS': '../Python-3.11.6/Modules/_ssl.h ' + '../Python-3.11.6/Modules/_ssl/cert.c ' + '../Python-3.11.6/Modules/_ssl/debughelpers.c ' + '../Python-3.11.6/Modules/_ssl/misc.c ' + '../Python-3.11.6/Modules/_ssl_data.h ' + '../Python-3.11.6/Modules/_ssl_data_111.h ' + '../Python-3.11.6/Modules/_ssl_data_300.h ' + '../Python-3.11.6/Modules/socketmodule.h', 'MODULE__SSL_LDFLAGS': '-lssl -lcrypto -lws2_32', 'MODULE__SSL_STATE': 'yes', 'MODULE__STATISTICS_LDFLAGS': '-lm', @@ -905,7 +906,7 @@ 'MODULE__STRUCT_STATE': 'yes', 'MODULE__SYMTABLE_LDFLAGS': '', 'MODULE__TESTBUFFER_STATE': 'yes', - 'MODULE__TESTCAPI_DEPS': '../Python-3.11.5/Modules/testcapi_long.h', + 'MODULE__TESTCAPI_DEPS': '../Python-3.11.6/Modules/testcapi_long.h', 'MODULE__TESTCAPI_STATE': 'yes', 'MODULE__TESTCLINIC_STATE': 'yes', 'MODULE__TESTIMPORTMULTIPLE_STATE': 'yes', @@ -984,9 +985,9 @@ '-DPY3_DLLNAME=\'L"libpython3.11.dll"\' ' '-DMS_DLL_ID=\'"3.11-32"\' -fprofile-use ' '-fprofile-correction ' - '-I../Python-3.11.5/Include/internal -IObjects ' + '-I../Python-3.11.6/Include/internal -IObjects ' '-IInclude -IPython -I. ' - '-I../Python-3.11.5/Include -I../Python-3.11.5/PC ' + '-I../Python-3.11.6/Include -I../Python-3.11.6/PC ' '-D__USE_MINGW_ANSI_STDIO=1 -I. ' '-D__USE_MINGW_ANSI_STDIO=1 ' '-DPy_BUILD_CORE_BUILTIN', @@ -999,7 +1000,7 @@ '-fvisibility=hidden -D_WIN32_WINNT=0x0602 ' '-DPY3_DLLNAME=\'L"libpython3.11.dll"\' ' '-DMS_DLL_ID=\'"3.11-32"\' -fprofile-use ' - '-fprofile-correction -I../Python-3.11.5/Include/internal', + '-fprofile-correction -I../Python-3.11.6/Include/internal', 'PY_COERCE_C_LOCALE': 0, 'PY_CORE_CFLAGS': '-DNDEBUG -g -fwrapv -O3 -Wall -march=pentium4 ' '-mtune=generic -O2 -pipe -Wp,-D_FORTIFY_SOURCE=2 ' @@ -1010,17 +1011,17 @@ '-fvisibility=hidden -D_WIN32_WINNT=0x0602 ' '-DPY3_DLLNAME=\'L"libpython3.11.dll"\' ' '-DMS_DLL_ID=\'"3.11-32"\' -fprofile-use ' - '-fprofile-correction -I../Python-3.11.5/Include/internal ' + '-fprofile-correction -I../Python-3.11.6/Include/internal ' '-IObjects -IInclude -IPython -I. ' - '-I../Python-3.11.5/Include -I../Python-3.11.5/PC ' + '-I../Python-3.11.6/Include -I../Python-3.11.6/PC ' '-D__USE_MINGW_ANSI_STDIO=1 -I. -D__USE_MINGW_ANSI_STDIO=1 ' '-DPy_BUILD_CORE', 'PY_CORE_LDFLAGS': '-pipe -Wl,--no-seh -Wl,--large-address-aware ' '-Wl,--large-address-aware -pipe -Wl,--no-seh ' '-Wl,--large-address-aware -Wl,--large-address-aware ' '-fno-semantic-interposition', - 'PY_CPPFLAGS': '-IObjects -IInclude -IPython -I. -I../Python-3.11.5/Include ' - '-I../Python-3.11.5/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' + 'PY_CPPFLAGS': '-IObjects -IInclude -IPython -I. -I../Python-3.11.6/Include ' + '-I../Python-3.11.6/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' '-D__USE_MINGW_ANSI_STDIO=1', 'PY_ENABLE_SHARED': 1, 'PY_FORMAT_SIZE_T': '"z"', @@ -1046,9 +1047,9 @@ '-DPY3_DLLNAME=\'L"libpython3.11.dll"\' ' '-DMS_DLL_ID=\'"3.11-32"\' -fprofile-use ' '-fprofile-correction ' - '-I../Python-3.11.5/Include/internal -IObjects ' - '-IInclude -IPython -I. -I../Python-3.11.5/Include ' - '-I../Python-3.11.5/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' + '-I../Python-3.11.6/Include/internal -IObjects ' + '-IInclude -IPython -I. -I../Python-3.11.6/Include ' + '-I../Python-3.11.6/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' '-D__USE_MINGW_ANSI_STDIO=1', 'PY_SUPPORT_TIER': 0, 'Py_DEBUG': 0, @@ -1057,7 +1058,7 @@ 'Py_STATS': 0, 'Py_TRACE_REFS': 0, 'QUICKTESTOPTS': '-x test_subprocess test_io test_lib2to3 \\', - 'RCFLAGS': '-DFIELD3=5150 -O COFF --target=pe-i386', + 'RCFLAGS': '-DFIELD3=6150 -O COFF --target=pe-i386', 'READELF': 'readelf', 'RESSRCDIR': 'Mac/Resources/framework', 'RETSIGTYPE': 'void', @@ -1094,7 +1095,7 @@ 'Modules/_sre Modules/_xxtestfuzz Modules/cjkcodecs ' 'Modules/expat Objects Parser Programs Python ' 'Python/frozen_modules Python/deepfreeze PC', - 'SRC_GDB_HOOKS': '../Python-3.11.5/Tools/gdb/libpython.py', + 'SRC_GDB_HOOKS': '../Python-3.11.6/Tools/gdb/libpython.py', 'STATIC_LIBPYTHON': 1, 'STDC_HEADERS': 1, 'STRICT_SYSV_CURSES': "/* Don't use ncurses extensions */", @@ -1107,7 +1108,7 @@ 'TESTPATH': '', 'TESTPYTHON': './python.exe -E', 'TESTPYTHONOPTS': '', - 'TESTRUNNER': './python.exe -E ../Python-3.11.5/Tools/scripts/run_tests.py', + 'TESTRUNNER': './python.exe -E ../Python-3.11.6/Tools/scripts/run_tests.py', 'TESTSUBDIRS': 'ctypes/test \\', 'TESTTIMEOUT': 1200, 'TEST_MODULES': 'yes', @@ -1118,11 +1119,11 @@ 'TZPATH': '/mingw32/share/zoneinfo', 'UNICODE_DEPS': '\\', 'UNIVERSALSDK': '', - 'UPDATE_FILE': '../Python-3.11.5/Tools/scripts/update_file.py', + 'UPDATE_FILE': '../Python-3.11.6/Tools/scripts/update_file.py', 'USE_COMPUTED_GOTOS': 0, 'VENVLAUNCHERDIR': '/mingw32/lib/python3.11/venv/scripts/nt', 'VERSION': '3.11', - 'VPATH': '../Python-3.11.5', + 'VPATH': '../Python-3.11.6', 'WASM_ASSETS_DIR': './mingw32', 'WASM_STDLIB': './mingw32/lib/python3.11/os.py', 'WHEEL_PKG_DIR': '', @@ -1142,14 +1143,14 @@ 'XMLLIBSUBDIRS': 'xml xml/dom xml/etree xml/parsers xml/sax', 'abs_builddir': 'C:/M/B/src/build-MINGW32', 'abs_builddir_b2h': 'C:/M/B/src/build-MINGW32', - 'abs_srcdir': 'C:/M/B/src/Python-3.11.5', - 'abs_srcdir_b2h': 'C:/M/B/src/Python-3.11.5', + 'abs_srcdir': 'C:/M/B/src/Python-3.11.6', + 'abs_srcdir_b2h': 'C:/M/B/src/Python-3.11.6', 'datarootdir': '/mingw32/share', 'exec_prefix': '/mingw32', 'prefix': 'D:/a/msys64/mingw32', 'prefix_b2h': 'D:/a/msys64/mingw32', - 'srcdir': 'C:/M/B/src/Python-3.11.5', - 'srcdir_b2h': 'C:/M/B/src/Python-3.11.5'} + 'srcdir': 'C:/M/B/src/Python-3.11.6', + 'srcdir_b2h': 'C:/M/B/src/Python-3.11.6'} keys_to_replace = [ diff --git a/mingw32/lib/python3.11/ast.py b/mingw32/lib/python3.11/ast.py index 623b9a1b805..d84d75e1f3a 100644 --- a/mingw32/lib/python3.11/ast.py +++ b/mingw32/lib/python3.11/ast.py @@ -1175,13 +1175,29 @@ def visit_JoinedStr(self, node): new_fstring_parts = [] quote_types = list(_ALL_QUOTES) + fallback_to_repr = False for value, is_constant in fstring_parts: - value, quote_types = self._str_literal_helper( + value, new_quote_types = self._str_literal_helper( value, quote_types=quote_types, escape_special_whitespace=is_constant, ) new_fstring_parts.append(value) + if set(new_quote_types).isdisjoint(quote_types): + fallback_to_repr = True + break + quote_types = new_quote_types + + if fallback_to_repr: + # If we weren't able to find a quote type that works for all parts + # of the JoinedStr, fallback to using repr and triple single quotes. + quote_types = ["'''"] + new_fstring_parts.clear() + for value, is_constant in fstring_parts: + value = repr('"' + value) # force repr to use single quotes + expected_prefix = "'\"" + assert value.startswith(expected_prefix), repr(value) + new_fstring_parts.append(value[len(expected_prefix):-1]) value = "".join(new_fstring_parts) quote_type = quote_types[0] diff --git a/mingw32/lib/python3.11/asyncio/streams.py b/mingw32/lib/python3.11/asyncio/streams.py index 3d577f12704..19d9154b66d 100644 --- a/mingw32/lib/python3.11/asyncio/streams.py +++ b/mingw32/lib/python3.11/asyncio/streams.py @@ -67,9 +67,8 @@ async def start_server(client_connected_cb, host=None, port=None, *, positional host and port, with various optional keyword arguments following. The return value is the same as loop.create_server(). - Additional optional keyword arguments are loop (to set the event loop - instance to use) and limit (to set the buffer limit passed to the - StreamReader). + Additional optional keyword argument is limit (to set the buffer + limit passed to the StreamReader). The return value is the same as loop.create_server(), i.e. a Server object which can be used to stop the service. diff --git a/mingw32/lib/python3.11/asyncio/subprocess.py b/mingw32/lib/python3.11/asyncio/subprocess.py index c380bbb0ee9..da4f00a4a07 100644 --- a/mingw32/lib/python3.11/asyncio/subprocess.py +++ b/mingw32/lib/python3.11/asyncio/subprocess.py @@ -147,14 +147,16 @@ def kill(self): async def _feed_stdin(self, input): debug = self._loop.get_debug() - self.stdin.write(input) - if debug: - logger.debug( - '%r communicate: feed stdin (%s bytes)', self, len(input)) try: + self.stdin.write(input) + if debug: + logger.debug( + '%r communicate: feed stdin (%s bytes)', self, len(input)) + await self.stdin.drain() except (BrokenPipeError, ConnectionResetError) as exc: - # communicate() ignores BrokenPipeError and ConnectionResetError + # communicate() ignores BrokenPipeError and ConnectionResetError. + # write() and drain() can raise these exceptions. if debug: logger.debug('%r communicate: stdin got %r', self, exc) diff --git a/mingw32/lib/python3.11/asyncio/tasks.py b/mingw32/lib/python3.11/asyncio/tasks.py index 3e07ce5294c..6ca545e30ac 100644 --- a/mingw32/lib/python3.11/asyncio/tasks.py +++ b/mingw32/lib/python3.11/asyncio/tasks.py @@ -81,15 +81,25 @@ class Task(futures._PyFuture): # Inherit Python Task implementation """A coroutine wrapped in a Future.""" # An important invariant maintained while a Task not done: + # _fut_waiter is either None or a Future. The Future + # can be either done() or not done(). + # The task can be in any of 3 states: # - # - Either _fut_waiter is None, and _step() is scheduled; - # - or _fut_waiter is some Future, and _step() is *not* scheduled. + # - 1: _fut_waiter is not None and not _fut_waiter.done(): + # __step() is *not* scheduled and the Task is waiting for _fut_waiter. + # - 2: (_fut_waiter is None or _fut_waiter.done()) and __step() is scheduled: + # the Task is waiting for __step() to be executed. + # - 3: _fut_waiter is None and __step() is *not* scheduled: + # the Task is currently executing (in __step()). # - # The only transition from the latter to the former is through - # _wakeup(). When _fut_waiter is not None, one of its callbacks - # must be _wakeup(). - - # If False, don't log a message if the task is destroyed whereas its + # * In state 1, one of the callbacks of __fut_waiter must be __wakeup(). + # * The transition from 1 to 2 happens when _fut_waiter becomes done(), + # as it schedules __wakeup() to be called (which calls __step() so + # we way that __step() is scheduled). + # * It transitions from 2 to 3 when __step() is executed, and it clears + # _fut_waiter to None. + + # If False, don't log a message if the task is destroyed while its # status is still pending _log_destroy_pending = True diff --git a/mingw32/lib/python3.11/calendar.py b/mingw32/lib/python3.11/calendar.py index 657396439c9..7cdf9311b57 100644 --- a/mingw32/lib/python3.11/calendar.py +++ b/mingw32/lib/python3.11/calendar.py @@ -693,7 +693,7 @@ def main(args): parser.add_argument( "-L", "--locale", default=None, - help="locale to be used from month and weekday names" + help="locale to use for month and weekday names" ) parser.add_argument( "-e", "--encoding", diff --git a/mingw32/lib/python3.11/codecs.py b/mingw32/lib/python3.11/codecs.py index 3b173b61210..c6165fcb142 100644 --- a/mingw32/lib/python3.11/codecs.py +++ b/mingw32/lib/python3.11/codecs.py @@ -414,6 +414,9 @@ def __enter__(self): def __exit__(self, type, value, tb): self.stream.close() + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + ### class StreamReader(Codec): @@ -663,6 +666,9 @@ def __enter__(self): def __exit__(self, type, value, tb): self.stream.close() + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + ### class StreamReaderWriter: @@ -750,6 +756,9 @@ def __enter__(self): def __exit__(self, type, value, tb): self.stream.close() + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + ### class StreamRecoder: @@ -866,6 +875,9 @@ def __enter__(self): def __exit__(self, type, value, tb): self.stream.close() + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + ### Shortcuts def open(filename, mode='r', encoding=None, errors='strict', buffering=-1): diff --git a/mingw32/lib/python3.11/concurrent/futures/process.py b/mingw32/lib/python3.11/concurrent/futures/process.py index 321608ab174..952fa903457 100644 --- a/mingw32/lib/python3.11/concurrent/futures/process.py +++ b/mingw32/lib/python3.11/concurrent/futures/process.py @@ -69,6 +69,11 @@ def __init__(self): self._reader, self._writer = mp.Pipe(duplex=False) def close(self): + # Please note that we do not take the shutdown lock when + # calling clear() (to avoid deadlocking) so this method can + # only be called safely from the same thread as all calls to + # clear() even if you hold the shutdown lock. Otherwise we + # might try to read from the closed pipe. if not self._closed: self._closed = True self._writer.close() @@ -424,8 +429,12 @@ def wait_result_broken_or_wakeup(self): elif wakeup_reader in ready: is_broken = False - with self.shutdown_lock: - self.thread_wakeup.clear() + # No need to hold the _shutdown_lock here because: + # 1. we're the only thread to use the wakeup reader + # 2. we're also the only thread to call thread_wakeup.close() + # 3. we want to avoid a possible deadlock when both reader and writer + # would block (gh-105829) + self.thread_wakeup.clear() return result_item, is_broken, cause @@ -501,6 +510,11 @@ def terminate_broken(self, cause): # https://github.com/python/cpython/issues/94777 self.call_queue._reader.close() + # gh-107219: Close the connection writer which can unblock + # Queue._feed() if it was stuck in send_bytes(). + if sys.platform == 'win32': + self.call_queue._writer.close() + # clean up resources self.join_executor_internals() @@ -704,7 +718,10 @@ def __init__(self, max_workers=None, mp_context=None, # as it could result in a deadlock if a worker process dies with the # _result_queue write lock still acquired. # - # _shutdown_lock must be locked to access _ThreadWakeup. + # _shutdown_lock must be locked to access _ThreadWakeup.close() and + # .wakeup(). Care must also be taken to not call clear or close from + # more than one thread since _ThreadWakeup.clear() is not protected by + # the _shutdown_lock self._executor_manager_thread_wakeup = _ThreadWakeup() # Create communication channels for the executor diff --git a/mingw32/lib/python3.11/config-3.11/Makefile b/mingw32/lib/python3.11/config-3.11/Makefile index 09bb125bc4f..59be80bf68b 100644 --- a/mingw32/lib/python3.11/config-3.11/Makefile +++ b/mingw32/lib/python3.11/config-3.11/Makefile @@ -29,9 +29,9 @@ MODLIBS= $(LOCALMODLIBS) $(BASEMODLIBS) # === Variables set by configure VERSION= 3.11 -srcdir= ../Python-3.11.5 -VPATH= ../Python-3.11.5 -abs_srcdir= /c/M/B/src/build-MINGW32/../Python-3.11.5 +srcdir= ../Python-3.11.6 +VPATH= ../Python-3.11.6 +abs_srcdir= /c/M/B/src/build-MINGW32/../Python-3.11.6 abs_builddir= /c/M/B/src/build-MINGW32 @@ -125,7 +125,7 @@ PY_CORE_CFLAGS= $(PY_STDMODULE_CFLAGS) -DPy_BUILD_CORE PY_CORE_LDFLAGS=$(PY_LDFLAGS) $(PY_LDFLAGS_NODIST) # Strict or non-strict aliasing flags used to compile dtoa.c, see above CFLAGS_ALIASING= -RCFLAGS= -DFIELD3=5150 -O COFF --target=pe-i386 +RCFLAGS= -DFIELD3=6150 -O COFF --target=pe-i386 # Machine-dependent subdirectories @@ -145,8 +145,8 @@ exec_prefix= ${prefix} datarootdir= ${prefix}/share # Locations needed for semi-native fixup of sysconfig. -srcdir_b2h= C:/M/B/src/Python-3.11.5 -abs_srcdir_b2h= C:/M/B/src/Python-3.11.5 +srcdir_b2h= C:/M/B/src/Python-3.11.6 +abs_srcdir_b2h= C:/M/B/src/Python-3.11.6 abs_builddir_b2h= C:/M/B/src/build-MINGW32 prefix_b2h= D:/a/msys64/mingw32 @@ -636,6 +636,7 @@ OBJECT_OBJS= \ Objects/unionobject.o \ Objects/weakrefobject.o +DEEPFREEZE_C = Python/deepfreeze/deepfreeze.c DEEPFREEZE_OBJS = Python/deepfreeze/deepfreeze.o ########################################################################## @@ -1332,12 +1333,12 @@ regen-frozen: Tools/scripts/freeze_modules.py $(FROZEN_FILES_IN) # Deepfreeze targets .PHONY: regen-deepfreeze -regen-deepfreeze: $(DEEPFREEZE_OBJS) +regen-deepfreeze: $(DEEPFREEZE_C) DEEPFREEZE_DEPS=$(srcdir)/Tools/scripts/deepfreeze.py $(FREEZE_MODULE_DEPS) $(FROZEN_FILES_OUT) # BEGIN: deepfreeze modules -Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS) +$(DEEPFREEZE_C): $(DEEPFREEZE_DEPS) $(PYTHON_FOR_FREEZE) $(srcdir)/Tools/scripts/deepfreeze.py \ Python/frozen_modules/importlib._bootstrap.h:importlib._bootstrap \ Python/frozen_modules/importlib._bootstrap_external.h:importlib._bootstrap_external \ @@ -1364,8 +1365,6 @@ Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS) Python/frozen_modules/frozen_only.h:frozen_only \ -o Python/deepfreeze/deepfreeze.c # END: deepfreeze modules - @echo "Note: Deepfreeze may have added some global objects," - @echo " so run 'make regen-global-objects' if necessary." # We keep this renamed target around for folks with muscle memory. .PHONY: regen-importlib @@ -1374,11 +1373,12 @@ regen-importlib: regen-frozen ############################################################################ # Global objects +# Dependencies which can add and/or remove _Py_ID() identifiers: +# - deepfreeze.c +# - "make clinic" .PHONY: regen-global-objects -regen-global-objects: $(srcdir)/Tools/scripts/generate_global_objects.py +regen-global-objects: $(srcdir)/Tools/scripts/generate_global_objects.py $(DEEPFREEZE_C) clinic $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_global_objects.py - @echo "Note: Global objects can be added or removed by other tools (e.g. deepfreeze), " - @echo " so be sure to re-run regen-global-objects after those tools." ############################################################################ # ABI @@ -1397,8 +1397,10 @@ regen-limited-abi: all ############################################################################ # Regenerate all generated files +# "clinic" is regenerated implicitly via "regen-global-objects". +.PHONY: regen-all regen-all: regen-opcode regen-opcode-targets regen-typeslots \ - regen-token regen-ast regen-keyword regen-sre regen-frozen clinic \ + regen-token regen-ast regen-keyword regen-sre regen-frozen \ regen-pegen-metaparser regen-pegen regen-test-frozenmain \ regen-global-objects @echo @@ -2152,8 +2154,10 @@ TESTSUBDIRS= ctypes/test \ test/test_asyncio \ test/test_capi \ test/test_cppext \ + test/test_dataclasses \ test/test_email \ test/test_email/data \ + test/test_future_stmt \ test/test_import \ test/test_import/data \ test/test_import/data/circular_imports \ @@ -2231,6 +2235,7 @@ TESTSUBDIRS= ctypes/test \ test/test_warnings/data \ test/test_zoneinfo \ test/test_zoneinfo/data \ + test/tokenizedata \ test/tracedmodules \ test/typinganndata \ test/xmltestdata \ @@ -2589,6 +2594,7 @@ recheck: autoconf: (cd $(srcdir); autoreconf -ivf -Werror) +# See https://github.com/tiran/cpython_autoconf container .PHONY: regen-configure regen-configure: @if command -v podman >/dev/null; then RUNTIME="podman"; else RUNTIME="docker"; fi; \ diff --git a/mingw32/lib/python3.11/config-3.11/config.c b/mingw32/lib/python3.11/config-3.11/config.c index 159ef46dd8f..804b2ff68c8 100644 --- a/mingw32/lib/python3.11/config-3.11/config.c +++ b/mingw32/lib/python3.11/config-3.11/config.c @@ -1,4 +1,4 @@ -/* Generated automatically from ../Python-3.11.5/Modules/config.c.in by makesetup. */ +/* Generated automatically from ../Python-3.11.6/Modules/config.c.in by makesetup. */ /* -*- C -*- *********************************************** Copyright (c) 2000, BeOpen.com. Copyright (c) 1995-2000, Corporation for National Research Initiatives. diff --git a/mingw32/lib/python3.11/config-3.11/python.o b/mingw32/lib/python3.11/config-3.11/python.o index 71ad6b4d86d..1d64aa76c6b 100644 Binary files a/mingw32/lib/python3.11/config-3.11/python.o and b/mingw32/lib/python3.11/config-3.11/python.o differ diff --git a/mingw32/lib/python3.11/datetime.py b/mingw32/lib/python3.11/datetime.py index c3c2568f986..474b4e9ae53 100644 --- a/mingw32/lib/python3.11/datetime.py +++ b/mingw32/lib/python3.11/datetime.py @@ -1002,13 +1002,9 @@ def fromisocalendar(cls, year, week, day): def __repr__(self): """Convert to formal string, for repr(). - >>> dt = datetime(2010, 1, 1) - >>> repr(dt) - 'datetime.datetime(2010, 1, 1, 0, 0)' - - >>> dt = datetime(2010, 1, 1, tzinfo=timezone.utc) - >>> repr(dt) - 'datetime.datetime(2010, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)' + >>> d = date(2010, 1, 1) + >>> repr(d) + 'datetime.date(2010, 1, 1)' """ return "%s.%s(%d, %d, %d)" % (self.__class__.__module__, self.__class__.__qualname__, @@ -1223,7 +1219,7 @@ def __reduce__(self): class tzinfo: """Abstract base class for time zone info classes. - Subclasses must override the name(), utcoffset() and dst() methods. + Subclasses must override the tzname(), utcoffset() and dst() methods. """ __slots__ = () diff --git a/mingw32/lib/python3.11/enum.py b/mingw32/lib/python3.11/enum.py index 1f447c878c1..155cb13022f 100644 --- a/mingw32/lib/python3.11/enum.py +++ b/mingw32/lib/python3.11/enum.py @@ -863,6 +863,8 @@ def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, s value = first_enum._generate_next_value_(name, start, count, last_values[:]) last_values.append(value) names.append((name, value)) + if names is None: + names = () # Here, names is either an iterable of (name, value) or a mapping. for item in names: @@ -1107,6 +1109,11 @@ def __new__(cls, value): for member in cls._member_map_.values(): if member._value_ == value: return member + # still not found -- verify that members exist, in-case somebody got here mistakenly + # (such as via super when trying to override __new__) + if not cls._member_map_: + raise TypeError("%r has no members defined" % cls) + # # still not found -- try _missing_ hook try: exc = None diff --git a/mingw32/lib/python3.11/lib-dynload/_asyncio.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_asyncio.cp311-mingw_i686.pyd index 03c3d7c2ed9..2762fdc5aca 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_asyncio.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_asyncio.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_bisect.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_bisect.cp311-mingw_i686.pyd index a6fc3da69b1..16da338287d 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_bisect.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_bisect.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_blake2.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_blake2.cp311-mingw_i686.pyd index 73598f6abaa..8b30038530e 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_blake2.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_blake2.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_bz2.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_bz2.cp311-mingw_i686.pyd index 67d559ee756..0736cf28c84 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_bz2.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_bz2.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_codecs_cn.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_codecs_cn.cp311-mingw_i686.pyd index ef58d856757..1d63410cf42 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_codecs_cn.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_codecs_cn.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_codecs_hk.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_codecs_hk.cp311-mingw_i686.pyd index dec5475e3fc..cc7a4a411d0 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_codecs_hk.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_codecs_hk.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_codecs_iso2022.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_codecs_iso2022.cp311-mingw_i686.pyd index 459f9cc2828..6d222a0e39e 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_codecs_iso2022.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_codecs_iso2022.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_codecs_jp.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_codecs_jp.cp311-mingw_i686.pyd index 9c35483e3c3..a7f5a96fe8b 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_codecs_jp.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_codecs_jp.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_codecs_kr.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_codecs_kr.cp311-mingw_i686.pyd index a9a77b5003c..83793e5b1a6 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_codecs_kr.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_codecs_kr.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_codecs_tw.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_codecs_tw.cp311-mingw_i686.pyd index b633d6973c3..87a4c1ade43 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_codecs_tw.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_codecs_tw.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_contextvars.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_contextvars.cp311-mingw_i686.pyd index ee14932fecd..51a21d2da61 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_contextvars.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_contextvars.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_csv.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_csv.cp311-mingw_i686.pyd index 98442c1d1cc..1083a2c0f22 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_csv.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_csv.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_ctypes.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_ctypes.cp311-mingw_i686.pyd index 50455c1909a..450324eed0e 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_ctypes.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_ctypes.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_ctypes_test.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_ctypes_test.cp311-mingw_i686.pyd index a5965169d06..0ec13f833ab 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_ctypes_test.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_ctypes_test.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_curses.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_curses.cp311-mingw_i686.pyd index d519a35a802..c12e77c159f 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_curses.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_curses.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_curses_panel.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_curses_panel.cp311-mingw_i686.pyd index 703e5281a85..6abb0f2cd8f 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_curses_panel.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_curses_panel.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_datetime.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_datetime.cp311-mingw_i686.pyd index d41262c8bdc..e61f014e9d6 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_datetime.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_datetime.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_decimal.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_decimal.cp311-mingw_i686.pyd index 51ddd887e4a..87387e962b5 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_decimal.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_decimal.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_elementtree.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_elementtree.cp311-mingw_i686.pyd index faf8b3fe15d..6ad46771e01 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_elementtree.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_elementtree.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_hashlib.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_hashlib.cp311-mingw_i686.pyd index c1721eb4485..9342fb602ed 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_hashlib.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_hashlib.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_heapq.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_heapq.cp311-mingw_i686.pyd index 9026bde5836..53fc5edf147 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_heapq.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_heapq.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_json.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_json.cp311-mingw_i686.pyd index baf845ad5ef..276c9a39d0a 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_json.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_json.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_lsprof.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_lsprof.cp311-mingw_i686.pyd index 9b743b72e38..004af01e5e0 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_lsprof.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_lsprof.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_lzma.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_lzma.cp311-mingw_i686.pyd index 224eb699f48..2ee9290e268 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_lzma.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_lzma.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_md5.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_md5.cp311-mingw_i686.pyd index c5b3da44029..3b60e661b4d 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_md5.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_md5.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_msi.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_msi.cp311-mingw_i686.pyd index aa2025c36c7..54baa109db4 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_msi.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_msi.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_multibytecodec.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_multibytecodec.cp311-mingw_i686.pyd index e4522bcae41..f1161b28ec6 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_multibytecodec.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_multibytecodec.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_multiprocessing.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_multiprocessing.cp311-mingw_i686.pyd index 4a4703a1fb3..07255eca72c 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_multiprocessing.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_multiprocessing.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_opcode.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_opcode.cp311-mingw_i686.pyd index 36cce90ea4f..d2f6b460109 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_opcode.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_opcode.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_overlapped.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_overlapped.cp311-mingw_i686.pyd index 30b4044986a..33cec305ee1 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_overlapped.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_overlapped.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_pickle.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_pickle.cp311-mingw_i686.pyd index 6a8d4566fe8..9fc562fc981 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_pickle.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_pickle.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_queue.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_queue.cp311-mingw_i686.pyd index ad3998101fe..098d18b8dc7 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_queue.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_queue.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_random.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_random.cp311-mingw_i686.pyd index 679eb422f99..3f22772fba3 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_random.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_random.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_sha1.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_sha1.cp311-mingw_i686.pyd index 7b80454af16..836f1ce417a 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_sha1.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_sha1.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_sha256.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_sha256.cp311-mingw_i686.pyd index 398d833d1c1..be3f1525dff 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_sha256.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_sha256.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_sha3.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_sha3.cp311-mingw_i686.pyd index 82dde34b0e1..0aad6c51dd7 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_sha3.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_sha3.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_sha512.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_sha512.cp311-mingw_i686.pyd index 172fd393d64..832e4ea9106 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_sha512.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_sha512.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_socket.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_socket.cp311-mingw_i686.pyd index 6a26b82c68a..fa9d24c7f59 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_socket.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_socket.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_sqlite3.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_sqlite3.cp311-mingw_i686.pyd index 0d353dc0a47..70f1a7ba7a3 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_sqlite3.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_sqlite3.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_ssl.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_ssl.cp311-mingw_i686.pyd index 8f8a5185861..80a9bbf5de7 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_ssl.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_ssl.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_statistics.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_statistics.cp311-mingw_i686.pyd index e7bb357d05e..e8dd53ddc38 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_statistics.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_statistics.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_struct.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_struct.cp311-mingw_i686.pyd index 89256b47beb..6f565a55758 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_struct.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_struct.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_testbuffer.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_testbuffer.cp311-mingw_i686.pyd index 5d254e2c480..cb388944323 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_testbuffer.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_testbuffer.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_testcapi.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_testcapi.cp311-mingw_i686.pyd index 4a0835e4e85..44e2f4b9fbf 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_testcapi.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_testcapi.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_testclinic.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_testclinic.cp311-mingw_i686.pyd index 8b0179b3a43..b1b15e445ff 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_testclinic.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_testclinic.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_testconsole.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_testconsole.cp311-mingw_i686.pyd index bfe63f6ec3e..36a67fe0e35 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_testconsole.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_testconsole.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_testimportmultiple.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_testimportmultiple.cp311-mingw_i686.pyd index bb7e97e566a..12ac3646893 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_testimportmultiple.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_testimportmultiple.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_testinternalcapi.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_testinternalcapi.cp311-mingw_i686.pyd index 36ceea9bf1e..514bc259031 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_testinternalcapi.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_testinternalcapi.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_testmultiphase.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_testmultiphase.cp311-mingw_i686.pyd index a5f182944c2..96c7b46d2b3 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_testmultiphase.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_testmultiphase.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_tkinter.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_tkinter.cp311-mingw_i686.pyd index bae46ae0053..da0a94d8af1 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_tkinter.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_tkinter.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_typing.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_typing.cp311-mingw_i686.pyd index ca786a10ffc..4175472ca08 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_typing.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_typing.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_xxsubinterpreters.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_xxsubinterpreters.cp311-mingw_i686.pyd index b979f3bb988..b2d626287f4 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_xxsubinterpreters.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_xxsubinterpreters.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_xxtestfuzz.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_xxtestfuzz.cp311-mingw_i686.pyd index f909f9eb4ff..7f860c3e173 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_xxtestfuzz.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_xxtestfuzz.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/_zoneinfo.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/_zoneinfo.cp311-mingw_i686.pyd index bee17165b08..9ffcf2b66b6 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/_zoneinfo.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/_zoneinfo.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/array.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/array.cp311-mingw_i686.pyd index d43fa0426ad..5230a572446 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/array.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/array.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/audioop.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/audioop.cp311-mingw_i686.pyd index c559d8059c1..eb19d23e066 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/audioop.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/audioop.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/binascii.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/binascii.cp311-mingw_i686.pyd index e9ceec6b296..64a82c772a7 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/binascii.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/binascii.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/cmath.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/cmath.cp311-mingw_i686.pyd index df84f43e53c..577659c7a64 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/cmath.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/cmath.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/math.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/math.cp311-mingw_i686.pyd index 8d9d6f84849..e7f9f3fd224 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/math.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/math.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/mmap.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/mmap.cp311-mingw_i686.pyd index e142819f24e..be30c2099c9 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/mmap.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/mmap.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/pyexpat.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/pyexpat.cp311-mingw_i686.pyd index d09a5841283..5b9a4c1aeaf 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/pyexpat.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/pyexpat.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/select.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/select.cp311-mingw_i686.pyd index 9fb4c0b4272..405247156ae 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/select.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/select.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/unicodedata.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/unicodedata.cp311-mingw_i686.pyd index 98d238e2886..5f696d2e58d 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/unicodedata.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/unicodedata.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/winsound.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/winsound.cp311-mingw_i686.pyd index 672ee4978d6..ced325f896a 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/winsound.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/winsound.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/xxlimited.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/xxlimited.cp311-mingw_i686.pyd index 8a887269050..35497bccd96 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/xxlimited.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/xxlimited.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/xxlimited_35.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/xxlimited_35.cp311-mingw_i686.pyd index 436d85d2792..790bbe7c870 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/xxlimited_35.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/xxlimited_35.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib-dynload/zlib.cp311-mingw_i686.pyd b/mingw32/lib/python3.11/lib-dynload/zlib.cp311-mingw_i686.pyd index d16aedcb3cb..f74f2eb223c 100644 Binary files a/mingw32/lib/python3.11/lib-dynload/zlib.cp311-mingw_i686.pyd and b/mingw32/lib/python3.11/lib-dynload/zlib.cp311-mingw_i686.pyd differ diff --git a/mingw32/lib/python3.11/lib2to3/Grammar3.11.5.final.0.pickle b/mingw32/lib/python3.11/lib2to3/Grammar3.11.6.final.0.pickle similarity index 100% rename from mingw32/lib/python3.11/lib2to3/Grammar3.11.5.final.0.pickle rename to mingw32/lib/python3.11/lib2to3/Grammar3.11.6.final.0.pickle diff --git a/mingw32/lib/python3.11/lib2to3/PatternGrammar3.11.5.final.0.pickle b/mingw32/lib/python3.11/lib2to3/PatternGrammar3.11.6.final.0.pickle similarity index 100% rename from mingw32/lib/python3.11/lib2to3/PatternGrammar3.11.5.final.0.pickle rename to mingw32/lib/python3.11/lib2to3/PatternGrammar3.11.6.final.0.pickle diff --git a/mingw32/lib/python3.11/multiprocessing/connection.py b/mingw32/lib/python3.11/multiprocessing/connection.py index b08144f7a1a..8b81f9954e4 100644 --- a/mingw32/lib/python3.11/multiprocessing/connection.py +++ b/mingw32/lib/python3.11/multiprocessing/connection.py @@ -9,6 +9,7 @@ __all__ = [ 'Client', 'Listener', 'Pipe', 'wait' ] +import errno import io import os import sys @@ -271,12 +272,22 @@ class PipeConnection(_ConnectionBase): with FILE_FLAG_OVERLAPPED. """ _got_empty_message = False + _send_ov = None def _close(self, _CloseHandle=_winapi.CloseHandle): + ov = self._send_ov + if ov is not None: + # Interrupt WaitForMultipleObjects() in _send_bytes() + ov.cancel() _CloseHandle(self._handle) def _send_bytes(self, buf): + if self._send_ov is not None: + # A connection should only be used by a single thread + raise ValueError("concurrent send_bytes() calls " + "are not supported") ov, err = _winapi.WriteFile(self._handle, buf, overlapped=True) + self._send_ov = ov try: if err == _winapi.ERROR_IO_PENDING: waitres = _winapi.WaitForMultipleObjects( @@ -286,7 +297,13 @@ def _send_bytes(self, buf): ov.cancel() raise finally: + self._send_ov = None nwritten, err = ov.GetOverlappedResult(True) + if err == _winapi.ERROR_OPERATION_ABORTED: + # close() was called by another thread while + # WaitForMultipleObjects() was waiting for the overlapped + # operation. + raise OSError(errno.EPIPE, "handle is closed") assert err == 0 assert nwritten == len(buf) diff --git a/mingw32/lib/python3.11/multiprocessing/popen_spawn_win32.py b/mingw32/lib/python3.11/multiprocessing/popen_spawn_win32.py index 4d60ffc030b..af044305709 100644 --- a/mingw32/lib/python3.11/multiprocessing/popen_spawn_win32.py +++ b/mingw32/lib/python3.11/multiprocessing/popen_spawn_win32.py @@ -14,6 +14,7 @@ # # +# Exit code used by Popen.terminate() TERMINATE = 0x10000 WINEXE = (sys.platform == 'win32' and getattr(sys, 'frozen', False)) WINSERVICE = sys.executable.lower().endswith("pythonservice.exe") @@ -122,9 +123,15 @@ def terminate(self): if self.returncode is None: try: _winapi.TerminateProcess(int(self._handle), TERMINATE) - except OSError: - if self.wait(timeout=1.0) is None: + except PermissionError: + # ERROR_ACCESS_DENIED (winerror 5) is received when the + # process already died. + code = _winapi.GetExitCodeProcess(int(self._handle)) + if code == _winapi.STILL_ACTIVE: raise + self.returncode = code + else: + self.returncode = -signal.SIGTERM kill = terminate diff --git a/mingw32/lib/python3.11/multiprocessing/resource_tracker.py b/mingw32/lib/python3.11/multiprocessing/resource_tracker.py index ea369507297..79e96ecf324 100644 --- a/mingw32/lib/python3.11/multiprocessing/resource_tracker.py +++ b/mingw32/lib/python3.11/multiprocessing/resource_tracker.py @@ -51,15 +51,31 @@ }) +class ReentrantCallError(RuntimeError): + pass + + class ResourceTracker(object): def __init__(self): - self._lock = threading.Lock() + self._lock = threading.RLock() self._fd = None self._pid = None + def _reentrant_call_error(self): + # gh-109629: this happens if an explicit call to the ResourceTracker + # gets interrupted by a garbage collection, invoking a finalizer (*) + # that itself calls back into ResourceTracker. + # (*) for example the SemLock finalizer + raise ReentrantCallError( + "Reentrant call into the multiprocessing resource tracker") + def _stop(self): with self._lock: + # This should not happen (_stop() isn't called by a finalizer) + # but we check for it anyway. + if self._lock._recursion_count() > 1: + return self._reentrant_call_error() if self._fd is None: # not running return @@ -81,6 +97,9 @@ def ensure_running(self): This can be run from any process. Usually a child process will use the resource created by its parent.''' with self._lock: + if self._lock._recursion_count() > 1: + # The code below is certainly not reentrant-safe, so bail out + return self._reentrant_call_error() if self._fd is not None: # resource tracker was launched before, is it still running? if self._check_alive(): @@ -159,7 +178,17 @@ def unregister(self, name, rtype): self._send('UNREGISTER', name, rtype) def _send(self, cmd, name, rtype): - self.ensure_running() + try: + self.ensure_running() + except ReentrantCallError: + # The code below might or might not work, depending on whether + # the resource tracker was already running and still alive. + # Better warn the user. + # (XXX is warnings.warn itself reentrant-safe? :-) + warnings.warn( + f"ResourceTracker called reentrantly for resource cleanup, " + f"which is unsupported. " + f"The {rtype} object {name!r} might leak.") msg = '{0}:{1}:{2}\n'.format(cmd, name, rtype).encode('ascii') if len(msg) > 512: # posix guarantees that writes to a pipe of less than PIPE_BUF @@ -176,6 +205,7 @@ def _send(self, cmd, name, rtype): unregister = _resource_tracker.unregister getfd = _resource_tracker.getfd + def main(fd): '''Run resource tracker.''' # protect the process from ^C and "killall python" etc diff --git a/mingw32/lib/python3.11/multiprocessing/synchronize.py b/mingw32/lib/python3.11/multiprocessing/synchronize.py index 2328d332123..3ccbfe311c7 100644 --- a/mingw32/lib/python3.11/multiprocessing/synchronize.py +++ b/mingw32/lib/python3.11/multiprocessing/synchronize.py @@ -50,8 +50,8 @@ class SemLock(object): def __init__(self, kind, value, maxvalue, *, ctx): if ctx is None: ctx = context._default_context.get_context() - self.is_fork_ctx = ctx.get_start_method() == 'fork' - unlink_now = sys.platform == 'win32' or self.is_fork_ctx + self._is_fork_ctx = ctx.get_start_method() == 'fork' + unlink_now = sys.platform == 'win32' or self._is_fork_ctx for i in range(100): try: sl = self._semlock = _multiprocessing.SemLock( @@ -103,7 +103,7 @@ def __getstate__(self): if sys.platform == 'win32': h = context.get_spawning_popen().duplicate_for_child(sl.handle) else: - if self.is_fork_ctx: + if self._is_fork_ctx: raise RuntimeError('A SemLock created in a fork context is being ' 'shared with a process in a spawn context. This is ' 'not supported. Please use the same context to create ' @@ -115,6 +115,8 @@ def __setstate__(self, state): self._semlock = _multiprocessing.SemLock._rebuild(*state) util.debug('recreated blocker with handle %r' % state[0]) self._make_methods() + # Ensure that deserialized SemLock can be serialized again (gh-108520). + self._is_fork_ctx = False @staticmethod def _make_name(): diff --git a/mingw32/lib/python3.11/pdb.py b/mingw32/lib/python3.11/pdb.py index d3824e19fa8..fe9eab9b5e1 100644 --- a/mingw32/lib/python3.11/pdb.py +++ b/mingw32/lib/python3.11/pdb.py @@ -1505,8 +1505,11 @@ def do_alias(self, arg): for alias in keys: self.message("%s = %s" % (alias, self.aliases[alias])) return - if args[0] in self.aliases and len(args) == 1: - self.message("%s = %s" % (args[0], self.aliases[args[0]])) + if len(args) == 1: + if args[0] in self.aliases: + self.message("%s = %s" % (args[0], self.aliases[args[0]])) + else: + self.error(f"Unknown alias '{args[0]}'") else: self.aliases[args[0]] = ' '.join(args[1:]) diff --git a/mingw32/lib/python3.11/pydoc_data/topics.py b/mingw32/lib/python3.11/pydoc_data/topics.py index 1b1251b6909..06422d21c6b 100644 --- a/mingw32/lib/python3.11/pydoc_data/topics.py +++ b/mingw32/lib/python3.11/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Thu Aug 24 13:07:17 2023 +# Autogenerated by Sphinx on Mon Oct 2 14:27:48 2023 # as part of the release process. topics = {'assert': 'The "assert" statement\n' '**********************\n' @@ -1076,9 +1076,7 @@ 'for each\n' ' instance.\n' '\n' - '\n' - 'Notes on using *__slots__*\n' - '--------------------------\n' + 'Notes on using *__slots__*:\n' '\n' '* When inheriting from a class without *__slots__*, the ' '"__dict__" and\n' @@ -10003,9 +10001,7 @@ 'each\n' ' instance.\n' '\n' - '\n' - 'Notes on using *__slots__*\n' - '~~~~~~~~~~~~~~~~~~~~~~~~~~\n' + 'Notes on using *__slots__*:\n' '\n' '* When inheriting from a class without *__slots__*, the ' '"__dict__" and\n' @@ -12374,71 +12370,71 @@ 'those\n' 'used by Standard C. The recognized escape sequences are:\n' '\n' - '+-------------------+-----------------------------------+---------+\n' - '| Escape Sequence | Meaning | Notes ' - '|\n' - '|===================|===================================|=========|\n' - '| "\\" | Backslash and newline ignored | ' - '(1) |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\\\" | Backslash ("\\") ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\\'" | Single quote ("\'") ' + '+---------------------------+-----------------------------------+---------+\n' + '| Escape Sequence | Meaning | ' + 'Notes |\n' + '|===========================|===================================|=========|\n' + '| "\\" | Backslash and newline ignored ' + '| (1) |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\\\" | Backslash ' + '("\\") | |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\\'" | Single quote ' + '("\'") | |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\"" | Double quote (""") ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\"" | Double quote (""") ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\a" | ASCII Bell (BEL) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\a" | ASCII Bell (BEL) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\b" | ASCII Backspace (BS) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\b" | ASCII Backspace (BS) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\f" | ASCII Formfeed (FF) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\f" | ASCII Formfeed (FF) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\n" | ASCII Linefeed (LF) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\n" | ASCII Linefeed (LF) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\r" | ASCII Carriage Return (CR) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\r" | ASCII Carriage Return (CR) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\t" | ASCII Horizontal Tab (TAB) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\t" | ASCII Horizontal Tab (TAB) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\v" | ASCII Vertical Tab (VT) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\v" | ASCII Vertical Tab (VT) ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\ooo" | Character with octal value *ooo* | ' - '(2,4) |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\xhh" | Character with hex value *hh* | ' - '(3,4) |\n' - '+-------------------+-----------------------------------+---------+\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\*ooo*" | Character with octal value *ooo* ' + '| (2,4) |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\x*hh*" | Character with hex value *hh* ' + '| (3,4) |\n' + '+---------------------------+-----------------------------------+---------+\n' '\n' 'Escape sequences only recognized in string literals are:\n' '\n' - '+-------------------+-----------------------------------+---------+\n' - '| Escape Sequence | Meaning | Notes ' - '|\n' - '|===================|===================================|=========|\n' - '| "\\N{name}" | Character named *name* in the | ' - '(5) |\n' - '| | Unicode database | ' - '|\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\uxxxx" | Character with 16-bit hex value | ' - '(6) |\n' - '| | *xxxx* | ' - '|\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\Uxxxxxxxx" | Character with 32-bit hex value | ' - '(7) |\n' - '| | *xxxxxxxx* | ' - '|\n' - '+-------------------+-----------------------------------+---------+\n' + '+---------------------------+-----------------------------------+---------+\n' + '| Escape Sequence | Meaning | ' + 'Notes |\n' + '|===========================|===================================|=========|\n' + '| "\\N{*name*}" | Character named *name* in the ' + '| (5) |\n' + '| | Unicode database ' + '| |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\u*xxxx*" | Character with 16-bit hex value ' + '| (6) |\n' + '| | *xxxx* ' + '| |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\U*xxxxxxxx*" | Character with 32-bit hex value ' + '| (7) |\n' + '| | *xxxxxxxx* ' + '| |\n' + '+---------------------------+-----------------------------------+---------+\n' '\n' 'Notes:\n' '\n' @@ -12896,1145 +12892,1172 @@ 'definition\n' 'may change in the future.\n' '\n' + '\n' 'None\n' - ' This type has a single value. There is a single object with ' - 'this\n' - ' value. This object is accessed through the built-in name "None". ' - 'It\n' - ' is used to signify the absence of a value in many situations, ' - 'e.g.,\n' - ' it is returned from functions that don’t explicitly return\n' - ' anything. Its truth value is false.\n' + '====\n' + '\n' + 'This type has a single value. There is a single object with this\n' + 'value. This object is accessed through the built-in name "None". It ' + 'is\n' + 'used to signify the absence of a value in many situations, e.g., it ' + 'is\n' + 'returned from functions that don’t explicitly return anything. Its\n' + 'truth value is false.\n' + '\n' '\n' 'NotImplemented\n' - ' This type has a single value. There is a single object with ' - 'this\n' - ' value. This object is accessed through the built-in name\n' - ' "NotImplemented". Numeric methods and rich comparison methods\n' - ' should return this value if they do not implement the operation ' - 'for\n' - ' the operands provided. (The interpreter will then try the\n' - ' reflected operation, or some other fallback, depending on the\n' - ' operator.) It should not be evaluated in a boolean context.\n' + '==============\n' + '\n' + 'This type has a single value. There is a single object with this\n' + 'value. This object is accessed through the built-in name\n' + '"NotImplemented". Numeric methods and rich comparison methods ' + 'should\n' + 'return this value if they do not implement the operation for the\n' + 'operands provided. (The interpreter will then try the reflected\n' + 'operation, or some other fallback, depending on the operator.) It\n' + 'should not be evaluated in a boolean context.\n' '\n' - ' See Implementing the arithmetic operations for more details.\n' + 'See Implementing the arithmetic operations for more details.\n' + '\n' + 'Changed in version 3.9: Evaluating "NotImplemented" in a boolean\n' + 'context is deprecated. While it currently evaluates as true, it ' + 'will\n' + 'emit a "DeprecationWarning". It will raise a "TypeError" in a ' + 'future\n' + 'version of Python.\n' '\n' - ' Changed in version 3.9: Evaluating "NotImplemented" in a ' - 'boolean\n' - ' context is deprecated. While it currently evaluates as true, it\n' - ' will emit a "DeprecationWarning". It will raise a "TypeError" in ' - 'a\n' - ' future version of Python.\n' '\n' 'Ellipsis\n' - ' This type has a single value. There is a single object with ' - 'this\n' - ' value. This object is accessed through the literal "..." or the\n' - ' built-in name "Ellipsis". Its truth value is true.\n' + '========\n' + '\n' + 'This type has a single value. There is a single object with this\n' + 'value. This object is accessed through the literal "..." or the ' + 'built-\n' + 'in name "Ellipsis". Its truth value is true.\n' + '\n' '\n' '"numbers.Number"\n' - ' These are created by numeric literals and returned as results ' - 'by\n' - ' arithmetic operators and arithmetic built-in functions. ' - 'Numeric\n' - ' objects are immutable; once created their value never changes.\n' - ' Python numbers are of course strongly related to mathematical\n' - ' numbers, but subject to the limitations of numerical ' - 'representation\n' - ' in computers.\n' - '\n' - ' The string representations of the numeric classes, computed by\n' - ' "__repr__()" and "__str__()", have the following properties:\n' - '\n' - ' * They are valid numeric literals which, when passed to their ' + '================\n' + '\n' + 'These are created by numeric literals and returned as results by\n' + 'arithmetic operators and arithmetic built-in functions. Numeric\n' + 'objects are immutable; once created their value never changes. ' + 'Python\n' + 'numbers are of course strongly related to mathematical numbers, ' + 'but\n' + 'subject to the limitations of numerical representation in ' + 'computers.\n' + '\n' + 'The string representations of the numeric classes, computed by\n' + '"__repr__()" and "__str__()", have the following properties:\n' + '\n' + '* They are valid numeric literals which, when passed to their ' 'class\n' - ' constructor, produce an object having the value of the ' - 'original\n' - ' numeric.\n' + ' constructor, produce an object having the value of the original\n' + ' numeric.\n' '\n' - ' * The representation is in base 10, when possible.\n' + '* The representation is in base 10, when possible.\n' '\n' - ' * Leading zeros, possibly excepting a single zero before a ' - 'decimal\n' - ' point, are not shown.\n' + '* Leading zeros, possibly excepting a single zero before a decimal\n' + ' point, are not shown.\n' '\n' - ' * Trailing zeros, possibly excepting a single zero after a ' - 'decimal\n' - ' point, are not shown.\n' + '* Trailing zeros, possibly excepting a single zero after a decimal\n' + ' point, are not shown.\n' '\n' - ' * A sign is shown only when the number is negative.\n' + '* A sign is shown only when the number is negative.\n' '\n' - ' Python distinguishes between integers, floating point numbers, ' - 'and\n' - ' complex numbers:\n' + 'Python distinguishes between integers, floating point numbers, and\n' + 'complex numbers:\n' '\n' - ' "numbers.Integral"\n' - ' These represent elements from the mathematical set of ' - 'integers\n' - ' (positive and negative).\n' '\n' - ' There are two types of integers:\n' + '"numbers.Integral"\n' + '------------------\n' '\n' - ' Integers ("int")\n' - ' These represent numbers in an unlimited range, subject to\n' - ' available (virtual) memory only. For the purpose of ' - 'shift\n' - ' and mask operations, a binary representation is assumed, ' - 'and\n' - ' negative numbers are represented in a variant of 2’s\n' - ' complement which gives the illusion of an infinite string ' - 'of\n' - ' sign bits extending to the left.\n' + 'These represent elements from the mathematical set of integers\n' + '(positive and negative).\n' '\n' - ' Booleans ("bool")\n' - ' These represent the truth values False and True. The two\n' - ' objects representing the values "False" and "True" are ' - 'the\n' - ' only Boolean objects. The Boolean type is a subtype of ' + 'Note:\n' + '\n' + ' The rules for integer representation are intended to give the ' + 'most\n' + ' meaningful interpretation of shift and mask operations involving\n' + ' negative integers.\n' + '\n' + 'There are two types of integers:\n' + '\n' + 'Integers ("int")\n' + ' These represent numbers in an unlimited range, subject to ' + 'available\n' + ' (virtual) memory only. For the purpose of shift and mask\n' + ' operations, a binary representation is assumed, and negative\n' + ' numbers are represented in a variant of 2’s complement which ' + 'gives\n' + ' the illusion of an infinite string of sign bits extending to ' 'the\n' - ' integer type, and Boolean values behave like the values 0 ' - 'and\n' - ' 1, respectively, in almost all contexts, the exception ' - 'being\n' - ' that when converted to a string, the strings ""False"" or\n' - ' ""True"" are returned, respectively.\n' + ' left.\n' + '\n' + 'Booleans ("bool")\n' + ' These represent the truth values False and True. The two ' + 'objects\n' + ' representing the values "False" and "True" are the only Boolean\n' + ' objects. The Boolean type is a subtype of the integer type, and\n' + ' Boolean values behave like the values 0 and 1, respectively, in\n' + ' almost all contexts, the exception being that when converted to ' + 'a\n' + ' string, the strings ""False"" or ""True"" are returned,\n' + ' respectively.\n' + '\n' + '\n' + '"numbers.Real" ("float")\n' + '------------------------\n' '\n' - ' The rules for integer representation are intended to give ' + 'These represent machine-level double precision floating point ' + 'numbers.\n' + 'You are at the mercy of the underlying machine architecture (and C ' + 'or\n' + 'Java implementation) for the accepted range and handling of ' + 'overflow.\n' + 'Python does not support single-precision floating point numbers; ' 'the\n' - ' most meaningful interpretation of shift and mask operations\n' - ' involving negative integers.\n' - '\n' - ' "numbers.Real" ("float")\n' - ' These represent machine-level double precision floating ' - 'point\n' - ' numbers. You are at the mercy of the underlying machine\n' - ' architecture (and C or Java implementation) for the accepted\n' - ' range and handling of overflow. Python does not support ' - 'single-\n' - ' precision floating point numbers; the savings in processor ' - 'and\n' - ' memory usage that are usually the reason for using these are\n' - ' dwarfed by the overhead of using objects in Python, so there ' - 'is\n' - ' no reason to complicate the language with two kinds of ' - 'floating\n' - ' point numbers.\n' - '\n' - ' "numbers.Complex" ("complex")\n' - ' These represent complex numbers as a pair of machine-level\n' - ' double precision floating point numbers. The same caveats ' - 'apply\n' - ' as for floating point numbers. The real and imaginary parts ' - 'of a\n' - ' complex number "z" can be retrieved through the read-only\n' - ' attributes "z.real" and "z.imag".\n' + 'savings in processor and memory usage that are usually the reason ' + 'for\n' + 'using these are dwarfed by the overhead of using objects in Python, ' + 'so\n' + 'there is no reason to complicate the language with two kinds of\n' + 'floating point numbers.\n' + '\n' + '\n' + '"numbers.Complex" ("complex")\n' + '-----------------------------\n' + '\n' + 'These represent complex numbers as a pair of machine-level double\n' + 'precision floating point numbers. The same caveats apply as for\n' + 'floating point numbers. The real and imaginary parts of a complex\n' + 'number "z" can be retrieved through the read-only attributes ' + '"z.real"\n' + 'and "z.imag".\n' + '\n' '\n' 'Sequences\n' - ' These represent finite ordered sets indexed by non-negative\n' - ' numbers. The built-in function "len()" returns the number of ' - 'items\n' - ' of a sequence. When the length of a sequence is *n*, the index ' + '=========\n' + '\n' + 'These represent finite ordered sets indexed by non-negative ' + 'numbers.\n' + 'The built-in function "len()" returns the number of items of a\n' + 'sequence. When the length of a sequence is *n*, the index set ' + 'contains\n' + 'the numbers 0, 1, …, *n*-1. Item *i* of sequence *a* is selected ' + 'by\n' + '"a[i]".\n' + '\n' + 'Sequences also support slicing: "a[i:j]" selects all items with ' + 'index\n' + '*k* such that *i* "<=" *k* "<" *j*. When used as an expression, a\n' + 'slice is a sequence of the same type. This implies that the index ' 'set\n' - ' contains the numbers 0, 1, …, *n*-1. Item *i* of sequence *a* ' - 'is\n' - ' selected by "a[i]".\n' + 'is renumbered so that it starts at 0.\n' '\n' - ' Sequences also support slicing: "a[i:j]" selects all items with\n' - ' index *k* such that *i* "<=" *k* "<" *j*. When used as an\n' - ' expression, a slice is a sequence of the same type. This ' - 'implies\n' - ' that the index set is renumbered so that it starts at 0.\n' + 'Some sequences also support “extended slicing†with a third “stepâ€\n' + 'parameter: "a[i:j:k]" selects all items of *a* with index *x* where ' + '"x\n' + '= i + n*k", *n* ">=" "0" and *i* "<=" *x* "<" *j*.\n' '\n' - ' Some sequences also support “extended slicing†with a third ' - '“stepâ€\n' - ' parameter: "a[i:j:k]" selects all items of *a* with index *x* ' - 'where\n' - ' "x = i + n*k", *n* ">=" "0" and *i* "<=" *x* "<" *j*.\n' + 'Sequences are distinguished according to their mutability:\n' '\n' - ' Sequences are distinguished according to their mutability:\n' '\n' - ' Immutable sequences\n' - ' An object of an immutable sequence type cannot change once it ' - 'is\n' - ' created. (If the object contains references to other ' - 'objects,\n' - ' these other objects may be mutable and may be changed; ' - 'however,\n' - ' the collection of objects directly referenced by an ' - 'immutable\n' - ' object cannot change.)\n' + 'Immutable sequences\n' + '-------------------\n' '\n' - ' The following types are immutable sequences:\n' + 'An object of an immutable sequence type cannot change once it is\n' + 'created. (If the object contains references to other objects, ' + 'these\n' + 'other objects may be mutable and may be changed; however, the\n' + 'collection of objects directly referenced by an immutable object\n' + 'cannot change.)\n' '\n' - ' Strings\n' - ' A string is a sequence of values that represent Unicode ' - 'code\n' - ' points. All the code points in the range "U+0000 - ' - 'U+10FFFF"\n' - ' can be represented in a string. Python doesn’t have a ' - 'char\n' - ' type; instead, every code point in the string is ' - 'represented\n' - ' as a string object with length "1". The built-in ' - 'function\n' - ' "ord()" converts a code point from its string form to an\n' - ' integer in the range "0 - 10FFFF"; "chr()" converts an\n' - ' integer in the range "0 - 10FFFF" to the corresponding ' - 'length\n' - ' "1" string object. "str.encode()" can be used to convert ' - 'a\n' - ' "str" to "bytes" using the given text encoding, and\n' - ' "bytes.decode()" can be used to achieve the opposite.\n' + 'The following types are immutable sequences:\n' '\n' - ' Tuples\n' - ' The items of a tuple are arbitrary Python objects. Tuples ' - 'of\n' - ' two or more items are formed by comma-separated lists of\n' - ' expressions. A tuple of one item (a ‘singleton’) can be\n' - ' formed by affixing a comma to an expression (an expression ' - 'by\n' - ' itself does not create a tuple, since parentheses must be\n' - ' usable for grouping of expressions). An empty tuple can ' + 'Strings\n' + ' A string is a sequence of values that represent Unicode code\n' + ' points. All the code points in the range "U+0000 - U+10FFFF" can ' 'be\n' - ' formed by an empty pair of parentheses.\n' - '\n' - ' Bytes\n' - ' A bytes object is an immutable array. The items are ' - '8-bit\n' - ' bytes, represented by integers in the range 0 <= x < 256.\n' - ' Bytes literals (like "b\'abc\'") and the built-in ' - '"bytes()"\n' - ' constructor can be used to create bytes objects. Also, ' - 'bytes\n' - ' objects can be decoded to strings via the "decode()" ' - 'method.\n' + ' represented in a string. Python doesn’t have a char type; ' + 'instead,\n' + ' every code point in the string is represented as a string ' + 'object\n' + ' with length "1". The built-in function "ord()" converts a code\n' + ' point from its string form to an integer in the range "0 - ' + '10FFFF";\n' + ' "chr()" converts an integer in the range "0 - 10FFFF" to the\n' + ' corresponding length "1" string object. "str.encode()" can be ' + 'used\n' + ' to convert a "str" to "bytes" using the given text encoding, ' + 'and\n' + ' "bytes.decode()" can be used to achieve the opposite.\n' '\n' - ' Mutable sequences\n' - ' Mutable sequences can be changed after they are created. ' - 'The\n' - ' subscription and slicing notations can be used as the target ' + 'Tuples\n' + ' The items of a tuple are arbitrary Python objects. Tuples of two ' + 'or\n' + ' more items are formed by comma-separated lists of expressions. ' + 'A\n' + ' tuple of one item (a ‘singleton’) can be formed by affixing a ' + 'comma\n' + ' to an expression (an expression by itself does not create a ' + 'tuple,\n' + ' since parentheses must be usable for grouping of expressions). ' + 'An\n' + ' empty tuple can be formed by an empty pair of parentheses.\n' + '\n' + 'Bytes\n' + ' A bytes object is an immutable array. The items are 8-bit ' + 'bytes,\n' + ' represented by integers in the range 0 <= x < 256. Bytes ' + 'literals\n' + ' (like "b\'abc\'") and the built-in "bytes()" constructor can be ' + 'used\n' + ' to create bytes objects. Also, bytes objects can be decoded to\n' + ' strings via the "decode()" method.\n' + '\n' + '\n' + 'Mutable sequences\n' + '-----------------\n' + '\n' + 'Mutable sequences can be changed after they are created. The\n' + 'subscription and slicing notations can be used as the target of\n' + 'assignment and "del" (delete) statements.\n' + '\n' + 'Note:\n' + '\n' + ' The "collections" and "array" module provide additional examples ' 'of\n' - ' assignment and "del" (delete) statements.\n' + ' mutable sequence types.\n' '\n' - ' There are currently two intrinsic mutable sequence types:\n' + 'There are currently two intrinsic mutable sequence types:\n' '\n' - ' Lists\n' - ' The items of a list are arbitrary Python objects. Lists ' - 'are\n' - ' formed by placing a comma-separated list of expressions ' - 'in\n' - ' square brackets. (Note that there are no special cases ' - 'needed\n' - ' to form lists of length 0 or 1.)\n' + 'Lists\n' + ' The items of a list are arbitrary Python objects. Lists are ' + 'formed\n' + ' by placing a comma-separated list of expressions in square\n' + ' brackets. (Note that there are no special cases needed to form\n' + ' lists of length 0 or 1.)\n' '\n' - ' Byte Arrays\n' - ' A bytearray object is a mutable array. They are created ' - 'by\n' - ' the built-in "bytearray()" constructor. Aside from being\n' - ' mutable (and hence unhashable), byte arrays otherwise ' - 'provide\n' - ' the same interface and functionality as immutable "bytes"\n' - ' objects.\n' + 'Byte Arrays\n' + ' A bytearray object is a mutable array. They are created by the\n' + ' built-in "bytearray()" constructor. Aside from being mutable ' + '(and\n' + ' hence unhashable), byte arrays otherwise provide the same ' + 'interface\n' + ' and functionality as immutable "bytes" objects.\n' '\n' - ' The extension module "array" provides an additional example ' - 'of a\n' - ' mutable sequence type, as does the "collections" module.\n' '\n' 'Set types\n' - ' These represent unordered, finite sets of unique, immutable\n' - ' objects. As such, they cannot be indexed by any subscript. ' - 'However,\n' - ' they can be iterated over, and the built-in function "len()"\n' - ' returns the number of items in a set. Common uses for sets are ' - 'fast\n' - ' membership testing, removing duplicates from a sequence, and\n' - ' computing mathematical operations such as intersection, union,\n' - ' difference, and symmetric difference.\n' - '\n' - ' For set elements, the same immutability rules apply as for\n' - ' dictionary keys. Note that numeric types obey the normal rules ' - 'for\n' - ' numeric comparison: if two numbers compare equal (e.g., "1" and\n' - ' "1.0"), only one of them can be contained in a set.\n' + '=========\n' + '\n' + 'These represent unordered, finite sets of unique, immutable ' + 'objects.\n' + 'As such, they cannot be indexed by any subscript. However, they can ' + 'be\n' + 'iterated over, and the built-in function "len()" returns the number ' + 'of\n' + 'items in a set. Common uses for sets are fast membership testing,\n' + 'removing duplicates from a sequence, and computing mathematical\n' + 'operations such as intersection, union, difference, and symmetric\n' + 'difference.\n' + '\n' + 'For set elements, the same immutability rules apply as for ' + 'dictionary\n' + 'keys. Note that numeric types obey the normal rules for numeric\n' + 'comparison: if two numbers compare equal (e.g., "1" and "1.0"), ' + 'only\n' + 'one of them can be contained in a set.\n' + '\n' + 'There are currently two intrinsic set types:\n' '\n' - ' There are currently two intrinsic set types:\n' + 'Sets\n' + ' These represent a mutable set. They are created by the built-in\n' + ' "set()" constructor and can be modified afterwards by several\n' + ' methods, such as "add()".\n' '\n' - ' Sets\n' - ' These represent a mutable set. They are created by the ' + 'Frozen sets\n' + ' These represent an immutable set. They are created by the ' 'built-in\n' - ' "set()" constructor and can be modified afterwards by ' - 'several\n' - ' methods, such as "add()".\n' - '\n' - ' Frozen sets\n' - ' These represent an immutable set. They are created by the\n' - ' built-in "frozenset()" constructor. As a frozenset is ' - 'immutable\n' - ' and *hashable*, it can be used again as an element of ' - 'another\n' - ' set, or as a dictionary key.\n' + ' "frozenset()" constructor. As a frozenset is immutable and\n' + ' *hashable*, it can be used again as an element of another set, ' + 'or\n' + ' as a dictionary key.\n' + '\n' '\n' 'Mappings\n' - ' These represent finite sets of objects indexed by arbitrary ' - 'index\n' - ' sets. The subscript notation "a[k]" selects the item indexed by ' + '========\n' + '\n' + 'These represent finite sets of objects indexed by arbitrary index\n' + 'sets. The subscript notation "a[k]" selects the item indexed by ' '"k"\n' - ' from the mapping "a"; this can be used in expressions and as ' - 'the\n' - ' target of assignments or "del" statements. The built-in ' - 'function\n' - ' "len()" returns the number of items in a mapping.\n' + 'from the mapping "a"; this can be used in expressions and as the\n' + 'target of assignments or "del" statements. The built-in function\n' + '"len()" returns the number of items in a mapping.\n' '\n' - ' There is currently a single intrinsic mapping type:\n' + 'There is currently a single intrinsic mapping type:\n' '\n' - ' Dictionaries\n' - ' These represent finite sets of objects indexed by nearly\n' - ' arbitrary values. The only types of values not acceptable ' - 'as\n' - ' keys are values containing lists or dictionaries or other\n' - ' mutable types that are compared by value rather than by ' - 'object\n' - ' identity, the reason being that the efficient implementation ' - 'of\n' - ' dictionaries requires a key’s hash value to remain constant.\n' - ' Numeric types used for keys obey the normal rules for ' - 'numeric\n' - ' comparison: if two numbers compare equal (e.g., "1" and ' - '"1.0")\n' - ' then they can be used interchangeably to index the same\n' - ' dictionary entry.\n' - '\n' - ' Dictionaries preserve insertion order, meaning that keys will ' - 'be\n' - ' produced in the same order they were added sequentially over ' - 'the\n' - ' dictionary. Replacing an existing key does not change the ' - 'order,\n' - ' however removing a key and re-inserting it will add it to ' + '\n' + 'Dictionaries\n' + '------------\n' + '\n' + 'These represent finite sets of objects indexed by nearly arbitrary\n' + 'values. The only types of values not acceptable as keys are ' + 'values\n' + 'containing lists or dictionaries or other mutable types that are\n' + 'compared by value rather than by object identity, the reason being\n' + 'that the efficient implementation of dictionaries requires a key’s\n' + 'hash value to remain constant. Numeric types used for keys obey ' 'the\n' - ' end instead of keeping its old place.\n' + 'normal rules for numeric comparison: if two numbers compare equal\n' + '(e.g., "1" and "1.0") then they can be used interchangeably to ' + 'index\n' + 'the same dictionary entry.\n' '\n' - ' Dictionaries are mutable; they can be created by the "{...}"\n' - ' notation (see section Dictionary displays).\n' + 'Dictionaries preserve insertion order, meaning that keys will be\n' + 'produced in the same order they were added sequentially over the\n' + 'dictionary. Replacing an existing key does not change the order,\n' + 'however removing a key and re-inserting it will add it to the end\n' + 'instead of keeping its old place.\n' '\n' - ' The extension modules "dbm.ndbm" and "dbm.gnu" provide\n' - ' additional examples of mapping types, as does the ' - '"collections"\n' - ' module.\n' + 'Dictionaries are mutable; they can be created by the "{...}" ' + 'notation\n' + '(see section Dictionary displays).\n' + '\n' + 'The extension modules "dbm.ndbm" and "dbm.gnu" provide additional\n' + 'examples of mapping types, as does the "collections" module.\n' + '\n' + 'Changed in version 3.7: Dictionaries did not preserve insertion ' + 'order\n' + 'in versions of Python before 3.6. In CPython 3.6, insertion order ' + 'was\n' + 'preserved, but it was considered an implementation detail at that ' + 'time\n' + 'rather than a language guarantee.\n' '\n' - ' Changed in version 3.7: Dictionaries did not preserve ' - 'insertion\n' - ' order in versions of Python before 3.6. In CPython 3.6,\n' - ' insertion order was preserved, but it was considered an\n' - ' implementation detail at that time rather than a language\n' - ' guarantee.\n' '\n' 'Callable types\n' - ' These are the types to which the function call operation (see\n' - ' section Calls) can be applied:\n' + '==============\n' '\n' - ' User-defined functions\n' - ' A user-defined function object is created by a function\n' - ' definition (see section Function definitions). It should be\n' - ' called with an argument list containing the same number of ' - 'items\n' - ' as the function’s formal parameter list.\n' + 'These are the types to which the function call operation (see ' + 'section\n' + 'Calls) can be applied:\n' '\n' - ' Special attributes:\n' '\n' - ' ' + 'User-defined functions\n' + '----------------------\n' + '\n' + 'A user-defined function object is created by a function definition\n' + '(see section Function definitions). It should be called with an\n' + 'argument list containing the same number of items as the ' + 'function’s\n' + 'formal parameter list.\n' + '\n' + 'Special attributes:\n' + '\n' '+---------------------------+---------------------------------+-------------+\n' - ' | Attribute | Meaning ' + '| Attribute | Meaning ' '| |\n' - ' ' '|===========================|=================================|=============|\n' - ' | "__doc__" | The function’s documentation ' - '| Writable |\n' - ' | | string, or "None" if ' + '| "__doc__" | The function’s documentation | ' + 'Writable |\n' + '| | string, or "None" if ' '| |\n' - ' | | unavailable; not inherited by ' + '| | unavailable; not inherited by ' '| |\n' - ' | | subclasses. ' + '| | subclasses. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__name__" | The function’s name. ' - '| Writable |\n' - ' ' + '| "__name__" | The function’s name. | ' + 'Writable |\n' '+---------------------------+---------------------------------+-------------+\n' - ' | "__qualname__" | The function’s *qualified ' - '| Writable |\n' - ' | | name*. New in version 3.3. ' + '| "__qualname__" | The function’s *qualified | ' + 'Writable |\n' + '| | name*. New in version 3.3. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__module__" | The name of the module the ' - '| Writable |\n' - ' | | function was defined in, or ' + '| "__module__" | The name of the module the | ' + 'Writable |\n' + '| | function was defined in, or ' '| |\n' - ' | | "None" if unavailable. ' + '| | "None" if unavailable. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__defaults__" | A tuple containing default ' - '| Writable |\n' - ' | | argument values for those ' + '| "__defaults__" | A tuple containing default | ' + 'Writable |\n' + '| | argument values for those ' '| |\n' - ' | | arguments that have defaults, ' + '| | arguments that have defaults, ' '| |\n' - ' | | or "None" if no arguments have ' + '| | or "None" if no arguments have ' '| |\n' - ' | | a default value. ' + '| | a default value. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__code__" | The code object representing ' - '| Writable |\n' - ' | | the compiled function body. ' + '| "__code__" | The code object representing | ' + 'Writable |\n' + '| | the compiled function body. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__globals__" | A reference to the dictionary ' - '| Read-only |\n' - ' | | that holds the function’s ' + '| "__globals__" | A reference to the dictionary | ' + 'Read-only |\n' + '| | that holds the function’s ' '| |\n' - ' | | global variables — the global ' + '| | global variables — the global ' '| |\n' - ' | | namespace of the module in ' + '| | namespace of the module in ' '| |\n' - ' | | which the function was defined. ' + '| | which the function was defined. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__dict__" | The namespace supporting ' - '| Writable |\n' - ' | | arbitrary function attributes. ' + '| "__dict__" | The namespace supporting | ' + 'Writable |\n' + '| | arbitrary function attributes. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__closure__" | "None" or a tuple of cells that ' - '| Read-only |\n' - ' | | contain bindings for the ' + '| "__closure__" | "None" or a tuple of cells that | ' + 'Read-only |\n' + '| | contain bindings for the ' '| |\n' - ' | | function’s free variables. See ' + '| | function’s free variables. See ' '| |\n' - ' | | below for information on the ' + '| | below for information on the ' '| |\n' - ' | | "cell_contents" attribute. ' + '| | "cell_contents" attribute. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__annotations__" | A dict containing annotations ' - '| Writable |\n' - ' | | of parameters. The keys of the ' + '| "__annotations__" | A dict containing annotations | ' + 'Writable |\n' + '| | of parameters. The keys of the ' + '| |\n' + '| | dict are the parameter names, ' '| |\n' - ' | | dict are the parameter names, ' + '| | and "\'return\'" for the return ' '| |\n' - ' | | and "\'return\'" for the ' - 'return | |\n' - ' | | annotation, if provided. For ' + '| | annotation, if provided. For ' '| |\n' - ' | | more information on working ' + '| | more information on working ' '| |\n' - ' | | with this attribute, see ' + '| | with this attribute, see ' '| |\n' - ' | | Annotations Best Practices. ' + '| | Annotations Best Practices. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__kwdefaults__" | A dict containing defaults for ' - '| Writable |\n' - ' | | keyword-only parameters. ' + '| "__kwdefaults__" | A dict containing defaults for | ' + 'Writable |\n' + '| | keyword-only parameters. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' '\n' - ' Most of the attributes labelled “Writable†check the type of ' - 'the\n' - ' assigned value.\n' + 'Most of the attributes labelled “Writable†check the type of the\n' + 'assigned value.\n' '\n' - ' Function objects also support getting and setting arbitrary\n' - ' attributes, which can be used, for example, to attach ' - 'metadata\n' - ' to functions. Regular attribute dot-notation is used to get ' - 'and\n' - ' set such attributes. *Note that the current implementation ' - 'only\n' - ' supports function attributes on user-defined functions. ' - 'Function\n' - ' attributes on built-in functions may be supported in the\n' - ' future.*\n' - '\n' - ' A cell object has the attribute "cell_contents". This can be\n' - ' used to get the value of the cell, as well as set the value.\n' - '\n' - ' Additional information about a function’s definition can be\n' - ' retrieved from its code object; see the description of ' - 'internal\n' - ' types below. The "cell" type can be accessed in the "types"\n' - ' module.\n' - '\n' - ' Instance methods\n' - ' An instance method object combines a class, a class instance ' - 'and\n' - ' any callable object (normally a user-defined function).\n' - '\n' - ' Special read-only attributes: "__self__" is the class ' - 'instance\n' - ' object, "__func__" is the function object; "__doc__" is the\n' - ' method’s documentation (same as "__func__.__doc__"); ' - '"__name__"\n' - ' is the method name (same as "__func__.__name__"); ' - '"__module__"\n' - ' is the name of the module the method was defined in, or ' - '"None"\n' - ' if unavailable.\n' + 'Function objects also support getting and setting arbitrary\n' + 'attributes, which can be used, for example, to attach metadata to\n' + 'functions. Regular attribute dot-notation is used to get and set ' + 'such\n' + 'attributes. *Note that the current implementation only supports\n' + 'function attributes on user-defined functions. Function attributes ' + 'on\n' + 'built-in functions may be supported in the future.*\n' '\n' - ' Methods also support accessing (but not setting) the ' - 'arbitrary\n' - ' function attributes on the underlying function object.\n' + 'A cell object has the attribute "cell_contents". This can be used ' + 'to\n' + 'get the value of the cell, as well as set the value.\n' '\n' - ' User-defined method objects may be created when getting an\n' - ' attribute of a class (perhaps via an instance of that class), ' - 'if\n' - ' that attribute is a user-defined function object or a class\n' - ' method object.\n' - '\n' - ' When an instance method object is created by retrieving a ' - 'user-\n' - ' defined function object from a class via one of its ' - 'instances,\n' - ' its "__self__" attribute is the instance, and the method ' - 'object\n' - ' is said to be bound. The new method’s "__func__" attribute ' - 'is\n' - ' the original function object.\n' + 'Additional information about a function’s definition can be ' + 'retrieved\n' + 'from its code object; see the description of internal types below. ' + 'The\n' + '"cell" type can be accessed in the "types" module.\n' '\n' - ' When an instance method object is created by retrieving a ' - 'class\n' - ' method object from a class or instance, its "__self__" ' - 'attribute\n' - ' is the class itself, and its "__func__" attribute is the\n' - ' function object underlying the class method.\n' '\n' - ' When an instance method object is called, the underlying\n' - ' function ("__func__") is called, inserting the class ' - 'instance\n' - ' ("__self__") in front of the argument list. For instance, ' - 'when\n' - ' "C" is a class which contains a definition for a function ' - '"f()",\n' - ' and "x" is an instance of "C", calling "x.f(1)" is equivalent ' - 'to\n' - ' calling "C.f(x, 1)".\n' + 'Instance methods\n' + '----------------\n' + '\n' + 'An instance method object combines a class, a class instance and ' + 'any\n' + 'callable object (normally a user-defined function).\n' '\n' - ' When an instance method object is derived from a class ' + 'Special read-only attributes: "__self__" is the class instance ' + 'object,\n' + '"__func__" is the function object; "__doc__" is the method’s\n' + 'documentation (same as "__func__.__doc__"); "__name__" is the ' 'method\n' - ' object, the “class instance†stored in "__self__" will ' - 'actually\n' - ' be the class itself, so that calling either "x.f(1)" or ' - '"C.f(1)"\n' - ' is equivalent to calling "f(C,1)" where "f" is the ' - 'underlying\n' - ' function.\n' - '\n' - ' Note that the transformation from function object to ' - 'instance\n' - ' method object happens each time the attribute is retrieved ' - 'from\n' - ' the instance. In some cases, a fruitful optimization is to\n' - ' assign the attribute to a local variable and call that local\n' - ' variable. Also notice that this transformation only happens ' - 'for\n' - ' user-defined functions; other callable objects (and all non-\n' - ' callable objects) are retrieved without transformation. It ' - 'is\n' - ' also important to note that user-defined functions which are\n' - ' attributes of a class instance are not converted to bound\n' - ' methods; this *only* happens when the function is an ' + 'name (same as "__func__.__name__"); "__module__" is the name of ' + 'the\n' + 'module the method was defined in, or "None" if unavailable.\n' + '\n' + 'Methods also support accessing (but not setting) the arbitrary\n' + 'function attributes on the underlying function object.\n' + '\n' + 'User-defined method objects may be created when getting an ' + 'attribute\n' + 'of a class (perhaps via an instance of that class), if that ' 'attribute\n' - ' of the class.\n' + 'is a user-defined function object or a class method object.\n' '\n' - ' Generator functions\n' - ' A function or method which uses the "yield" statement (see\n' - ' section The yield statement) is called a *generator ' - 'function*.\n' - ' Such a function, when called, always returns an *iterator*\n' - ' object which can be used to execute the body of the ' - 'function:\n' - ' calling the iterator’s "iterator.__next__()" method will ' - 'cause\n' - ' the function to execute until it provides a value using the\n' - ' "yield" statement. When the function executes a "return"\n' - ' statement or falls off the end, a "StopIteration" exception ' - 'is\n' - ' raised and the iterator will have reached the end of the set ' + 'When an instance method object is created by retrieving a ' + 'user-defined\n' + 'function object from a class via one of its instances, its ' + '"__self__"\n' + 'attribute is the instance, and the method object is said to be ' + 'bound.\n' + 'The new method’s "__func__" attribute is the original function ' + 'object.\n' + '\n' + 'When an instance method object is created by retrieving a class ' + 'method\n' + 'object from a class or instance, its "__self__" attribute is the ' + 'class\n' + 'itself, and its "__func__" attribute is the function object ' + 'underlying\n' + 'the class method.\n' + '\n' + 'When an instance method object is called, the underlying function\n' + '("__func__") is called, inserting the class instance ("__self__") ' + 'in\n' + 'front of the argument list. For instance, when "C" is a class ' + 'which\n' + 'contains a definition for a function "f()", and "x" is an instance ' 'of\n' - ' values to be returned.\n' - '\n' - ' Coroutine functions\n' - ' A function or method which is defined using "async def" is\n' - ' called a *coroutine function*. Such a function, when ' - 'called,\n' - ' returns a *coroutine* object. It may contain "await"\n' - ' expressions, as well as "async with" and "async for" ' - 'statements.\n' - ' See also the Coroutine Objects section.\n' - '\n' - ' Asynchronous generator functions\n' - ' A function or method which is defined using "async def" and\n' - ' which uses the "yield" statement is called a *asynchronous\n' - ' generator function*. Such a function, when called, returns ' - 'an\n' - ' *asynchronous iterator* object which can be used in an ' - '"async\n' - ' for" statement to execute the body of the function.\n' + '"C", calling "x.f(1)" is equivalent to calling "C.f(x, 1)".\n' '\n' - ' Calling the asynchronous iterator’s "aiterator.__anext__" ' + 'When an instance method object is derived from a class method ' + 'object,\n' + 'the “class instance†stored in "__self__" will actually be the ' + 'class\n' + 'itself, so that calling either "x.f(1)" or "C.f(1)" is equivalent ' + 'to\n' + 'calling "f(C,1)" where "f" is the underlying function.\n' + '\n' + 'Note that the transformation from function object to instance ' 'method\n' - ' will return an *awaitable* which when awaited will execute ' + 'object happens each time the attribute is retrieved from the ' + 'instance.\n' + 'In some cases, a fruitful optimization is to assign the attribute ' + 'to a\n' + 'local variable and call that local variable. Also notice that this\n' + 'transformation only happens for user-defined functions; other ' + 'callable\n' + 'objects (and all non-callable objects) are retrieved without\n' + 'transformation. It is also important to note that user-defined\n' + 'functions which are attributes of a class instance are not ' + 'converted\n' + 'to bound methods; this *only* happens when the function is an\n' + 'attribute of the class.\n' + '\n' + '\n' + 'Generator functions\n' + '-------------------\n' + '\n' + 'A function or method which uses the "yield" statement (see section ' + 'The\n' + 'yield statement) is called a *generator function*. Such a ' + 'function,\n' + 'when called, always returns an *iterator* object which can be used ' + 'to\n' + 'execute the body of the function: calling the iterator’s\n' + '"iterator.__next__()" method will cause the function to execute ' 'until\n' - ' it provides a value using the "yield" expression. When the\n' - ' function executes an empty "return" statement or falls off ' + 'it provides a value using the "yield" statement. When the ' + 'function\n' + 'executes a "return" statement or falls off the end, a ' + '"StopIteration"\n' + 'exception is raised and the iterator will have reached the end of ' 'the\n' - ' end, a "StopAsyncIteration" exception is raised and the\n' - ' asynchronous iterator will have reached the end of the set ' - 'of\n' - ' values to be yielded.\n' + 'set of values to be returned.\n' '\n' - ' Built-in functions\n' - ' A built-in function object is a wrapper around a C function.\n' - ' Examples of built-in functions are "len()" and "math.sin()"\n' - ' ("math" is a standard built-in module). The number and type ' - 'of\n' - ' the arguments are determined by the C function. Special ' - 'read-\n' - ' only attributes: "__doc__" is the function’s documentation\n' - ' string, or "None" if unavailable; "__name__" is the ' - 'function’s\n' - ' name; "__self__" is set to "None" (but see the next item);\n' - ' "__module__" is the name of the module the function was ' - 'defined\n' - ' in or "None" if unavailable.\n' '\n' - ' Built-in methods\n' - ' This is really a different disguise of a built-in function, ' - 'this\n' - ' time containing an object passed to the C function as an\n' - ' implicit extra argument. An example of a built-in method is\n' - ' "alist.append()", assuming *alist* is a list object. In this\n' - ' case, the special read-only attribute "__self__" is set to ' + 'Coroutine functions\n' + '-------------------\n' + '\n' + 'A function or method which is defined using "async def" is called ' + 'a\n' + '*coroutine function*. Such a function, when called, returns a\n' + '*coroutine* object. It may contain "await" expressions, as well ' + 'as\n' + '"async with" and "async for" statements. See also the Coroutine\n' + 'Objects section.\n' + '\n' + '\n' + 'Asynchronous generator functions\n' + '--------------------------------\n' + '\n' + 'A function or method which is defined using "async def" and which ' + 'uses\n' + 'the "yield" statement is called a *asynchronous generator ' + 'function*.\n' + 'Such a function, when called, returns an *asynchronous iterator*\n' + 'object which can be used in an "async for" statement to execute ' 'the\n' - ' object denoted by *alist*.\n' + 'body of the function.\n' + '\n' + 'Calling the asynchronous iterator’s "aiterator.__anext__" method ' + 'will\n' + 'return an *awaitable* which when awaited will execute until it\n' + 'provides a value using the "yield" expression. When the function\n' + 'executes an empty "return" statement or falls off the end, a\n' + '"StopAsyncIteration" exception is raised and the asynchronous ' + 'iterator\n' + 'will have reached the end of the set of values to be yielded.\n' + '\n' + '\n' + 'Built-in functions\n' + '------------------\n' + '\n' + 'A built-in function object is a wrapper around a C function. ' + 'Examples\n' + 'of built-in functions are "len()" and "math.sin()" ("math" is a\n' + 'standard built-in module). The number and type of the arguments ' + 'are\n' + 'determined by the C function. Special read-only attributes: ' + '"__doc__"\n' + 'is the function’s documentation string, or "None" if unavailable;\n' + '"__name__" is the function’s name; "__self__" is set to "None" ' + '(but\n' + 'see the next item); "__module__" is the name of the module the\n' + 'function was defined in or "None" if unavailable.\n' + '\n' + '\n' + 'Built-in methods\n' + '----------------\n' + '\n' + 'This is really a different disguise of a built-in function, this ' + 'time\n' + 'containing an object passed to the C function as an implicit extra\n' + 'argument. An example of a built-in method is "alist.append()",\n' + 'assuming *alist* is a list object. In this case, the special ' + 'read-only\n' + 'attribute "__self__" is set to the object denoted by *alist*.\n' + '\n' + '\n' + 'Classes\n' + '-------\n' + '\n' + 'Classes are callable. These objects normally act as factories for ' + 'new\n' + 'instances of themselves, but variations are possible for class ' + 'types\n' + 'that override "__new__()". The arguments of the call are passed ' + 'to\n' + '"__new__()" and, in the typical case, to "__init__()" to ' + 'initialize\n' + 'the new instance.\n' '\n' - ' Classes\n' - ' Classes are callable. These objects normally act as ' - 'factories\n' - ' for new instances of themselves, but variations are possible ' - 'for\n' - ' class types that override "__new__()". The arguments of the\n' - ' call are passed to "__new__()" and, in the typical case, to\n' - ' "__init__()" to initialize the new instance.\n' '\n' - ' Class Instances\n' - ' Instances of arbitrary classes can be made callable by ' - 'defining\n' - ' a "__call__()" method in their class.\n' + 'Class Instances\n' + '---------------\n' + '\n' + 'Instances of arbitrary classes can be made callable by defining a\n' + '"__call__()" method in their class.\n' + '\n' '\n' 'Modules\n' - ' Modules are a basic organizational unit of Python code, and are\n' - ' created by the import system as invoked either by the "import"\n' - ' statement, or by calling functions such as\n' - ' "importlib.import_module()" and built-in "__import__()". A ' - 'module\n' - ' object has a namespace implemented by a dictionary object (this ' - 'is\n' - ' the dictionary referenced by the "__globals__" attribute of\n' - ' functions defined in the module). Attribute references are\n' - ' translated to lookups in this dictionary, e.g., "m.x" is ' - 'equivalent\n' - ' to "m.__dict__["x"]". A module object does not contain the code\n' - ' object used to initialize the module (since it isn’t needed ' - 'once\n' - ' the initialization is done).\n' + '=======\n' + '\n' + 'Modules are a basic organizational unit of Python code, and are\n' + 'created by the import system as invoked either by the "import"\n' + 'statement, or by calling functions such as ' + '"importlib.import_module()"\n' + 'and built-in "__import__()". A module object has a namespace\n' + 'implemented by a dictionary object (this is the dictionary ' + 'referenced\n' + 'by the "__globals__" attribute of functions defined in the ' + 'module).\n' + 'Attribute references are translated to lookups in this dictionary,\n' + 'e.g., "m.x" is equivalent to "m.__dict__["x"]". A module object ' + 'does\n' + 'not contain the code object used to initialize the module (since ' + 'it\n' + 'isn’t needed once the initialization is done).\n' + '\n' + 'Attribute assignment updates the module’s namespace dictionary, ' + 'e.g.,\n' + '"m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n' '\n' - ' Attribute assignment updates the module’s namespace dictionary,\n' - ' e.g., "m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n' + 'Predefined (writable) attributes:\n' '\n' - ' Predefined (writable) attributes:\n' + ' "__name__"\n' + ' The module’s name.\n' '\n' - ' "__name__"\n' - ' The module’s name.\n' + ' "__doc__"\n' + ' The module’s documentation string, or "None" if unavailable.\n' '\n' - ' "__doc__"\n' - ' The module’s documentation string, or "None" if ' - 'unavailable.\n' + ' "__file__"\n' + ' The pathname of the file from which the module was loaded, if ' + 'it\n' + ' was loaded from a file. The "__file__" attribute may be ' + 'missing\n' + ' for certain types of modules, such as C modules that are\n' + ' statically linked into the interpreter. For extension ' + 'modules\n' + ' loaded dynamically from a shared library, it’s the pathname ' + 'of\n' + ' the shared library file.\n' '\n' - ' "__file__"\n' - ' The pathname of the file from which the module was loaded, ' - 'if\n' - ' it was loaded from a file. The "__file__" attribute may ' - 'be\n' - ' missing for certain types of modules, such as C modules ' - 'that\n' - ' are statically linked into the interpreter. For ' - 'extension\n' - ' modules loaded dynamically from a shared library, it’s ' - 'the\n' - ' pathname of the shared library file.\n' - '\n' - ' "__annotations__"\n' - ' A dictionary containing *variable annotations* collected\n' - ' during module body execution. For best practices on ' - 'working\n' - ' with "__annotations__", please see Annotations Best\n' - ' Practices.\n' - '\n' - ' Special read-only attribute: "__dict__" is the module’s ' - 'namespace\n' - ' as a dictionary object.\n' - '\n' - ' **CPython implementation detail:** Because of the way CPython\n' - ' clears module dictionaries, the module dictionary will be ' - 'cleared\n' - ' when the module falls out of scope even if the dictionary still ' - 'has\n' - ' live references. To avoid this, copy the dictionary or keep ' + ' "__annotations__"\n' + ' A dictionary containing *variable annotations* collected ' + 'during\n' + ' module body execution. For best practices on working with\n' + ' "__annotations__", please see Annotations Best Practices.\n' + '\n' + 'Special read-only attribute: "__dict__" is the module’s namespace ' + 'as a\n' + 'dictionary object.\n' + '\n' + '**CPython implementation detail:** Because of the way CPython ' + 'clears\n' + 'module dictionaries, the module dictionary will be cleared when ' 'the\n' - ' module around while using its dictionary directly.\n' + 'module falls out of scope even if the dictionary still has live\n' + 'references. To avoid this, copy the dictionary or keep the module\n' + 'around while using its dictionary directly.\n' + '\n' '\n' 'Custom classes\n' - ' Custom class types are typically created by class definitions ' - '(see\n' - ' section Class definitions). A class has a namespace implemented ' - 'by\n' - ' a dictionary object. Class attribute references are translated ' - 'to\n' - ' lookups in this dictionary, e.g., "C.x" is translated to\n' - ' "C.__dict__["x"]" (although there are a number of hooks which ' + '==============\n' + '\n' + 'Custom class types are typically created by class definitions (see\n' + 'section Class definitions). A class has a namespace implemented by ' + 'a\n' + 'dictionary object. Class attribute references are translated to\n' + 'lookups in this dictionary, e.g., "C.x" is translated to\n' + '"C.__dict__["x"]" (although there are a number of hooks which ' 'allow\n' - ' for other means of locating attributes). When the attribute name ' + 'for other means of locating attributes). When the attribute name ' 'is\n' - ' not found there, the attribute search continues in the base\n' - ' classes. This search of the base classes uses the C3 method\n' - ' resolution order which behaves correctly even in the presence ' - 'of\n' - ' ‘diamond’ inheritance structures where there are multiple\n' - ' inheritance paths leading back to a common ancestor. Additional\n' - ' details on the C3 MRO used by Python can be found in the\n' - ' documentation accompanying the 2.3 release at\n' - ' https://www.python.org/download/releases/2.3/mro/.\n' - '\n' - ' When a class attribute reference (for class "C", say) would ' - 'yield a\n' - ' class method object, it is transformed into an instance method\n' - ' object whose "__self__" attribute is "C". When it would yield ' + 'not found there, the attribute search continues in the base ' + 'classes.\n' + 'This search of the base classes uses the C3 method resolution ' + 'order\n' + 'which behaves correctly even in the presence of ‘diamond’ ' + 'inheritance\n' + 'structures where there are multiple inheritance paths leading back ' + 'to\n' + 'a common ancestor. Additional details on the C3 MRO used by Python ' + 'can\n' + 'be found in the documentation accompanying the 2.3 release at\n' + 'https://www.python.org/download/releases/2.3/mro/.\n' + '\n' + 'When a class attribute reference (for class "C", say) would yield ' 'a\n' - ' static method object, it is transformed into the object wrapped ' - 'by\n' - ' the static method object. See section Implementing Descriptors ' - 'for\n' - ' another way in which attributes retrieved from a class may ' - 'differ\n' - ' from those actually contained in its "__dict__".\n' + 'class method object, it is transformed into an instance method ' + 'object\n' + 'whose "__self__" attribute is "C". When it would yield a static\n' + 'method object, it is transformed into the object wrapped by the ' + 'static\n' + 'method object. See section Implementing Descriptors for another way ' + 'in\n' + 'which attributes retrieved from a class may differ from those ' + 'actually\n' + 'contained in its "__dict__".\n' '\n' - ' Class attribute assignments update the class’s dictionary, ' - 'never\n' - ' the dictionary of a base class.\n' + 'Class attribute assignments update the class’s dictionary, never ' + 'the\n' + 'dictionary of a base class.\n' + '\n' + 'A class object can be called (see above) to yield a class instance\n' + '(see below).\n' '\n' - ' A class object can be called (see above) to yield a class ' - 'instance\n' - ' (see below).\n' + 'Special attributes:\n' '\n' - ' Special attributes:\n' + ' "__name__"\n' + ' The class name.\n' '\n' - ' "__name__"\n' - ' The class name.\n' + ' "__module__"\n' + ' The name of the module in which the class was defined.\n' '\n' - ' "__module__"\n' - ' The name of the module in which the class was defined.\n' + ' "__dict__"\n' + ' The dictionary containing the class’s namespace.\n' '\n' - ' "__dict__"\n' - ' The dictionary containing the class’s namespace.\n' + ' "__bases__"\n' + ' A tuple containing the base classes, in the order of their\n' + ' occurrence in the base class list.\n' '\n' - ' "__bases__"\n' - ' A tuple containing the base classes, in the order of ' - 'their\n' - ' occurrence in the base class list.\n' + ' "__doc__"\n' + ' The class’s documentation string, or "None" if undefined.\n' '\n' - ' "__doc__"\n' - ' The class’s documentation string, or "None" if undefined.\n' + ' "__annotations__"\n' + ' A dictionary containing *variable annotations* collected ' + 'during\n' + ' class body execution. For best practices on working with\n' + ' "__annotations__", please see Annotations Best Practices.\n' '\n' - ' "__annotations__"\n' - ' A dictionary containing *variable annotations* collected\n' - ' during class body execution. For best practices on ' - 'working\n' - ' with "__annotations__", please see Annotations Best\n' - ' Practices.\n' '\n' 'Class instances\n' - ' A class instance is created by calling a class object (see ' - 'above).\n' - ' A class instance has a namespace implemented as a dictionary ' - 'which\n' - ' is the first place in which attribute references are searched.\n' - ' When an attribute is not found there, and the instance’s class ' - 'has\n' - ' an attribute by that name, the search continues with the class\n' - ' attributes. If a class attribute is found that is a ' - 'user-defined\n' - ' function object, it is transformed into an instance method ' - 'object\n' - ' whose "__self__" attribute is the instance. Static method and\n' - ' class method objects are also transformed; see above under\n' - ' “Classesâ€. See section Implementing Descriptors for another way ' - 'in\n' - ' which attributes of a class retrieved via its instances may ' - 'differ\n' - ' from the objects actually stored in the class’s "__dict__". If ' - 'no\n' - ' class attribute is found, and the object’s class has a\n' - ' "__getattr__()" method, that is called to satisfy the lookup.\n' + '===============\n' '\n' - ' Attribute assignments and deletions update the instance’s\n' - ' dictionary, never a class’s dictionary. If the class has a\n' - ' "__setattr__()" or "__delattr__()" method, this is called ' - 'instead\n' - ' of updating the instance dictionary directly.\n' + 'A class instance is created by calling a class object (see above). ' + 'A\n' + 'class instance has a namespace implemented as a dictionary which ' + 'is\n' + 'the first place in which attribute references are searched. When ' + 'an\n' + 'attribute is not found there, and the instance’s class has an\n' + 'attribute by that name, the search continues with the class\n' + 'attributes. If a class attribute is found that is a user-defined\n' + 'function object, it is transformed into an instance method object\n' + 'whose "__self__" attribute is the instance. Static method and ' + 'class\n' + 'method objects are also transformed; see above under “Classesâ€. ' + 'See\n' + 'section Implementing Descriptors for another way in which ' + 'attributes\n' + 'of a class retrieved via its instances may differ from the objects\n' + 'actually stored in the class’s "__dict__". If no class attribute ' + 'is\n' + 'found, and the object’s class has a "__getattr__()" method, that ' + 'is\n' + 'called to satisfy the lookup.\n' '\n' - ' Class instances can pretend to be numbers, sequences, or ' - 'mappings\n' - ' if they have methods with certain special names. See section\n' - ' Special method names.\n' + 'Attribute assignments and deletions update the instance’s ' + 'dictionary,\n' + 'never a class’s dictionary. If the class has a "__setattr__()" or\n' + '"__delattr__()" method, this is called instead of updating the\n' + 'instance dictionary directly.\n' + '\n' + 'Class instances can pretend to be numbers, sequences, or mappings ' + 'if\n' + 'they have methods with certain special names. See section Special\n' + 'method names.\n' + '\n' + 'Special attributes: "__dict__" is the attribute dictionary;\n' + '"__class__" is the instance’s class.\n' '\n' - ' Special attributes: "__dict__" is the attribute dictionary;\n' - ' "__class__" is the instance’s class.\n' '\n' 'I/O objects (also known as file objects)\n' - ' A *file object* represents an open file. Various shortcuts are\n' - ' available to create file objects: the "open()" built-in ' - 'function,\n' - ' and also "os.popen()", "os.fdopen()", and the "makefile()" ' - 'method\n' - ' of socket objects (and perhaps by other functions or methods\n' - ' provided by extension modules).\n' + '========================================\n' + '\n' + 'A *file object* represents an open file. Various shortcuts are\n' + 'available to create file objects: the "open()" built-in function, ' + 'and\n' + 'also "os.popen()", "os.fdopen()", and the "makefile()" method of\n' + 'socket objects (and perhaps by other functions or methods provided ' + 'by\n' + 'extension modules).\n' + '\n' + 'The objects "sys.stdin", "sys.stdout" and "sys.stderr" are ' + 'initialized\n' + 'to file objects corresponding to the interpreter’s standard input,\n' + 'output and error streams; they are all open in text mode and ' + 'therefore\n' + 'follow the interface defined by the "io.TextIOBase" abstract ' + 'class.\n' '\n' - ' The objects "sys.stdin", "sys.stdout" and "sys.stderr" are\n' - ' initialized to file objects corresponding to the interpreter’s\n' - ' standard input, output and error streams; they are all open in ' - 'text\n' - ' mode and therefore follow the interface defined by the\n' - ' "io.TextIOBase" abstract class.\n' '\n' 'Internal types\n' - ' A few types used internally by the interpreter are exposed to ' - 'the\n' - ' user. Their definitions may change with future versions of the\n' - ' interpreter, but they are mentioned here for completeness.\n' - '\n' - ' Code objects\n' - ' Code objects represent *byte-compiled* executable Python ' - 'code,\n' - ' or *bytecode*. The difference between a code object and a\n' - ' function object is that the function object contains an ' - 'explicit\n' - ' reference to the function’s globals (the module in which it ' - 'was\n' - ' defined), while a code object contains no context; also the\n' - ' default argument values are stored in the function object, ' - 'not\n' - ' in the code object (because they represent values calculated ' - 'at\n' - ' run-time). Unlike function objects, code objects are ' - 'immutable\n' - ' and contain no references (directly or indirectly) to ' - 'mutable\n' - ' objects.\n' - '\n' - ' Special read-only attributes: "co_name" gives the function ' - 'name;\n' - ' "co_qualname" gives the fully qualified function name;\n' - ' "co_argcount" is the total number of positional arguments\n' - ' (including positional-only arguments and arguments with ' - 'default\n' - ' values); "co_posonlyargcount" is the number of ' - 'positional-only\n' - ' arguments (including arguments with default values);\n' - ' "co_kwonlyargcount" is the number of keyword-only arguments\n' - ' (including arguments with default values); "co_nlocals" is ' - 'the\n' - ' number of local variables used by the function (including\n' - ' arguments); "co_varnames" is a tuple containing the names of ' - 'the\n' - ' local variables (starting with the argument names);\n' - ' "co_cellvars" is a tuple containing the names of local ' - 'variables\n' - ' that are referenced by nested functions; "co_freevars" is a\n' - ' tuple containing the names of free variables; "co_code" is a\n' - ' string representing the sequence of bytecode instructions;\n' - ' "co_consts" is a tuple containing the literals used by the\n' - ' bytecode; "co_names" is a tuple containing the names used by ' - 'the\n' - ' bytecode; "co_filename" is the filename from which the code ' - 'was\n' - ' compiled; "co_firstlineno" is the first line number of the\n' - ' function; "co_lnotab" is a string encoding the mapping from\n' - ' bytecode offsets to line numbers (for details see the source\n' - ' code of the interpreter); "co_stacksize" is the required ' - 'stack\n' - ' size; "co_flags" is an integer encoding a number of flags ' - 'for\n' - ' the interpreter.\n' + '==============\n' + '\n' + 'A few types used internally by the interpreter are exposed to the\n' + 'user. Their definitions may change with future versions of the\n' + 'interpreter, but they are mentioned here for completeness.\n' '\n' - ' The following flag bits are defined for "co_flags": bit ' - '"0x04"\n' - ' is set if the function uses the "*arguments" syntax to accept ' - 'an\n' - ' arbitrary number of positional arguments; bit "0x08" is set ' - 'if\n' - ' the function uses the "**keywords" syntax to accept ' - 'arbitrary\n' - ' keyword arguments; bit "0x20" is set if the function is a\n' - ' generator.\n' '\n' - ' Future feature declarations ("from __future__ import ' - 'division")\n' - ' also use bits in "co_flags" to indicate whether a code ' + 'Code objects\n' + '------------\n' + '\n' + 'Code objects represent *byte-compiled* executable Python code, or\n' + '*bytecode*. The difference between a code object and a function ' 'object\n' - ' was compiled with a particular feature enabled: bit "0x2000" ' + 'is that the function object contains an explicit reference to the\n' + 'function’s globals (the module in which it was defined), while a ' + 'code\n' + 'object contains no context; also the default argument values are\n' + 'stored in the function object, not in the code object (because ' + 'they\n' + 'represent values calculated at run-time). Unlike function ' + 'objects,\n' + 'code objects are immutable and contain no references (directly or\n' + 'indirectly) to mutable objects.\n' + '\n' + 'Special read-only attributes: "co_name" gives the function name;\n' + '"co_qualname" gives the fully qualified function name; ' + '"co_argcount"\n' + 'is the total number of positional arguments (including ' + 'positional-only\n' + 'arguments and arguments with default values); "co_posonlyargcount" ' 'is\n' - ' set if the function was compiled with future division ' - 'enabled;\n' - ' bits "0x10" and "0x1000" were used in earlier versions of\n' - ' Python.\n' + 'the number of positional-only arguments (including arguments with\n' + 'default values); "co_kwonlyargcount" is the number of keyword-only\n' + 'arguments (including arguments with default values); "co_nlocals" ' + 'is\n' + 'the number of local variables used by the function (including\n' + 'arguments); "co_varnames" is a tuple containing the names of the ' + 'local\n' + 'variables (starting with the argument names); "co_cellvars" is a ' + 'tuple\n' + 'containing the names of local variables that are referenced by ' + 'nested\n' + 'functions; "co_freevars" is a tuple containing the names of free\n' + 'variables; "co_code" is a string representing the sequence of ' + 'bytecode\n' + 'instructions; "co_consts" is a tuple containing the literals used ' + 'by\n' + 'the bytecode; "co_names" is a tuple containing the names used by ' + 'the\n' + 'bytecode; "co_filename" is the filename from which the code was\n' + 'compiled; "co_firstlineno" is the first line number of the ' + 'function;\n' + '"co_lnotab" is a string encoding the mapping from bytecode offsets ' + 'to\n' + 'line numbers (for details see the source code of the interpreter);\n' + '"co_stacksize" is the required stack size; "co_flags" is an ' + 'integer\n' + 'encoding a number of flags for the interpreter.\n' '\n' - ' Other bits in "co_flags" are reserved for internal use.\n' + 'The following flag bits are defined for "co_flags": bit "0x04" is ' + 'set\n' + 'if the function uses the "*arguments" syntax to accept an ' + 'arbitrary\n' + 'number of positional arguments; bit "0x08" is set if the function ' + 'uses\n' + 'the "**keywords" syntax to accept arbitrary keyword arguments; bit\n' + '"0x20" is set if the function is a generator.\n' + '\n' + 'Future feature declarations ("from __future__ import division") ' + 'also\n' + 'use bits in "co_flags" to indicate whether a code object was ' + 'compiled\n' + 'with a particular feature enabled: bit "0x2000" is set if the ' + 'function\n' + 'was compiled with future division enabled; bits "0x10" and ' + '"0x1000"\n' + 'were used in earlier versions of Python.\n' '\n' - ' If a code object represents a function, the first item in\n' - ' "co_consts" is the documentation string of the function, or\n' - ' "None" if undefined.\n' + 'Other bits in "co_flags" are reserved for internal use.\n' '\n' - ' codeobject.co_positions()\n' + 'If a code object represents a function, the first item in ' + '"co_consts"\n' + 'is the documentation string of the function, or "None" if ' + 'undefined.\n' '\n' - ' Returns an iterable over the source code positions of ' - 'each\n' - ' bytecode instruction in the code object.\n' + 'codeobject.co_positions()\n' '\n' - ' The iterator returns tuples containing the "(start_line,\n' - ' end_line, start_column, end_column)". The *i-th* tuple\n' - ' corresponds to the position of the source code that ' - 'compiled\n' - ' to the *i-th* instruction. Column information is ' - '0-indexed\n' - ' utf-8 byte offsets on the given source line.\n' + ' Returns an iterable over the source code positions of each ' + 'bytecode\n' + ' instruction in the code object.\n' '\n' - ' This positional information can be missing. A ' - 'non-exhaustive\n' - ' lists of cases where this may happen:\n' + ' The iterator returns tuples containing the "(start_line, ' + 'end_line,\n' + ' start_column, end_column)". The *i-th* tuple corresponds to the\n' + ' position of the source code that compiled to the *i-th*\n' + ' instruction. Column information is 0-indexed utf-8 byte offsets ' + 'on\n' + ' the given source line.\n' '\n' - ' * Running the interpreter with "-X" "no_debug_ranges".\n' + ' This positional information can be missing. A non-exhaustive ' + 'lists\n' + ' of cases where this may happen:\n' '\n' - ' * Loading a pyc file compiled while using "-X"\n' - ' "no_debug_ranges".\n' + ' * Running the interpreter with "-X" "no_debug_ranges".\n' '\n' - ' * Position tuples corresponding to artificial ' - 'instructions.\n' + ' * Loading a pyc file compiled while using "-X" ' + '"no_debug_ranges".\n' '\n' - ' * Line and column numbers that can’t be represented due ' - 'to\n' - ' implementation specific limitations.\n' + ' * Position tuples corresponding to artificial instructions.\n' '\n' - ' When this occurs, some or all of the tuple elements can ' - 'be\n' - ' "None".\n' + ' * Line and column numbers that can’t be represented due to\n' + ' implementation specific limitations.\n' '\n' - ' New in version 3.11.\n' + ' When this occurs, some or all of the tuple elements can be ' + '"None".\n' '\n' - ' Note:\n' + ' New in version 3.11.\n' '\n' - ' This feature requires storing column positions in code\n' - ' objects which may result in a small increase of disk ' - 'usage\n' - ' of compiled Python files or interpreter memory usage. ' - 'To\n' - ' avoid storing the extra information and/or deactivate\n' - ' printing the extra traceback information, the "-X"\n' - ' "no_debug_ranges" command line flag or the\n' - ' "PYTHONNODEBUGRANGES" environment variable can be used.\n' + ' Note:\n' '\n' - ' Frame objects\n' - ' Frame objects represent execution frames. They may occur in\n' - ' traceback objects (see below), and are also passed to ' - 'registered\n' - ' trace functions.\n' + ' This feature requires storing column positions in code ' + 'objects\n' + ' which may result in a small increase of disk usage of ' + 'compiled\n' + ' Python files or interpreter memory usage. To avoid storing ' + 'the\n' + ' extra information and/or deactivate printing the extra ' + 'traceback\n' + ' information, the "-X" "no_debug_ranges" command line flag or ' + 'the\n' + ' "PYTHONNODEBUGRANGES" environment variable can be used.\n' + '\n' + '\n' + 'Frame objects\n' + '-------------\n' + '\n' + 'Frame objects represent execution frames. They may occur in ' + 'traceback\n' + 'objects (see below), and are also passed to registered trace\n' + 'functions.\n' + '\n' + 'Special read-only attributes: "f_back" is to the previous stack ' + 'frame\n' + '(towards the caller), or "None" if this is the bottom stack frame;\n' + '"f_code" is the code object being executed in this frame; ' + '"f_locals"\n' + 'is the dictionary used to look up local variables; "f_globals" is ' + 'used\n' + 'for global variables; "f_builtins" is used for built-in ' + '(intrinsic)\n' + 'names; "f_lasti" gives the precise instruction (this is an index ' + 'into\n' + 'the bytecode string of the code object).\n' + '\n' + 'Accessing "f_code" raises an auditing event "object.__getattr__" ' + 'with\n' + 'arguments "obj" and ""f_code"".\n' + '\n' + 'Special writable attributes: "f_trace", if not "None", is a ' + 'function\n' + 'called for various events during code execution (this is used by ' + 'the\n' + 'debugger). Normally an event is triggered for each new source line ' + '-\n' + 'this can be disabled by setting "f_trace_lines" to "False".\n' '\n' - ' Special read-only attributes: "f_back" is to the previous ' - 'stack\n' - ' frame (towards the caller), or "None" if this is the bottom\n' - ' stack frame; "f_code" is the code object being executed in ' + 'Implementations *may* allow per-opcode events to be requested by\n' + 'setting "f_trace_opcodes" to "True". Note that this may lead to\n' + 'undefined interpreter behaviour if exceptions raised by the trace\n' + 'function escape to the function being traced.\n' + '\n' + '"f_lineno" is the current line number of the frame — writing to ' 'this\n' - ' frame; "f_locals" is the dictionary used to look up local\n' - ' variables; "f_globals" is used for global variables;\n' - ' "f_builtins" is used for built-in (intrinsic) names; ' - '"f_lasti"\n' - ' gives the precise instruction (this is an index into the\n' - ' bytecode string of the code object).\n' - '\n' - ' Accessing "f_code" raises an auditing event ' - '"object.__getattr__"\n' - ' with arguments "obj" and ""f_code"".\n' - '\n' - ' Special writable attributes: "f_trace", if not "None", is a\n' - ' function called for various events during code execution ' - '(this\n' - ' is used by the debugger). Normally an event is triggered for\n' - ' each new source line - this can be disabled by setting\n' - ' "f_trace_lines" to "False".\n' - '\n' - ' Implementations *may* allow per-opcode events to be requested ' - 'by\n' - ' setting "f_trace_opcodes" to "True". Note that this may lead ' - 'to\n' - ' undefined interpreter behaviour if exceptions raised by the\n' - ' trace function escape to the function being traced.\n' + 'from within a trace function jumps to the given line (only for the\n' + 'bottom-most frame). A debugger can implement a Jump command (aka ' + 'Set\n' + 'Next Statement) by writing to f_lineno.\n' '\n' - ' "f_lineno" is the current line number of the frame — writing ' - 'to\n' - ' this from within a trace function jumps to the given line ' - '(only\n' - ' for the bottom-most frame). A debugger can implement a Jump\n' - ' command (aka Set Next Statement) by writing to f_lineno.\n' + 'Frame objects support one method:\n' '\n' - ' Frame objects support one method:\n' + 'frame.clear()\n' '\n' - ' frame.clear()\n' + ' This method clears all references to local variables held by ' + 'the\n' + ' frame. Also, if the frame belonged to a generator, the ' + 'generator\n' + ' is finalized. This helps break reference cycles involving ' + 'frame\n' + ' objects (for example when catching an exception and storing its\n' + ' traceback for later use).\n' '\n' - ' This method clears all references to local variables held ' - 'by\n' - ' the frame. Also, if the frame belonged to a generator, ' + ' "RuntimeError" is raised if the frame is currently executing.\n' + '\n' + ' New in version 3.4.\n' + '\n' + '\n' + 'Traceback objects\n' + '-----------------\n' + '\n' + 'Traceback objects represent a stack trace of an exception. A\n' + 'traceback object is implicitly created when an exception occurs, ' + 'and\n' + 'may also be explicitly created by calling "types.TracebackType".\n' + '\n' + 'For implicitly created tracebacks, when the search for an ' + 'exception\n' + 'handler unwinds the execution stack, at each unwound level a ' + 'traceback\n' + 'object is inserted in front of the current traceback. When an\n' + 'exception handler is entered, the stack trace is made available to ' 'the\n' - ' generator is finalized. This helps break reference ' - 'cycles\n' - ' involving frame objects (for example when catching an\n' - ' exception and storing its traceback for later use).\n' + 'program. (See section The try statement.) It is accessible as the\n' + 'third item of the tuple returned by "sys.exc_info()", and as the\n' + '"__traceback__" attribute of the caught exception.\n' '\n' - ' "RuntimeError" is raised if the frame is currently ' - 'executing.\n' + 'When the program contains no suitable handler, the stack trace is\n' + 'written (nicely formatted) to the standard error stream; if the\n' + 'interpreter is interactive, it is also made available to the user ' + 'as\n' + '"sys.last_traceback".\n' '\n' - ' New in version 3.4.\n' + 'For explicitly created tracebacks, it is up to the creator of the\n' + 'traceback to determine how the "tb_next" attributes should be ' + 'linked\n' + 'to form a full stack trace.\n' '\n' - ' Traceback objects\n' - ' Traceback objects represent a stack trace of an exception. ' - 'A\n' - ' traceback object is implicitly created when an exception ' - 'occurs,\n' - ' and may also be explicitly created by calling\n' - ' "types.TracebackType".\n' - '\n' - ' For implicitly created tracebacks, when the search for an\n' - ' exception handler unwinds the execution stack, at each ' - 'unwound\n' - ' level a traceback object is inserted in front of the current\n' - ' traceback. When an exception handler is entered, the stack\n' - ' trace is made available to the program. (See section The try\n' - ' statement.) It is accessible as the third item of the tuple\n' - ' returned by "sys.exc_info()", and as the "__traceback__"\n' - ' attribute of the caught exception.\n' - '\n' - ' When the program contains no suitable handler, the stack ' - 'trace\n' - ' is written (nicely formatted) to the standard error stream; ' - 'if\n' - ' the interpreter is interactive, it is also made available to ' + 'Special read-only attributes: "tb_frame" points to the execution ' + 'frame\n' + 'of the current level; "tb_lineno" gives the line number where the\n' + 'exception occurred; "tb_lasti" indicates the precise instruction. ' + 'The\n' + 'line number and last instruction in the traceback may differ from ' 'the\n' - ' user as "sys.last_traceback".\n' + 'line number of its frame object if the exception occurred in a ' + '"try"\n' + 'statement with no matching except clause or with a finally clause.\n' '\n' - ' For explicitly created tracebacks, it is up to the creator ' - 'of\n' - ' the traceback to determine how the "tb_next" attributes ' - 'should\n' - ' be linked to form a full stack trace.\n' - '\n' - ' Special read-only attributes: "tb_frame" points to the ' - 'execution\n' - ' frame of the current level; "tb_lineno" gives the line ' - 'number\n' - ' where the exception occurred; "tb_lasti" indicates the ' - 'precise\n' - ' instruction. The line number and last instruction in the\n' - ' traceback may differ from the line number of its frame object ' + 'Accessing "tb_frame" raises an auditing event "object.__getattr__"\n' + 'with arguments "obj" and ""tb_frame"".\n' + '\n' + 'Special writable attribute: "tb_next" is the next level in the ' + 'stack\n' + 'trace (towards the frame where the exception occurred), or "None" ' 'if\n' - ' the exception occurred in a "try" statement with no matching\n' - ' except clause or with a finally clause.\n' + 'there is no next level.\n' '\n' - ' Accessing "tb_frame" raises an auditing event\n' - ' "object.__getattr__" with arguments "obj" and ""tb_frame"".\n' + 'Changed in version 3.7: Traceback objects can now be explicitly\n' + 'instantiated from Python code, and the "tb_next" attribute of ' + 'existing\n' + 'instances can be updated.\n' '\n' - ' Special writable attribute: "tb_next" is the next level in ' - 'the\n' - ' stack trace (towards the frame where the exception occurred), ' - 'or\n' - ' "None" if there is no next level.\n' '\n' - ' Changed in version 3.7: Traceback objects can now be ' - 'explicitly\n' - ' instantiated from Python code, and the "tb_next" attribute ' - 'of\n' - ' existing instances can be updated.\n' + 'Slice objects\n' + '-------------\n' '\n' - ' Slice objects\n' - ' Slice objects are used to represent slices for ' - '"__getitem__()"\n' - ' methods. They are also created by the built-in "slice()"\n' - ' function.\n' + 'Slice objects are used to represent slices for "__getitem__()"\n' + 'methods. They are also created by the built-in "slice()" ' + 'function.\n' '\n' - ' Special read-only attributes: "start" is the lower bound; ' - '"stop"\n' - ' is the upper bound; "step" is the step value; each is "None" ' - 'if\n' - ' omitted. These attributes can have any type.\n' + 'Special read-only attributes: "start" is the lower bound; "stop" ' + 'is\n' + 'the upper bound; "step" is the step value; each is "None" if ' + 'omitted.\n' + 'These attributes can have any type.\n' '\n' - ' Slice objects support one method:\n' + 'Slice objects support one method:\n' '\n' - ' slice.indices(self, length)\n' + 'slice.indices(self, length)\n' '\n' - ' This method takes a single integer argument *length* and\n' - ' computes information about the slice that the slice ' - 'object\n' - ' would describe if applied to a sequence of *length* ' - 'items.\n' - ' It returns a tuple of three integers; respectively these ' - 'are\n' - ' the *start* and *stop* indices and the *step* or stride\n' - ' length of the slice. Missing or out-of-bounds indices are\n' - ' handled in a manner consistent with regular slices.\n' - '\n' - ' Static method objects\n' - ' Static method objects provide a way of defeating the\n' - ' transformation of function objects to method objects ' - 'described\n' - ' above. A static method object is a wrapper around any other\n' - ' object, usually a user-defined method object. When a static\n' - ' method object is retrieved from a class or a class instance, ' - 'the\n' - ' object actually returned is the wrapped object, which is not\n' - ' subject to any further transformation. Static method objects ' - 'are\n' - ' also callable. Static method objects are created by the ' - 'built-in\n' - ' "staticmethod()" constructor.\n' + ' This method takes a single integer argument *length* and ' + 'computes\n' + ' information about the slice that the slice object would describe ' + 'if\n' + ' applied to a sequence of *length* items. It returns a tuple of\n' + ' three integers; respectively these are the *start* and *stop*\n' + ' indices and the *step* or stride length of the slice. Missing ' + 'or\n' + ' out-of-bounds indices are handled in a manner consistent with\n' + ' regular slices.\n' '\n' - ' Class method objects\n' - ' A class method object, like a static method object, is a ' - 'wrapper\n' - ' around another object that alters the way in which that ' - 'object\n' - ' is retrieved from classes and class instances. The behaviour ' + '\n' + 'Static method objects\n' + '---------------------\n' + '\n' + 'Static method objects provide a way of defeating the transformation ' 'of\n' - ' class method objects upon such retrieval is described above,\n' - ' under “User-defined methodsâ€. Class method objects are ' - 'created\n' - ' by the built-in "classmethod()" constructor.\n', + 'function objects to method objects described above. A static ' + 'method\n' + 'object is a wrapper around any other object, usually a ' + 'user-defined\n' + 'method object. When a static method object is retrieved from a ' + 'class\n' + 'or a class instance, the object actually returned is the wrapped\n' + 'object, which is not subject to any further transformation. Static\n' + 'method objects are also callable. Static method objects are created ' + 'by\n' + 'the built-in "staticmethod()" constructor.\n' + '\n' + '\n' + 'Class method objects\n' + '--------------------\n' + '\n' + 'A class method object, like a static method object, is a wrapper\n' + 'around another object that alters the way in which that object is\n' + 'retrieved from classes and class instances. The behaviour of class\n' + 'method objects upon such retrieval is described above, under ' + '“User-\n' + 'defined methodsâ€. Class method objects are created by the built-in\n' + '"classmethod()" constructor.\n', 'typesfunctions': 'Functions\n' '*********\n' '\n' diff --git a/mingw32/lib/python3.11/selectors.py b/mingw32/lib/python3.11/selectors.py index af6a4f94b50..c3b065b5226 100644 --- a/mingw32/lib/python3.11/selectors.py +++ b/mingw32/lib/python3.11/selectors.py @@ -509,6 +509,7 @@ class KqueueSelector(_BaseSelectorImpl): def __init__(self): super().__init__() self._selector = select.kqueue() + self._max_events = 0 def fileno(self): return self._selector.fileno() @@ -520,10 +521,12 @@ def register(self, fileobj, events, data=None): kev = select.kevent(key.fd, select.KQ_FILTER_READ, select.KQ_EV_ADD) self._selector.control([kev], 0, 0) + self._max_events += 1 if events & EVENT_WRITE: kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, select.KQ_EV_ADD) self._selector.control([kev], 0, 0) + self._max_events += 1 except: super().unregister(fileobj) raise @@ -534,6 +537,7 @@ def unregister(self, fileobj): if key.events & EVENT_READ: kev = select.kevent(key.fd, select.KQ_FILTER_READ, select.KQ_EV_DELETE) + self._max_events -= 1 try: self._selector.control([kev], 0, 0) except OSError: @@ -543,6 +547,7 @@ def unregister(self, fileobj): if key.events & EVENT_WRITE: kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, select.KQ_EV_DELETE) + self._max_events -= 1 try: self._selector.control([kev], 0, 0) except OSError: @@ -555,7 +560,7 @@ def select(self, timeout=None): # If max_ev is 0, kqueue will ignore the timeout. For consistent # behavior with the other selector classes, we prevent that here # (using max). See https://bugs.python.org/issue29255 - max_ev = max(len(self._fd_to_key), 1) + max_ev = self._max_events or 1 ready = [] try: kev_list = self._selector.control(None, max_ev, timeout) diff --git a/mingw32/lib/python3.11/shutil.py b/mingw32/lib/python3.11/shutil.py index 1c3a75da55b..d108986d130 100644 --- a/mingw32/lib/python3.11/shutil.py +++ b/mingw32/lib/python3.11/shutil.py @@ -454,7 +454,7 @@ def _copytree(entries, src, dst, symlinks, ignore, copy_function, if ignore is not None: ignored_names = ignore(os.fspath(src), [x.name for x in entries]) else: - ignored_names = set() + ignored_names = () os.makedirs(dst, exist_ok=dirs_exist_ok) errors = [] diff --git a/mingw32/lib/python3.11/sqlite3/dump.py b/mingw32/lib/python3.11/sqlite3/dump.py index 07b9da10b92..1cf8759f897 100644 --- a/mingw32/lib/python3.11/sqlite3/dump.py +++ b/mingw32/lib/python3.11/sqlite3/dump.py @@ -16,6 +16,7 @@ def _iterdump(connection): directly but instead called from the Connection method, iterdump(). """ + writeable_schema = False cu = connection.cursor() yield('BEGIN TRANSACTION;') @@ -42,13 +43,15 @@ def _iterdump(connection): yield('ANALYZE "sqlite_master";') elif table_name.startswith('sqlite_'): continue - # NOTE: Virtual table support not implemented - #elif sql.startswith('CREATE VIRTUAL TABLE'): - # qtable = table_name.replace("'", "''") - # yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"\ - # "VALUES('table','{0}','{0}',0,'{1}');".format( - # qtable, - # sql.replace("''"))) + elif sql.startswith('CREATE VIRTUAL TABLE'): + if not writeable_schema: + writeable_schema = True + yield('PRAGMA writable_schema=ON;') + yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" + "VALUES('table','{0}','{0}',0,'{1}');".format( + table_name.replace("'", "''"), + sql.replace("'", "''"), + )) else: yield('{0};'.format(sql)) @@ -74,6 +77,9 @@ def _iterdump(connection): for name, type, sql in schema_res.fetchall(): yield('{0};'.format(sql)) + if writeable_schema: + yield('PRAGMA writable_schema=OFF;') + # gh-79009: Yield statements concerning the sqlite_sequence table at the # end of the transaction. for row in sqlite_sequence: diff --git a/mingw32/lib/python3.11/test/_test_eintr.py b/mingw32/lib/python3.11/test/_test_eintr.py index e43b59d064f..54a5412f828 100644 --- a/mingw32/lib/python3.11/test/_test_eintr.py +++ b/mingw32/lib/python3.11/test/_test_eintr.py @@ -25,6 +25,12 @@ from test.support import os_helper from test.support import socket_helper + +# gh-109592: Tolerate a difference of 20 ms when comparing timings +# (clock resolution) +CLOCK_RES = 0.020 + + @contextlib.contextmanager def kill_on_error(proc): """Context manager killing the subprocess if a Python exception is raised.""" @@ -75,6 +81,9 @@ def subprocess(self, *args, **kw): cmd_args = (sys.executable, '-c') + args return subprocess.Popen(cmd_args, **kw) + def check_elapsed_time(self, elapsed): + self.assertGreaterEqual(elapsed, self.sleep_time - CLOCK_RES) + @unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") class OSEINTRTest(EINTRBaseTest): @@ -373,7 +382,7 @@ def test_sleep(self): time.sleep(self.sleep_time) self.stop_alarm() dt = time.monotonic() - t0 - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) @unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") @@ -437,7 +446,7 @@ def test_select(self): select.select([], [], [], self.sleep_time) dt = time.monotonic() - t0 self.stop_alarm() - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) @unittest.skipIf(sys.platform == "darwin", "poll may fail on macOS; see issue #28087") @@ -449,7 +458,7 @@ def test_poll(self): poller.poll(self.sleep_time * 1e3) dt = time.monotonic() - t0 self.stop_alarm() - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) @unittest.skipUnless(hasattr(select, 'epoll'), 'need select.epoll') def test_epoll(self): @@ -460,7 +469,7 @@ def test_epoll(self): poller.poll(self.sleep_time) dt = time.monotonic() - t0 self.stop_alarm() - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) @unittest.skipUnless(hasattr(select, 'kqueue'), 'need select.kqueue') def test_kqueue(self): @@ -471,7 +480,7 @@ def test_kqueue(self): kqueue.control(None, 1, self.sleep_time) dt = time.monotonic() - t0 self.stop_alarm() - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) @unittest.skipUnless(hasattr(select, 'devpoll'), 'need select.devpoll') def test_devpoll(self): @@ -482,7 +491,7 @@ def test_devpoll(self): poller.poll(self.sleep_time * 1e3) dt = time.monotonic() - t0 self.stop_alarm() - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) class FNTLEINTRTest(EINTRBaseTest): @@ -512,8 +521,8 @@ def _lock(self, lock_func, lock_name): # potential context switch delay lock_func(f, fcntl.LOCK_EX) dt = time.monotonic() - start_time - self.assertGreaterEqual(dt, self.sleep_time) self.stop_alarm() + self.check_elapsed_time(dt) proc.wait() # Issue 35633: See https://bugs.python.org/issue35633#msg333662 diff --git a/mingw32/lib/python3.11/test/_test_multiprocessing.py b/mingw32/lib/python3.11/test/_test_multiprocessing.py index 9bc8242cbfa..6249062639b 100644 --- a/mingw32/lib/python3.11/test/_test_multiprocessing.py +++ b/mingw32/lib/python3.11/test/_test_multiprocessing.py @@ -78,7 +78,7 @@ if support.check_sanitizer(address=True): - # bpo-45200: Skip multiprocessing tests if Python is built with ASAN to + # gh-89363: Skip multiprocessing tests if Python is built with ASAN to # work around a libasan race condition: dead lock in pthread_create(). raise unittest.SkipTest("libasan has a pthread_create() dead lock") @@ -328,6 +328,7 @@ def test_set_executable(self): p.join() self.assertEqual(p.exitcode, 0) + @support.requires_resource('cpu') def test_args_argument(self): # bpo-45735: Using list or tuple as *args* in constructor could # achieve the same effect. @@ -555,13 +556,14 @@ def handler(*args): def test_terminate(self): exitcode = self._kill_process(multiprocessing.Process.terminate) - if os.name != 'nt': - self.assertEqual(exitcode, -signal.SIGTERM) + self.assertEqual(exitcode, -signal.SIGTERM) def test_kill(self): exitcode = self._kill_process(multiprocessing.Process.kill) if os.name != 'nt': self.assertEqual(exitcode, -signal.SIGKILL) + else: + self.assertEqual(exitcode, -signal.SIGTERM) def test_cpu_count(self): try: @@ -673,6 +675,7 @@ def test_close(self): close_queue(q) + @support.requires_resource('walltime') def test_many_processes(self): if self.TYPE == 'threads': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -4470,6 +4473,7 @@ def test_finalize(self): result = [obj for obj in iter(conn.recv, 'STOP')] self.assertEqual(result, ['a', 'b', 'd10', 'd03', 'd02', 'd01', 'e']) + @support.requires_resource('cpu') def test_thread_safety(self): # bpo-24484: _run_finalizers() should be thread-safe def cb(): @@ -4917,6 +4921,7 @@ def test_wait_slow(self): def test_wait_socket_slow(self): self.test_wait_socket(True) + @support.requires_resource('walltime') def test_wait_timeout(self): from multiprocessing.connection import wait @@ -4945,6 +4950,7 @@ def signal_and_sleep(cls, sem, period): sem.release() time.sleep(period) + @support.requires_resource('walltime') def test_wait_integer(self): from multiprocessing.connection import wait @@ -5367,6 +5373,34 @@ def test_mixed_startmethod(self): p.start() p.join() + @classmethod + def _put_one_in_queue(cls, queue): + queue.put(1) + + @classmethod + def _put_two_and_nest_once(cls, queue): + queue.put(2) + process = multiprocessing.Process(target=cls._put_one_in_queue, args=(queue,)) + process.start() + process.join() + + def test_nested_startmethod(self): + # gh-108520: Regression test to ensure that child process can send its + # arguments to another process + queue = multiprocessing.Queue() + + process = multiprocessing.Process(target=self._put_two_and_nest_once, args=(queue,)) + process.start() + process.join() + + results = [] + while not queue.empty(): + results.append(queue.get()) + + # gh-109706: queue.put(1) can write into the queue before queue.put(2), + # there is no synchronization in the test. + self.assertSetEqual(set(results), set([2, 1])) + @unittest.skipIf(sys.platform == "win32", "test semantics don't make sense on Windows") @@ -6049,7 +6083,8 @@ class ThreadsMixin(BaseMixin): # Functions used to create test cases from the base ones in this module # -def install_tests_in_module_dict(remote_globs, start_method): +def install_tests_in_module_dict(remote_globs, start_method, + only_type=None, exclude_types=False): __module__ = remote_globs['__name__'] local_globs = globals() ALL_TYPES = {'processes', 'threads', 'manager'} @@ -6062,6 +6097,10 @@ def install_tests_in_module_dict(remote_globs, start_method): continue assert set(base.ALLOWED_TYPES) <= ALL_TYPES, base.ALLOWED_TYPES for type_ in base.ALLOWED_TYPES: + if only_type and type_ != only_type: + continue + if exclude_types: + continue newname = 'With' + type_.capitalize() + name[1:] Mixin = local_globs[type_.capitalize() + 'Mixin'] class Temp(base, Mixin, unittest.TestCase): @@ -6072,6 +6111,9 @@ class Temp(base, Mixin, unittest.TestCase): Temp.__module__ = __module__ remote_globs[newname] = Temp elif issubclass(base, unittest.TestCase): + if only_type: + continue + class Temp(base, object): pass Temp.__name__ = Temp.__qualname__ = name diff --git a/mingw32/lib/python3.11/test/libregrtest/cmdline.py b/mingw32/lib/python3.11/test/libregrtest/cmdline.py index ebe57920d91..40ae8fc46e9 100644 --- a/mingw32/lib/python3.11/test/libregrtest/cmdline.py +++ b/mingw32/lib/python3.11/test/libregrtest/cmdline.py @@ -107,6 +107,8 @@ cpu - Used for certain CPU-heavy tests. + walltime - Long running but not CPU-bound tests. + subprocess Run all tests for the subprocess module. urlfetch - It is okay to download files required on testing. @@ -129,7 +131,7 @@ ALL_RESOURCES = ('audio', 'curses', 'largefile', 'network', - 'decimal', 'cpu', 'subprocess', 'urlfetch', 'gui') + 'decimal', 'cpu', 'subprocess', 'urlfetch', 'gui', 'walltime') # Other resources excluded from --use=all: # diff --git a/mingw32/lib/python3.11/test/libregrtest/main.py b/mingw32/lib/python3.11/test/libregrtest/main.py index 0125227bf11..7192244c69c 100644 --- a/mingw32/lib/python3.11/test/libregrtest/main.py +++ b/mingw32/lib/python3.11/test/libregrtest/main.py @@ -11,14 +11,14 @@ import unittest from test.libregrtest.cmdline import _parse_args from test.libregrtest.runtest import ( - findtests, runtest, get_abs_module, is_failed, - STDTESTS, NOTTESTS, PROGRESS_MIN_TIME, - Passed, Failed, EnvChanged, Skipped, ResourceDenied, Interrupted, - ChildError, DidNotRun) + findtests, split_test_packages, runtest, get_abs_module, + PROGRESS_MIN_TIME, State) from test.libregrtest.setup import setup_tests from test.libregrtest.pgo import setup_pgo_tests -from test.libregrtest.utils import removepy, count, format_duration, printlist +from test.libregrtest.utils import (removepy, count, format_duration, + printlist, get_build_info) from test import support +from test.support import TestStats from test.support import os_helper from test.support import threading_helper @@ -77,13 +77,14 @@ def __init__(self): self.good = [] self.bad = [] self.skipped = [] - self.resource_denieds = [] + self.resource_denied = [] self.environment_changed = [] self.run_no_tests = [] self.need_rerun = [] self.rerun = [] self.first_result = None self.interrupted = False + self.stats_dict: dict[str, TestStats] = {} # used by --slow self.test_times = [] @@ -92,7 +93,7 @@ def __init__(self): self.tracer = None # used to display the progress bar "[ 3/100]" - self.start_time = time.monotonic() + self.start_time = time.perf_counter() self.test_count = '' self.test_count_width = 1 @@ -110,36 +111,41 @@ def __init__(self): def get_executed(self): return (set(self.good) | set(self.bad) | set(self.skipped) - | set(self.resource_denieds) | set(self.environment_changed) + | set(self.resource_denied) | set(self.environment_changed) | set(self.run_no_tests)) def accumulate_result(self, result, rerun=False): - test_name = result.name - - if not isinstance(result, (ChildError, Interrupted)) and not rerun: - self.test_times.append((result.duration_sec, test_name)) - - if isinstance(result, Passed): - self.good.append(test_name) - elif isinstance(result, ResourceDenied): - self.skipped.append(test_name) - self.resource_denieds.append(test_name) - elif isinstance(result, Skipped): - self.skipped.append(test_name) - elif isinstance(result, EnvChanged): - self.environment_changed.append(test_name) - elif isinstance(result, Failed): - if not rerun: - self.bad.append(test_name) - self.need_rerun.append(result) - elif isinstance(result, DidNotRun): - self.run_no_tests.append(test_name) - elif isinstance(result, Interrupted): - self.interrupted = True - else: - raise ValueError("invalid test result: %r" % result) + test_name = result.test_name + + if result.has_meaningful_duration() and not rerun: + self.test_times.append((result.duration, test_name)) - if rerun and not isinstance(result, (Failed, Interrupted)): + match result.state: + case State.PASSED: + self.good.append(test_name) + case State.ENV_CHANGED: + self.environment_changed.append(test_name) + case State.SKIPPED: + self.skipped.append(test_name) + case State.RESOURCE_DENIED: + self.skipped.append(test_name) + self.resource_denied.append(test_name) + case State.INTERRUPTED: + self.interrupted = True + case State.DID_NOT_RUN: + self.run_no_tests.append(test_name) + case _: + if result.is_failed(self.ns.fail_env_changed): + if not rerun: + self.bad.append(test_name) + self.need_rerun.append(result) + else: + raise ValueError(f"invalid test state: {state!r}") + + if result.stats is not None: + self.stats_dict[result.test_name] = result.stats + + if rerun and not(result.is_failed(False) or result.state == State.INTERRUPTED): self.bad.remove(test_name) xml_data = result.xml_data @@ -161,7 +167,7 @@ def log(self, line=''): line = f"load avg: {load_avg:.2f} {line}" # add the timestamp prefix: "0:01:05 " - test_time = time.monotonic() - self.start_time + test_time = time.perf_counter() - self.start_time mins, secs = divmod(int(test_time), 60) hours, mins = divmod(mins, 60) @@ -245,26 +251,23 @@ def find_tests(self, tests): # add default PGO tests if no tests are specified setup_pgo_tests(self.ns) - stdtests = STDTESTS[:] - nottests = NOTTESTS.copy() + exclude = set() if self.ns.exclude: for arg in self.ns.args: - if arg in stdtests: - stdtests.remove(arg) - nottests.add(arg) + exclude.add(arg) self.ns.args = [] - # if testdir is set, then we are not running the python tests suite, so - # don't add default tests to be executed or skipped (pass empty values) - if self.ns.testdir: - alltests = findtests(self.ns.testdir, list(), set()) - else: - alltests = findtests(self.ns.testdir, stdtests, nottests) + alltests = findtests(testdir=self.ns.testdir, exclude=exclude) if not self.ns.fromfile: - self.selected = self.tests or self.ns.args or alltests + self.selected = self.tests or self.ns.args + if self.selected: + self.selected = split_test_packages(self.selected) + else: + self.selected = alltests else: self.selected = self.tests + if self.ns.single: self.selected = self.selected[:1] try: @@ -339,7 +342,7 @@ def rerun_failed_tests(self): rerun_list = list(self.need_rerun) self.need_rerun.clear() for result in rerun_list: - test_name = result.name + test_name = result.test_name self.rerun.append(test_name) errors = result.errors or [] @@ -366,7 +369,7 @@ def rerun_failed_tests(self): self.accumulate_result(result, rerun=True) - if isinstance(result, Interrupted): + if result.state == State.INTERRUPTED: break if self.bad: @@ -463,7 +466,7 @@ def run_tests_sequential(self): previous_test = None for test_index, test_name in enumerate(self.tests, 1): - start_time = time.monotonic() + start_time = time.perf_counter() text = test_name if previous_test: @@ -482,14 +485,14 @@ def run_tests_sequential(self): result = runtest(self.ns, test_name) self.accumulate_result(result) - if isinstance(result, Interrupted): + if result.state == State.INTERRUPTED: break previous_test = str(result) - test_time = time.monotonic() - start_time + test_time = time.perf_counter() - start_time if test_time >= PROGRESS_MIN_TIME: previous_test = "%s in %s" % (previous_test, format_duration(test_time)) - elif isinstance(result, Passed): + elif result.state == State.PASSED: # be quiet: say nothing if the test passed shortly previous_test = None @@ -498,7 +501,7 @@ def run_tests_sequential(self): if module not in save_modules and module.startswith("test."): support.unload(module) - if self.ns.failfast and is_failed(result, self.ns): + if self.ns.failfast and result.is_failed(self.ns.fail_env_changed): break if previous_test: @@ -518,12 +521,44 @@ def display_header(self): print("==", platform.python_implementation(), *sys.version.split()) print("==", platform.platform(aliased=True), "%s-endian" % sys.byteorder) + print("== Python build:", ' '.join(get_build_info())) print("== cwd:", os.getcwd()) cpu_count = os.cpu_count() if cpu_count: print("== CPU count:", cpu_count) print("== encodings: locale=%s, FS=%s" % (locale.getencoding(), sys.getfilesystemencoding())) + self.display_sanitizers() + + def display_sanitizers(self): + # This makes it easier to remember what to set in your local + # environment when trying to reproduce a sanitizer failure. + asan = support.check_sanitizer(address=True) + msan = support.check_sanitizer(memory=True) + ubsan = support.check_sanitizer(ub=True) + sanitizers = [] + if asan: + sanitizers.append("address") + if msan: + sanitizers.append("memory") + if ubsan: + sanitizers.append("undefined behavior") + if not sanitizers: + return + + print(f"== sanitizers: {', '.join(sanitizers)}") + for sanitizer, env_var in ( + (asan, "ASAN_OPTIONS"), + (msan, "MSAN_OPTIONS"), + (ubsan, "UBSAN_OPTIONS"), + ): + options= os.environ.get(env_var) + if sanitizer and options is not None: + print(f"== {env_var}={options!r}") + + def no_tests_run(self): + return not any((self.good, self.bad, self.skipped, self.interrupted, + self.environment_changed)) def get_tests_result(self): result = [] @@ -531,9 +566,8 @@ def get_tests_result(self): result.append("FAILURE") elif self.ns.fail_env_changed and self.environment_changed: result.append("ENV CHANGED") - elif not any((self.good, self.bad, self.skipped, self.interrupted, - self.environment_changed)): - result.append("NO TEST RUN") + elif self.no_tests_run(): + result.append("NO TESTS RAN") if self.interrupted: result.append("INTERRUPTED") @@ -609,13 +643,48 @@ def finalize(self): coverdir=self.ns.coverdir) print() - duration = time.monotonic() - self.start_time - print("Total duration: %s" % format_duration(duration)) - print("Tests result: %s" % self.get_tests_result()) + self.display_summary() if self.ns.runleaks: os.system("leaks %d" % os.getpid()) + def display_summary(self): + duration = time.perf_counter() - self.start_time + + # Total duration + print("Total duration: %s" % format_duration(duration)) + + # Total tests + total = TestStats() + for stats in self.stats_dict.values(): + total.accumulate(stats) + stats = [f'run={total.tests_run:,}'] + if total.failures: + stats.append(f'failures={total.failures:,}') + if total.skipped: + stats.append(f'skipped={total.skipped:,}') + print(f"Total tests: {' '.join(stats)}") + + # Total test files + report = [f'success={len(self.good)}'] + if self.bad: + report.append(f'failed={len(self.bad)}') + if self.environment_changed: + report.append(f'env_changed={len(self.environment_changed)}') + if self.skipped: + report.append(f'skipped={len(self.skipped)}') + if self.resource_denied: + report.append(f'resource_denied={len(self.resource_denied)}') + if self.rerun: + report.append(f'rerun={len(self.rerun)}') + if self.run_no_tests: + report.append(f'run_no_tests={len(self.run_no_tests)}') + print(f"Total test files: {' '.join(report)}") + + # Result + result = self.get_tests_result() + print(f"Result: {result}") + def save_xml_result(self): if not self.ns.xmlpath and not self.testsuite_xml: return @@ -662,11 +731,13 @@ def set_temp_dir(self): if sysconfig.is_python_build(): self.tmp_dir = sysconfig.get_config_var('abs_builddir') if self.tmp_dir is None: - # bpo-30284: On Windows, only srcdir is available. Using - # abs_builddir mostly matters on UNIX when building Python - # out of the source tree, especially when the source tree - # is read only. - self.tmp_dir = sysconfig.get_config_var('srcdir') + self.tmp_dir = sysconfig.get_config_var('abs_srcdir') + if not self.tmp_dir: + # gh-74470: On Windows, only srcdir is available. Using + # abs_builddir mostly matters on UNIX when building + # Python out of the source tree, especially when the + # source tree is read only. + self.tmp_dir = sysconfig.get_config_var('srcdir') self.tmp_dir = os.path.join(self.tmp_dir, 'build') else: self.tmp_dir = tempfile.gettempdir() @@ -782,11 +853,13 @@ def _main(self, tests, kwargs): self.save_xml_result() if self.bad: - sys.exit(2) + sys.exit(EXITCODE_BAD_TEST) if self.interrupted: - sys.exit(130) + sys.exit(EXITCODE_INTERRUPTED) if self.ns.fail_env_changed and self.environment_changed: - sys.exit(3) + sys.exit(EXITCODE_ENV_CHANGED) + if self.no_tests_run(): + sys.exit(EXITCODE_NO_TESTS_RAN) sys.exit(0) diff --git a/mingw32/lib/python3.11/test/libregrtest/refleak.py b/mingw32/lib/python3.11/test/libregrtest/refleak.py index a0538cbb3c3..58a1419e050 100644 --- a/mingw32/lib/python3.11/test/libregrtest/refleak.py +++ b/mingw32/lib/python3.11/test/libregrtest/refleak.py @@ -83,11 +83,12 @@ def get_pooled_int(value): print(("1234567890"*(repcount//10 + 1))[:repcount], file=sys.stderr, flush=True) + results = None dash_R_cleanup(fs, ps, pic, zdc, abcs) support.gc_collect() for i in rep_range: - test_func() + results = test_func() dash_R_cleanup(fs, ps, pic, zdc, abcs) support.gc_collect() @@ -146,7 +147,7 @@ def check_fd_deltas(deltas): print(msg, file=refrep) refrep.flush() failed = True - return failed + return (failed, results) def dash_R_cleanup(fs, ps, pic, zdc, abcs): diff --git a/mingw32/lib/python3.11/test/libregrtest/runtest.py b/mingw32/lib/python3.11/test/libregrtest/runtest.py index 62cf1a3f117..000a4aa75c4 100644 --- a/mingw32/lib/python3.11/test/libregrtest/runtest.py +++ b/mingw32/lib/python3.11/test/libregrtest/runtest.py @@ -1,3 +1,5 @@ +import dataclasses +import doctest import faulthandler import functools import gc @@ -10,6 +12,7 @@ import unittest from test import support +from test.support import TestStats from test.support import os_helper from test.support import threading_helper from test.libregrtest.cmdline import Namespace @@ -17,153 +20,174 @@ from test.libregrtest.utils import clear_caches, format_duration, print_warning +# Avoid enum.Enum to reduce the number of imports when tests are run +class State: + PASSED = "PASSED" + FAILED = "FAILED" + SKIPPED = "SKIPPED" + UNCAUGHT_EXC = "UNCAUGHT_EXC" + REFLEAK = "REFLEAK" + ENV_CHANGED = "ENV_CHANGED" + RESOURCE_DENIED = "RESOURCE_DENIED" + INTERRUPTED = "INTERRUPTED" + MULTIPROCESSING_ERROR = "MULTIPROCESSING_ERROR" + DID_NOT_RUN = "DID_NOT_RUN" + TIMEOUT = "TIMEOUT" + + @staticmethod + def is_failed(state): + return state in { + State.FAILED, + State.UNCAUGHT_EXC, + State.REFLEAK, + State.MULTIPROCESSING_ERROR, + State.TIMEOUT} + + @staticmethod + def has_meaningful_duration(state): + # Consider that the duration is meaningless for these cases. + # For example, if a whole test file is skipped, its duration + # is unlikely to be the duration of executing its tests, + # but just the duration to execute code which skips the test. + return state not in { + State.SKIPPED, + State.RESOURCE_DENIED, + State.INTERRUPTED, + State.MULTIPROCESSING_ERROR, + State.DID_NOT_RUN} + + +@dataclasses.dataclass(slots=True) class TestResult: - def __init__( - self, - name: str, - duration_sec: float = 0.0, - xml_data: list[str] | None = None, - ) -> None: - self.name = name - self.duration_sec = duration_sec - self.xml_data = xml_data - - def __str__(self) -> str: - return f"{self.name} finished" - - -class Passed(TestResult): - def __str__(self) -> str: - return f"{self.name} passed" - - -class Failed(TestResult): - def __init__( - self, - name: str, - duration_sec: float = 0.0, - xml_data: list[str] | None = None, - errors: list[tuple[str, str]] | None = None, - failures: list[tuple[str, str]] | None = None, - ) -> None: - super().__init__(name, duration_sec=duration_sec, xml_data=xml_data) - self.errors = errors - self.failures = failures - - def __str__(self) -> str: + test_name: str + state: str | None = None + # Test duration in seconds + duration: float | None = None + xml_data: list[str] | None = None + stats: TestStats | None = None + + # errors and failures copied from support.TestFailedWithDetails + errors: list[tuple[str, str]] | None = None + failures: list[tuple[str, str]] | None = None + + def is_failed(self, fail_env_changed: bool) -> bool: + if self.state == State.ENV_CHANGED: + return fail_env_changed + return State.is_failed(self.state) + + def _format_failed(self): if self.errors and self.failures: le = len(self.errors) lf = len(self.failures) error_s = "error" + ("s" if le > 1 else "") failure_s = "failure" + ("s" if lf > 1 else "") - return f"{self.name} failed ({le} {error_s}, {lf} {failure_s})" + return f"{self.test_name} failed ({le} {error_s}, {lf} {failure_s})" if self.errors: le = len(self.errors) error_s = "error" + ("s" if le > 1 else "") - return f"{self.name} failed ({le} {error_s})" + return f"{self.test_name} failed ({le} {error_s})" if self.failures: lf = len(self.failures) failure_s = "failure" + ("s" if lf > 1 else "") - return f"{self.name} failed ({lf} {failure_s})" - - return f"{self.name} failed" - - -class UncaughtException(Failed): - def __str__(self) -> str: - return f"{self.name} failed (uncaught exception)" - - -class EnvChanged(Failed): - def __str__(self) -> str: - return f"{self.name} failed (env changed)" - - -class RefLeak(Failed): - def __str__(self) -> str: - return f"{self.name} failed (reference leak)" - - -class Skipped(TestResult): - def __str__(self) -> str: - return f"{self.name} skipped" - - -class ResourceDenied(Skipped): - def __str__(self) -> str: - return f"{self.name} skipped (resource denied)" - - -class Interrupted(TestResult): - def __str__(self) -> str: - return f"{self.name} interrupted" - - -class ChildError(Failed): - def __str__(self) -> str: - return f"{self.name} crashed" - - -class DidNotRun(TestResult): - def __str__(self) -> str: - return f"{self.name} ran no tests" + return f"{self.test_name} failed ({lf} {failure_s})" + return f"{self.test_name} failed" -class Timeout(Failed): def __str__(self) -> str: - return f"{self.name} timed out ({format_duration(self.duration_sec)})" + match self.state: + case State.PASSED: + return f"{self.test_name} passed" + case State.FAILED: + return self._format_failed() + case State.SKIPPED: + return f"{self.test_name} skipped" + case State.UNCAUGHT_EXC: + return f"{self.test_name} failed (uncaught exception)" + case State.REFLEAK: + return f"{self.test_name} failed (reference leak)" + case State.ENV_CHANGED: + return f"{self.test_name} failed (env changed)" + case State.RESOURCE_DENIED: + return f"{self.test_name} skipped (resource denied)" + case State.INTERRUPTED: + return f"{self.test_name} interrupted" + case State.MULTIPROCESSING_ERROR: + return f"{self.test_name} process crashed" + case State.DID_NOT_RUN: + return f"{self.test_name} ran no tests" + case State.TIMEOUT: + return f"{self.test_name} timed out ({format_duration(self.duration)})" + case _: + raise ValueError("unknown result state: {state!r}") + + def has_meaningful_duration(self): + return State.has_meaningful_duration(self.state) + + def set_env_changed(self): + if self.state is None or self.state == State.PASSED: + self.state = State.ENV_CHANGED # Minimum duration of a test to display its duration or to mention that # the test is running in background PROGRESS_MIN_TIME = 30.0 # seconds -# small set of tests to determine if we have a basically functioning interpreter -# (i.e. if any of these fail, then anything else is likely to follow) -STDTESTS = [ - 'test_grammar', - 'test_opcodes', - 'test_dict', - 'test_builtin', - 'test_exceptions', - 'test_types', - 'test_unittest', - 'test_doctest', - 'test_doctest2', - 'test_support' -] - -# set of tests that we don't want to be executed when using regrtest -NOTTESTS = set() +#If these test directories are encountered recurse into them and treat each +# test_ .py or dir as a separate test module. This can increase parallelism. +# Beware this can't generally be done for any directory with sub-tests as the +# __init__.py may do things which alter what tests are to be run. +SPLITTESTDIRS = { + "test_asyncio", + "test_concurrent_futures", + "test_future_stmt", + "test_multiprocessing_fork", + "test_multiprocessing_forkserver", + "test_multiprocessing_spawn", +} # Storage of uncollectable objects FOUND_GARBAGE = [] -def is_failed(result: TestResult, ns: Namespace) -> bool: - if isinstance(result, EnvChanged): - return ns.fail_env_changed - return isinstance(result, Failed) - - def findtestdir(path=None): return path or os.path.dirname(os.path.dirname(__file__)) or os.curdir -def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS): +def findtests(*, testdir=None, exclude=(), + split_test_dirs=SPLITTESTDIRS, base_mod=""): """Return a list of all applicable test modules.""" testdir = findtestdir(testdir) - names = os.listdir(testdir) tests = [] - others = set(stdtests) | nottests - for name in names: + for name in os.listdir(testdir): mod, ext = os.path.splitext(name) - if mod[:5] == "test_" and ext in (".py", "") and mod not in others: - tests.append(mod) - return stdtests + sorted(tests) + if (not mod.startswith("test_")) or (mod in exclude): + continue + if mod in split_test_dirs: + subdir = os.path.join(testdir, mod) + mod = f"{base_mod or 'test'}.{mod}" + tests.extend(findtests(testdir=subdir, exclude=exclude, + split_test_dirs=split_test_dirs, base_mod=mod)) + elif ext in (".py", ""): + tests.append(f"{base_mod}.{mod}" if base_mod else mod) + return sorted(tests) + + +def split_test_packages(tests, *, testdir=None, exclude=(), + split_test_dirs=SPLITTESTDIRS): + testdir = findtestdir(testdir) + splitted = [] + for name in tests: + if name in split_test_dirs: + subdir = os.path.join(testdir, name) + splitted.extend(findtests(testdir=subdir, exclude=exclude, + split_test_dirs=split_test_dirs, + base_mod=name)) + else: + splitted.append(name) + return splitted def get_abs_module(ns: Namespace, test_name: str) -> str: @@ -174,9 +198,9 @@ def get_abs_module(ns: Namespace, test_name: str) -> str: return 'test.' + test_name -def _runtest(ns: Namespace, test_name: str) -> TestResult: - # Handle faulthandler timeout, capture stdout+stderr, XML serialization - # and measure time. +def _runtest_capture_output_timeout_junit(result: TestResult, ns: Namespace) -> None: + # Capture stdout and stderr, set faulthandler timeout, + # and create JUnit XML report. output_on_failure = ns.verbose3 @@ -186,7 +210,6 @@ def _runtest(ns: Namespace, test_name: str) -> TestResult: if use_timeout: faulthandler.dump_traceback_later(ns.timeout, exit=True) - start_time = time.perf_counter() try: support.set_match_tests(ns.match_tests, ns.ignore_tests) support.junit_xml_list = xml_list = [] if ns.xmlpath else None @@ -211,9 +234,9 @@ def _runtest(ns: Namespace, test_name: str) -> TestResult: # warnings will be written to sys.stderr below. print_warning.orig_stderr = stream - result = _runtest_inner(ns, test_name, - display_failure=False) - if not isinstance(result, Passed): + _runtest_env_changed_exc(result, ns, display_failure=False) + # Ignore output if the test passed successfully + if result.state != State.PASSED: output = stream.getvalue() finally: sys.stdout = orig_stdout @@ -227,18 +250,13 @@ def _runtest(ns: Namespace, test_name: str) -> TestResult: # Tell tests to be moderately quiet support.verbose = ns.verbose - result = _runtest_inner(ns, test_name, - display_failure=not ns.verbose) + _runtest_env_changed_exc(result, ns, + display_failure=not ns.verbose) if xml_list: import xml.etree.ElementTree as ET - result.xml_data = [ - ET.tostring(x).decode('us-ascii') - for x in xml_list - ] - - result.duration_sec = time.perf_counter() - start_time - return result + result.xml_data = [ET.tostring(x).decode('us-ascii') + for x in xml_list] finally: if use_timeout: faulthandler.cancel_dump_traceback_later() @@ -251,19 +269,23 @@ def runtest(ns: Namespace, test_name: str) -> TestResult: ns -- regrtest namespace of options test_name -- the name of the test - Returns a TestResult sub-class depending on the kind of result received. + Returns a TestResult. If ns.xmlpath is not None, xml_data is a list containing each generated testsuite element. """ + start_time = time.perf_counter() + result = TestResult(test_name) try: - return _runtest(ns, test_name) + _runtest_capture_output_timeout_junit(result, ns) except: if not ns.pgo: msg = traceback.format_exc() print(f"test {test_name} crashed -- {msg}", file=sys.stderr, flush=True) - return Failed(test_name) + result.state = State.UNCAUGHT_EXC + result.duration = time.perf_counter() - start_time + return result def _test_module(the_module): @@ -273,18 +295,48 @@ def _test_module(the_module): print(error, file=sys.stderr) if loader.errors: raise Exception("errors while loading tests") - support.run_unittest(tests) + return support.run_unittest(tests) def save_env(ns: Namespace, test_name: str): return saved_test_environment(test_name, ns.verbose, ns.quiet, pgo=ns.pgo) -def _runtest_inner2(ns: Namespace, test_name: str) -> bool: - # Load the test function, run the test function, handle huntrleaks - # to detect leaks. +def regrtest_runner(result, test_func, ns) -> None: + # Run test_func(), collect statistics, and detect reference and memory + # leaks. + + if ns.huntrleaks: + from test.libregrtest.refleak import dash_R + refleak, test_result = dash_R(ns, result.test_name, test_func) + else: + test_result = test_func() + refleak = False + + if refleak: + result.state = State.REFLEAK + + match test_result: + case TestStats(): + stats = test_result + case unittest.TestResult(): + stats = TestStats.from_unittest(test_result) + case doctest.TestResults(): + stats = TestStats.from_doctest(test_result) + case None: + print_warning(f"{result.test_name} test runner returned None: {test_func}") + stats = None + case _: + print_warning(f"Unknown test result type: {type(test_result)}") + stats = None + + result.stats = stats + - abstest = get_abs_module(ns, test_name) +def _load_run_test(result: TestResult, ns: Namespace) -> None: + # Load the test function, run the test function. + + abstest = get_abs_module(ns, result.test_name) # remove the module from sys.module to reload it if it was already imported try: @@ -294,23 +346,14 @@ def _runtest_inner2(ns: Namespace, test_name: str) -> bool: the_module = importlib.import_module(abstest) - if ns.huntrleaks: - from test.libregrtest.refleak import dash_R - - # If the test has a test_main, that will run the appropriate - # tests. If not, use normal unittest test loading. - test_runner = getattr(the_module, "test_main", None) - if test_runner is None: - test_runner = functools.partial(_test_module, the_module) + if hasattr(the_module, "test_main"): + # https://github.com/python/cpython/issues/89392 + raise Exception(f"Module {result.test_name} defines test_main() which is no longer supported by regrtest") + test_func = functools.partial(_test_module, the_module) try: - with save_env(ns, test_name): - if ns.huntrleaks: - # Return True if the test leaked references - refleak = dash_R(ns, test_name, test_runner) - else: - test_runner() - refleak = False + with save_env(ns, result.test_name): + regrtest_runner(result, test_func, ns) finally: # First kill any dangling references to open files etc. # This can also issue some ResourceWarnings which would otherwise get @@ -318,11 +361,11 @@ def _runtest_inner2(ns: Namespace, test_name: str) -> bool: # failures. support.gc_collect() - cleanup_test_droppings(test_name, ns.verbose) + cleanup_test_droppings(result.test_name, ns.verbose) if gc.garbage: support.environment_altered = True - print_warning(f"{test_name} created {len(gc.garbage)} " + print_warning(f"{result.test_name} created {len(gc.garbage)} " f"uncollectable object(s).") # move the uncollectable objects somewhere, @@ -332,12 +375,9 @@ def _runtest_inner2(ns: Namespace, test_name: str) -> bool: support.reap_children() - return refleak - -def _runtest_inner( - ns: Namespace, test_name: str, display_failure: bool = True -) -> TestResult: +def _runtest_env_changed_exc(result: TestResult, ns: Namespace, + display_failure: bool = True) -> None: # Detect environment changes, handle exceptions. # Reset the environment_altered flag to detect if a test altered @@ -347,49 +387,61 @@ def _runtest_inner( if ns.pgo: display_failure = False + test_name = result.test_name try: clear_caches() support.gc_collect() with save_env(ns, test_name): - refleak = _runtest_inner2(ns, test_name) + _load_run_test(result, ns) except support.ResourceDenied as msg: if not ns.quiet and not ns.pgo: print(f"{test_name} skipped -- {msg}", flush=True) - return ResourceDenied(test_name) + result.state = State.RESOURCE_DENIED + return except unittest.SkipTest as msg: if not ns.quiet and not ns.pgo: print(f"{test_name} skipped -- {msg}", flush=True) - return Skipped(test_name) + result.state = State.SKIPPED + return except support.TestFailedWithDetails as exc: msg = f"test {test_name} failed" if display_failure: msg = f"{msg} -- {exc}" print(msg, file=sys.stderr, flush=True) - return Failed(test_name, errors=exc.errors, failures=exc.failures) + result.state = State.FAILED + result.errors = exc.errors + result.failures = exc.failures + result.stats = exc.stats + return except support.TestFailed as exc: msg = f"test {test_name} failed" if display_failure: msg = f"{msg} -- {exc}" print(msg, file=sys.stderr, flush=True) - return Failed(test_name) + result.state = State.FAILED + result.stats = exc.stats + return except support.TestDidNotRun: - return DidNotRun(test_name) + result.state = State.DID_NOT_RUN + return except KeyboardInterrupt: print() - return Interrupted(test_name) + result.state = State.INTERRUPTED + return except: if not ns.pgo: msg = traceback.format_exc() print(f"test {test_name} crashed -- {msg}", file=sys.stderr, flush=True) - return UncaughtException(test_name) + result.state = State.UNCAUGHT_EXC + return - if refleak: - return RefLeak(test_name) if support.environment_altered: - return EnvChanged(test_name) - return Passed(test_name) + result.set_env_changed() + # Don't override the state if it was already set (REFLEAK or ENV_CHANGED) + if result.state is None: + result.state = State.PASSED def cleanup_test_droppings(test_name: str, verbose: int) -> None: diff --git a/mingw32/lib/python3.11/test/libregrtest/runtest_mp.py b/mingw32/lib/python3.11/test/libregrtest/runtest_mp.py index 8587e64e515..fb1f80b0c05 100644 --- a/mingw32/lib/python3.11/test/libregrtest/runtest_mp.py +++ b/mingw32/lib/python3.11/test/libregrtest/runtest_mp.py @@ -1,6 +1,7 @@ +import dataclasses import faulthandler import json -import os +import os.path import queue import signal import subprocess @@ -13,11 +14,13 @@ from test import support from test.support import os_helper +from test.support import TestStats from test.libregrtest.cmdline import Namespace from test.libregrtest.main import Regrtest from test.libregrtest.runtest import ( - runtest, is_failed, TestResult, Interrupted, Timeout, ChildError, PROGRESS_MIN_TIME) + runtest, TestResult, State, + PROGRESS_MIN_TIME) from test.libregrtest.setup import setup_tests from test.libregrtest.utils import format_duration, print_warning @@ -42,9 +45,9 @@ def must_stop(result: TestResult, ns: Namespace) -> bool: - if isinstance(result, Interrupted): + if result.state == State.INTERRUPTED: return True - if ns.failfast and is_failed(result, ns): + if ns.failfast and result.is_failed(ns.fail_env_changed): return True return False @@ -55,7 +58,7 @@ def parse_worker_args(worker_args) -> tuple[Namespace, str]: return (ns, test_name) -def run_test_in_subprocess(testname: str, ns: Namespace, stdout_fh: TextIO) -> subprocess.Popen: +def run_test_in_subprocess(testname: str, ns: Namespace, tmp_dir: str, stdout_fh: TextIO) -> subprocess.Popen: ns_dict = vars(ns) worker_args = (ns_dict, testname) worker_args = json.dumps(worker_args) @@ -68,10 +71,17 @@ def run_test_in_subprocess(testname: str, ns: Namespace, stdout_fh: TextIO) -> s '-m', 'test.regrtest', '--worker-args', worker_args] + env = dict(os.environ) + if tmp_dir is not None: + env['TMPDIR'] = tmp_dir + env['TEMP'] = tmp_dir + env['TMP'] = tmp_dir + # Running the child from the same working directory as regrtest's original # invocation ensures that TEMPDIR for the child is the same when # sysconfig.is_python_build() is true. See issue 15300. kw = dict( + env=env, stdout=stdout_fh, # bpo-45410: Write stderr into stdout to keep messages order stderr=stdout_fh, @@ -122,8 +132,8 @@ def stop(self): class MultiprocessResult(NamedTuple): result: TestResult # bpo-45410: stderr is written into stdout to keep messages order - stdout: str - error_msg: str + worker_stdout: str | None = None + err_msg: str | None = None ExcStr = str @@ -201,18 +211,15 @@ def stop(self) -> None: def mp_result_error( self, test_result: TestResult, - stdout: str = '', + stdout: str | None = None, err_msg=None ) -> MultiprocessResult: - test_result.duration_sec = time.monotonic() - self.start_time return MultiprocessResult(test_result, stdout, err_msg) - def _run_process(self, test_name: str, stdout_fh: TextIO) -> int: - self.start_time = time.monotonic() - + def _run_process(self, test_name: str, tmp_dir: str, stdout_fh: TextIO) -> int: self.current_test_name = test_name try: - popen = run_test_in_subprocess(test_name, self.ns, stdout_fh) + popen = run_test_in_subprocess(test_name, self.ns, tmp_dir, stdout_fh) self._killed = False self._popen = popen @@ -276,7 +283,20 @@ def _runtest(self, test_name: str) -> MultiprocessResult: # gh-93353: Check for leaked temporary files in the parent process, # since the deletion of temporary files can happen late during # Python finalization: too late for libregrtest. - retcode = self._run_process(test_name, stdout_fh) + if not support.is_wasi: + # Don't check for leaked temporary files and directories if Python is + # run on WASI. WASI don't pass environment variables like TMPDIR to + # worker processes. + tmp_dir = tempfile.mkdtemp(prefix="test_python_") + tmp_dir = os.path.abspath(tmp_dir) + try: + retcode = self._run_process(test_name, tmp_dir, stdout_fh) + finally: + tmp_files = os.listdir(tmp_dir) + os_helper.rmtree(tmp_dir) + else: + retcode = self._run_process(test_name, None, stdout_fh) + tmp_files = () stdout_fh.seek(0) try: @@ -285,30 +305,41 @@ def _runtest(self, test_name: str) -> MultiprocessResult: # gh-101634: Catch UnicodeDecodeError if stdout cannot be # decoded from encoding err_msg = f"Cannot read process stdout: {exc}" - return self.mp_result_error(ChildError(test_name), '', err_msg) + result = TestResult(test_name, state=State.MULTIPROCESSING_ERROR) + return self.mp_result_error(result, err_msg=err_msg) if retcode is None: - return self.mp_result_error(Timeout(test_name), stdout) + result = TestResult(test_name, state=State.TIMEOUT) + return self.mp_result_error(result, stdout) err_msg = None if retcode != 0: err_msg = "Exit code %s" % retcode else: - stdout, _, result = stdout.rpartition("\n") + stdout, _, worker_json = stdout.rpartition("\n") stdout = stdout.rstrip() - if not result: + if not worker_json: err_msg = "Failed to parse worker stdout" else: try: # deserialize run_tests_worker() output - result = json.loads(result, object_hook=decode_test_result) + result = json.loads(worker_json, + object_hook=decode_test_result) except Exception as exc: err_msg = "Failed to parse worker JSON: %s" % exc - if err_msg is not None: - return self.mp_result_error(ChildError(test_name), stdout, err_msg) + if err_msg: + result = TestResult(test_name, state=State.MULTIPROCESSING_ERROR) + return self.mp_result_error(result, stdout, err_msg) + + if tmp_files: + msg = (f'\n\n' + f'Warning -- {test_name} leaked temporary files ' + f'({len(tmp_files)}): {", ".join(sorted(tmp_files))}') + stdout += msg + result.set_env_changed() - return MultiprocessResult(result, stdout, err_msg) + return MultiprocessResult(result, stdout) def run(self) -> None: while not self._stopped: @@ -318,7 +349,9 @@ def run(self) -> None: except StopIteration: break + self.start_time = time.monotonic() mp_result = self._runtest(test_name) + mp_result.result.duration = time.monotonic() - self.start_time self.output.put((False, mp_result)) if must_stop(mp_result.result, self.ns): @@ -444,11 +477,11 @@ def display_result(self, mp_result: MultiprocessResult) -> None: result = mp_result.result text = str(result) - if mp_result.error_msg is not None: - # CHILD_ERROR - text += ' (%s)' % mp_result.error_msg - elif (result.duration_sec >= PROGRESS_MIN_TIME and not self.ns.pgo): - text += ' (%s)' % format_duration(result.duration_sec) + if mp_result.err_msg: + # MULTIPROCESSING_ERROR + text += ' (%s)' % mp_result.err_msg + elif (result.duration >= PROGRESS_MIN_TIME and not self.ns.pgo): + text += ' (%s)' % format_duration(result.duration) running = get_running(self.workers) if running and not self.ns.pgo: text += ' -- running: %s' % ', '.join(running) @@ -460,7 +493,7 @@ def _process_result(self, item: QueueOutput) -> bool: # Thread got an exception format_exc = item[1] print_warning(f"regrtest worker thread failed: {format_exc}") - result = ChildError("") + result = TestResult("", state=State.MULTIPROCESSING_ERROR) self.regrtest.accumulate_result(result) return True @@ -469,8 +502,8 @@ def _process_result(self, item: QueueOutput) -> bool: self.regrtest.accumulate_result(mp_result.result) self.display_result(mp_result) - if mp_result.stdout: - print(mp_result.stdout, flush=True) + if mp_result.worker_stdout: + print(mp_result.worker_stdout, flush=True) if must_stop(mp_result.result, self.ns): return True @@ -512,32 +545,20 @@ class EncodeTestResult(json.JSONEncoder): def default(self, o: Any) -> dict[str, Any]: if isinstance(o, TestResult): - result = vars(o) + result = dataclasses.asdict(o) result["__test_result__"] = o.__class__.__name__ return result return super().default(o) -def decode_test_result(d: dict[str, Any]) -> TestResult | dict[str, Any]: +def decode_test_result(d: dict[str, Any]) -> TestResult | TestStats | dict[str, Any]: """Decode a TestResult (sub)class object from a JSON dict.""" if "__test_result__" not in d: return d - cls_name = d.pop("__test_result__") - for cls in get_all_test_result_classes(): - if cls.__name__ == cls_name: - return cls(**d) - - -def get_all_test_result_classes() -> set[type[TestResult]]: - prev_count = 0 - classes = {TestResult} - while len(classes) > prev_count: - prev_count = len(classes) - to_add = [] - for cls in classes: - to_add.extend(cls.__subclasses__()) - classes.update(to_add) - return classes + d.pop('__test_result__') + if d['stats'] is not None: + d['stats'] = TestStats(**d['stats']) + return TestResult(**d) diff --git a/mingw32/lib/python3.11/test/libregrtest/save_env.py b/mingw32/lib/python3.11/test/libregrtest/save_env.py index 60c9be24617..7e801a59132 100644 --- a/mingw32/lib/python3.11/test/libregrtest/save_env.py +++ b/mingw32/lib/python3.11/test/libregrtest/save_env.py @@ -23,7 +23,7 @@ class SkipTestEnvironment(Exception): class saved_test_environment: """Save bits of the test environment and restore them at block exit. - with saved_test_environment(testname, verbose, quiet): + with saved_test_environment(test_name, verbose, quiet): #stuff Unless quiet is True, a warning is printed to stderr if any of @@ -34,8 +34,8 @@ class saved_test_environment: items is also printed. """ - def __init__(self, testname, verbose=0, quiet=False, *, pgo=False): - self.testname = testname + def __init__(self, test_name, verbose=0, quiet=False, *, pgo=False): + self.test_name = test_name self.verbose = verbose self.quiet = quiet self.pgo = pgo @@ -321,7 +321,7 @@ def __exit__(self, exc_type, exc_val, exc_tb): restore(original) if not self.quiet and not self.pgo: print_warning( - f"{name} was modified by {self.testname}\n" + f"{name} was modified by {self.test_name}\n" f" Before: {original}\n" f" After: {current} ") return False diff --git a/mingw32/lib/python3.11/test/libregrtest/utils.py b/mingw32/lib/python3.11/test/libregrtest/utils.py index 8578a028c78..49f3a236f3d 100644 --- a/mingw32/lib/python3.11/test/libregrtest/utils.py +++ b/mingw32/lib/python3.11/test/libregrtest/utils.py @@ -1,6 +1,7 @@ import math import os.path import sys +import sysconfig import textwrap from test import support @@ -210,3 +211,84 @@ def clear_caches(): else: for f in typing._cleanups: f() + + +def get_build_info(): + # Get most important configure and build options as a list of strings. + # Example: ['debug', 'ASAN+MSAN'] or ['release', 'LTO+PGO']. + + config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' + cflags = sysconfig.get_config_var('PY_CFLAGS') or '' + cflags_nodist = sysconfig.get_config_var('PY_CFLAGS_NODIST') or '' + ldflags_nodist = sysconfig.get_config_var('PY_LDFLAGS_NODIST') or '' + + build = [] + + # --disable-gil + if sysconfig.get_config_var('Py_NOGIL'): + build.append("nogil") + + if hasattr(sys, 'gettotalrefcount'): + # --with-pydebug + build.append('debug') + + if '-DNDEBUG' in (cflags + cflags_nodist): + build.append('without_assert') + else: + build.append('release') + + if '--with-assertions' in config_args: + build.append('with_assert') + elif '-DNDEBUG' not in (cflags + cflags_nodist): + build.append('with_assert') + + # --enable-framework=name + framework = sysconfig.get_config_var('PYTHONFRAMEWORK') + if framework: + build.append(f'framework={framework}') + + # --enable-shared + shared = int(sysconfig.get_config_var('PY_ENABLE_SHARED') or '0') + if shared: + build.append('shared') + + # --with-lto + optimizations = [] + if '-flto=thin' in ldflags_nodist: + optimizations.append('ThinLTO') + elif '-flto' in ldflags_nodist: + optimizations.append('LTO') + + if support.check_cflags_pgo(): + # PGO (--enable-optimizations) + optimizations.append('PGO') + if optimizations: + build.append('+'.join(optimizations)) + + # --with-address-sanitizer + sanitizers = [] + if support.check_sanitizer(address=True): + sanitizers.append("ASAN") + # --with-memory-sanitizer + if support.check_sanitizer(memory=True): + sanitizers.append("MSAN") + # --with-undefined-behavior-sanitizer + if support.check_sanitizer(ub=True): + sanitizers.append("UBSAN") + if sanitizers: + build.append('+'.join(sanitizers)) + + # --with-trace-refs + if hasattr(sys, 'getobjects'): + build.append("TraceRefs") + # --enable-pystats + if hasattr(sys, '_stats_on'): + build.append("pystats") + # --with-valgrind + if sysconfig.get_config_var('WITH_VALGRIND'): + build.append("valgrind") + # --with-dtrace + if sysconfig.get_config_var('WITH_DTRACE'): + build.append("dtrace") + + return build diff --git a/mingw32/lib/python3.11/test/lock_tests.py b/mingw32/lib/python3.11/test/lock_tests.py index f16c7ed952c..d5ac1319064 100644 --- a/mingw32/lib/python3.11/test/lock_tests.py +++ b/mingw32/lib/python3.11/test/lock_tests.py @@ -331,6 +331,42 @@ def test_release_save_unacquired(self): lock.release() self.assertRaises(RuntimeError, lock._release_save) + def test_recursion_count(self): + lock = self.locktype() + self.assertEqual(0, lock._recursion_count()) + lock.acquire() + self.assertEqual(1, lock._recursion_count()) + lock.acquire() + lock.acquire() + self.assertEqual(3, lock._recursion_count()) + lock.release() + self.assertEqual(2, lock._recursion_count()) + lock.release() + lock.release() + self.assertEqual(0, lock._recursion_count()) + + phase = [] + + def f(): + lock.acquire() + phase.append(None) + while len(phase) == 1: + _wait() + lock.release() + phase.append(None) + + with threading_helper.wait_threads_exit(): + start_new_thread(f, ()) + while len(phase) == 0: + _wait() + self.assertEqual(len(phase), 1) + self.assertEqual(0, lock._recursion_count()) + phase.append(None) + while len(phase) == 2: + _wait() + self.assertEqual(len(phase), 3) + self.assertEqual(0, lock._recursion_count()) + def test_different_thread(self): # Cannot release from a different thread lock = self.locktype() @@ -1015,13 +1051,15 @@ def test_default_timeout(self): """ Test the barrier's default timeout """ - # create a barrier with a low default timeout - barrier = self.barriertype(self.N, timeout=0.3) + # gh-109401: Barrier timeout should be long enough + # to create 4 threads on a slow CI. + timeout = 1.0 + barrier = self.barriertype(self.N, timeout=timeout) def f(): i = barrier.wait() if i == self.N // 2: - # One thread is later than the default timeout of 0.3s. - time.sleep(1.0) + # One thread is later than the default timeout. + time.sleep(timeout * 2) self.assertRaises(threading.BrokenBarrierError, barrier.wait) self.run_threads(f) diff --git a/mingw32/lib/python3.11/test/pickletester.py b/mingw32/lib/python3.11/test/pickletester.py index 6e87370c206..a687fe06290 100644 --- a/mingw32/lib/python3.11/test/pickletester.py +++ b/mingw32/lib/python3.11/test/pickletester.py @@ -2576,6 +2576,7 @@ def check_frame_opcodes(self, pickled): self.assertLess(pos - frameless_start, self.FRAME_SIZE_MIN) @support.skip_if_pgo_task + @support.requires_resource('cpu') def test_framing_many_objects(self): obj = list(range(10**5)) for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): diff --git a/mingw32/lib/python3.11/test/pythoninfo.py b/mingw32/lib/python3.11/test/pythoninfo.py index 61fd734d4c6..db8dfe247cc 100644 --- a/mingw32/lib/python3.11/test/pythoninfo.py +++ b/mingw32/lib/python3.11/test/pythoninfo.py @@ -112,6 +112,7 @@ def collect_sys(info_add): call_func(info_add, 'sys.androidapilevel', sys, 'getandroidapilevel') call_func(info_add, 'sys.windowsversion', sys, 'getwindowsversion') + call_func(info_add, 'sys.getrecursionlimit', sys, 'getrecursionlimit') encoding = sys.getfilesystemencoding() if hasattr(sys, 'getfilesystemencodeerrors'): @@ -163,6 +164,26 @@ def collect_platform(info_add): if libc_ver: info_add('platform.libc_ver', libc_ver) + try: + os_release = platform.freedesktop_os_release() + except OSError: + pass + else: + for key in ( + 'ID', + 'NAME', + 'PRETTY_NAME' + 'VARIANT', + 'VARIANT_ID', + 'VERSION', + 'VERSION_CODENAME', + 'VERSION_ID', + ): + if key not in os_release: + continue + info_add(f'platform.freedesktop_os_release[{key}]', + os_release[key]) + def collect_locale(info_add): import locale @@ -309,6 +330,13 @@ def format_groups(groups): "_PYTHON_PROJECT_BASE", "_PYTHON_SYSCONFIGDATA_NAME", "__PYVENV_LAUNCHER__", + + # Sanitizer options + "ASAN_OPTIONS", + "LSAN_OPTIONS", + "MSAN_OPTIONS", + "TSAN_OPTIONS", + "UBSAN_OPTIONS", )) for name, value in os.environ.items(): uname = name.upper() @@ -493,9 +521,13 @@ def collect_sysconfig(info_add): 'PY_STDMODULE_CFLAGS', 'Py_DEBUG', 'Py_ENABLE_SHARED', + 'Py_NOGIL', 'SHELL', 'SOABI', + 'abs_builddir', + 'abs_srcdir', 'prefix', + 'srcdir', ): value = sysconfig.get_config_var(name) if name == 'ANDROID_API_LEVEL' and not value: @@ -846,6 +878,15 @@ def collect_fips(info_add): pass +def collect_libregrtest_utils(info_add): + try: + from test.libregrtest import utils + except ImportError: + return + + info_add('libregrtests.build_info', ' '.join(utils.get_build_info())) + + def collect_info(info): error = False info_add = info.add @@ -883,6 +924,7 @@ def collect_info(info): collect_tkinter, collect_windows, collect_zlib, + collect_libregrtest_utils, # Collecting from tests should be last as they have side effects. collect_test_socket, @@ -912,7 +954,6 @@ def dump_info(info, file=None): for key, value in infos: value = value.replace("\n", " ") print("%s: %s" % (key, value)) - print() def main(): @@ -921,6 +962,7 @@ def main(): dump_info(info) if error: + print() print("Collection failed: exit with error", file=sys.stderr) sys.exit(1) diff --git a/mingw32/lib/python3.11/test/sgml_input.html b/mingw32/lib/python3.11/test/sgml_input.html deleted file mode 100644 index f4d2e6cc805..00000000000 --- a/mingw32/lib/python3.11/test/sgml_input.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - - - -
- - - - - -
-
- - - - - -
- - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - -
  MetalCristalDeuterioEnergía  
160.6363.40639.230-80/3.965
-
-
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Flotas (max. 9)
Num.MisiónCantidadComienzoSalidaObjetivoLlegadaOrden
1 - Espionaje - (F) - 3[2:250:6]Wed Aug 9 18:00:02[2:242:5]Wed Aug 9 18:01:02 -
- - -
-
2 - Espionaje - (V) - 3[2:250:6]Wed Aug 9 17:59:55[2:242:1]Wed Aug 9 18:01:55 -
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Nueva misión: elegir naves
NavesDisponibles--
Nave pequeña de carga10máx
Nave grande de carga19máx
Crucero6máx
Reciclador1máx
Sonda de espionaje139máx
Ninguna naveTodas las naves
- -

-
- - diff --git a/mingw32/lib/python3.11/test/signalinterproctester.py b/mingw32/lib/python3.11/test/signalinterproctester.py index bc60b747f71..5dafc029005 100644 --- a/mingw32/lib/python3.11/test/signalinterproctester.py +++ b/mingw32/lib/python3.11/test/signalinterproctester.py @@ -1,3 +1,4 @@ +import gc import os import signal import subprocess @@ -60,6 +61,13 @@ def test_interprocess_signal(self): self.assertEqual(self.got_signals, {'SIGHUP': 1, 'SIGUSR1': 0, 'SIGALRM': 0}) + # gh-110033: Make sure that the subprocess.Popen is deleted before + # the next test which raises an exception. Otherwise, the exception + # may be raised when Popen.__del__() is executed and so be logged + # as "Exception ignored in: ". + child = None + gc.collect() + with self.assertRaises(SIGUSR1Exception): with self.subprocess_send_signal(pid, "SIGUSR1") as child: self.wait_signal(child, 'SIGUSR1') diff --git a/mingw32/lib/python3.11/test/string_tests.py b/mingw32/lib/python3.11/test/string_tests.py index d69edd7bf45..fdced1c26cf 100644 --- a/mingw32/lib/python3.11/test/string_tests.py +++ b/mingw32/lib/python3.11/test/string_tests.py @@ -327,11 +327,12 @@ def reference_find(p, s): for i in range(len(s)): if s.startswith(p, i): return i + if p == '' and s == '': + return 0 return -1 - rr = random.randrange - choices = random.choices - for _ in range(1000): + def check_pattern(rr): + choices = random.choices p0 = ''.join(choices('abcde', k=rr(10))) * rr(10, 20) p = p0[:len(p0) - rr(10)] # pop off some characters left = ''.join(choices('abcdef', k=rr(2000))) @@ -341,6 +342,13 @@ def reference_find(p, s): self.checkequal(reference_find(p, text), text, 'find', p) + rr = random.randrange + for _ in range(1000): + check_pattern(rr) + + # Test that empty string always work: + check_pattern(lambda *args: 0) + def test_find_shift_table_overflow(self): """When the table of 8-bit shifts overflows.""" N = 2**8 + 100 diff --git a/mingw32/lib/python3.11/test/support/__init__.py b/mingw32/lib/python3.11/test/support/__init__.py index 98be9cdd0e1..2e6518cf241 100644 --- a/mingw32/lib/python3.11/test/support/__init__.py +++ b/mingw32/lib/python3.11/test/support/__init__.py @@ -4,6 +4,7 @@ raise ImportError('support must be imported from the test package') import contextlib +import dataclasses import functools import getpass import os @@ -116,17 +117,20 @@ class Error(Exception): class TestFailed(Error): """Test failed.""" + def __init__(self, msg, *args, stats=None): + self.msg = msg + self.stats = stats + super().__init__(msg, *args) + + def __str__(self): + return self.msg class TestFailedWithDetails(TestFailed): """Test failed.""" - def __init__(self, msg, errors, failures): - self.msg = msg + def __init__(self, msg, errors, failures, stats): self.errors = errors self.failures = failures - super().__init__(msg, errors, failures) - - def __str__(self): - return self.msg + super().__init__(msg, errors, failures, stats=stats) class TestDidNotRun(Error): """Test did not run any subtests.""" @@ -400,19 +404,19 @@ def check_sanitizer(*, address=False, memory=False, ub=False): raise ValueError('At least one of address, memory, or ub must be True') - _cflags = sysconfig.get_config_var('CFLAGS') or '' - _config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' + cflags = sysconfig.get_config_var('CFLAGS') or '' + config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' memory_sanitizer = ( - '-fsanitize=memory' in _cflags or - '--with-memory-sanitizer' in _config_args + '-fsanitize=memory' in cflags or + '--with-memory-sanitizer' in config_args ) address_sanitizer = ( - '-fsanitize=address' in _cflags or - '--with-memory-sanitizer' in _config_args + '-fsanitize=address' in cflags or + '--with-address-sanitizer' in config_args ) ub_sanitizer = ( - '-fsanitize=undefined' in _cflags or - '--with-undefined-behavior-sanitizer' in _config_args + '-fsanitize=undefined' in cflags or + '--with-undefined-behavior-sanitizer' in config_args ) return ( (memory and memory_sanitizer) or @@ -761,6 +765,21 @@ def python_is_optimized(): return final_opt not in ('', '-O0', '-Og') +def check_cflags_pgo(): + # Check if Python was built with ./configure --enable-optimizations: + # with Profile Guided Optimization (PGO). + cflags_nodist = sysconfig.get_config_var('PY_CFLAGS_NODIST') or '' + pgo_options = ( + # GCC + '-fprofile-use', + # clang: -fprofile-instr-use=code.profclangd + '-fprofile-instr-use', + # ICC + "-prof-use", + ) + return any(option in cflags_nodist for option in pgo_options) + + _header = 'nP' _align = '0n' if hasattr(sys, "getobjects"): @@ -1086,6 +1105,29 @@ def _filter_suite(suite, pred): newtests.append(test) suite._tests = newtests +@dataclasses.dataclass(slots=True) +class TestStats: + tests_run: int = 0 + failures: int = 0 + skipped: int = 0 + + @staticmethod + def from_unittest(result): + return TestStats(result.testsRun, + len(result.failures), + len(result.skipped)) + + @staticmethod + def from_doctest(results): + return TestStats(results.attempted, + results.failed) + + def accumulate(self, stats): + self.tests_run += stats.tests_run + self.failures += stats.failures + self.skipped += stats.skipped + + def _run_suite(suite): """Run tests from a unittest.TestSuite-derived class.""" runner = get_test_runner(sys.stdout, @@ -1100,6 +1142,7 @@ def _run_suite(suite): if not result.testsRun and not result.skipped and not result.errors: raise TestDidNotRun if not result.wasSuccessful(): + stats = TestStats.from_unittest(result) if len(result.errors) == 1 and not result.failures: err = result.errors[0][1] elif len(result.failures) == 1 and not result.errors: @@ -1109,7 +1152,8 @@ def _run_suite(suite): if not verbose: err += "; run in verbose mode for details" errors = [(str(tc), exc_str) for tc, exc_str in result.errors] failures = [(str(tc), exc_str) for tc, exc_str in result.failures] - raise TestFailedWithDetails(err, errors, failures) + raise TestFailedWithDetails(err, errors, failures, stats=stats) + return result # By default, don't filter tests @@ -1218,7 +1262,7 @@ def run_unittest(*classes): else: suite.addTest(loader.loadTestsFromTestCase(cls)) _filter_suite(suite, match_test) - _run_suite(suite) + return _run_suite(suite) #======================================================================= # Check for the presence of docstrings. @@ -1258,13 +1302,18 @@ def run_doctest(module, verbosity=None, optionflags=0): else: verbosity = None - f, t = doctest.testmod(module, verbose=verbosity, optionflags=optionflags) - if f: - raise TestFailed("%d of %d doctests failed" % (f, t)) + results = doctest.testmod(module, + verbose=verbosity, + optionflags=optionflags) + if results.failed: + stats = TestStats.from_doctest(results) + raise TestFailed(f"{results.failed} of {results.attempted} " + f"doctests failed", + stats=stats) if verbose: print('doctest (%s) ... %d tests with zero failures' % - (module.__name__, t)) - return f, t + (module.__name__, results.attempted)) + return results #======================================================================= @@ -2163,20 +2212,70 @@ def check_disallow_instantiation(testcase, tp, *args, **kwds): msg = f"cannot create '{re.escape(qualname)}' instances" testcase.assertRaisesRegex(TypeError, msg, tp, *args, **kwds) +def get_recursion_depth(): + """Get the recursion depth of the caller function. + + In the __main__ module, at the module level, it should be 1. + """ + try: + import _testinternalcapi + depth = _testinternalcapi.get_recursion_depth() + except (ImportError, RecursionError) as exc: + # sys._getframe() + frame.f_back implementation. + try: + depth = 0 + frame = sys._getframe() + while frame is not None: + depth += 1 + frame = frame.f_back + finally: + # Break any reference cycles. + frame = None + + # Ignore get_recursion_depth() frame. + return max(depth - 1, 1) + +def get_recursion_available(): + """Get the number of available frames before RecursionError. + + It depends on the current recursion depth of the caller function and + sys.getrecursionlimit(). + """ + limit = sys.getrecursionlimit() + depth = get_recursion_depth() + + try: + from _testcapi import USE_STACKCHECK + except ImportError: + USE_STACKCHECK = False + + if USE_STACKCHECK: + return max(limit - depth - 1, 0) + else: + return limit - depth + @contextlib.contextmanager -def infinite_recursion(max_depth=75): +def set_recursion_limit(limit): + """Temporarily change the recursion limit.""" + original_limit = sys.getrecursionlimit() + try: + sys.setrecursionlimit(limit) + yield + finally: + sys.setrecursionlimit(original_limit) + +def infinite_recursion(max_depth=100): """Set a lower limit for tests that interact with infinite recursions (e.g test_ast.ASTHelpers_Test.test_recursion_direct) since on some debug windows builds, due to not enough functions being inlined the stack size might not handle the default recursion limit (1000). See bpo-11105 for details.""" - - original_depth = sys.getrecursionlimit() - try: - sys.setrecursionlimit(max_depth) - yield - finally: - sys.setrecursionlimit(original_depth) + if max_depth < 4: + raise ValueError("max_depth must be at least 4, got {max_depth}") + depth = get_recursion_depth() + depth = max(depth - 1, 1) # Ignore infinite_recursion() frame. + limit = depth + max_depth + return set_recursion_limit(limit) def ignore_deprecations_from(module: str, *, like: str) -> object: token = object() @@ -2234,3 +2333,29 @@ def adjust_int_max_str_digits(max_digits): yield finally: sys.set_int_max_str_digits(current) + +_BASE_COPY_SRC_DIR_IGNORED_NAMES = frozenset({ + # SRC_DIR/.git + '.git', + # ignore all __pycache__/ sub-directories + '__pycache__', +}) + +# Ignore function for shutil.copytree() to copy the Python source code. +def copy_python_src_ignore(path, names): + ignored = _BASE_COPY_SRC_DIR_IGNORED_NAMES + if os.path.basename(path) == 'Doc': + ignored |= { + # SRC_DIR/Doc/build/ + 'build', + # SRC_DIR/Doc/venv/ + 'venv', + } + + # check if we are at the root of the source code + elif 'Modules' in names: + ignored |= { + # SRC_DIR/build/ + 'build', + } + return ignored diff --git a/mingw32/lib/python3.11/test/support/import_helper.py b/mingw32/lib/python3.11/test/support/import_helper.py index 5201dc84cf6..a803d9f1b40 100644 --- a/mingw32/lib/python3.11/test/support/import_helper.py +++ b/mingw32/lib/python3.11/test/support/import_helper.py @@ -8,7 +8,7 @@ import unittest import warnings -from .os_helper import unlink +from .os_helper import unlink, temp_dir @contextlib.contextmanager @@ -246,3 +246,26 @@ def modules_cleanup(oldmodules): # do currently). Implicitly imported *real* modules should be left alone # (see issue 10556). sys.modules.update(oldmodules) + + +@contextlib.contextmanager +def ready_to_import(name=None, source=""): + from test.support import script_helper + + # 1. Sets up a temporary directory and removes it afterwards + # 2. Creates the module file + # 3. Temporarily clears the module from sys.modules (if any) + # 4. Reverts or removes the module when cleaning up + name = name or "spam" + with temp_dir() as tempdir: + path = script_helper.make_script(tempdir, name, source) + old_module = sys.modules.pop(name, None) + try: + sys.path.insert(0, tempdir) + yield name, path + sys.path.remove(tempdir) + finally: + if old_module is not None: + sys.modules[name] = old_module + else: + sys.modules.pop(name, None) diff --git a/mingw32/lib/python3.11/test/support/socket_helper.py b/mingw32/lib/python3.11/test/support/socket_helper.py index 50e1d4d56c9..ec6d1dee4e9 100644 --- a/mingw32/lib/python3.11/test/support/socket_helper.py +++ b/mingw32/lib/python3.11/test/support/socket_helper.py @@ -1,8 +1,9 @@ import contextlib import errno import socket -import unittest +import subprocess import sys +import unittest from .. import support from . import warnings_helper @@ -270,3 +271,62 @@ def filter_error(err): # __cause__ or __context__? finally: socket.setdefaulttimeout(old_timeout) + + +# consider that sysctl values should not change while tests are running +_sysctl_cache = {} + +def _get_sysctl(name): + """Get a sysctl value as an integer.""" + try: + return _sysctl_cache[name] + except KeyError: + pass + + # At least Linux and FreeBSD support the "-n" option + cmd = ['sysctl', '-n', name] + proc = subprocess.run(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True) + if proc.returncode: + support.print_warning(f"{' '.join(cmd)!r} command failed with " + f"exit code {proc.returncode}") + # cache the error to only log the warning once + _sysctl_cache[name] = None + return None + output = proc.stdout + + # Parse '0\n' to get '0' + try: + value = int(output.strip()) + except Exception as exc: + support.print_warning(f"Failed to parse {' '.join(cmd)!r} " + f"command output {output!r}: {exc!r}") + # cache the error to only log the warning once + _sysctl_cache[name] = None + return None + + _sysctl_cache[name] = value + return value + + +def tcp_blackhole(): + if not sys.platform.startswith('freebsd'): + return False + + # gh-109015: test if FreeBSD TCP blackhole is enabled + value = _get_sysctl('net.inet.tcp.blackhole') + if value is None: + # don't skip if we fail to get the sysctl value + return False + return (value != 0) + + +def skip_if_tcp_blackhole(test): + """Decorator skipping test if TCP blackhole is enabled.""" + skip_if = unittest.skipIf( + tcp_blackhole(), + "TCP blackhole is enabled (sysctl net.inet.tcp.blackhole)" + ) + return skip_if(test) diff --git a/mingw32/lib/python3.11/test/test_ast.py b/mingw32/lib/python3.11/test/test_ast.py index 33c13ee29a2..c8d2f916dbd 100644 --- a/mingw32/lib/python3.11/test/test_ast.py +++ b/mingw32/lib/python3.11/test/test_ast.py @@ -1701,6 +1701,7 @@ def test_tuple(self): def test_nameconstant(self): self.expr(ast.NameConstant(4)) + @support.requires_resource('cpu') def test_stdlib_validates(self): stdlib = os.path.dirname(ast.__file__) tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")] diff --git a/mingw32/lib/python3.11/test/test_asyncgen.py b/mingw32/lib/python3.11/test/test_asyncgen.py index fb22f411c2e..2241b39f3b1 100644 --- a/mingw32/lib/python3.11/test/test_asyncgen.py +++ b/mingw32/lib/python3.11/test/test_asyncgen.py @@ -1037,8 +1037,7 @@ async def gen(): while True: yield 1 finally: - await asyncio.sleep(0.01) - await asyncio.sleep(0.01) + await asyncio.sleep(0) DONE = 1 async def run(): @@ -1048,7 +1047,10 @@ async def run(): del g gc_collect() # For PyPy or other GCs. - await asyncio.sleep(0.1) + # Starts running the aclose task + await asyncio.sleep(0) + # For asyncio.sleep(0) in finally block + await asyncio.sleep(0) self.loop.run_until_complete(run()) self.assertEqual(DONE, 1) diff --git a/mingw32/lib/python3.11/test/test_asyncio/test_base_events.py b/mingw32/lib/python3.11/test/test_asyncio/test_base_events.py index 6ba602dd619..f3f83ad318c 100644 --- a/mingw32/lib/python3.11/test/test_asyncio/test_base_events.py +++ b/mingw32/lib/python3.11/test/test_asyncio/test_base_events.py @@ -273,7 +273,7 @@ def cb(): self.loop.stop() self.loop._process_events = mock.Mock() - delay = 0.1 + delay = 0.100 when = self.loop.time() + delay self.loop.call_at(when, cb) @@ -282,10 +282,7 @@ def cb(): dt = self.loop.time() - t0 # 50 ms: maximum granularity of the event loop - self.assertGreaterEqual(dt, delay - 0.050, dt) - # tolerate a difference of +800 ms because some Python buildbots - # are really slow - self.assertLessEqual(dt, 0.9, dt) + self.assertGreaterEqual(dt, delay - test_utils.CLOCK_RES) with self.assertRaises(TypeError, msg="when cannot be None"): self.loop.call_at(None, cb) diff --git a/mingw32/lib/python3.11/test/test_asyncio/test_events.py b/mingw32/lib/python3.11/test/test_asyncio/test_events.py index 5728d25254f..d7871d3e538 100644 --- a/mingw32/lib/python3.11/test/test_asyncio/test_events.py +++ b/mingw32/lib/python3.11/test/test_asyncio/test_events.py @@ -31,6 +31,7 @@ from asyncio import events from asyncio import proactor_events from asyncio import selector_events +from multiprocessing.util import _cleanup_tests as multiprocessing_cleanup_tests from test.test_asyncio import utils as test_utils from test import support from test.support import socket_helper @@ -293,10 +294,11 @@ async def coro2(): # 15.6 msec, we use fairly long sleep times here (~100 msec). def test_run_until_complete(self): + delay = 0.100 t0 = self.loop.time() - self.loop.run_until_complete(asyncio.sleep(0.1)) - t1 = self.loop.time() - self.assertTrue(0.08 <= t1-t0 <= 0.8, t1-t0) + self.loop.run_until_complete(asyncio.sleep(delay)) + dt = self.loop.time() - t0 + self.assertGreaterEqual(dt, delay - test_utils.CLOCK_RES) def test_run_until_complete_stopped(self): @@ -671,6 +673,7 @@ def test_create_connection_local_addr(self): self.assertEqual(port, expected) tr.close() + @socket_helper.skip_if_tcp_blackhole def test_create_connection_local_addr_skip_different_family(self): # See https://github.com/python/cpython/issues/86508 port1 = socket_helper.find_unused_port() @@ -692,6 +695,7 @@ async def getaddrinfo(host, port, *args, **kwargs): with self.assertRaises(OSError): self.loop.run_until_complete(f) + @socket_helper.skip_if_tcp_blackhole def test_create_connection_local_addr_nomatch_family(self): # See https://github.com/python/cpython/issues/86508 port1 = socket_helper.find_unused_port() @@ -1248,6 +1252,7 @@ def connection_made(self, transport): server.close() + @socket_helper.skip_if_tcp_blackhole def test_server_close(self): f = self.loop.create_server(MyProto, '0.0.0.0', 0) server = self.loop.run_until_complete(f) @@ -1666,12 +1671,9 @@ async def main(): self.loop.stop() return res - start = time.monotonic() t = self.loop.create_task(main()) self.loop.run_forever() - elapsed = time.monotonic() - start - self.assertLess(elapsed, 0.1) self.assertEqual(t.result(), 'cancelled') self.assertRaises(asyncio.CancelledError, f.result) if ov is not None: @@ -1691,7 +1693,6 @@ def _run_once(): self.loop._run_once = _run_once async def wait(): - loop = self.loop await asyncio.sleep(1e-2) await asyncio.sleep(1e-4) await asyncio.sleep(1e-6) @@ -2727,6 +2728,8 @@ def test_get_event_loop_new_process(self): # multiprocessing.synchronize module cannot be imported. support.skip_if_broken_multiprocessing_synchronize() + self.addCleanup(multiprocessing_cleanup_tests) + async def main(): pool = concurrent.futures.ProcessPoolExecutor() result = await self.loop.run_in_executor( diff --git a/mingw32/lib/python3.11/test/test_asyncio/test_sock_lowlevel.py b/mingw32/lib/python3.11/test/test_asyncio/test_sock_lowlevel.py index db47616d183..1f8f4e2ddfc 100644 --- a/mingw32/lib/python3.11/test/test_asyncio/test_sock_lowlevel.py +++ b/mingw32/lib/python3.11/test/test_asyncio/test_sock_lowlevel.py @@ -10,6 +10,10 @@ from test import support from test.support import socket_helper +if socket_helper.tcp_blackhole(): + raise unittest.SkipTest('Not relevant to ProactorEventLoop') + + def tearDownModule(): asyncio.set_event_loop_policy(None) diff --git a/mingw32/lib/python3.11/test/test_asyncio/test_sslproto.py b/mingw32/lib/python3.11/test/test_asyncio/test_sslproto.py index 52a45f1c7c6..37d01533976 100644 --- a/mingw32/lib/python3.11/test/test_asyncio/test_sslproto.py +++ b/mingw32/lib/python3.11/test/test_asyncio/test_sslproto.py @@ -5,6 +5,7 @@ import unittest import weakref from test import support +from test.support import socket_helper from unittest import mock try: import ssl @@ -350,6 +351,7 @@ async def client(addr): support.gc_collect() self.assertIsNone(client_context()) + @socket_helper.skip_if_tcp_blackhole def test_start_tls_client_buf_proto_1(self): HELLO_MSG = b'1' * self.PAYLOAD_SIZE @@ -502,6 +504,7 @@ async def client(addr): asyncio.wait_for(client(srv.addr), timeout=support.SHORT_TIMEOUT)) + @socket_helper.skip_if_tcp_blackhole def test_start_tls_server_1(self): HELLO_MSG = b'1' * self.PAYLOAD_SIZE ANSWER = b'answer' diff --git a/mingw32/lib/python3.11/test/test_asyncio/test_subprocess.py b/mingw32/lib/python3.11/test/test_asyncio/test_subprocess.py index bea2314a528..8b4f14eb48d 100644 --- a/mingw32/lib/python3.11/test/test_asyncio/test_subprocess.py +++ b/mingw32/lib/python3.11/test/test_asyncio/test_subprocess.py @@ -2,6 +2,7 @@ import shutil import signal import sys +import textwrap import unittest import warnings from unittest import mock @@ -13,9 +14,14 @@ from test import support from test.support import os_helper -if sys.platform != 'win32': + +MS_WINDOWS = (sys.platform == 'win32') +if MS_WINDOWS: + import msvcrt +else: from asyncio import unix_events + if support.check_sanitizer(address=True): raise unittest.SkipTest("Exposes ASAN flakiness in GitHub CI") @@ -253,26 +259,43 @@ async def send_signal(proc): finally: signal.signal(signal.SIGHUP, old_handler) - def prepare_broken_pipe_test(self): + def test_stdin_broken_pipe(self): # buffer large enough to feed the whole pipe buffer large_data = b'x' * support.PIPE_MAX_SIZE + rfd, wfd = os.pipe() + self.addCleanup(os.close, rfd) + self.addCleanup(os.close, wfd) + if MS_WINDOWS: + handle = msvcrt.get_osfhandle(rfd) + os.set_handle_inheritable(handle, True) + code = textwrap.dedent(f''' + import os, msvcrt + handle = {handle} + fd = msvcrt.open_osfhandle(handle, os.O_RDONLY) + os.read(fd, 1) + ''') + from subprocess import STARTUPINFO + startupinfo = STARTUPINFO() + startupinfo.lpAttributeList = {"handle_list": [handle]} + kwargs = dict(startupinfo=startupinfo) + else: + code = f'import os; fd = {rfd}; os.read(fd, 1)' + kwargs = dict(pass_fds=(rfd,)) + # the program ends before the stdin can be fed proc = self.loop.run_until_complete( asyncio.create_subprocess_exec( - sys.executable, '-c', 'pass', + sys.executable, '-c', code, stdin=subprocess.PIPE, + **kwargs ) ) - return (proc, large_data) - - def test_stdin_broken_pipe(self): - proc, large_data = self.prepare_broken_pipe_test() - async def write_stdin(proc, data): - await asyncio.sleep(0.5) proc.stdin.write(data) + # Only exit the child process once the write buffer is filled + os.write(wfd, b'go') await proc.stdin.drain() coro = write_stdin(proc, large_data) @@ -283,7 +306,16 @@ async def write_stdin(proc, data): self.loop.run_until_complete(proc.wait()) def test_communicate_ignore_broken_pipe(self): - proc, large_data = self.prepare_broken_pipe_test() + # buffer large enough to feed the whole pipe buffer + large_data = b'x' * support.PIPE_MAX_SIZE + + # the program ends before the stdin can be fed + proc = self.loop.run_until_complete( + asyncio.create_subprocess_exec( + sys.executable, '-c', 'pass', + stdin=subprocess.PIPE, + ) + ) # communicate() must ignore BrokenPipeError when feeding stdin self.loop.set_exception_handler(lambda loop, msg: None) diff --git a/mingw32/lib/python3.11/test/test_asyncio/test_timeouts.py b/mingw32/lib/python3.11/test/test_asyncio/test_timeouts.py index cc8feb8d0c1..5a4093e9470 100644 --- a/mingw32/lib/python3.11/test/test_asyncio/test_timeouts.py +++ b/mingw32/lib/python3.11/test/test_asyncio/test_timeouts.py @@ -47,7 +47,6 @@ async def test_nested_timeouts(self): self.assertTrue(cm2.expired()) async def test_waiter_cancelled(self): - loop = asyncio.get_running_loop() cancelled = False with self.assertRaises(TimeoutError): async with asyncio.timeout(0.01): @@ -60,39 +59,26 @@ async def test_waiter_cancelled(self): async def test_timeout_not_called(self): loop = asyncio.get_running_loop() - t0 = loop.time() async with asyncio.timeout(10) as cm: await asyncio.sleep(0.01) t1 = loop.time() self.assertFalse(cm.expired()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) self.assertGreater(cm.when(), t1) async def test_timeout_disabled(self): - loop = asyncio.get_running_loop() - t0 = loop.time() async with asyncio.timeout(None) as cm: await asyncio.sleep(0.01) - t1 = loop.time() self.assertFalse(cm.expired()) self.assertIsNone(cm.when()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) async def test_timeout_at_disabled(self): - loop = asyncio.get_running_loop() - t0 = loop.time() async with asyncio.timeout_at(None) as cm: await asyncio.sleep(0.01) - t1 = loop.time() self.assertFalse(cm.expired()) self.assertIsNone(cm.when()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) async def test_timeout_zero(self): loop = asyncio.get_running_loop() @@ -102,8 +88,6 @@ async def test_timeout_zero(self): await asyncio.sleep(10) t1 = loop.time() self.assertTrue(cm.expired()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) self.assertTrue(t0 <= cm.when() <= t1) async def test_timeout_zero_sleep_zero(self): @@ -114,8 +98,6 @@ async def test_timeout_zero_sleep_zero(self): await asyncio.sleep(0) t1 = loop.time() self.assertTrue(cm.expired()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) self.assertTrue(t0 <= cm.when() <= t1) async def test_timeout_in_the_past_sleep_zero(self): @@ -126,8 +108,6 @@ async def test_timeout_in_the_past_sleep_zero(self): await asyncio.sleep(0) t1 = loop.time() self.assertTrue(cm.expired()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) self.assertTrue(t0 >= cm.when() <= t1) async def test_foreign_exception_passed(self): diff --git a/mingw32/lib/python3.11/test/test_asyncio/test_waitfor.py b/mingw32/lib/python3.11/test/test_asyncio/test_waitfor.py index 45498fa097f..c0cc606825b 100644 --- a/mingw32/lib/python3.11/test/test_asyncio/test_waitfor.py +++ b/mingw32/lib/python3.11/test/test_asyncio/test_waitfor.py @@ -1,6 +1,7 @@ import asyncio import unittest import time +from test import support def tearDownModule(): @@ -65,17 +66,12 @@ async def test_wait_for_timeout_less_then_0_or_0_future_done(self): fut = loop.create_future() fut.set_result('done') - t0 = loop.time() ret = await asyncio.wait_for(fut, 0) - t1 = loop.time() self.assertEqual(ret, 'done') self.assertTrue(fut.done()) - self.assertLess(t1 - t0, 0.1) async def test_wait_for_timeout_less_then_0_or_0_coroutine_do_not_started(self): - loop = asyncio.get_running_loop() - foo_started = False async def foo(): @@ -83,12 +79,9 @@ async def foo(): foo_started = True with self.assertRaises(asyncio.TimeoutError): - t0 = loop.time() await asyncio.wait_for(foo(), 0) - t1 = loop.time() self.assertEqual(foo_started, False) - self.assertLess(t1 - t0, 0.1) async def test_wait_for_timeout_less_then_0_or_0(self): loop = asyncio.get_running_loop() @@ -112,25 +105,21 @@ async def foo(): await started with self.assertRaises(asyncio.TimeoutError): - t0 = loop.time() await asyncio.wait_for(fut, timeout) - t1 = loop.time() self.assertTrue(fut.done()) # it should have been cancelled due to the timeout self.assertTrue(fut.cancelled()) self.assertEqual(foo_running, False) - self.assertLess(t1 - t0, 0.1) async def test_wait_for(self): - loop = asyncio.get_running_loop() foo_running = None async def foo(): nonlocal foo_running foo_running = True try: - await asyncio.sleep(10) + await asyncio.sleep(support.LONG_TIMEOUT) finally: foo_running = False return 'done' @@ -138,13 +127,10 @@ async def foo(): fut = asyncio.create_task(foo()) with self.assertRaises(asyncio.TimeoutError): - t0 = loop.time() await asyncio.wait_for(fut, 0.1) - t1 = loop.time() self.assertTrue(fut.done()) # it should have been cancelled due to the timeout self.assertTrue(fut.cancelled()) - self.assertLess(t1 - t0, 0.5) self.assertEqual(foo_running, False) async def test_wait_for_blocking(self): diff --git a/mingw32/lib/python3.11/test/test_asyncio/test_windows_events.py b/mingw32/lib/python3.11/test/test_asyncio/test_windows_events.py index a36119a8004..6e6c90a247b 100644 --- a/mingw32/lib/python3.11/test/test_asyncio/test_windows_events.py +++ b/mingw32/lib/python3.11/test/test_asyncio/test_windows_events.py @@ -163,29 +163,25 @@ def test_wait_for_handle(self): # Wait for unset event with 0.5s timeout; # result should be False at timeout - fut = self.loop._proactor.wait_for_handle(event, 0.5) + timeout = 0.5 + fut = self.loop._proactor.wait_for_handle(event, timeout) start = self.loop.time() done = self.loop.run_until_complete(fut) elapsed = self.loop.time() - start self.assertEqual(done, False) self.assertFalse(fut.result()) - # bpo-31008: Tolerate only 450 ms (at least 500 ms expected), - # because of bad clock resolution on Windows - self.assertTrue(0.45 <= elapsed <= 0.9, elapsed) + self.assertGreaterEqual(elapsed, timeout - test_utils.CLOCK_RES) _overlapped.SetEvent(event) # Wait for set event; # result should be True immediately fut = self.loop._proactor.wait_for_handle(event, 10) - start = self.loop.time() done = self.loop.run_until_complete(fut) - elapsed = self.loop.time() - start self.assertEqual(done, True) self.assertTrue(fut.result()) - self.assertTrue(0 <= elapsed < 0.3, elapsed) # asyncio issue #195: cancelling a done _WaitHandleFuture # must not crash @@ -199,11 +195,8 @@ def test_wait_for_handle_cancel(self): # CancelledError should be raised immediately fut = self.loop._proactor.wait_for_handle(event, 10) fut.cancel() - start = self.loop.time() with self.assertRaises(asyncio.CancelledError): self.loop.run_until_complete(fut) - elapsed = self.loop.time() - start - self.assertTrue(0 <= elapsed < 0.1, elapsed) # asyncio issue #195: cancelling a _WaitHandleFuture twice # must not crash diff --git a/mingw32/lib/python3.11/test/test_asyncio/utils.py b/mingw32/lib/python3.11/test/test_asyncio/utils.py index c32494d40cc..19de8540fdb 100644 --- a/mingw32/lib/python3.11/test/test_asyncio/utils.py +++ b/mingw32/lib/python3.11/test/test_asyncio/utils.py @@ -37,6 +37,12 @@ from test.support import threading_helper +# Use the maximum known clock resolution (gh-75191, gh-110088): Windows +# GetTickCount64() has a resolution of 15.6 ms. Use 20 ms to tolerate rounding +# issues. +CLOCK_RES = 0.020 + + def data_file(filename): if hasattr(support, 'TEST_HOME_DIR'): fullname = os.path.join(support.TEST_HOME_DIR, filename) diff --git a/mingw32/lib/python3.11/test/test_buffer.py b/mingw32/lib/python3.11/test/test_buffer.py index 468c6ea9def..e9149d1ac49 100644 --- a/mingw32/lib/python3.11/test/test_buffer.py +++ b/mingw32/lib/python3.11/test/test_buffer.py @@ -1019,6 +1019,7 @@ def match(req, flag): ndim=ndim, shape=shape, strides=strides, lst=lst, sliced=sliced) + @support.requires_resource('cpu') def test_ndarray_getbuf(self): requests = ( # distinct flags @@ -2750,6 +2751,7 @@ def iter_roundtrip(ex, m, items, fmt): m = memoryview(ex) iter_roundtrip(ex, m, items, fmt) + @support.requires_resource('cpu') def test_memoryview_cast_1D_ND(self): # Cast between C-contiguous buffers. At least one buffer must # be 1D, at least one format must be 'c', 'b' or 'B'. diff --git a/mingw32/lib/python3.11/test/test_builtin.py b/mingw32/lib/python3.11/test/test_builtin.py index 9078c409cc4..2f561216166 100644 --- a/mingw32/lib/python3.11/test/test_builtin.py +++ b/mingw32/lib/python3.11/test/test_builtin.py @@ -918,6 +918,7 @@ def test_filter_pickle(self): f2 = filter(filter_char, "abcdeabcde") self.check_iter_pickle(f1, list(f2), proto) + @support.requires_resource('cpu') def test_filter_dealloc(self): # Tests recursive deallocation of nested filter objects using the # thrashcan mechanism. See gh-102356 for more details. diff --git a/mingw32/lib/python3.11/test/test_bz2.py b/mingw32/lib/python3.11/test/test_bz2.py index c97ed1cea0d..ba1c02c8338 100644 --- a/mingw32/lib/python3.11/test/test_bz2.py +++ b/mingw32/lib/python3.11/test/test_bz2.py @@ -721,10 +721,10 @@ def testEOFError(self): @bigmemtest(size=_4G + 100, memuse=3.3) def testDecompress4G(self, size): # "Test BZ2Decompressor.decompress() with >4GiB input" - blocksize = 10 * 1024 * 1024 + blocksize = min(10 * 1024 * 1024, size) block = random.randbytes(blocksize) try: - data = block * (size // blocksize + 1) + data = block * ((size-1) // blocksize + 1) compressed = bz2.compress(data) bz2d = BZ2Decompressor() decompressed = bz2d.decompress(compressed) diff --git a/mingw32/lib/python3.11/test/test_codecs.py b/mingw32/lib/python3.11/test/test_codecs.py index e170a30263f..684e6cf7515 100644 --- a/mingw32/lib/python3.11/test/test_codecs.py +++ b/mingw32/lib/python3.11/test/test_codecs.py @@ -1,7 +1,9 @@ import codecs import contextlib +import copy import io import locale +import pickle import sys import unittest import encodings @@ -1772,6 +1774,61 @@ def test_readlines(self): f = self.reader(self.stream) self.assertEqual(f.readlines(), ['\ud55c\n', '\uae00']) + def test_copy(self): + f = self.reader(Queue(b'\xed\x95\x9c\n\xea\xb8\x80')) + with self.assertRaisesRegex(TypeError, 'StreamReader'): + copy.copy(f) + with self.assertRaisesRegex(TypeError, 'StreamReader'): + copy.deepcopy(f) + + def test_pickle(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + f = self.reader(Queue(b'\xed\x95\x9c\n\xea\xb8\x80')) + with self.assertRaisesRegex(TypeError, 'StreamReader'): + pickle.dumps(f, proto) + + +class StreamWriterTest(unittest.TestCase): + + def setUp(self): + self.writer = codecs.getwriter('utf-8') + + def test_copy(self): + f = self.writer(Queue(b'')) + with self.assertRaisesRegex(TypeError, 'StreamWriter'): + copy.copy(f) + with self.assertRaisesRegex(TypeError, 'StreamWriter'): + copy.deepcopy(f) + + def test_pickle(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + f = self.writer(Queue(b'')) + with self.assertRaisesRegex(TypeError, 'StreamWriter'): + pickle.dumps(f, proto) + + +class StreamReaderWriterTest(unittest.TestCase): + + def setUp(self): + self.reader = codecs.getreader('latin1') + self.writer = codecs.getwriter('utf-8') + + def test_copy(self): + f = codecs.StreamReaderWriter(Queue(b''), self.reader, self.writer) + with self.assertRaisesRegex(TypeError, 'StreamReaderWriter'): + copy.copy(f) + with self.assertRaisesRegex(TypeError, 'StreamReaderWriter'): + copy.deepcopy(f) + + def test_pickle(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + f = codecs.StreamReaderWriter(Queue(b''), self.reader, self.writer) + with self.assertRaisesRegex(TypeError, 'StreamReaderWriter'): + pickle.dumps(f, proto) + class EncodedFileTest(unittest.TestCase): @@ -3369,6 +3426,28 @@ def test_seeking_write(self): self.assertEqual(sr.readline(), b'abc\n') self.assertEqual(sr.readline(), b'789\n') + def test_copy(self): + bio = io.BytesIO() + codec = codecs.lookup('ascii') + sr = codecs.StreamRecoder(bio, codec.encode, codec.decode, + encodings.ascii.StreamReader, encodings.ascii.StreamWriter) + + with self.assertRaisesRegex(TypeError, 'StreamRecoder'): + copy.copy(sr) + with self.assertRaisesRegex(TypeError, 'StreamRecoder'): + copy.deepcopy(sr) + + def test_pickle(self): + q = Queue(b'') + codec = codecs.lookup('ascii') + sr = codecs.StreamRecoder(q, codec.encode, codec.decode, + encodings.ascii.StreamReader, encodings.ascii.StreamWriter) + + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + with self.assertRaisesRegex(TypeError, 'StreamRecoder'): + pickle.dumps(sr, proto) + @unittest.skipIf(_testinternalcapi is None, 'need _testinternalcapi module') class LocaleCodecTest(unittest.TestCase): diff --git a/mingw32/lib/python3.11/test/test_compile.py b/mingw32/lib/python3.11/test/test_compile.py index c756d43a3cf..408064919b0 100644 --- a/mingw32/lib/python3.11/test/test_compile.py +++ b/mingw32/lib/python3.11/test/test_compile.py @@ -442,6 +442,33 @@ def f(): self.assertIn("_A__mangled_mod", A.f.__code__.co_varnames) self.assertIn("__package__", A.f.__code__.co_varnames) + def test_compile_invalid_namedexpr(self): + # gh-109351 + m = ast.Module( + body=[ + ast.Expr( + value=ast.ListComp( + elt=ast.NamedExpr( + target=ast.Constant(value=1), + value=ast.Constant(value=3), + ), + generators=[ + ast.comprehension( + target=ast.Name(id="x", ctx=ast.Store()), + iter=ast.Name(id="y", ctx=ast.Load()), + ifs=[], + is_async=0, + ) + ], + ) + ) + ], + type_ignores=[], + ) + + with self.assertRaisesRegex(TypeError, "NamedExpr target must be a Name"): + compile(ast.fix_missing_locations(m), "", "exec") + def test_compile_ast(self): fname = __file__ if fname.lower().endswith('pyc'): @@ -741,6 +768,7 @@ def test_path_like_objects(self): # An implicit test for PyUnicode_FSDecoder(). compile("42", FakePath("test_compile_pathlike"), "single") + @support.requires_resource('cpu') def test_stack_overflow(self): # bpo-31113: Stack overflow when compile a long sequence of # complex statements. diff --git a/mingw32/lib/python3.11/test/test_compileall.py b/mingw32/lib/python3.11/test/test_compileall.py index 05154c8f1c6..9cd92ad365c 100644 --- a/mingw32/lib/python3.11/test/test_compileall.py +++ b/mingw32/lib/python3.11/test/test_compileall.py @@ -18,6 +18,7 @@ try: # compileall relies on ProcessPoolExecutor if ProcessPoolExecutor exists # and it can function. + from multiprocessing.util import _cleanup_tests as multiprocessing_cleanup_tests from concurrent.futures import ProcessPoolExecutor from concurrent.futures.process import _check_system_limits _check_system_limits() @@ -54,6 +55,8 @@ class CompileallTestsBase: def setUp(self): self.directory = tempfile.mkdtemp() + self.addCleanup(shutil.rmtree, self.directory) + self.source_path = os.path.join(self.directory, '_test.py') self.bc_path = importlib.util.cache_from_source(self.source_path) with open(self.source_path, 'w', encoding="utf-8") as file: @@ -66,9 +69,6 @@ def setUp(self): self.source_path3 = os.path.join(self.subdirectory, '_test3.py') shutil.copyfile(self.source_path, self.source_path3) - def tearDown(self): - shutil.rmtree(self.directory) - def add_bad_source_file(self): self.bad_source_path = os.path.join(self.directory, '_test_bad.py') with open(self.bad_source_path, 'w', encoding="utf-8") as file: @@ -307,9 +307,13 @@ def _test_ddir_only(self, *, ddir, parallel=True): script_helper.make_script(path, "__init__", "") mods.append(script_helper.make_script(path, "mod", "def fn(): 1/0\nfn()\n")) + + if parallel: + self.addCleanup(multiprocessing_cleanup_tests) compileall.compile_dir( self.directory, quiet=True, ddir=ddir, workers=2 if parallel else 1) + self.assertTrue(mods) for mod in mods: self.assertTrue(mod.startswith(self.directory), mod) @@ -551,6 +555,7 @@ def test_no_args_compiles_path(self): self.assertNotCompiled(self.barfn) @without_source_date_epoch # timestamp invalidation test + @support.requires_resource('cpu') def test_no_args_respects_force_flag(self): bazfn = script_helper.make_script(self.directory, 'baz', '') with self.temporary_pycache_prefix() as env: @@ -568,6 +573,7 @@ def test_no_args_respects_force_flag(self): mtime2 = os.stat(pycpath).st_mtime self.assertNotEqual(mtime, mtime2) + @support.requires_resource('cpu') def test_no_args_respects_quiet_flag(self): script_helper.make_script(self.directory, 'baz', '') with self.temporary_pycache_prefix() as env: diff --git a/mingw32/lib/python3.11/test/test_concurrent_futures.py b/mingw32/lib/python3.11/test/test_concurrent_futures.py deleted file mode 100644 index 11d5001bc63..00000000000 --- a/mingw32/lib/python3.11/test/test_concurrent_futures.py +++ /dev/null @@ -1,1674 +0,0 @@ -from test import support -from test.support import import_helper -from test.support import threading_helper - -# Skip tests if _multiprocessing wasn't built. -import_helper.import_module('_multiprocessing') - -from test.support import hashlib_helper -from test.support.script_helper import assert_python_ok - -import contextlib -import itertools -import logging -from logging.handlers import QueueHandler -import os -import queue -import signal -import sys -import threading -import time -import unittest -import weakref -from pickle import PicklingError - -from concurrent import futures -from concurrent.futures._base import ( - PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED, Future, - BrokenExecutor) -from concurrent.futures.process import BrokenProcessPool, _check_system_limits - -import multiprocessing.process -import multiprocessing.util -import multiprocessing as mp - - -if support.check_sanitizer(address=True, memory=True): - # bpo-46633: Skip the test because it is too slow when Python is built - # with ASAN/MSAN: between 5 and 20 minutes on GitHub Actions. - raise unittest.SkipTest("test too slow on ASAN/MSAN build") - - -def create_future(state=PENDING, exception=None, result=None): - f = Future() - f._state = state - f._exception = exception - f._result = result - return f - - -PENDING_FUTURE = create_future(state=PENDING) -RUNNING_FUTURE = create_future(state=RUNNING) -CANCELLED_FUTURE = create_future(state=CANCELLED) -CANCELLED_AND_NOTIFIED_FUTURE = create_future(state=CANCELLED_AND_NOTIFIED) -EXCEPTION_FUTURE = create_future(state=FINISHED, exception=OSError()) -SUCCESSFUL_FUTURE = create_future(state=FINISHED, result=42) - -INITIALIZER_STATUS = 'uninitialized' - -def mul(x, y): - return x * y - -def capture(*args, **kwargs): - return args, kwargs - -def sleep_and_raise(t): - time.sleep(t) - raise Exception('this is an exception') - -def sleep_and_print(t, msg): - time.sleep(t) - print(msg) - sys.stdout.flush() - -def init(x): - global INITIALIZER_STATUS - INITIALIZER_STATUS = x - -def get_init_status(): - return INITIALIZER_STATUS - -def init_fail(log_queue=None): - if log_queue is not None: - logger = logging.getLogger('concurrent.futures') - logger.addHandler(QueueHandler(log_queue)) - logger.setLevel('CRITICAL') - logger.propagate = False - time.sleep(0.1) # let some futures be scheduled - raise ValueError('error in initializer') - - -class MyObject(object): - def my_method(self): - pass - - -class EventfulGCObj(): - def __init__(self, mgr): - self.event = mgr.Event() - - def __del__(self): - self.event.set() - - -def make_dummy_object(_): - return MyObject() - - -class BaseTestCase(unittest.TestCase): - def setUp(self): - self._thread_key = threading_helper.threading_setup() - - def tearDown(self): - support.reap_children() - threading_helper.threading_cleanup(*self._thread_key) - - -class ExecutorMixin: - worker_count = 5 - executor_kwargs = {} - - def setUp(self): - super().setUp() - - self.t1 = time.monotonic() - if hasattr(self, "ctx"): - self.executor = self.executor_type( - max_workers=self.worker_count, - mp_context=self.get_context(), - **self.executor_kwargs) - else: - self.executor = self.executor_type( - max_workers=self.worker_count, - **self.executor_kwargs) - - def tearDown(self): - self.executor.shutdown(wait=True) - self.executor = None - - dt = time.monotonic() - self.t1 - if support.verbose: - print("%.2fs" % dt, end=' ') - self.assertLess(dt, 300, "synchronization issue: test lasted too long") - - super().tearDown() - - def get_context(self): - return mp.get_context(self.ctx) - - -class ThreadPoolMixin(ExecutorMixin): - executor_type = futures.ThreadPoolExecutor - - -class ProcessPoolForkMixin(ExecutorMixin): - executor_type = futures.ProcessPoolExecutor - ctx = "fork" - - def get_context(self): - try: - _check_system_limits() - except NotImplementedError: - self.skipTest("ProcessPoolExecutor unavailable on this system") - if sys.platform == "win32": - self.skipTest("require unix system") - return super().get_context() - - -class ProcessPoolSpawnMixin(ExecutorMixin): - executor_type = futures.ProcessPoolExecutor - ctx = "spawn" - - def get_context(self): - try: - _check_system_limits() - except NotImplementedError: - self.skipTest("ProcessPoolExecutor unavailable on this system") - return super().get_context() - - -class ProcessPoolForkserverMixin(ExecutorMixin): - executor_type = futures.ProcessPoolExecutor - ctx = "forkserver" - - def get_context(self): - try: - _check_system_limits() - except NotImplementedError: - self.skipTest("ProcessPoolExecutor unavailable on this system") - if sys.platform == "win32": - self.skipTest("require unix system") - return super().get_context() - - -def create_executor_tests(mixin, bases=(BaseTestCase,), - executor_mixins=(ThreadPoolMixin, - ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)): - def strip_mixin(name): - if name.endswith(('Mixin', 'Tests')): - return name[:-5] - elif name.endswith('Test'): - return name[:-4] - else: - return name - - for exe in executor_mixins: - name = ("%s%sTest" - % (strip_mixin(exe.__name__), strip_mixin(mixin.__name__))) - cls = type(name, (mixin,) + (exe,) + bases, {}) - globals()[name] = cls - - -class InitializerMixin(ExecutorMixin): - worker_count = 2 - - def setUp(self): - global INITIALIZER_STATUS - INITIALIZER_STATUS = 'uninitialized' - self.executor_kwargs = dict(initializer=init, - initargs=('initialized',)) - super().setUp() - - def test_initializer(self): - futures = [self.executor.submit(get_init_status) - for _ in range(self.worker_count)] - - for f in futures: - self.assertEqual(f.result(), 'initialized') - - -class FailingInitializerMixin(ExecutorMixin): - worker_count = 2 - - def setUp(self): - if hasattr(self, "ctx"): - # Pass a queue to redirect the child's logging output - self.mp_context = self.get_context() - self.log_queue = self.mp_context.Queue() - self.executor_kwargs = dict(initializer=init_fail, - initargs=(self.log_queue,)) - else: - # In a thread pool, the child shares our logging setup - # (see _assert_logged()) - self.mp_context = None - self.log_queue = None - self.executor_kwargs = dict(initializer=init_fail) - super().setUp() - - def test_initializer(self): - with self._assert_logged('ValueError: error in initializer'): - try: - future = self.executor.submit(get_init_status) - except BrokenExecutor: - # Perhaps the executor is already broken - pass - else: - with self.assertRaises(BrokenExecutor): - future.result() - # At some point, the executor should break - t1 = time.monotonic() - while not self.executor._broken: - if time.monotonic() - t1 > 5: - self.fail("executor not broken after 5 s.") - time.sleep(0.01) - # ... and from this point submit() is guaranteed to fail - with self.assertRaises(BrokenExecutor): - self.executor.submit(get_init_status) - - @contextlib.contextmanager - def _assert_logged(self, msg): - if self.log_queue is not None: - yield - output = [] - try: - while True: - output.append(self.log_queue.get_nowait().getMessage()) - except queue.Empty: - pass - else: - with self.assertLogs('concurrent.futures', 'CRITICAL') as cm: - yield - output = cm.output - self.assertTrue(any(msg in line for line in output), - output) - - -create_executor_tests(InitializerMixin) -create_executor_tests(FailingInitializerMixin) - - -class ExecutorShutdownTest: - def test_run_after_shutdown(self): - self.executor.shutdown() - self.assertRaises(RuntimeError, - self.executor.submit, - pow, 2, 5) - - def test_interpreter_shutdown(self): - # Test the atexit hook for shutdown of worker threads and processes - rc, out, err = assert_python_ok('-c', """if 1: - from concurrent.futures import {executor_type} - from time import sleep - from test.test_concurrent_futures import sleep_and_print - if __name__ == "__main__": - context = '{context}' - if context == "": - t = {executor_type}(5) - else: - from multiprocessing import get_context - context = get_context(context) - t = {executor_type}(5, mp_context=context) - t.submit(sleep_and_print, 1.0, "apple") - """.format(executor_type=self.executor_type.__name__, - context=getattr(self, "ctx", ""))) - # Errors in atexit hooks don't change the process exit code, check - # stderr manually. - self.assertFalse(err) - self.assertEqual(out.strip(), b"apple") - - def test_submit_after_interpreter_shutdown(self): - # Test the atexit hook for shutdown of worker threads and processes - rc, out, err = assert_python_ok('-c', """if 1: - import atexit - @atexit.register - def run_last(): - try: - t.submit(id, None) - except RuntimeError: - print("runtime-error") - raise - from concurrent.futures import {executor_type} - if __name__ == "__main__": - context = '{context}' - if not context: - t = {executor_type}(5) - else: - from multiprocessing import get_context - context = get_context(context) - t = {executor_type}(5, mp_context=context) - t.submit(id, 42).result() - """.format(executor_type=self.executor_type.__name__, - context=getattr(self, "ctx", ""))) - # Errors in atexit hooks don't change the process exit code, check - # stderr manually. - self.assertIn("RuntimeError: cannot schedule new futures", err.decode()) - self.assertEqual(out.strip(), b"runtime-error") - - def test_hang_issue12364(self): - fs = [self.executor.submit(time.sleep, 0.1) for _ in range(50)] - self.executor.shutdown() - for f in fs: - f.result() - - def test_cancel_futures(self): - assert self.worker_count <= 5, "test needs few workers" - fs = [self.executor.submit(time.sleep, .1) for _ in range(50)] - self.executor.shutdown(cancel_futures=True) - # We can't guarantee the exact number of cancellations, but we can - # guarantee that *some* were cancelled. With few workers, many of - # the submitted futures should have been cancelled. - cancelled = [fut for fut in fs if fut.cancelled()] - self.assertGreater(len(cancelled), 20) - - # Ensure the other futures were able to finish. - # Use "not fut.cancelled()" instead of "fut.done()" to include futures - # that may have been left in a pending state. - others = [fut for fut in fs if not fut.cancelled()] - for fut in others: - self.assertTrue(fut.done(), msg=f"{fut._state=}") - self.assertIsNone(fut.exception()) - - # Similar to the number of cancelled futures, we can't guarantee the - # exact number that completed. But, we can guarantee that at least - # one finished. - self.assertGreater(len(others), 0) - - def test_hang_gh83386(self): - """shutdown(wait=False) doesn't hang at exit with running futures. - - See https://github.com/python/cpython/issues/83386. - """ - if self.executor_type == futures.ProcessPoolExecutor: - raise unittest.SkipTest( - "Hangs, see https://github.com/python/cpython/issues/83386") - - rc, out, err = assert_python_ok('-c', """if True: - from concurrent.futures import {executor_type} - from test.test_concurrent_futures import sleep_and_print - if __name__ == "__main__": - if {context!r}: multiprocessing.set_start_method({context!r}) - t = {executor_type}(max_workers=3) - t.submit(sleep_and_print, 1.0, "apple") - t.shutdown(wait=False) - """.format(executor_type=self.executor_type.__name__, - context=getattr(self, 'ctx', None))) - self.assertFalse(err) - self.assertEqual(out.strip(), b"apple") - - def test_hang_gh94440(self): - """shutdown(wait=True) doesn't hang when a future was submitted and - quickly canceled right before shutdown. - - See https://github.com/python/cpython/issues/94440. - """ - if not hasattr(signal, 'alarm'): - raise unittest.SkipTest( - "Tested platform does not support the alarm signal") - - def timeout(_signum, _frame): - raise RuntimeError("timed out waiting for shutdown") - - kwargs = {} - if getattr(self, 'ctx', None): - kwargs['mp_context'] = self.get_context() - executor = self.executor_type(max_workers=1, **kwargs) - executor.submit(int).result() - old_handler = signal.signal(signal.SIGALRM, timeout) - try: - signal.alarm(5) - executor.submit(int).cancel() - executor.shutdown(wait=True) - finally: - signal.alarm(0) - signal.signal(signal.SIGALRM, old_handler) - - -class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest, BaseTestCase): - def test_threads_terminate(self): - def acquire_lock(lock): - lock.acquire() - - sem = threading.Semaphore(0) - for i in range(3): - self.executor.submit(acquire_lock, sem) - self.assertEqual(len(self.executor._threads), 3) - for i in range(3): - sem.release() - self.executor.shutdown() - for t in self.executor._threads: - t.join() - - def test_context_manager_shutdown(self): - with futures.ThreadPoolExecutor(max_workers=5) as e: - executor = e - self.assertEqual(list(e.map(abs, range(-5, 5))), - [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) - - for t in executor._threads: - t.join() - - def test_del_shutdown(self): - executor = futures.ThreadPoolExecutor(max_workers=5) - res = executor.map(abs, range(-5, 5)) - threads = executor._threads - del executor - - for t in threads: - t.join() - - # Make sure the results were all computed before the - # executor got shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - def test_shutdown_no_wait(self): - # Ensure that the executor cleans up the threads when calling - # shutdown with wait=False - executor = futures.ThreadPoolExecutor(max_workers=5) - res = executor.map(abs, range(-5, 5)) - threads = executor._threads - executor.shutdown(wait=False) - for t in threads: - t.join() - - # Make sure the results were all computed before the - # executor got shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - - def test_thread_names_assigned(self): - executor = futures.ThreadPoolExecutor( - max_workers=5, thread_name_prefix='SpecialPool') - executor.map(abs, range(-5, 5)) - threads = executor._threads - del executor - support.gc_collect() # For PyPy or other GCs. - - for t in threads: - self.assertRegex(t.name, r'^SpecialPool_[0-4]$') - t.join() - - def test_thread_names_default(self): - executor = futures.ThreadPoolExecutor(max_workers=5) - executor.map(abs, range(-5, 5)) - threads = executor._threads - del executor - support.gc_collect() # For PyPy or other GCs. - - for t in threads: - # Ensure that our default name is reasonably sane and unique when - # no thread_name_prefix was supplied. - self.assertRegex(t.name, r'ThreadPoolExecutor-\d+_[0-4]$') - t.join() - - def test_cancel_futures_wait_false(self): - # Can only be reliably tested for TPE, since PPE often hangs with - # `wait=False` (even without *cancel_futures*). - rc, out, err = assert_python_ok('-c', """if True: - from concurrent.futures import ThreadPoolExecutor - from test.test_concurrent_futures import sleep_and_print - if __name__ == "__main__": - t = ThreadPoolExecutor() - t.submit(sleep_and_print, .1, "apple") - t.shutdown(wait=False, cancel_futures=True) - """) - # Errors in atexit hooks don't change the process exit code, check - # stderr manually. - self.assertFalse(err) - self.assertEqual(out.strip(), b"apple") - - -class ProcessPoolShutdownTest(ExecutorShutdownTest): - def test_processes_terminate(self): - def acquire_lock(lock): - lock.acquire() - - mp_context = self.get_context() - if mp_context.get_start_method(allow_none=False) == "fork": - # fork pre-spawns, not on demand. - expected_num_processes = self.worker_count - else: - expected_num_processes = 3 - - sem = mp_context.Semaphore(0) - for _ in range(3): - self.executor.submit(acquire_lock, sem) - self.assertEqual(len(self.executor._processes), expected_num_processes) - for _ in range(3): - sem.release() - processes = self.executor._processes - self.executor.shutdown() - - for p in processes.values(): - p.join() - - def test_context_manager_shutdown(self): - with futures.ProcessPoolExecutor( - max_workers=5, mp_context=self.get_context()) as e: - processes = e._processes - self.assertEqual(list(e.map(abs, range(-5, 5))), - [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) - - for p in processes.values(): - p.join() - - def test_del_shutdown(self): - executor = futures.ProcessPoolExecutor( - max_workers=5, mp_context=self.get_context()) - res = executor.map(abs, range(-5, 5)) - executor_manager_thread = executor._executor_manager_thread - processes = executor._processes - call_queue = executor._call_queue - executor_manager_thread = executor._executor_manager_thread - del executor - support.gc_collect() # For PyPy or other GCs. - - # Make sure that all the executor resources were properly cleaned by - # the shutdown process - executor_manager_thread.join() - for p in processes.values(): - p.join() - call_queue.join_thread() - - # Make sure the results were all computed before the - # executor got shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - def test_shutdown_no_wait(self): - # Ensure that the executor cleans up the processes when calling - # shutdown with wait=False - executor = futures.ProcessPoolExecutor( - max_workers=5, mp_context=self.get_context()) - res = executor.map(abs, range(-5, 5)) - processes = executor._processes - call_queue = executor._call_queue - executor_manager_thread = executor._executor_manager_thread - executor.shutdown(wait=False) - - # Make sure that all the executor resources were properly cleaned by - # the shutdown process - executor_manager_thread.join() - for p in processes.values(): - p.join() - call_queue.join_thread() - - # Make sure the results were all computed before the executor got - # shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - -create_executor_tests(ProcessPoolShutdownTest, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - - -class WaitTests: - def test_20369(self): - # See https://bugs.python.org/issue20369 - future = self.executor.submit(time.sleep, 1.5) - done, not_done = futures.wait([future, future], - return_when=futures.ALL_COMPLETED) - self.assertEqual({future}, done) - self.assertEqual(set(), not_done) - - - def test_first_completed(self): - future1 = self.executor.submit(mul, 21, 2) - future2 = self.executor.submit(time.sleep, 1.5) - - done, not_done = futures.wait( - [CANCELLED_FUTURE, future1, future2], - return_when=futures.FIRST_COMPLETED) - - self.assertEqual(set([future1]), done) - self.assertEqual(set([CANCELLED_FUTURE, future2]), not_done) - - def test_first_completed_some_already_completed(self): - future1 = self.executor.submit(time.sleep, 1.5) - - finished, pending = futures.wait( - [CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE, future1], - return_when=futures.FIRST_COMPLETED) - - self.assertEqual( - set([CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE]), - finished) - self.assertEqual(set([future1]), pending) - - def test_first_exception(self): - future1 = self.executor.submit(mul, 2, 21) - future2 = self.executor.submit(sleep_and_raise, 1.5) - future3 = self.executor.submit(time.sleep, 3) - - finished, pending = futures.wait( - [future1, future2, future3], - return_when=futures.FIRST_EXCEPTION) - - self.assertEqual(set([future1, future2]), finished) - self.assertEqual(set([future3]), pending) - - def test_first_exception_some_already_complete(self): - future1 = self.executor.submit(divmod, 21, 0) - future2 = self.executor.submit(time.sleep, 1.5) - - finished, pending = futures.wait( - [SUCCESSFUL_FUTURE, - CANCELLED_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - future1, future2], - return_when=futures.FIRST_EXCEPTION) - - self.assertEqual(set([SUCCESSFUL_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - future1]), finished) - self.assertEqual(set([CANCELLED_FUTURE, future2]), pending) - - def test_first_exception_one_already_failed(self): - future1 = self.executor.submit(time.sleep, 2) - - finished, pending = futures.wait( - [EXCEPTION_FUTURE, future1], - return_when=futures.FIRST_EXCEPTION) - - self.assertEqual(set([EXCEPTION_FUTURE]), finished) - self.assertEqual(set([future1]), pending) - - def test_all_completed(self): - future1 = self.executor.submit(divmod, 2, 0) - future2 = self.executor.submit(mul, 2, 21) - - finished, pending = futures.wait( - [SUCCESSFUL_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - future1, - future2], - return_when=futures.ALL_COMPLETED) - - self.assertEqual(set([SUCCESSFUL_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - future1, - future2]), finished) - self.assertEqual(set(), pending) - - def test_timeout(self): - future1 = self.executor.submit(mul, 6, 7) - future2 = self.executor.submit(time.sleep, 6) - - finished, pending = futures.wait( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1, future2], - timeout=5, - return_when=futures.ALL_COMPLETED) - - self.assertEqual(set([CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1]), finished) - self.assertEqual(set([future2]), pending) - - -class ThreadPoolWaitTests(ThreadPoolMixin, WaitTests, BaseTestCase): - - def test_pending_calls_race(self): - # Issue #14406: multi-threaded race condition when waiting on all - # futures. - event = threading.Event() - def future_func(): - event.wait() - oldswitchinterval = sys.getswitchinterval() - sys.setswitchinterval(1e-6) - try: - fs = {self.executor.submit(future_func) for i in range(100)} - event.set() - futures.wait(fs, return_when=futures.ALL_COMPLETED) - finally: - sys.setswitchinterval(oldswitchinterval) - - -create_executor_tests(WaitTests, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - - -class AsCompletedTests: - # TODO(brian@sweetapp.com): Should have a test with a non-zero timeout. - def test_no_timeout(self): - future1 = self.executor.submit(mul, 2, 21) - future2 = self.executor.submit(mul, 7, 6) - - completed = set(futures.as_completed( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1, future2])) - self.assertEqual(set( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1, future2]), - completed) - - def test_zero_timeout(self): - future1 = self.executor.submit(time.sleep, 2) - completed_futures = set() - try: - for future in futures.as_completed( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1], - timeout=0): - completed_futures.add(future) - except futures.TimeoutError: - pass - - self.assertEqual(set([CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE]), - completed_futures) - - def test_duplicate_futures(self): - # Issue 20367. Duplicate futures should not raise exceptions or give - # duplicate responses. - # Issue #31641: accept arbitrary iterables. - future1 = self.executor.submit(time.sleep, 2) - completed = [ - f for f in futures.as_completed(itertools.repeat(future1, 3)) - ] - self.assertEqual(len(completed), 1) - - def test_free_reference_yielded_future(self): - # Issue #14406: Generator should not keep references - # to finished futures. - futures_list = [Future() for _ in range(8)] - futures_list.append(create_future(state=CANCELLED_AND_NOTIFIED)) - futures_list.append(create_future(state=FINISHED, result=42)) - - with self.assertRaises(futures.TimeoutError): - for future in futures.as_completed(futures_list, timeout=0): - futures_list.remove(future) - wr = weakref.ref(future) - del future - support.gc_collect() # For PyPy or other GCs. - self.assertIsNone(wr()) - - futures_list[0].set_result("test") - for future in futures.as_completed(futures_list): - futures_list.remove(future) - wr = weakref.ref(future) - del future - support.gc_collect() # For PyPy or other GCs. - self.assertIsNone(wr()) - if futures_list: - futures_list[0].set_result("test") - - def test_correct_timeout_exception_msg(self): - futures_list = [CANCELLED_AND_NOTIFIED_FUTURE, PENDING_FUTURE, - RUNNING_FUTURE, SUCCESSFUL_FUTURE] - - with self.assertRaises(futures.TimeoutError) as cm: - list(futures.as_completed(futures_list, timeout=0)) - - self.assertEqual(str(cm.exception), '2 (of 4) futures unfinished') - - -create_executor_tests(AsCompletedTests) - - -class ExecutorTest: - # Executor.shutdown() and context manager usage is tested by - # ExecutorShutdownTest. - def test_submit(self): - future = self.executor.submit(pow, 2, 8) - self.assertEqual(256, future.result()) - - def test_submit_keyword(self): - future = self.executor.submit(mul, 2, y=8) - self.assertEqual(16, future.result()) - future = self.executor.submit(capture, 1, self=2, fn=3) - self.assertEqual(future.result(), ((1,), {'self': 2, 'fn': 3})) - with self.assertRaises(TypeError): - self.executor.submit(fn=capture, arg=1) - with self.assertRaises(TypeError): - self.executor.submit(arg=1) - - def test_map(self): - self.assertEqual( - list(self.executor.map(pow, range(10), range(10))), - list(map(pow, range(10), range(10)))) - - self.assertEqual( - list(self.executor.map(pow, range(10), range(10), chunksize=3)), - list(map(pow, range(10), range(10)))) - - def test_map_exception(self): - i = self.executor.map(divmod, [1, 1, 1, 1], [2, 3, 0, 5]) - self.assertEqual(i.__next__(), (0, 1)) - self.assertEqual(i.__next__(), (0, 1)) - self.assertRaises(ZeroDivisionError, i.__next__) - - def test_map_timeout(self): - results = [] - try: - for i in self.executor.map(time.sleep, - [0, 0, 6], - timeout=5): - results.append(i) - except futures.TimeoutError: - pass - else: - self.fail('expected TimeoutError') - - self.assertEqual([None, None], results) - - def test_shutdown_race_issue12456(self): - # Issue #12456: race condition at shutdown where trying to post a - # sentinel in the call queue blocks (the queue is full while processes - # have exited). - self.executor.map(str, [2] * (self.worker_count + 1)) - self.executor.shutdown() - - @support.cpython_only - def test_no_stale_references(self): - # Issue #16284: check that the executors don't unnecessarily hang onto - # references. - my_object = MyObject() - my_object_collected = threading.Event() - my_object_callback = weakref.ref( - my_object, lambda obj: my_object_collected.set()) - # Deliberately discarding the future. - self.executor.submit(my_object.my_method) - del my_object - - collected = my_object_collected.wait(timeout=support.SHORT_TIMEOUT) - self.assertTrue(collected, - "Stale reference not collected within timeout.") - - def test_max_workers_negative(self): - for number in (0, -1): - with self.assertRaisesRegex(ValueError, - "max_workers must be greater " - "than 0"): - self.executor_type(max_workers=number) - - def test_free_reference(self): - # Issue #14406: Result iterator should not keep an internal - # reference to result objects. - for obj in self.executor.map(make_dummy_object, range(10)): - wr = weakref.ref(obj) - del obj - support.gc_collect() # For PyPy or other GCs. - self.assertIsNone(wr()) - - -class ThreadPoolExecutorTest(ThreadPoolMixin, ExecutorTest, BaseTestCase): - def test_map_submits_without_iteration(self): - """Tests verifying issue 11777.""" - finished = [] - def record_finished(n): - finished.append(n) - - self.executor.map(record_finished, range(10)) - self.executor.shutdown(wait=True) - self.assertCountEqual(finished, range(10)) - - def test_default_workers(self): - executor = self.executor_type() - expected = min(32, (os.cpu_count() or 1) + 4) - self.assertEqual(executor._max_workers, expected) - - def test_saturation(self): - executor = self.executor_type(4) - def acquire_lock(lock): - lock.acquire() - - sem = threading.Semaphore(0) - for i in range(15 * executor._max_workers): - executor.submit(acquire_lock, sem) - self.assertEqual(len(executor._threads), executor._max_workers) - for i in range(15 * executor._max_workers): - sem.release() - executor.shutdown(wait=True) - - def test_idle_thread_reuse(self): - executor = self.executor_type() - executor.submit(mul, 21, 2).result() - executor.submit(mul, 6, 7).result() - executor.submit(mul, 3, 14).result() - self.assertEqual(len(executor._threads), 1) - executor.shutdown(wait=True) - - @unittest.skipUnless(hasattr(os, 'register_at_fork'), 'need os.register_at_fork') - def test_hang_global_shutdown_lock(self): - # bpo-45021: _global_shutdown_lock should be reinitialized in the child - # process, otherwise it will never exit - def submit(pool): - pool.submit(submit, pool) - - with futures.ThreadPoolExecutor(1) as pool: - pool.submit(submit, pool) - - for _ in range(50): - with futures.ProcessPoolExecutor(1, mp_context=mp.get_context('fork')) as workers: - workers.submit(tuple) - - def test_executor_map_current_future_cancel(self): - stop_event = threading.Event() - log = [] - - def log_n_wait(ident): - log.append(f"{ident=} started") - try: - stop_event.wait() - finally: - log.append(f"{ident=} stopped") - - with self.executor_type(max_workers=1) as pool: - # submit work to saturate the pool - fut = pool.submit(log_n_wait, ident="first") - try: - with contextlib.closing( - pool.map(log_n_wait, ["second", "third"], timeout=0) - ) as gen: - with self.assertRaises(TimeoutError): - next(gen) - finally: - stop_event.set() - fut.result() - # ident='second' is cancelled as a result of raising a TimeoutError - # ident='third' is cancelled because it remained in the collection of futures - self.assertListEqual(log, ["ident='first' started", "ident='first' stopped"]) - - -class ProcessPoolExecutorTest(ExecutorTest): - - @unittest.skipUnless(sys.platform=='win32', 'Windows-only process limit') - def test_max_workers_too_large(self): - with self.assertRaisesRegex(ValueError, - "max_workers must be <= 61"): - futures.ProcessPoolExecutor(max_workers=62) - - def test_killed_child(self): - # When a child process is abruptly terminated, the whole pool gets - # "broken". - futures = [self.executor.submit(time.sleep, 3)] - # Get one of the processes, and terminate (kill) it - p = next(iter(self.executor._processes.values())) - p.terminate() - for fut in futures: - self.assertRaises(BrokenProcessPool, fut.result) - # Submitting other jobs fails as well. - self.assertRaises(BrokenProcessPool, self.executor.submit, pow, 2, 8) - - def test_map_chunksize(self): - def bad_map(): - list(self.executor.map(pow, range(40), range(40), chunksize=-1)) - - ref = list(map(pow, range(40), range(40))) - self.assertEqual( - list(self.executor.map(pow, range(40), range(40), chunksize=6)), - ref) - self.assertEqual( - list(self.executor.map(pow, range(40), range(40), chunksize=50)), - ref) - self.assertEqual( - list(self.executor.map(pow, range(40), range(40), chunksize=40)), - ref) - self.assertRaises(ValueError, bad_map) - - @classmethod - def _test_traceback(cls): - raise RuntimeError(123) # some comment - - def test_traceback(self): - # We want ensure that the traceback from the child process is - # contained in the traceback raised in the main process. - future = self.executor.submit(self._test_traceback) - with self.assertRaises(Exception) as cm: - future.result() - - exc = cm.exception - self.assertIs(type(exc), RuntimeError) - self.assertEqual(exc.args, (123,)) - cause = exc.__cause__ - self.assertIs(type(cause), futures.process._RemoteTraceback) - self.assertIn('raise RuntimeError(123) # some comment', cause.tb) - - with support.captured_stderr() as f1: - try: - raise exc - except RuntimeError: - sys.excepthook(*sys.exc_info()) - self.assertIn('raise RuntimeError(123) # some comment', - f1.getvalue()) - - @hashlib_helper.requires_hashdigest('md5') - def test_ressources_gced_in_workers(self): - # Ensure that argument for a job are correctly gc-ed after the job - # is finished - mgr = self.get_context().Manager() - obj = EventfulGCObj(mgr) - future = self.executor.submit(id, obj) - future.result() - - self.assertTrue(obj.event.wait(timeout=1)) - - # explicitly destroy the object to ensure that EventfulGCObj.__del__() - # is called while manager is still running. - obj = None - support.gc_collect() - - mgr.shutdown() - mgr.join() - - def test_saturation(self): - executor = self.executor - mp_context = self.get_context() - sem = mp_context.Semaphore(0) - job_count = 15 * executor._max_workers - for _ in range(job_count): - executor.submit(sem.acquire) - self.assertEqual(len(executor._processes), executor._max_workers) - for _ in range(job_count): - sem.release() - - def test_idle_process_reuse_one(self): - executor = self.executor - assert executor._max_workers >= 4 - if self.get_context().get_start_method(allow_none=False) == "fork": - raise unittest.SkipTest("Incompatible with the fork start method.") - executor.submit(mul, 21, 2).result() - executor.submit(mul, 6, 7).result() - executor.submit(mul, 3, 14).result() - self.assertEqual(len(executor._processes), 1) - - def test_idle_process_reuse_multiple(self): - executor = self.executor - assert executor._max_workers <= 5 - if self.get_context().get_start_method(allow_none=False) == "fork": - raise unittest.SkipTest("Incompatible with the fork start method.") - executor.submit(mul, 12, 7).result() - executor.submit(mul, 33, 25) - executor.submit(mul, 25, 26).result() - executor.submit(mul, 18, 29) - executor.submit(mul, 1, 2).result() - executor.submit(mul, 0, 9) - self.assertLessEqual(len(executor._processes), 3) - executor.shutdown() - - def test_max_tasks_per_child(self): - context = self.get_context() - if context.get_start_method(allow_none=False) == "fork": - with self.assertRaises(ValueError): - self.executor_type(1, mp_context=context, max_tasks_per_child=3) - return - # not using self.executor as we need to control construction. - # arguably this could go in another class w/o that mixin. - executor = self.executor_type( - 1, mp_context=context, max_tasks_per_child=3) - f1 = executor.submit(os.getpid) - original_pid = f1.result() - # The worker pid remains the same as the worker could be reused - f2 = executor.submit(os.getpid) - self.assertEqual(f2.result(), original_pid) - self.assertEqual(len(executor._processes), 1) - f3 = executor.submit(os.getpid) - self.assertEqual(f3.result(), original_pid) - - # A new worker is spawned, with a statistically different pid, - # while the previous was reaped. - f4 = executor.submit(os.getpid) - new_pid = f4.result() - self.assertNotEqual(original_pid, new_pid) - self.assertEqual(len(executor._processes), 1) - - executor.shutdown() - - def test_max_tasks_per_child_defaults_to_spawn_context(self): - # not using self.executor as we need to control construction. - # arguably this could go in another class w/o that mixin. - executor = self.executor_type(1, max_tasks_per_child=3) - self.assertEqual(executor._mp_context.get_start_method(), "spawn") - - def test_max_tasks_early_shutdown(self): - context = self.get_context() - if context.get_start_method(allow_none=False) == "fork": - raise unittest.SkipTest("Incompatible with the fork start method.") - # not using self.executor as we need to control construction. - # arguably this could go in another class w/o that mixin. - executor = self.executor_type( - 3, mp_context=context, max_tasks_per_child=1) - futures = [] - for i in range(6): - futures.append(executor.submit(mul, i, i)) - executor.shutdown() - for i, future in enumerate(futures): - self.assertEqual(future.result(), mul(i, i)) - - -create_executor_tests(ProcessPoolExecutorTest, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - -def _crash(delay=None): - """Induces a segfault.""" - if delay: - time.sleep(delay) - import faulthandler - faulthandler.disable() - faulthandler._sigsegv() - - -def _crash_with_data(data): - """Induces a segfault with dummy data in input.""" - _crash() - - -def _exit(): - """Induces a sys exit with exitcode 1.""" - sys.exit(1) - - -def _raise_error(Err): - """Function that raises an Exception in process.""" - raise Err() - - -def _raise_error_ignore_stderr(Err): - """Function that raises an Exception in process and ignores stderr.""" - import io - sys.stderr = io.StringIO() - raise Err() - - -def _return_instance(cls): - """Function that returns a instance of cls.""" - return cls() - - -class CrashAtPickle(object): - """Bad object that triggers a segfault at pickling time.""" - def __reduce__(self): - _crash() - - -class CrashAtUnpickle(object): - """Bad object that triggers a segfault at unpickling time.""" - def __reduce__(self): - return _crash, () - - -class ExitAtPickle(object): - """Bad object that triggers a process exit at pickling time.""" - def __reduce__(self): - _exit() - - -class ExitAtUnpickle(object): - """Bad object that triggers a process exit at unpickling time.""" - def __reduce__(self): - return _exit, () - - -class ErrorAtPickle(object): - """Bad object that triggers an error at pickling time.""" - def __reduce__(self): - from pickle import PicklingError - raise PicklingError("Error in pickle") - - -class ErrorAtUnpickle(object): - """Bad object that triggers an error at unpickling time.""" - def __reduce__(self): - from pickle import UnpicklingError - return _raise_error_ignore_stderr, (UnpicklingError, ) - - -class ExecutorDeadlockTest: - TIMEOUT = support.SHORT_TIMEOUT - - def _fail_on_deadlock(self, executor): - # If we did not recover before TIMEOUT seconds, consider that the - # executor is in a deadlock state and forcefully clean all its - # composants. - import faulthandler - from tempfile import TemporaryFile - with TemporaryFile(mode="w+") as f: - faulthandler.dump_traceback(file=f) - f.seek(0) - tb = f.read() - for p in executor._processes.values(): - p.terminate() - # This should be safe to call executor.shutdown here as all possible - # deadlocks should have been broken. - executor.shutdown(wait=True) - print(f"\nTraceback:\n {tb}", file=sys.__stderr__) - self.fail(f"Executor deadlock:\n\n{tb}") - - - def _check_crash(self, error, func, *args, ignore_stderr=False): - # test for deadlock caused by crashes in a pool - self.executor.shutdown(wait=True) - - executor = self.executor_type( - max_workers=2, mp_context=self.get_context()) - res = executor.submit(func, *args) - - if ignore_stderr: - cm = support.captured_stderr() - else: - cm = contextlib.nullcontext() - - try: - with self.assertRaises(error): - with cm: - res.result(timeout=self.TIMEOUT) - except futures.TimeoutError: - # If we did not recover before TIMEOUT seconds, - # consider that the executor is in a deadlock state - self._fail_on_deadlock(executor) - executor.shutdown(wait=True) - - def test_error_at_task_pickle(self): - # Check problem occurring while pickling a task in - # the task_handler thread - self._check_crash(PicklingError, id, ErrorAtPickle()) - - def test_exit_at_task_unpickle(self): - # Check problem occurring while unpickling a task on workers - self._check_crash(BrokenProcessPool, id, ExitAtUnpickle()) - - def test_error_at_task_unpickle(self): - # Check problem occurring while unpickling a task on workers - self._check_crash(BrokenProcessPool, id, ErrorAtUnpickle()) - - def test_crash_at_task_unpickle(self): - # Check problem occurring while unpickling a task on workers - self._check_crash(BrokenProcessPool, id, CrashAtUnpickle()) - - def test_crash_during_func_exec_on_worker(self): - # Check problem occurring during func execution on workers - self._check_crash(BrokenProcessPool, _crash) - - def test_exit_during_func_exec_on_worker(self): - # Check problem occurring during func execution on workers - self._check_crash(SystemExit, _exit) - - def test_error_during_func_exec_on_worker(self): - # Check problem occurring during func execution on workers - self._check_crash(RuntimeError, _raise_error, RuntimeError) - - def test_crash_during_result_pickle_on_worker(self): - # Check problem occurring while pickling a task result - # on workers - self._check_crash(BrokenProcessPool, _return_instance, CrashAtPickle) - - def test_exit_during_result_pickle_on_worker(self): - # Check problem occurring while pickling a task result - # on workers - self._check_crash(SystemExit, _return_instance, ExitAtPickle) - - def test_error_during_result_pickle_on_worker(self): - # Check problem occurring while pickling a task result - # on workers - self._check_crash(PicklingError, _return_instance, ErrorAtPickle) - - def test_error_during_result_unpickle_in_result_handler(self): - # Check problem occurring while unpickling a task in - # the result_handler thread - self._check_crash(BrokenProcessPool, - _return_instance, ErrorAtUnpickle, - ignore_stderr=True) - - def test_exit_during_result_unpickle_in_result_handler(self): - # Check problem occurring while unpickling a task in - # the result_handler thread - self._check_crash(BrokenProcessPool, _return_instance, ExitAtUnpickle) - - def test_shutdown_deadlock(self): - # Test that the pool calling shutdown do not cause deadlock - # if a worker fails after the shutdown call. - self.executor.shutdown(wait=True) - with self.executor_type(max_workers=2, - mp_context=self.get_context()) as executor: - self.executor = executor # Allow clean up in fail_on_deadlock - f = executor.submit(_crash, delay=.1) - executor.shutdown(wait=True) - with self.assertRaises(BrokenProcessPool): - f.result() - - def test_shutdown_deadlock_pickle(self): - # Test that the pool calling shutdown with wait=False does not cause - # a deadlock if a task fails at pickle after the shutdown call. - # Reported in bpo-39104. - self.executor.shutdown(wait=True) - with self.executor_type(max_workers=2, - mp_context=self.get_context()) as executor: - self.executor = executor # Allow clean up in fail_on_deadlock - - # Start the executor and get the executor_manager_thread to collect - # the threads and avoid dangling thread that should be cleaned up - # asynchronously. - executor.submit(id, 42).result() - executor_manager = executor._executor_manager_thread - - # Submit a task that fails at pickle and shutdown the executor - # without waiting - f = executor.submit(id, ErrorAtPickle()) - executor.shutdown(wait=False) - with self.assertRaises(PicklingError): - f.result() - - # Make sure the executor is eventually shutdown and do not leave - # dangling threads - executor_manager.join() - - def test_crash_big_data(self): - # https://github.com/python/cpython/issues/107219 - return - # Test that there is a clean exception instad of a deadlock when a - # child process crashes while some data is being written into the - # queue. - # https://github.com/python/cpython/issues/94777 - self.executor.shutdown(wait=True) - data = "a" * support.PIPE_MAX_SIZE - with self.executor_type(max_workers=2, - mp_context=self.get_context()) as executor: - self.executor = executor # Allow clean up in fail_on_deadlock - with self.assertRaises(BrokenProcessPool): - list(executor.map(_crash_with_data, [data] * 10)) - - -create_executor_tests(ExecutorDeadlockTest, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - - -class FutureTests(BaseTestCase): - def test_done_callback_with_result(self): - callback_result = None - def fn(callback_future): - nonlocal callback_result - callback_result = callback_future.result() - - f = Future() - f.add_done_callback(fn) - f.set_result(5) - self.assertEqual(5, callback_result) - - def test_done_callback_with_exception(self): - callback_exception = None - def fn(callback_future): - nonlocal callback_exception - callback_exception = callback_future.exception() - - f = Future() - f.add_done_callback(fn) - f.set_exception(Exception('test')) - self.assertEqual(('test',), callback_exception.args) - - def test_done_callback_with_cancel(self): - was_cancelled = None - def fn(callback_future): - nonlocal was_cancelled - was_cancelled = callback_future.cancelled() - - f = Future() - f.add_done_callback(fn) - self.assertTrue(f.cancel()) - self.assertTrue(was_cancelled) - - def test_done_callback_raises(self): - with support.captured_stderr() as stderr: - raising_was_called = False - fn_was_called = False - - def raising_fn(callback_future): - nonlocal raising_was_called - raising_was_called = True - raise Exception('doh!') - - def fn(callback_future): - nonlocal fn_was_called - fn_was_called = True - - f = Future() - f.add_done_callback(raising_fn) - f.add_done_callback(fn) - f.set_result(5) - self.assertTrue(raising_was_called) - self.assertTrue(fn_was_called) - self.assertIn('Exception: doh!', stderr.getvalue()) - - def test_done_callback_already_successful(self): - callback_result = None - def fn(callback_future): - nonlocal callback_result - callback_result = callback_future.result() - - f = Future() - f.set_result(5) - f.add_done_callback(fn) - self.assertEqual(5, callback_result) - - def test_done_callback_already_failed(self): - callback_exception = None - def fn(callback_future): - nonlocal callback_exception - callback_exception = callback_future.exception() - - f = Future() - f.set_exception(Exception('test')) - f.add_done_callback(fn) - self.assertEqual(('test',), callback_exception.args) - - def test_done_callback_already_cancelled(self): - was_cancelled = None - def fn(callback_future): - nonlocal was_cancelled - was_cancelled = callback_future.cancelled() - - f = Future() - self.assertTrue(f.cancel()) - f.add_done_callback(fn) - self.assertTrue(was_cancelled) - - def test_done_callback_raises_already_succeeded(self): - with support.captured_stderr() as stderr: - def raising_fn(callback_future): - raise Exception('doh!') - - f = Future() - - # Set the result first to simulate a future that runs instantly, - # effectively allowing the callback to be run immediately. - f.set_result(5) - f.add_done_callback(raising_fn) - - self.assertIn('exception calling callback for', stderr.getvalue()) - self.assertIn('doh!', stderr.getvalue()) - - - def test_repr(self): - self.assertRegex(repr(PENDING_FUTURE), - '') - self.assertRegex(repr(RUNNING_FUTURE), - '') - self.assertRegex(repr(CANCELLED_FUTURE), - '') - self.assertRegex(repr(CANCELLED_AND_NOTIFIED_FUTURE), - '') - self.assertRegex( - repr(EXCEPTION_FUTURE), - '') - self.assertRegex( - repr(SUCCESSFUL_FUTURE), - '') - - - def test_cancel(self): - f1 = create_future(state=PENDING) - f2 = create_future(state=RUNNING) - f3 = create_future(state=CANCELLED) - f4 = create_future(state=CANCELLED_AND_NOTIFIED) - f5 = create_future(state=FINISHED, exception=OSError()) - f6 = create_future(state=FINISHED, result=5) - - self.assertTrue(f1.cancel()) - self.assertEqual(f1._state, CANCELLED) - - self.assertFalse(f2.cancel()) - self.assertEqual(f2._state, RUNNING) - - self.assertTrue(f3.cancel()) - self.assertEqual(f3._state, CANCELLED) - - self.assertTrue(f4.cancel()) - self.assertEqual(f4._state, CANCELLED_AND_NOTIFIED) - - self.assertFalse(f5.cancel()) - self.assertEqual(f5._state, FINISHED) - - self.assertFalse(f6.cancel()) - self.assertEqual(f6._state, FINISHED) - - def test_cancelled(self): - self.assertFalse(PENDING_FUTURE.cancelled()) - self.assertFalse(RUNNING_FUTURE.cancelled()) - self.assertTrue(CANCELLED_FUTURE.cancelled()) - self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.cancelled()) - self.assertFalse(EXCEPTION_FUTURE.cancelled()) - self.assertFalse(SUCCESSFUL_FUTURE.cancelled()) - - def test_done(self): - self.assertFalse(PENDING_FUTURE.done()) - self.assertFalse(RUNNING_FUTURE.done()) - self.assertTrue(CANCELLED_FUTURE.done()) - self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.done()) - self.assertTrue(EXCEPTION_FUTURE.done()) - self.assertTrue(SUCCESSFUL_FUTURE.done()) - - def test_running(self): - self.assertFalse(PENDING_FUTURE.running()) - self.assertTrue(RUNNING_FUTURE.running()) - self.assertFalse(CANCELLED_FUTURE.running()) - self.assertFalse(CANCELLED_AND_NOTIFIED_FUTURE.running()) - self.assertFalse(EXCEPTION_FUTURE.running()) - self.assertFalse(SUCCESSFUL_FUTURE.running()) - - def test_result_with_timeout(self): - self.assertRaises(futures.TimeoutError, - PENDING_FUTURE.result, timeout=0) - self.assertRaises(futures.TimeoutError, - RUNNING_FUTURE.result, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_FUTURE.result, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_AND_NOTIFIED_FUTURE.result, timeout=0) - self.assertRaises(OSError, EXCEPTION_FUTURE.result, timeout=0) - self.assertEqual(SUCCESSFUL_FUTURE.result(timeout=0), 42) - - def test_result_with_success(self): - # TODO(brian@sweetapp.com): This test is timing dependent. - def notification(): - # Wait until the main thread is waiting for the result. - time.sleep(1) - f1.set_result(42) - - f1 = create_future(state=PENDING) - t = threading.Thread(target=notification) - t.start() - - self.assertEqual(f1.result(timeout=5), 42) - t.join() - - def test_result_with_cancel(self): - # TODO(brian@sweetapp.com): This test is timing dependent. - def notification(): - # Wait until the main thread is waiting for the result. - time.sleep(1) - f1.cancel() - - f1 = create_future(state=PENDING) - t = threading.Thread(target=notification) - t.start() - - self.assertRaises(futures.CancelledError, - f1.result, timeout=support.SHORT_TIMEOUT) - t.join() - - def test_exception_with_timeout(self): - self.assertRaises(futures.TimeoutError, - PENDING_FUTURE.exception, timeout=0) - self.assertRaises(futures.TimeoutError, - RUNNING_FUTURE.exception, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_FUTURE.exception, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_AND_NOTIFIED_FUTURE.exception, timeout=0) - self.assertTrue(isinstance(EXCEPTION_FUTURE.exception(timeout=0), - OSError)) - self.assertEqual(SUCCESSFUL_FUTURE.exception(timeout=0), None) - - def test_exception_with_success(self): - def notification(): - # Wait until the main thread is waiting for the exception. - time.sleep(1) - with f1._condition: - f1._state = FINISHED - f1._exception = OSError() - f1._condition.notify_all() - - f1 = create_future(state=PENDING) - t = threading.Thread(target=notification) - t.start() - - self.assertTrue(isinstance(f1.exception(timeout=support.SHORT_TIMEOUT), OSError)) - t.join() - - def test_multiple_set_result(self): - f = create_future(state=PENDING) - f.set_result(1) - - with self.assertRaisesRegex( - futures.InvalidStateError, - 'FINISHED: ' - ): - f.set_result(2) - - self.assertTrue(f.done()) - self.assertEqual(f.result(), 1) - - def test_multiple_set_exception(self): - f = create_future(state=PENDING) - e = ValueError() - f.set_exception(e) - - with self.assertRaisesRegex( - futures.InvalidStateError, - 'FINISHED: ' - ): - f.set_exception(Exception()) - - self.assertEqual(f.exception(), e) - - -def setUpModule(): - unittest.addModuleCleanup(multiprocessing.util._cleanup_tests) - thread_info = threading_helper.threading_setup() - unittest.addModuleCleanup(threading_helper.threading_cleanup, *thread_info) - - -if __name__ == "__main__": - unittest.main() diff --git a/mingw32/lib/python3.11/test/test_context.py b/mingw32/lib/python3.11/test/test_context.py index b1aece4f5c9..dc6856509a4 100644 --- a/mingw32/lib/python3.11/test/test_context.py +++ b/mingw32/lib/python3.11/test/test_context.py @@ -6,6 +6,7 @@ import time import unittest import weakref +from test import support from test.support import threading_helper try: @@ -570,6 +571,7 @@ def test_hamt_collision_3(self): self.assertEqual({k.name for k in h.keys()}, {'C', 'D', 'E'}) + @support.requires_resource('cpu') def test_hamt_stress(self): COLLECTION_SIZE = 7000 TEST_ITERS_EVERY = 647 diff --git a/mingw32/lib/python3.11/test/test_cppext/__init__.py b/mingw32/lib/python3.11/test/test_cppext/__init__.py index 4ce29b7ff2c..37247e4ac01 100644 --- a/mingw32/lib/python3.11/test/test_cppext/__init__.py +++ b/mingw32/lib/python3.11/test/test_cppext/__init__.py @@ -15,9 +15,11 @@ @support.requires_subprocess() class TestCPPExt(unittest.TestCase): + @support.requires_resource('cpu') def test_build_cpp11(self): self.check_build(False, '_testcpp11ext') + @support.requires_resource('cpu') def test_build_cpp03(self): self.check_build(True, '_testcpp03ext') diff --git a/mingw64/lib/python3.11/test/test_dataclasses.py b/mingw32/lib/python3.11/test/test_dataclasses/__init__.py similarity index 99% rename from mingw64/lib/python3.11/test/test_dataclasses.py rename to mingw32/lib/python3.11/test/test_dataclasses/__init__.py index 4714d0bca86..682f351c6bd 100644 --- a/mingw64/lib/python3.11/test/test_dataclasses.py +++ b/mingw32/lib/python3.11/test/test_dataclasses/__init__.py @@ -3568,10 +3568,10 @@ class C: self.assertEqual(C(10).x, 10) def test_classvar_module_level_import(self): - from test import dataclass_module_1 - from test import dataclass_module_1_str - from test import dataclass_module_2 - from test import dataclass_module_2_str + from test.test_dataclasses import dataclass_module_1 + from test.test_dataclasses import dataclass_module_1_str + from test.test_dataclasses import dataclass_module_2 + from test.test_dataclasses import dataclass_module_2_str for m in (dataclass_module_1, dataclass_module_1_str, dataclass_module_2, dataclass_module_2_str, @@ -3609,7 +3609,7 @@ def test_classvar_module_level_import(self): self.assertNotIn('not_iv4', c.__dict__) def test_text_annotations(self): - from test import dataclass_textanno + from test.test_dataclasses import dataclass_textanno self.assertEqual( get_type_hints(dataclass_textanno.Bar), diff --git a/mingw32/lib/python3.11/test/dataclass_module_1.py b/mingw32/lib/python3.11/test/test_dataclasses/dataclass_module_1.py similarity index 100% rename from mingw32/lib/python3.11/test/dataclass_module_1.py rename to mingw32/lib/python3.11/test/test_dataclasses/dataclass_module_1.py diff --git a/mingw32/lib/python3.11/test/dataclass_module_1_str.py b/mingw32/lib/python3.11/test/test_dataclasses/dataclass_module_1_str.py similarity index 100% rename from mingw32/lib/python3.11/test/dataclass_module_1_str.py rename to mingw32/lib/python3.11/test/test_dataclasses/dataclass_module_1_str.py diff --git a/mingw32/lib/python3.11/test/dataclass_module_2.py b/mingw32/lib/python3.11/test/test_dataclasses/dataclass_module_2.py similarity index 100% rename from mingw32/lib/python3.11/test/dataclass_module_2.py rename to mingw32/lib/python3.11/test/test_dataclasses/dataclass_module_2.py diff --git a/mingw32/lib/python3.11/test/dataclass_module_2_str.py b/mingw32/lib/python3.11/test/test_dataclasses/dataclass_module_2_str.py similarity index 100% rename from mingw32/lib/python3.11/test/dataclass_module_2_str.py rename to mingw32/lib/python3.11/test/test_dataclasses/dataclass_module_2_str.py diff --git a/mingw32/lib/python3.11/test/dataclass_textanno.py b/mingw32/lib/python3.11/test/test_dataclasses/dataclass_textanno.py similarity index 100% rename from mingw32/lib/python3.11/test/dataclass_textanno.py rename to mingw32/lib/python3.11/test/test_dataclasses/dataclass_textanno.py diff --git a/mingw32/lib/python3.11/test/test_descr.py b/mingw32/lib/python3.11/test/test_descr.py index f07d7d45965..e356624af04 100644 --- a/mingw32/lib/python3.11/test/test_descr.py +++ b/mingw32/lib/python3.11/test/test_descr.py @@ -1980,7 +1980,7 @@ def __getattr__(self, attr): ns = {} exec(code, ns) number_attrs = ns["number_attrs"] - # Warm up the the function for quickening (PEP 659) + # Warm up the function for quickening (PEP 659) for _ in range(30): self.assertEqual(number_attrs(Numbers()), list(range(280))) @@ -4453,6 +4453,7 @@ class Oops(object): o.whatever = Provoker(o) del o + @support.requires_resource('cpu') def test_wrapper_segfault(self): # SF 927248: deeply nested wrappers could cause stack overflow f = lambda:None diff --git a/mingw32/lib/python3.11/test/test_doctest.py b/mingw32/lib/python3.11/test/test_doctest.py index 00aeacddc12..e48d91fafed 100644 --- a/mingw32/lib/python3.11/test/test_doctest.py +++ b/mingw32/lib/python3.11/test/test_doctest.py @@ -742,15 +742,13 @@ class TestDocTestFinder(unittest.TestCase): def test_issue35753(self): # This import of `call` should trigger issue35753 when - # `support.run_doctest` is called due to unwrap failing, + # DocTestFinder.find() is called due to inspect.unwrap() failing, # however with a patched doctest this should succeed. from unittest.mock import call dummy_module = types.ModuleType("dummy") dummy_module.__dict__['inject_call'] = call - try: - support.run_doctest(dummy_module, verbosity=True) - except ValueError as e: - raise support.TestFailed("Doctest unwrap failed") from e + finder = doctest.DocTestFinder() + self.assertEqual(finder.find(dummy_module), []) def test_empty_namespace_package(self): pkg_name = 'doctest_empty_pkg' diff --git a/mingw32/lib/python3.11/test/test_eintr.py b/mingw32/lib/python3.11/test/test_eintr.py index 528147802ba..49b15f1a2db 100644 --- a/mingw32/lib/python3.11/test/test_eintr.py +++ b/mingw32/lib/python3.11/test/test_eintr.py @@ -9,6 +9,7 @@ class EINTRTests(unittest.TestCase): @unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") + @support.requires_resource('walltime') def test_all(self): # Run the tester in a sub-process, to make sure there is only one # thread (for reliable signal delivery). diff --git a/mingw32/lib/python3.11/test/test_email/test_email.py b/mingw32/lib/python3.11/test/test_email/test_email.py index 2bb651609f5..677f2094b83 100644 --- a/mingw32/lib/python3.11/test/test_email/test_email.py +++ b/mingw32/lib/python3.11/test/test_email/test_email.py @@ -39,6 +39,7 @@ from email import quoprimime from email import utils +from test import support from test.support import threading_helper from test.support.os_helper import unlink from test.test_email import openfile, TestEmailBase @@ -3342,6 +3343,7 @@ def test_getaddresses_header_obj(self): self.assertEqual(addrs[0][1], 'aperson@dom.ain') @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_make_msgid_collisions(self): # Test make_msgid uniqueness, even with multiple threads class MsgidsThread(Thread): diff --git a/mingw32/lib/python3.11/test/test_enum.py b/mingw32/lib/python3.11/test/test_enum.py index cc66875bde0..ed1c3a59ce4 100644 --- a/mingw32/lib/python3.11/test/test_enum.py +++ b/mingw32/lib/python3.11/test/test_enum.py @@ -322,6 +322,17 @@ def spam(cls): with self.assertRaises(AttributeError): del Season.SPRING.name + def test_bad_new_super(self): + with self.assertRaisesRegex( + TypeError, + 'has no members defined', + ): + class BadSuper(self.enum_type): + def __new__(cls, value): + obj = super().__new__(cls, value) + return obj + failed = 1 + def test_basics(self): TE = self.MainEnum if self.is_flag: diff --git a/mingw32/lib/python3.11/test/test_exceptions.py b/mingw32/lib/python3.11/test/test_exceptions.py index d7133adf058..6f34e29e42f 100644 --- a/mingw32/lib/python3.11/test/test_exceptions.py +++ b/mingw32/lib/python3.11/test/test_exceptions.py @@ -1304,6 +1304,7 @@ def g(): @cpython_only + @support.requires_resource('cpu') def test_trashcan_recursion(self): # See bpo-33930 diff --git a/mingw32/lib/python3.11/test/test_faulthandler.py b/mingw32/lib/python3.11/test/test_faulthandler.py index 8d106daaf65..0e03ee21288 100644 --- a/mingw32/lib/python3.11/test/test_faulthandler.py +++ b/mingw32/lib/python3.11/test/test_faulthandler.py @@ -676,6 +676,7 @@ def test_dump_traceback_later_fd(self): with tempfile.TemporaryFile('wb+') as fp: self.check_dump_traceback_later(fd=fp.fileno()) + @support.requires_resource('walltime') def test_dump_traceback_later_twice(self): self.check_dump_traceback_later(loops=2) diff --git a/mingw32/lib/python3.11/test/test_float.py b/mingw32/lib/python3.11/test/test_float.py index 304388e1f78..c6af0b92a73 100644 --- a/mingw32/lib/python3.11/test/test_float.py +++ b/mingw32/lib/python3.11/test/test_float.py @@ -734,8 +734,13 @@ def test_format_testfile(self): lhs, rhs = map(str.strip, line.split('->')) fmt, arg = lhs.split() - self.assertEqual(fmt % float(arg), rhs) - self.assertEqual(fmt % -float(arg), '-' + rhs) + f = float(arg) + self.assertEqual(fmt % f, rhs) + self.assertEqual(fmt % -f, '-' + rhs) + if fmt != '%r': + fmt2 = fmt[1:] + self.assertEqual(format(f, fmt2), rhs) + self.assertEqual(format(-f, fmt2), '-' + rhs) def test_issue5864(self): self.assertEqual(format(123.456, '.4'), '123.5') diff --git a/mingw32/lib/python3.11/test/test_frame.py b/mingw32/lib/python3.11/test/test_frame.py index 9cb2686f175..1e52164a6ba 100644 --- a/mingw32/lib/python3.11/test/test_frame.py +++ b/mingw32/lib/python3.11/test/test_frame.py @@ -317,7 +317,7 @@ def f(): sneaky_frame_object = None gc.enable() next(g) - # g.gi_frame should be the the frame object from the callback (the + # g.gi_frame should be the frame object from the callback (the # one that was *requested* second, but *created* first): self.assertIs(g.gi_frame, sneaky_frame_object) finally: diff --git a/mingw32/lib/python3.11/test/test_ftplib.py b/mingw32/lib/python3.11/test/test_ftplib.py index 082a90d46ba..7d6b12ffadc 100644 --- a/mingw32/lib/python3.11/test/test_ftplib.py +++ b/mingw32/lib/python3.11/test/test_ftplib.py @@ -34,7 +34,7 @@ DEFAULT_ENCODING = 'utf-8' # the dummy data returned by server over the data channel when # RETR, LIST, NLST, MLSD commands are issued -RETR_DATA = 'abcde12345\r\n' * 1000 + 'non-ascii char \xAE\r\n' +RETR_DATA = 'abcde\xB9\xB2\xB3\xA4\xA6\r\n' * 1000 LIST_DATA = 'foo\r\nbar\r\n non-ascii char \xAE\r\n' NLST_DATA = 'foo\r\nbar\r\n non-ascii char \xAE\r\n' MLSD_DATA = ("type=cdir;perm=el;unique==keVO1+ZF4; test\r\n" @@ -69,11 +69,11 @@ class DummyDTPHandler(asynchat.async_chat): def __init__(self, conn, baseclass): asynchat.async_chat.__init__(self, conn) self.baseclass = baseclass - self.baseclass.last_received_data = '' + self.baseclass.last_received_data = bytearray() self.encoding = baseclass.encoding def handle_read(self): - new_data = self.recv(1024).decode(self.encoding, 'replace') + new_data = self.recv(1024) self.baseclass.last_received_data += new_data def handle_close(self): @@ -109,7 +109,7 @@ def __init__(self, conn, encoding=DEFAULT_ENCODING): self.in_buffer = [] self.dtp = None self.last_received_cmd = None - self.last_received_data = '' + self.last_received_data = bytearray() self.next_response = '' self.next_data = None self.rest = None @@ -592,19 +592,17 @@ def test_abort(self): self.client.abort() def test_retrbinary(self): - def callback(data): - received.append(data.decode(self.client.encoding)) received = [] - self.client.retrbinary('retr', callback) - self.check_data(''.join(received), RETR_DATA) + self.client.retrbinary('retr', received.append) + self.check_data(b''.join(received), + RETR_DATA.encode(self.client.encoding)) def test_retrbinary_rest(self): - def callback(data): - received.append(data.decode(self.client.encoding)) for rest in (0, 10, 20): received = [] - self.client.retrbinary('retr', callback, rest=rest) - self.check_data(''.join(received), RETR_DATA[rest:]) + self.client.retrbinary('retr', received.append, rest=rest) + self.check_data(b''.join(received), + RETR_DATA[rest:].encode(self.client.encoding)) def test_retrlines(self): received = [] @@ -614,7 +612,8 @@ def test_retrlines(self): def test_storbinary(self): f = io.BytesIO(RETR_DATA.encode(self.client.encoding)) self.client.storbinary('stor', f) - self.check_data(self.server.handler_instance.last_received_data, RETR_DATA) + self.check_data(self.server.handler_instance.last_received_data, + RETR_DATA.encode(self.server.encoding)) # test new callback arg flag = [] f.seek(0) @@ -633,7 +632,8 @@ def test_storlines(self): data = RETR_DATA.replace('\r\n', '\n').encode(self.client.encoding) f = io.BytesIO(data) self.client.storlines('stor', f) - self.check_data(self.server.handler_instance.last_received_data, RETR_DATA) + self.check_data(self.server.handler_instance.last_received_data, + RETR_DATA.encode(self.server.encoding)) # test new callback arg flag = [] f.seek(0) @@ -651,7 +651,7 @@ def test_nlst(self): def test_dir(self): l = [] - self.client.dir(lambda x: l.append(x)) + self.client.dir(l.append) self.assertEqual(''.join(l), LIST_DATA.replace('\r\n', '')) def test_mlsd(self): @@ -891,12 +891,10 @@ def test_makepasv(self): def test_transfer(self): def retr(): - def callback(data): - received.append(data.decode(self.client.encoding)) received = [] - self.client.retrbinary('retr', callback) - self.assertEqual(len(''.join(received)), len(RETR_DATA)) - self.assertEqual(''.join(received), RETR_DATA) + self.client.retrbinary('retr', received.append) + self.assertEqual(b''.join(received), + RETR_DATA.encode(self.client.encoding)) self.client.set_pasv(True) retr() self.client.set_pasv(False) diff --git a/mingw32/lib/python3.11/test/test_functools.py b/mingw32/lib/python3.11/test/test_functools.py index 382e7dbffdd..fb6e1860ac1 100644 --- a/mingw32/lib/python3.11/test/test_functools.py +++ b/mingw32/lib/python3.11/test/test_functools.py @@ -27,10 +27,16 @@ py_functools = import_helper.import_fresh_module('functools', blocked=['_functools']) -c_functools = import_helper.import_fresh_module('functools') +c_functools = import_helper.import_fresh_module('functools', + fresh=['_functools']) decimal = import_helper.import_fresh_module('decimal', fresh=['_decimal']) +_partial_types = [py_functools.partial] +if c_functools: + _partial_types.append(c_functools.partial) + + @contextlib.contextmanager def replaced_module(name, replacement): original_module = sys.modules[name] @@ -202,7 +208,7 @@ def test_repr(self): kwargs = {'a': object(), 'b': object()} kwargs_reprs = ['a={a!r}, b={b!r}'.format_map(kwargs), 'b={b!r}, a={a!r}'.format_map(kwargs)] - if self.partial in (c_functools.partial, py_functools.partial): + if self.partial in _partial_types: name = 'functools.partial' else: name = self.partial.__name__ @@ -224,7 +230,7 @@ def test_repr(self): for kwargs_repr in kwargs_reprs]) def test_recursive_repr(self): - if self.partial in (c_functools.partial, py_functools.partial): + if self.partial in _partial_types: name = 'functools.partial' else: name = self.partial.__name__ @@ -251,7 +257,7 @@ def test_recursive_repr(self): f.__setstate__((capture, (), {}, {})) def test_pickle(self): - with self.AllowPickle(): + with replaced_module('functools', self.module): f = self.partial(signature, ['asdf'], bar=[True]) f.attr = [] for proto in range(pickle.HIGHEST_PROTOCOL + 1): @@ -334,7 +340,7 @@ def test_setstate_subclasses(self): self.assertIs(type(r[0]), tuple) def test_recursive_pickle(self): - with self.AllowPickle(): + with replaced_module('functools', self.module): f = self.partial(capture) f.__setstate__((f, (), {}, {})) try: @@ -388,14 +394,9 @@ def __getitem__(self, key): @unittest.skipUnless(c_functools, 'requires the C _functools module') class TestPartialC(TestPartial, unittest.TestCase): if c_functools: + module = c_functools partial = c_functools.partial - class AllowPickle: - def __enter__(self): - return self - def __exit__(self, type, value, tb): - return False - def test_attributes_unwritable(self): # attributes should not be writable p = self.partial(capture, 1, 2, a=10, b=20) @@ -438,15 +439,9 @@ def __str__(self): class TestPartialPy(TestPartial, unittest.TestCase): + module = py_functools partial = py_functools.partial - class AllowPickle: - def __init__(self): - self._cm = replaced_module("functools", py_functools) - def __enter__(self): - return self._cm.__enter__() - def __exit__(self, type, value, tb): - return self._cm.__exit__(type, value, tb) if c_functools: class CPartialSubclass(c_functools.partial): @@ -1860,9 +1855,10 @@ def test_staticmethod(x): def py_cached_func(x, y): return 3 * x + y -@c_functools.lru_cache() -def c_cached_func(x, y): - return 3 * x + y +if c_functools: + @c_functools.lru_cache() + def c_cached_func(x, y): + return 3 * x + y class TestLRUPy(TestLRU, unittest.TestCase): @@ -1879,18 +1875,20 @@ def cached_staticmeth(x, y): return 3 * x + y +@unittest.skipUnless(c_functools, 'requires the C _functools module') class TestLRUC(TestLRU, unittest.TestCase): - module = c_functools - cached_func = c_cached_func, + if c_functools: + module = c_functools + cached_func = c_cached_func, - @module.lru_cache() - def cached_meth(self, x, y): - return 3 * x + y + @module.lru_cache() + def cached_meth(self, x, y): + return 3 * x + y - @staticmethod - @module.lru_cache() - def cached_staticmeth(x, y): - return 3 * x + y + @staticmethod + @module.lru_cache() + def cached_staticmeth(x, y): + return 3 * x + y class TestSingleDispatch(unittest.TestCase): diff --git a/mingw32/lib/python3.11/test/test_future_stmt/__init__.py b/mingw32/lib/python3.11/test/test_future_stmt/__init__.py new file mode 100644 index 00000000000..f2a39a3fe29 --- /dev/null +++ b/mingw32/lib/python3.11/test/test_future_stmt/__init__.py @@ -0,0 +1,6 @@ +import os +from test import support + + +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/mingw32/lib/python3.11/test/badsyntax_future10.py b/mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future10.py similarity index 100% rename from mingw32/lib/python3.11/test/badsyntax_future10.py rename to mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future10.py diff --git a/mingw32/lib/python3.11/test/badsyntax_future3.py b/mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future3.py similarity index 100% rename from mingw32/lib/python3.11/test/badsyntax_future3.py rename to mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future3.py diff --git a/mingw32/lib/python3.11/test/badsyntax_future4.py b/mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future4.py similarity index 100% rename from mingw32/lib/python3.11/test/badsyntax_future4.py rename to mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future4.py diff --git a/mingw32/lib/python3.11/test/badsyntax_future5.py b/mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future5.py similarity index 100% rename from mingw32/lib/python3.11/test/badsyntax_future5.py rename to mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future5.py diff --git a/mingw32/lib/python3.11/test/badsyntax_future6.py b/mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future6.py similarity index 100% rename from mingw32/lib/python3.11/test/badsyntax_future6.py rename to mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future6.py diff --git a/mingw32/lib/python3.11/test/badsyntax_future7.py b/mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future7.py similarity index 100% rename from mingw32/lib/python3.11/test/badsyntax_future7.py rename to mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future7.py diff --git a/mingw32/lib/python3.11/test/badsyntax_future8.py b/mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future8.py similarity index 100% rename from mingw32/lib/python3.11/test/badsyntax_future8.py rename to mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future8.py diff --git a/mingw32/lib/python3.11/test/badsyntax_future9.py b/mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future9.py similarity index 100% rename from mingw32/lib/python3.11/test/badsyntax_future9.py rename to mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future9.py diff --git a/mingw32/lib/python3.11/test/future_test1.py b/mingw32/lib/python3.11/test/test_future_stmt/future_test1.py similarity index 100% rename from mingw32/lib/python3.11/test/future_test1.py rename to mingw32/lib/python3.11/test/test_future_stmt/future_test1.py diff --git a/mingw32/lib/python3.11/test/future_test2.py b/mingw32/lib/python3.11/test/test_future_stmt/future_test2.py similarity index 100% rename from mingw32/lib/python3.11/test/future_test2.py rename to mingw32/lib/python3.11/test/test_future_stmt/future_test2.py diff --git a/mingw64/lib/python3.11/test/test_future.py b/mingw32/lib/python3.11/test/test_future_stmt/test_future.py similarity index 91% rename from mingw64/lib/python3.11/test/test_future.py rename to mingw32/lib/python3.11/test/test_future_stmt/test_future.py index c3e8420d667..13cee3ff6e4 100644 --- a/mingw64/lib/python3.11/test/test_future.py +++ b/mingw32/lib/python3.11/test/test_future_stmt/test_future.py @@ -25,57 +25,71 @@ def check_syntax_error(self, err, basename, lineno, offset=1): self.assertEqual(err.offset, offset) def test_future1(self): - with import_helper.CleanImport('future_test1'): - from test import future_test1 + with import_helper.CleanImport('test.test_future_stmt.future_test1'): + from test.test_future_stmt import future_test1 self.assertEqual(future_test1.result, 6) def test_future2(self): - with import_helper.CleanImport('future_test2'): - from test import future_test2 + with import_helper.CleanImport('test.test_future_stmt.future_test2'): + from test.test_future_stmt import future_test2 self.assertEqual(future_test2.result, 6) - def test_future3(self): - with import_helper.CleanImport('test_future3'): - from test import test_future3 + def test_future_single_import(self): + with import_helper.CleanImport( + 'test.test_future_stmt.test_future_single_import', + ): + from test.test_future_stmt import test_future_single_import + + def test_future_multiple_imports(self): + with import_helper.CleanImport( + 'test.test_future_stmt.test_future_multiple_imports', + ): + from test.test_future_stmt import test_future_multiple_imports + + def test_future_multiple_features(self): + with import_helper.CleanImport( + "test.test_future_stmt.test_future_multiple_features", + ): + from test.test_future_stmt import test_future_multiple_features def test_badfuture3(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future3 + from test.test_future_stmt import badsyntax_future3 self.check_syntax_error(cm.exception, "badsyntax_future3", 3) def test_badfuture4(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future4 + from test.test_future_stmt import badsyntax_future4 self.check_syntax_error(cm.exception, "badsyntax_future4", 3) def test_badfuture5(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future5 + from test.test_future_stmt import badsyntax_future5 self.check_syntax_error(cm.exception, "badsyntax_future5", 4) def test_badfuture6(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future6 + from test.test_future_stmt import badsyntax_future6 self.check_syntax_error(cm.exception, "badsyntax_future6", 3) def test_badfuture7(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future7 + from test.test_future_stmt import badsyntax_future7 self.check_syntax_error(cm.exception, "badsyntax_future7", 3, 53) def test_badfuture8(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future8 + from test.test_future_stmt import badsyntax_future8 self.check_syntax_error(cm.exception, "badsyntax_future8", 3) def test_badfuture9(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future9 + from test.test_future_stmt import badsyntax_future9 self.check_syntax_error(cm.exception, "badsyntax_future9", 3) def test_badfuture10(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future10 + from test.test_future_stmt import badsyntax_future10 self.check_syntax_error(cm.exception, "badsyntax_future10", 3) def test_ensure_flags_dont_clash(self): @@ -113,10 +127,6 @@ def test_parserhack(self): else: self.fail("syntax error didn't occur") - def test_multiple_features(self): - with import_helper.CleanImport("test.test_future5"): - from test import test_future5 - def test_unicode_literals_exec(self): scope = {} exec("from __future__ import unicode_literals; x = ''", {}, scope) diff --git a/mingw32/lib/python3.11/test/test___future__.py b/mingw32/lib/python3.11/test/test_future_stmt/test_future_flags.py similarity index 100% rename from mingw32/lib/python3.11/test/test___future__.py rename to mingw32/lib/python3.11/test/test_future_stmt/test_future_flags.py diff --git a/mingw32/lib/python3.11/test/test_future5.py b/mingw32/lib/python3.11/test/test_future_stmt/test_future_multiple_features.py similarity index 100% rename from mingw32/lib/python3.11/test/test_future5.py rename to mingw32/lib/python3.11/test/test_future_stmt/test_future_multiple_features.py diff --git a/mingw32/lib/python3.11/test/test_future4.py b/mingw32/lib/python3.11/test/test_future_stmt/test_future_multiple_imports.py similarity index 100% rename from mingw32/lib/python3.11/test/test_future4.py rename to mingw32/lib/python3.11/test/test_future_stmt/test_future_multiple_imports.py diff --git a/mingw32/lib/python3.11/test/test_future3.py b/mingw32/lib/python3.11/test/test_future_stmt/test_future_single_import.py similarity index 100% rename from mingw32/lib/python3.11/test/test_future3.py rename to mingw32/lib/python3.11/test/test_future_stmt/test_future_single_import.py diff --git a/mingw32/lib/python3.11/test/test_gdb.py b/mingw32/lib/python3.11/test/test_gdb.py index 0f39b8f4571..5d042a45587 100644 --- a/mingw32/lib/python3.11/test/test_gdb.py +++ b/mingw32/lib/python3.11/test/test_gdb.py @@ -55,10 +55,6 @@ def get_gdb_version(): if not sysconfig.is_python_build(): raise unittest.SkipTest("test_gdb only works on source builds at the moment.") -if 'Clang' in platform.python_compiler() and sys.platform == 'darwin': - raise unittest.SkipTest("test_gdb doesn't work correctly when python is" - " built with LLVM clang") - if ((sysconfig.get_config_var('PGO_PROF_USE_FLAG') or 'xxx') in (sysconfig.get_config_var('PY_CORE_CFLAGS') or '')): raise unittest.SkipTest("test_gdb is not reliable on PGO builds") @@ -247,6 +243,17 @@ def get_stack_trace(self, source=None, script=None, for pattern in ( '(frame information optimized out)', 'Unable to read information on python frame', + # gh-91960: On Python built with "clang -Og", gdb gets + # "frame=" for _PyEval_EvalFrameDefault() parameter + '(unable to read python frame information)', + # gh-104736: On Python built with "clang -Og" on ppc64le, + # "py-bt" displays a truncated or not traceback, but "where" + # logs this error message: + 'Backtrace stopped: frame did not save the PC', + # gh-104736: When "bt" command displays something like: + # "#1 0x0000000000000000 in ?? ()", the traceback is likely + # truncated or wrong. + ' ?? ()', ): if pattern in out: raise unittest.SkipTest(f"{pattern!r} found in gdb output") @@ -317,6 +324,7 @@ def assertGdbRepr(self, val, exp_repr=None): ('%r did not equal expected %r; full output was:\n%s' % (gdb_repr, exp_repr, gdb_output))) + @support.requires_resource('cpu') def test_int(self): 'Verify the pretty-printing of various int values' self.assertGdbRepr(42) @@ -343,6 +351,7 @@ def test_lists(self): self.assertGdbRepr([]) self.assertGdbRepr(list(range(5))) + @support.requires_resource('cpu') def test_bytes(self): 'Verify the pretty-printing of bytes' self.assertGdbRepr(b'') @@ -357,6 +366,7 @@ def test_bytes(self): self.assertGdbRepr(bytes([b for b in range(255)])) + @support.requires_resource('cpu') def test_strings(self): 'Verify the pretty-printing of unicode strings' # We cannot simply call locale.getpreferredencoding() here, @@ -407,6 +417,7 @@ def test_tuples(self): self.assertGdbRepr((1,), '(1,)') self.assertGdbRepr(('foo', 'bar', 'baz')) + @support.requires_resource('cpu') def test_sets(self): 'Verify the pretty-printing of sets' if (gdb_major_version, gdb_minor_version) < (7, 3): @@ -425,6 +436,7 @@ def test_sets(self): id(s)''') self.assertEqual(gdb_repr, "{'b'}") + @support.requires_resource('cpu') def test_frozensets(self): 'Verify the pretty-printing of frozensets' if (gdb_major_version, gdb_minor_version) < (7, 3): @@ -828,6 +840,7 @@ def test_bt_full(self): @unittest.skipIf(python_is_optimized(), "Python was compiled with optimizations") + @support.requires_resource('cpu') def test_threads(self): 'Verify that "py-bt" indicates threads that are waiting for the GIL' cmd = ''' @@ -889,6 +902,7 @@ def test_gc(self): @unittest.skipIf(python_is_optimized(), "Python was compiled with optimizations") + @support.requires_resource('cpu') # Some older versions of gdb will fail with # "Cannot find new threads: generic error" # unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround diff --git a/mingw32/lib/python3.11/test/test_getopt.py b/mingw32/lib/python3.11/test/test_getopt.py index 64b9ce01e05..e1a66898136 100644 --- a/mingw32/lib/python3.11/test/test_getopt.py +++ b/mingw32/lib/python3.11/test/test_getopt.py @@ -1,8 +1,8 @@ # test_getopt.py # David Goodger 2000-08-19 -from test.support import verbose, run_doctest from test.support.os_helper import EnvironmentVarGuard +import doctest import unittest import getopt @@ -134,48 +134,49 @@ def test_gnu_getopt(self): self.assertEqual(opts, [('-a', '')]) self.assertEqual(args, ['arg1', '-b', '1', '--alpha', '--beta=2']) - def test_libref_examples(self): - s = """ - Examples from the Library Reference: Doc/lib/libgetopt.tex + def test_issue4629(self): + longopts, shortopts = getopt.getopt(['--help='], '', ['help=']) + self.assertEqual(longopts, [('--help', '')]) + longopts, shortopts = getopt.getopt(['--help=x'], '', ['help=']) + self.assertEqual(longopts, [('--help', 'x')]) + self.assertRaises(getopt.GetoptError, getopt.getopt, ['--help='], '', ['help']) - An example using only Unix style options: +def test_libref_examples(): + """ + Examples from the Library Reference: Doc/lib/libgetopt.tex + An example using only Unix style options: - >>> import getopt - >>> args = '-a -b -cfoo -d bar a1 a2'.split() - >>> args - ['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2'] - >>> optlist, args = getopt.getopt(args, 'abc:d:') - >>> optlist - [('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')] - >>> args - ['a1', 'a2'] - Using long option names is equally easy: + >>> import getopt + >>> args = '-a -b -cfoo -d bar a1 a2'.split() + >>> args + ['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2'] + >>> optlist, args = getopt.getopt(args, 'abc:d:') + >>> optlist + [('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')] + >>> args + ['a1', 'a2'] + Using long option names is equally easy: - >>> s = '--condition=foo --testing --output-file abc.def -x a1 a2' - >>> args = s.split() - >>> args - ['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2'] - >>> optlist, args = getopt.getopt(args, 'x', [ - ... 'condition=', 'output-file=', 'testing']) - >>> optlist - [('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')] - >>> args - ['a1', 'a2'] - """ - import types - m = types.ModuleType("libreftest", s) - run_doctest(m, verbose) + >>> s = '--condition=foo --testing --output-file abc.def -x a1 a2' + >>> args = s.split() + >>> args + ['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2'] + >>> optlist, args = getopt.getopt(args, 'x', [ + ... 'condition=', 'output-file=', 'testing']) + >>> optlist + [('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')] + >>> args + ['a1', 'a2'] + """ + +def load_tests(loader, tests, pattern): + tests.addTest(doctest.DocTestSuite()) + return tests - def test_issue4629(self): - longopts, shortopts = getopt.getopt(['--help='], '', ['help=']) - self.assertEqual(longopts, [('--help', '')]) - longopts, shortopts = getopt.getopt(['--help=x'], '', ['help=']) - self.assertEqual(longopts, [('--help', 'x')]) - self.assertRaises(getopt.GetoptError, getopt.getopt, ['--help='], '', ['help']) if __name__ == "__main__": unittest.main() diff --git a/mingw32/lib/python3.11/test/test_grammar.py b/mingw32/lib/python3.11/test/test_grammar.py index bcd8d584b0f..a00280b184e 100644 --- a/mingw32/lib/python3.11/test/test_grammar.py +++ b/mingw32/lib/python3.11/test/test_grammar.py @@ -13,10 +13,9 @@ # different import patterns to check that __annotations__ does not interfere # with import machinery -import test.ann_module as ann_module +import test.typinganndata.ann_module as ann_module import typing -from collections import ChainMap -from test import ann_module2 +from test.typinganndata import ann_module2 import test # These are shared with test_tokenize and other test modules. @@ -238,6 +237,10 @@ def check(test, error=False): check(f"[{num}for x in ()]") check(f"{num}spam", error=True) + # gh-88943: Invalid non-ASCII character following a numerical literal. + with self.assertRaisesRegex(SyntaxError, r"invalid character 'â„' \(U\+2044\)"): + compile(f"{num}â„7", "", "eval") + with warnings.catch_warnings(): warnings.filterwarnings('ignore', '"is" with a literal', SyntaxWarning) @@ -355,6 +358,11 @@ def test_var_annot_syntax_errors(self): check_syntax_error(self, "x: int: str") check_syntax_error(self, "def f():\n" " nonlocal x: int\n") + check_syntax_error(self, "def f():\n" + " global x: int\n") + check_syntax_error(self, "x: int = y = 1") + check_syntax_error(self, "z = w: int = 1") + check_syntax_error(self, "x: int = y: int = 1") # AST pass check_syntax_error(self, "[x, 0]: int\n") check_syntax_error(self, "f(): int\n") @@ -368,6 +376,12 @@ def test_var_annot_syntax_errors(self): check_syntax_error(self, "def f():\n" " global x\n" " x: int\n") + check_syntax_error(self, "def f():\n" + " x: int\n" + " nonlocal x\n") + check_syntax_error(self, "def f():\n" + " nonlocal x\n" + " x: int\n") def test_var_annot_basic_semantics(self): # execution order @@ -457,7 +471,7 @@ def test_var_annot_module_semantics(self): def test_var_annot_in_module(self): # check that functions fail the same way when executed # outside of module where they were defined - ann_module3 = import_helper.import_fresh_module("test.ann_module3") + ann_module3 = import_helper.import_fresh_module("test.typinganndata.ann_module3") with self.assertRaises(NameError): ann_module3.f_bad_ann() with self.assertRaises(NameError): diff --git a/mingw32/lib/python3.11/test/test_httplib.py b/mingw32/lib/python3.11/test/test_httplib.py index acae0127a13..47dbf08f370 100644 --- a/mingw32/lib/python3.11/test/test_httplib.py +++ b/mingw32/lib/python3.11/test/test_httplib.py @@ -1911,6 +1911,7 @@ def test_networked_good_cert(self): h.close() self.assertIn('nginx', server_string) + @support.requires_resource('walltime') def test_networked_bad_cert(self): # We feed a "CA" cert that is unrelated to the server's cert import ssl diff --git a/mingw32/lib/python3.11/test/test_imaplib.py b/mingw32/lib/python3.11/test/test_imaplib.py index ed26fa16d6e..f097ba68154 100644 --- a/mingw32/lib/python3.11/test/test_imaplib.py +++ b/mingw32/lib/python3.11/test/test_imaplib.py @@ -11,7 +11,7 @@ import socket from test.support import (verbose, - run_with_tz, run_with_locale, cpython_only, + run_with_tz, run_with_locale, cpython_only, requires_resource, requires_working_socket) from test.support import hashlib_helper from test.support import threading_helper @@ -77,6 +77,7 @@ def test_that_Time2Internaldate_returns_a_result(self): for t in self.timevalues(): imaplib.Time2Internaldate(t) + @socket_helper.skip_if_tcp_blackhole def test_imap4_host_default_value(self): # Check whether the IMAP4_PORT is truly unavailable. with socket.socket() as s: @@ -459,6 +460,7 @@ def test_simple_with_statement(self): with self.imap_class(*server.server_address): pass + @requires_resource('walltime') def test_imaplib_timeout_test(self): _, server = self._setup(SimpleIMAPHandler) addr = server.server_address[1] @@ -552,6 +554,7 @@ class NewIMAPSSLTests(NewIMAPTestsMixin, unittest.TestCase): imap_class = IMAP4_SSL server_class = SecureTCPServer + @requires_resource('walltime') def test_ssl_raises(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) self.assertEqual(ssl_context.verify_mode, ssl.CERT_REQUIRED) @@ -566,6 +569,7 @@ def test_ssl_raises(self): ssl_context=ssl_context) client.shutdown() + @requires_resource('walltime') def test_ssl_verified(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ssl_context.load_verify_locations(CAFILE) diff --git a/mingw32/lib/python3.11/test/test_imp.py b/mingw32/lib/python3.11/test/test_imp.py index 4bb03908fc2..4062afd7254 100644 --- a/mingw32/lib/python3.11/test/test_imp.py +++ b/mingw32/lib/python3.11/test/test_imp.py @@ -78,7 +78,7 @@ def test_find_module_encoding(self): with imp.find_module('module_' + mod, self.test_path)[0] as fd: self.assertEqual(fd.encoding, encoding) - path = [os.path.dirname(__file__)] + path = [os.path.join(os.path.dirname(__file__), 'tokenizedata')] with self.assertRaises(SyntaxError): imp.find_module('badsyntax_pep3120', path) @@ -203,9 +203,11 @@ def test_issue5604(self): os_helper.rmtree('__pycache__') def test_issue9319(self): - path = os.path.dirname(__file__) + path = os.path.join(os.path.dirname(__file__), "tokenizedata") self.assertRaises(SyntaxError, - imp.find_module, "badsyntax_pep3120", [path]) + imp.find_module, + "badsyntax_pep3120", + [path]) def test_load_from_source(self): # Verify that the imp module can correctly load and find .py files diff --git a/mingw32/lib/python3.11/test/test_import/__init__.py b/mingw32/lib/python3.11/test/test_import/__init__.py index 6e2606cdb05..131aebbd4e1 100644 --- a/mingw32/lib/python3.11/test/test_import/__init__.py +++ b/mingw32/lib/python3.11/test/test_import/__init__.py @@ -24,9 +24,10 @@ STDLIB_DIR, is_jython, swap_attr, swap_item, cpython_only, is_emscripten, is_wasi) from test.support.import_helper import ( - forget, make_legacy_pyc, unlink, unload, DirsOnSysPath, CleanImport) + forget, make_legacy_pyc, unlink, unload, ready_to_import, + DirsOnSysPath, CleanImport) from test.support.os_helper import ( - TESTFN, rmtree, temp_umask, TESTFN_UNENCODABLE, temp_dir) + TESTFN, rmtree, temp_umask, TESTFN_UNENCODABLE) from test.support import script_helper from test.support import threading_helper from test.test_importlib.util import uncache @@ -46,27 +47,6 @@ def remove_files(name): rmtree('__pycache__') -@contextlib.contextmanager -def _ready_to_import(name=None, source=""): - # sets up a temporary directory and removes it - # creates the module file - # temporarily clears the module from sys.modules (if any) - # reverts or removes the module when cleaning up - name = name or "spam" - with temp_dir() as tempdir: - path = script_helper.make_script(tempdir, name, source) - old_module = sys.modules.pop(name, None) - try: - sys.path.insert(0, tempdir) - yield name, path - sys.path.remove(tempdir) - finally: - if old_module is not None: - sys.modules[name] = old_module - elif name in sys.modules: - del sys.modules[name] - - class ImportTests(unittest.TestCase): def setUp(self): @@ -130,7 +110,7 @@ def test_from_import_missing_attr_path_is_canonical(self): def test_from_import_star_invalid_type(self): import re - with _ready_to_import() as (name, path): + with ready_to_import() as (name, path): with open(path, 'w', encoding='utf-8') as f: f.write("__all__ = [b'invalid_type']") globals = {} @@ -139,7 +119,7 @@ def test_from_import_star_invalid_type(self): ): exec(f"from {name} import *", globals) self.assertNotIn(b"invalid_type", globals) - with _ready_to_import() as (name, path): + with ready_to_import() as (name, path): with open(path, 'w', encoding='utf-8') as f: f.write("globals()[b'invalid_type'] = object()") globals = {} @@ -550,7 +530,7 @@ class FilePermissionTests(unittest.TestCase): ) def test_creation_mode(self): mask = 0o022 - with temp_umask(mask), _ready_to_import() as (name, path): + with temp_umask(mask), ready_to_import() as (name, path): cached_path = importlib.util.cache_from_source(path) module = __import__(name) if not os.path.exists(cached_path): @@ -569,7 +549,7 @@ def test_creation_mode(self): def test_cached_mode_issue_2051(self): # permissions of .pyc should match those of .py, regardless of mask mode = 0o600 - with temp_umask(0o022), _ready_to_import() as (name, path): + with temp_umask(0o022), ready_to_import() as (name, path): cached_path = importlib.util.cache_from_source(path) os.chmod(path, mode) __import__(name) @@ -585,7 +565,7 @@ def test_cached_mode_issue_2051(self): @os_helper.skip_unless_working_chmod def test_cached_readonly(self): mode = 0o400 - with temp_umask(0o022), _ready_to_import() as (name, path): + with temp_umask(0o022), ready_to_import() as (name, path): cached_path = importlib.util.cache_from_source(path) os.chmod(path, mode) __import__(name) @@ -600,7 +580,7 @@ def test_cached_readonly(self): def test_pyc_always_writable(self): # Initially read-only .pyc files on Windows used to cause problems # with later updates, see issue #6074 for details - with _ready_to_import() as (name, path): + with ready_to_import() as (name, path): # Write a Python file, make it read-only and import it with open(path, 'w', encoding='utf-8') as f: f.write("x = 'original'\n") diff --git a/mingw32/lib/python3.11/test/test_importlib/test_locks.py b/mingw32/lib/python3.11/test/test_importlib/test_locks.py index 56d73c496e6..5549d5448ba 100644 --- a/mingw32/lib/python3.11/test/test_importlib/test_locks.py +++ b/mingw32/lib/python3.11/test/test_importlib/test_locks.py @@ -29,6 +29,8 @@ class ModuleLockAsRLockTests: test_timeout = None # _release_save() unsupported test_release_save_unacquired = None + # _recursion_count() unsupported + test_recursion_count = None # lock status in repr unsupported test_repr = None test_locked_repr = None diff --git a/mingw32/lib/python3.11/test/test_inspect.py b/mingw32/lib/python3.11/test/test_inspect.py index fb4cba05721..650d56e39c4 100644 --- a/mingw32/lib/python3.11/test/test_inspect.py +++ b/mingw32/lib/python3.11/test/test_inspect.py @@ -27,7 +27,7 @@ from test.support import cpython_only from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ -from test.support.import_helper import DirsOnSysPath +from test.support.import_helper import DirsOnSysPath, ready_to_import from test.support.os_helper import TESTFN from test.support.script_helper import assert_python_ok, assert_python_failure from test import inspect_fodder as mod @@ -37,8 +37,6 @@ from test import inspect_stringized_annotations from test import inspect_stringized_annotations_2 -from test.test_import import _ready_to_import - # Functions tested in this suite: # ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode, @@ -4353,7 +4351,7 @@ def func(*args, **kwargs): def test_base_class_have_text_signature(self): # see issue 43118 - from test.ann_module7 import BufferedReader + from test.typinganndata.ann_module7 import BufferedReader class MyBufferedReader(BufferedReader): """buffer reader class.""" @@ -4505,7 +4503,7 @@ def assertInspectEqual(self, path, source): def test_getsource_reload(self): # see issue 1218234 - with _ready_to_import('reload_bug', self.src_before) as (name, path): + with ready_to_import('reload_bug', self.src_before) as (name, path): module = importlib.import_module(name) self.assertInspectEqual(path, module) with open(path, 'w', encoding='utf-8') as src: diff --git a/mingw32/lib/python3.11/test/test_io.py b/mingw32/lib/python3.11/test/test_io.py index 79aa2da5862..e54a13c2d84 100644 --- a/mingw32/lib/python3.11/test/test_io.py +++ b/mingw32/lib/python3.11/test/test_io.py @@ -1459,8 +1459,8 @@ def test_read_all(self): self.assertEqual(b"abcdefg", bufio.read()) - @support.requires_resource('cpu') @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threads(self): try: # Write out many bytes with exactly the same number of 0's, @@ -1834,8 +1834,8 @@ def test_truncate_after_write(self): f.truncate() self.assertEqual(f.tell(), buffer_size + 2) - @support.requires_resource('cpu') @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threads(self): try: # Write out many bytes from many threads and test they were @@ -4380,10 +4380,12 @@ def run(): self.assertFalse(err.strip('.!')) @threading_helper.requires_working_threading() + @support.requires_resource('walltime') def test_daemon_threads_shutdown_stdout_deadlock(self): self.check_daemon_threads_shutdown_deadlock('stdout') @threading_helper.requires_working_threading() + @support.requires_resource('walltime') def test_daemon_threads_shutdown_stderr_deadlock(self): self.check_daemon_threads_shutdown_deadlock('stderr') @@ -4557,11 +4559,13 @@ def alarm_handler(sig, frame): os.close(r) @requires_alarm + @support.requires_resource('walltime') def test_interrupted_read_retry_buffered(self): self.check_interrupted_read_retry(lambda x: x.decode('latin1'), mode="rb") @requires_alarm + @support.requires_resource('walltime') def test_interrupted_read_retry_text(self): self.check_interrupted_read_retry(lambda x: x, mode="r", encoding="latin1") @@ -4635,10 +4639,12 @@ def alarm2(sig, frame): raise @requires_alarm + @support.requires_resource('walltime') def test_interrupted_write_retry_buffered(self): self.check_interrupted_write_retry(b"x", mode="wb") @requires_alarm + @support.requires_resource('walltime') def test_interrupted_write_retry_text(self): self.check_interrupted_write_retry("x", mode="w", encoding="latin1") diff --git a/mingw32/lib/python3.11/test/test_itertools.py b/mingw32/lib/python3.11/test/test_itertools.py index 311c2a3288d..0d0030e4160 100644 --- a/mingw32/lib/python3.11/test/test_itertools.py +++ b/mingw32/lib/python3.11/test/test_itertools.py @@ -2229,6 +2229,7 @@ def gen2(x): self.assertEqual(hist, [0,1]) @support.skip_if_pgo_task + @support.requires_resource('cpu') def test_long_chain_of_empty_iterables(self): # Make sure itertools.chain doesn't run into recursion limits when # dealing with long chains of empty iterables. Even with a high diff --git a/mingw32/lib/python3.11/test/test_largefile.py b/mingw32/lib/python3.11/test/test_largefile.py index 3c11c59baef..3b0930fe69e 100644 --- a/mingw32/lib/python3.11/test/test_largefile.py +++ b/mingw32/lib/python3.11/test/test_largefile.py @@ -8,7 +8,7 @@ import socket import shutil import threading -from test.support import requires, bigmemtest +from test.support import requires, bigmemtest, requires_resource from test.support import SHORT_TIMEOUT from test.support import socket_helper from test.support.os_helper import TESTFN, unlink @@ -173,6 +173,7 @@ class TestCopyfile(LargeFileTest, unittest.TestCase): # Exact required disk space would be (size * 2), but let's give it a # bit more tolerance. @skip_no_disk_space(TESTFN, size * 2.5) + @requires_resource('cpu') def test_it(self): # Internally shutil.copyfile() can use "fast copy" methods like # os.sendfile(). @@ -222,6 +223,7 @@ def run(sock): # Exact required disk space would be (size * 2), but let's give it a # bit more tolerance. @skip_no_disk_space(TESTFN, size * 2.5) + @requires_resource('cpu') def test_it(self): port = socket_helper.find_unused_port() with socket.create_server(("", port)) as sock: diff --git a/mingw32/lib/python3.11/test/test_logging.py b/mingw32/lib/python3.11/test/test_logging.py index f1f2b75fef8..55c5cd56581 100644 --- a/mingw32/lib/python3.11/test/test_logging.py +++ b/mingw32/lib/python3.11/test/test_logging.py @@ -631,6 +631,7 @@ def test_path_objects(self): support.is_emscripten, "Emscripten cannot fstat unlinked files." ) @threading_helper.requires_working_threading() + @support.requires_resource('walltime') def test_race(self): # Issue #14632 refers. def remove_loop(fname, tries): diff --git a/mingw32/lib/python3.11/test/test_lzma.py b/mingw32/lib/python3.11/test/test_lzma.py index 145c8cfced4..49042d7390b 100644 --- a/mingw32/lib/python3.11/test/test_lzma.py +++ b/mingw32/lib/python3.11/test/test_lzma.py @@ -352,10 +352,10 @@ def test_compressor_bigmem(self, size): @bigmemtest(size=_4G + 100, memuse=3) def test_decompressor_bigmem(self, size): lzd = LZMADecompressor() - blocksize = 10 * 1024 * 1024 + blocksize = min(10 * 1024 * 1024, size) block = random.randbytes(blocksize) try: - input = block * (size // blocksize + 1) + input = block * ((size-1) // blocksize + 1) cdata = lzma.compress(input) ddata = lzd.decompress(cdata) self.assertEqual(ddata, input) diff --git a/mingw32/lib/python3.11/test/test_mailcap.py b/mingw32/lib/python3.11/test/test_mailcap.py index 8185f4a7806..e80e34063b2 100644 --- a/mingw32/lib/python3.11/test/test_mailcap.py +++ b/mingw32/lib/python3.11/test/test_mailcap.py @@ -128,7 +128,6 @@ def test_subst(self): (["", "audio/*", "foo.txt"], ""), (["echo foo", "audio/*", "foo.txt"], "echo foo"), (["echo %s", "audio/*", "foo.txt"], "echo foo.txt"), - (["echo %t", "audio/*", "foo.txt"], None), (["echo %t", "audio/wav", "foo.txt"], "echo audio/wav"), (["echo \\%t", "audio/*", "foo.txt"], "echo %t"), (["echo foo", "audio/*", "foo.txt", plist], "echo foo"), @@ -211,9 +210,6 @@ def test_findmatch(self): ([c, "audio/basic"], {"key": "description", "filename": fname}, ('"An audio fragment"', audio_basic_entry)), - ([c, "audio/*"], - {"filename": fname}, - (None, None)), ([c, "audio/wav"], {"filename": fname}, ("/usr/local/bin/showaudio audio/wav", audio_entry)), @@ -246,6 +242,30 @@ def test_test(self): ] self._run_cases(cases) + def test_unsafe_mailcap_input(self): + with self.assertWarnsRegex(mailcap.UnsafeMailcapInput, + 'Refusing to substitute parameter.*' + 'into a shell command'): + unsafe_param = mailcap.subst("echo %{total}", + "audio/wav", + "foo.txt", + ["total=*"]) + self.assertEqual(unsafe_param, None) + + with self.assertWarnsRegex(mailcap.UnsafeMailcapInput, + 'Refusing to substitute MIME type' + '.*into a shell'): + unsafe_mimetype = mailcap.subst("echo %t", "audio/*", "foo.txt") + self.assertEqual(unsafe_mimetype, None) + + with self.assertWarnsRegex(mailcap.UnsafeMailcapInput, + 'Refusing to use mailcap with filename.*' + 'Use a safe temporary filename.'): + unsafe_filename = mailcap.findmatch(MAILCAPDICT, + "audio/wav", + filename="foo*.txt") + self.assertEqual(unsafe_filename, (None, None)) + def _run_cases(self, cases): for c in cases: self.assertEqual(mailcap.findmatch(*c[0], **c[1]), c[2]) diff --git a/mingw32/lib/python3.11/test/test_mmap.py b/mingw32/lib/python3.11/test/test_mmap.py index bab86860089..dfcf3039422 100644 --- a/mingw32/lib/python3.11/test/test_mmap.py +++ b/mingw32/lib/python3.11/test/test_mmap.py @@ -255,10 +255,15 @@ def test_access_parameter(self): # Try writing with PROT_EXEC and without PROT_WRITE prot = mmap.PROT_READ | getattr(mmap, 'PROT_EXEC', 0) with open(TESTFN, "r+b") as f: - m = mmap.mmap(f.fileno(), mapsize, prot=prot) - self.assertRaises(TypeError, m.write, b"abcdef") - self.assertRaises(TypeError, m.write_byte, 0) - m.close() + try: + m = mmap.mmap(f.fileno(), mapsize, prot=prot) + except PermissionError: + # on macOS 14, PROT_READ | PROT_EXEC is not allowed + pass + else: + self.assertRaises(TypeError, m.write, b"abcdef") + self.assertRaises(TypeError, m.write_byte, 0) + m.close() def test_bad_file_desc(self): # Try opening a bad file descriptor... diff --git a/mingw32/lib/python3.11/test/test_module/__init__.py b/mingw32/lib/python3.11/test/test_module/__init__.py index 87d1a8e3d6c..c2bca45bb60 100644 --- a/mingw32/lib/python3.11/test/test_module/__init__.py +++ b/mingw32/lib/python3.11/test/test_module/__init__.py @@ -326,7 +326,9 @@ def test_annotations_getset_raises(self): del foo.__annotations__ def test_annotations_are_created_correctly(self): - ann_module4 = import_helper.import_fresh_module('test.ann_module4') + ann_module4 = import_helper.import_fresh_module( + 'test.typinganndata.ann_module4', + ) self.assertTrue("__annotations__" in ann_module4.__dict__) del ann_module4.__annotations__ self.assertFalse("__annotations__" in ann_module4.__dict__) diff --git a/mingw32/lib/python3.11/test/test_multibytecodec.py b/mingw32/lib/python3.11/test/test_multibytecodec.py index cf8bb5e3a05..6451df14696 100644 --- a/mingw32/lib/python3.11/test/test_multibytecodec.py +++ b/mingw32/lib/python3.11/test/test_multibytecodec.py @@ -363,6 +363,7 @@ def test_iso2022_jp_g0(self): e = '\u3406'.encode(encoding) self.assertFalse(any(x > 0x80 for x in e)) + @support.requires_resource('cpu') def test_bug1572832(self): for x in range(0x10000, 0x110000): # Any ISO 2022 codec will cause the segfault diff --git a/mingw32/lib/python3.11/test/test_multiprocessing_fork.py b/mingw32/lib/python3.11/test/test_multiprocessing_fork.py deleted file mode 100644 index 5000edb7c5c..00000000000 --- a/mingw32/lib/python3.11/test/test_multiprocessing_fork.py +++ /dev/null @@ -1,19 +0,0 @@ -import unittest -import test._test_multiprocessing - -import sys -from test import support - -if support.PGO: - raise unittest.SkipTest("test is not helpful for PGO") - -if sys.platform == "win32": - raise unittest.SkipTest("fork is not available on Windows") - -if sys.platform == 'darwin': - raise unittest.SkipTest("test may crash on macOS (bpo-33725)") - -test._test_multiprocessing.install_tests_in_module_dict(globals(), 'fork') - -if __name__ == '__main__': - unittest.main() diff --git a/mingw32/lib/python3.11/test/test_multiprocessing_forkserver.py b/mingw32/lib/python3.11/test/test_multiprocessing_forkserver.py deleted file mode 100644 index 6ad5faf9e8a..00000000000 --- a/mingw32/lib/python3.11/test/test_multiprocessing_forkserver.py +++ /dev/null @@ -1,16 +0,0 @@ -import unittest -import test._test_multiprocessing - -import sys -from test import support - -if support.PGO: - raise unittest.SkipTest("test is not helpful for PGO") - -if sys.platform == "win32": - raise unittest.SkipTest("forkserver is not available on Windows") - -test._test_multiprocessing.install_tests_in_module_dict(globals(), 'forkserver') - -if __name__ == '__main__': - unittest.main() diff --git a/mingw32/lib/python3.11/test/test_multiprocessing_spawn.py b/mingw32/lib/python3.11/test/test_multiprocessing_spawn.py deleted file mode 100644 index 6558952308f..00000000000 --- a/mingw32/lib/python3.11/test/test_multiprocessing_spawn.py +++ /dev/null @@ -1,12 +0,0 @@ -import unittest -import test._test_multiprocessing - -from test import support - -if support.PGO: - raise unittest.SkipTest("test is not helpful for PGO") - -test._test_multiprocessing.install_tests_in_module_dict(globals(), 'spawn') - -if __name__ == '__main__': - unittest.main() diff --git a/mingw32/lib/python3.11/test/test_netrc.py b/mingw32/lib/python3.11/test/test_netrc.py index 573d636de95..81e11a293cc 100644 --- a/mingw32/lib/python3.11/test/test_netrc.py +++ b/mingw32/lib/python3.11/test/test_netrc.py @@ -1,5 +1,5 @@ import netrc, os, unittest, sys, textwrap -from test.support import os_helper, run_unittest +from test.support import os_helper try: import pwd @@ -308,8 +308,6 @@ def test_security(self): self.assertEqual(nrc.hosts['foo.domain.com'], ('anonymous', '', 'pass')) -def test_main(): - run_unittest(NetrcTestCase) if __name__ == "__main__": - test_main() + unittest.main() diff --git a/mingw32/lib/python3.11/test/test_opcodes.py b/mingw32/lib/python3.11/test/test_opcodes.py index e880c3f1ac8..72488b2bb6b 100644 --- a/mingw32/lib/python3.11/test/test_opcodes.py +++ b/mingw32/lib/python3.11/test/test_opcodes.py @@ -1,7 +1,8 @@ # Python test set -- part 2, opcodes import unittest -from test import ann_module, support +from test import support +from test.typinganndata import ann_module class OpcodeTest(unittest.TestCase): diff --git a/mingw32/lib/python3.11/test/test_os.py b/mingw32/lib/python3.11/test/test_os.py index aa414ca1488..1e1980e3ac4 100644 --- a/mingw32/lib/python3.11/test/test_os.py +++ b/mingw32/lib/python3.11/test/test_os.py @@ -726,7 +726,7 @@ def test_access_denied(self): # denied. See issue 28075. # os.environ['TEMP'] should be located on a volume that # supports file ACLs. - fname = os.path.join(os.environ['TEMP'], self.fname) + fname = os.path.join(os.environ['TEMP'], self.fname + "_access") self.addCleanup(os_helper.unlink, fname) create_file(fname, b'ABC') # Deny the right to [S]YNCHRONIZE on the file to diff --git a/mingw32/lib/python3.11/test/test_pdb.py b/mingw32/lib/python3.11/test/test_pdb.py index 4f4a5692280..22fc2b35819 100644 --- a/mingw32/lib/python3.11/test/test_pdb.py +++ b/mingw32/lib/python3.11/test/test_pdb.py @@ -640,8 +640,10 @@ def test_pdb_alias_command(): ... o.method() >>> with PdbTestInput([ # doctest: +ELLIPSIS + ... 'alias pi', ... 'alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}")', ... 'alias ps pi self', + ... 'alias ps', ... 'pi o', ... 's', ... 'ps', @@ -650,8 +652,12 @@ def test_pdb_alias_command(): ... test_function() > (4)test_function() -> o.method() + (Pdb) alias pi + *** Unknown alias 'pi' (Pdb) alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}") (Pdb) alias ps pi self + (Pdb) alias ps + ps = pi self (Pdb) pi o o.attr1 = 10 o.attr2 = str diff --git a/mingw32/lib/python3.11/test/test_peepholer.py b/mingw32/lib/python3.11/test/test_peepholer.py index 241644ad7d2..d06a70bd296 100644 --- a/mingw32/lib/python3.11/test/test_peepholer.py +++ b/mingw32/lib/python3.11/test/test_peepholer.py @@ -3,6 +3,7 @@ import textwrap import unittest +from test import support from test.support.bytecode_helper import BytecodeTestCase @@ -523,6 +524,7 @@ def genexpr(): return (y for x in a for y in [f(x)]) self.assertEqual(count_instr_recursively(genexpr, 'FOR_ITER'), 1) + @support.requires_resource('cpu') def test_format_combinations(self): flags = '-+ #0' testcases = [ diff --git a/mingw32/lib/python3.11/test/test_pep646_syntax.py b/mingw32/lib/python3.11/test/test_pep646_syntax.py index 3ffa82dc55f..aac089b190b 100644 --- a/mingw32/lib/python3.11/test/test_pep646_syntax.py +++ b/mingw32/lib/python3.11/test/test_pep646_syntax.py @@ -1,3 +1,6 @@ +import doctest +import unittest + doctests = """ Setup @@ -317,10 +320,10 @@ __test__ = {'doctests' : doctests} -def test_main(verbose=False): - from test import support - from test import test_pep646_syntax - support.run_doctest(test_pep646_syntax, verbose) +def load_tests(loader, tests, pattern): + tests.addTest(doctest.DocTestSuite()) + return tests + if __name__ == "__main__": - test_main(verbose=True) + unittest.main() diff --git a/mingw32/lib/python3.11/test/test_poll.py b/mingw32/lib/python3.11/test/test_poll.py index 02165a0244d..1847ae95db9 100644 --- a/mingw32/lib/python3.11/test/test_poll.py +++ b/mingw32/lib/python3.11/test/test_poll.py @@ -8,7 +8,7 @@ import time import unittest from test.support import ( - cpython_only, requires_subprocess, requires_working_socket + cpython_only, requires_subprocess, requires_working_socket, requires_resource ) from test.support import threading_helper from test.support.os_helper import TESTFN @@ -124,6 +124,7 @@ def fileno(self): # select(), modified to use poll() instead. @requires_subprocess() + @requires_resource('walltime') def test_poll2(self): cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done' proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, diff --git a/mingw32/lib/python3.11/test/test_pty.py b/mingw32/lib/python3.11/test/test_pty.py index c9c2b42861c..a971f6b0250 100644 --- a/mingw32/lib/python3.11/test/test_pty.py +++ b/mingw32/lib/python3.11/test/test_pty.py @@ -80,17 +80,9 @@ def expectedFailureIfStdinIsTTY(fun): # because pty code is not too portable. class PtyTest(unittest.TestCase): def setUp(self): - old_alarm = signal.signal(signal.SIGALRM, self.handle_sig) - self.addCleanup(signal.signal, signal.SIGALRM, old_alarm) - old_sighup = signal.signal(signal.SIGHUP, self.handle_sighup) self.addCleanup(signal.signal, signal.SIGHUP, old_sighup) - # isatty() and close() can hang on some platforms. Set an alarm - # before running the test to make sure we don't hang forever. - self.addCleanup(signal.alarm, 0) - signal.alarm(10) - # Save original stdin window size. self.stdin_dim = None if _HAVE_WINSZ: @@ -101,9 +93,6 @@ def setUp(self): except tty.error: pass - def handle_sig(self, sig, frame): - self.fail("isatty hung") - @staticmethod def handle_sighup(signum, frame): pass diff --git a/mingw32/lib/python3.11/test/test_py_compile.py b/mingw32/lib/python3.11/test/test_py_compile.py index a4a52b180db..6a54d48eb16 100644 --- a/mingw32/lib/python3.11/test/test_py_compile.py +++ b/mingw32/lib/python3.11/test/test_py_compile.py @@ -132,7 +132,9 @@ def test_exceptions_propagate(self): os.chmod(self.directory, mode.st_mode) def test_bad_coding(self): - bad_coding = os.path.join(os.path.dirname(__file__), 'bad_coding2.py') + bad_coding = os.path.join(os.path.dirname(__file__), + 'tokenizedata', + 'bad_coding2.py') with support.captured_stderr(): self.assertIsNone(py_compile.compile(bad_coding, doraise=False)) self.assertFalse(os.path.exists( @@ -195,7 +197,9 @@ def test_invalidation_mode(self): self.assertEqual(flags, 0b1) def test_quiet(self): - bad_coding = os.path.join(os.path.dirname(__file__), 'bad_coding2.py') + bad_coding = os.path.join(os.path.dirname(__file__), + 'tokenizedata', + 'bad_coding2.py') with support.captured_stderr() as stderr: self.assertIsNone(py_compile.compile(bad_coding, doraise=False, quiet=2)) self.assertIsNone(py_compile.compile(bad_coding, doraise=True, quiet=2)) @@ -259,14 +263,18 @@ def test_with_files(self): self.assertTrue(os.path.exists(self.cache_path)) def test_bad_syntax(self): - bad_syntax = os.path.join(os.path.dirname(__file__), 'badsyntax_3131.py') + bad_syntax = os.path.join(os.path.dirname(__file__), + 'tokenizedata', + 'badsyntax_3131.py') rc, stdout, stderr = self.pycompilecmd_failure(bad_syntax) self.assertEqual(rc, 1) self.assertEqual(stdout, b'') self.assertIn(b'SyntaxError', stderr) def test_bad_syntax_with_quiet(self): - bad_syntax = os.path.join(os.path.dirname(__file__), 'badsyntax_3131.py') + bad_syntax = os.path.join(os.path.dirname(__file__), + 'tokenizedata', + 'badsyntax_3131.py') rc, stdout, stderr = self.pycompilecmd_failure('-q', bad_syntax) self.assertEqual(rc, 1) self.assertEqual(stdout, b'') diff --git a/mingw32/lib/python3.11/test/test_pyexpat.py b/mingw32/lib/python3.11/test/test_pyexpat.py index 6f0441b66d9..fa19c0ad9ee 100644 --- a/mingw32/lib/python3.11/test/test_pyexpat.py +++ b/mingw32/lib/python3.11/test/test_pyexpat.py @@ -1,13 +1,15 @@ # XXX TypeErrors on calling handlers, or on bad return values from a # handler, are obscure and unhelpful. -from io import BytesIO import os import platform import sys import sysconfig import unittest import traceback +from io import BytesIO +from test import support +from test.support import os_helper from xml.parsers import expat from xml.parsers.expat import errors @@ -441,37 +443,59 @@ def test7(self): # Test handling of exception from callback: class HandlerExceptionTest(unittest.TestCase): def StartElementHandler(self, name, attrs): - raise RuntimeError(name) + raise RuntimeError(f'StartElementHandler: <{name}>') def check_traceback_entry(self, entry, filename, funcname): - self.assertEqual(os.path.basename(entry[0]), filename) - self.assertEqual(entry[2], funcname) + self.assertEqual(os.path.basename(entry.filename), filename) + self.assertEqual(entry.name, funcname) + @support.cpython_only def test_exception(self): + # gh-66652: test _PyTraceback_Add() used by pyexpat.c to inject frames + + # Change the current directory to the Python source code directory + # if it is available. + src_dir = sysconfig.get_config_var('abs_builddir') + if src_dir: + have_source = os.path.isdir(src_dir) + else: + have_source = False + if have_source: + with os_helper.change_cwd(src_dir): + self._test_exception(have_source) + else: + self._test_exception(have_source) + + def _test_exception(self, have_source): + # Use path relative to the current directory which should be the Python + # source code directory (if it is available). + PYEXPAT_C = os.path.join('Modules', 'pyexpat.c') + parser = expat.ParserCreate() parser.StartElementHandler = self.StartElementHandler try: parser.Parse(b"", True) - self.fail() - except RuntimeError as e: - self.assertEqual(e.args[0], 'a', - "Expected RuntimeError for element 'a', but" + \ - " found %r" % e.args[0]) - # Check that the traceback contains the relevant line in pyexpat.c - entries = traceback.extract_tb(e.__traceback__) - self.assertEqual(len(entries), 3) - self.check_traceback_entry(entries[0], - "test_pyexpat.py", "test_exception") - self.check_traceback_entry(entries[1], - "pyexpat.c", "StartElement") - self.check_traceback_entry(entries[2], - "test_pyexpat.py", "StartElementHandler") - if (sysconfig.is_python_build() - and not (sys.platform == 'win32' and platform.machine() == 'ARM') - and not is_emscripten - and not is_wasi - ): - self.assertIn('call_with_frame("StartElement"', entries[1][3]) + + self.fail("the parser did not raise RuntimeError") + except RuntimeError as exc: + self.assertEqual(exc.args[0], 'StartElementHandler: ', exc) + entries = traceback.extract_tb(exc.__traceback__) + + self.assertEqual(len(entries), 3, entries) + self.check_traceback_entry(entries[0], + "test_pyexpat.py", "_test_exception") + self.check_traceback_entry(entries[1], + os.path.basename(PYEXPAT_C), + "StartElement") + self.check_traceback_entry(entries[2], + "test_pyexpat.py", "StartElementHandler") + + # Check that the traceback contains the relevant line in + # Modules/pyexpat.c. Skip the test if Modules/pyexpat.c is not + # available. + if have_source and os.path.exists(PYEXPAT_C): + self.assertIn('call_with_frame("StartElement"', + entries[1].line) # Test Current* members: diff --git a/mingw32/lib/python3.11/test/test_regrtest.py b/mingw32/lib/python3.11/test/test_regrtest.py index 78552590a72..88c59b79dd5 100644 --- a/mingw32/lib/python3.11/test/test_regrtest.py +++ b/mingw32/lib/python3.11/test/test_regrtest.py @@ -20,7 +20,7 @@ import unittest from test import libregrtest from test import support -from test.support import os_helper +from test.support import os_helper, TestStats from test.libregrtest import utils, setup if not support.has_subprocess_support: @@ -411,7 +411,9 @@ def regex_search(self, regex, output): self.fail("%r not found in %r" % (regex, output)) return match - def check_line(self, output, regex): + def check_line(self, output, regex, full=False): + if full: + regex += '\n' regex = re.compile(r'^' + regex, re.MULTILINE) self.assertRegex(output, regex) @@ -423,21 +425,27 @@ def parse_executed_tests(self, output): def check_executed_tests(self, output, tests, skipped=(), failed=(), env_changed=(), omitted=(), - rerun={}, no_test_ran=(), + rerun={}, run_no_tests=(), + resource_denied=(), randomize=False, interrupted=False, - fail_env_changed=False): + fail_env_changed=False, + *, stats): if isinstance(tests, str): tests = [tests] if isinstance(skipped, str): skipped = [skipped] + if isinstance(resource_denied, str): + resource_denied = [resource_denied] if isinstance(failed, str): failed = [failed] if isinstance(env_changed, str): env_changed = [env_changed] if isinstance(omitted, str): omitted = [omitted] - if isinstance(no_test_ran, str): - no_test_ran = [no_test_ran] + if isinstance(run_no_tests, str): + run_no_tests = [run_no_tests] + if isinstance(stats, int): + stats = TestStats(stats) executed = self.parse_executed_tests(output) if randomize: @@ -481,12 +489,12 @@ def list_regex(line_format, tests): regex = LOG_PREFIX + f"Re-running {name} in verbose mode \\(matching: {match}\\)" self.check_line(output, regex) - if no_test_ran: - regex = list_regex('%s test%s run no tests', no_test_ran) + if run_no_tests: + regex = list_regex('%s test%s run no tests', run_no_tests) self.check_line(output, regex) good = (len(tests) - len(skipped) - len(failed) - - len(omitted) - len(env_changed) - len(no_test_ran)) + - len(omitted) - len(env_changed) - len(run_no_tests)) if good: regex = r'%s test%s OK\.$' % (good, plural(good)) if not skipped and not failed and good > 1: @@ -496,6 +504,33 @@ def list_regex(line_format, tests): if interrupted: self.check_line(output, 'Test suite interrupted by signal SIGINT.') + # Total tests + parts = [f'run={stats.tests_run:,}'] + if stats.failures: + parts.append(f'failures={stats.failures:,}') + if stats.skipped: + parts.append(f'skipped={stats.skipped:,}') + line = fr'Total tests: {" ".join(parts)}' + self.check_line(output, line, full=True) + + # Total test files + report = [f'success={good}'] + if failed: + report.append(f'failed={len(failed)}') + if env_changed: + report.append(f'env_changed={len(env_changed)}') + if skipped: + report.append(f'skipped={len(skipped)}') + if resource_denied: + report.append(f'resource_denied={len(resource_denied)}') + if rerun: + report.append(f'rerun={len(rerun)}') + if run_no_tests: + report.append(f'run_no_tests={len(run_no_tests)}') + line = fr'Total test files: {" ".join(report)}' + self.check_line(output, line, full=True) + + # Result result = [] if failed: result.append('FAILURE') @@ -505,15 +540,13 @@ def list_regex(line_format, tests): result.append('INTERRUPTED') if not any((good, result, failed, interrupted, skipped, env_changed, fail_env_changed)): - result.append("NO TEST RUN") + result.append("NO TESTS RAN") elif not result: result.append('SUCCESS') result = ', '.join(result) if rerun: - self.check_line(output, 'Tests result: FAILURE') result = 'FAILURE then %s' % result - - self.check_line(output, 'Tests result: %s' % result) + self.check_line(output, f'Result: {result}', full=True) def parse_random_seed(self, output): match = self.regex_search(r'Using random seed ([0-9]+)', output) @@ -602,7 +635,8 @@ def setUp(self): def check_output(self, output): self.parse_random_seed(output) - self.check_executed_tests(output, self.tests, randomize=True) + self.check_executed_tests(output, self.tests, + randomize=True, stats=len(self.tests)) def run_tests(self, args): output = self.run_python(args) @@ -715,8 +749,9 @@ def test_failing(self): test_failing = self.create_test('failing', code=code) tests = [test_ok, test_failing] - output = self.run_tests(*tests, exitcode=2) - self.check_executed_tests(output, tests, failed=test_failing) + output = self.run_tests(*tests, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, tests, failed=test_failing, + stats=TestStats(2, 1)) def test_resources(self): # test -u command line option @@ -735,17 +770,21 @@ def test_pass(self): # -u all: 2 resources enabled output = self.run_tests('-u', 'all', *test_names) - self.check_executed_tests(output, test_names) + self.check_executed_tests(output, test_names, stats=2) # -u audio: 1 resource enabled output = self.run_tests('-uaudio', *test_names) self.check_executed_tests(output, test_names, - skipped=tests['network']) + skipped=tests['network'], + resource_denied=tests['network'], + stats=1) # no option: 0 resources enabled output = self.run_tests(*test_names) self.check_executed_tests(output, test_names, - skipped=test_names) + skipped=test_names, + resource_denied=test_names, + stats=0) def test_random(self): # test -r and --randseed command line option @@ -756,13 +795,14 @@ def test_random(self): test = self.create_test('random', code) # first run to get the output with the random seed - output = self.run_tests('-r', test) + output = self.run_tests('-r', test, exitcode=EXITCODE_NO_TESTS_RAN) randseed = self.parse_random_seed(output) match = self.regex_search(r'TESTRANDOM: ([0-9]+)', output) test_random = int(match.group(1)) # try to reproduce with the random seed - output = self.run_tests('-r', '--randseed=%s' % randseed, test) + output = self.run_tests('-r', '--randseed=%s' % randseed, test, + exitcode=EXITCODE_NO_TESTS_RAN) randseed2 = self.parse_random_seed(output) self.assertEqual(randseed2, randseed) @@ -792,7 +832,8 @@ def test_fromfile(self): previous = name output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + stats = len(tests) + self.check_executed_tests(output, tests, stats=stats) # test format '[2/7] test_opcodes' with open(filename, "w") as fp: @@ -800,7 +841,7 @@ def test_fromfile(self): print("[%s/%s] %s" % (index, len(tests), name), file=fp) output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=stats) # test format 'test_opcodes' with open(filename, "w") as fp: @@ -808,7 +849,7 @@ def test_fromfile(self): print(name, file=fp) output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=stats) # test format 'Lib/test/test_opcodes.py' with open(filename, "w") as fp: @@ -816,20 +857,20 @@ def test_fromfile(self): print('Lib/test/%s.py' % name, file=fp) output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=stats) def test_interrupted(self): code = TEST_INTERRUPTED test = self.create_test('sigint', code=code) - output = self.run_tests(test, exitcode=130) + output = self.run_tests(test, exitcode=EXITCODE_INTERRUPTED) self.check_executed_tests(output, test, omitted=test, - interrupted=True) + interrupted=True, stats=0) def test_slowest(self): # test --slowest tests = [self.create_test() for index in range(3)] output = self.run_tests("--slowest", *tests) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=len(tests)) regex = ('10 slowest tests:\n' '(?:- %s: .*\n){%s}' % (self.TESTNAME_REGEX, len(tests))) @@ -846,9 +887,10 @@ def test_slowest_interrupted(self): args = ("--slowest", "-j2", test) else: args = ("--slowest", test) - output = self.run_tests(*args, exitcode=130) + output = self.run_tests(*args, exitcode=EXITCODE_INTERRUPTED) self.check_executed_tests(output, test, - omitted=test, interrupted=True) + omitted=test, interrupted=True, + stats=0) regex = ('10 slowest tests:\n') self.check_line(output, regex) @@ -857,7 +899,7 @@ def test_coverage(self): # test --coverage test = self.create_test('coverage') output = self.run_tests("--coverage", test) - self.check_executed_tests(output, [test]) + self.check_executed_tests(output, [test], stats=1) regex = (r'lines +cov% +module +\(path\)\n' r'(?: *[0-9]+ *[0-9]{1,2}% *[^ ]+ +\([^)]+\)+)+') self.check_line(output, regex) @@ -886,8 +928,9 @@ def test_run(self): builtins.__dict__['RUN'] = 1 """) test = self.create_test('forever', code=code) - output = self.run_tests('--forever', test, exitcode=2) - self.check_executed_tests(output, [test]*3, failed=test) + output = self.run_tests('--forever', test, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, [test]*3, failed=test, + stats=TestStats(1, 1)) def check_leak(self, code, what): test = self.create_test('huntrleaks', code=code) @@ -895,9 +938,9 @@ def check_leak(self, code, what): filename = 'reflog.txt' self.addCleanup(os_helper.unlink, filename) output = self.run_tests('--huntrleaks', '3:3:', test, - exitcode=2, + exitcode=EXITCODE_BAD_TEST, stderr=subprocess.STDOUT) - self.check_executed_tests(output, [test], failed=test) + self.check_executed_tests(output, [test], failed=test, stats=1) line = 'beginning 6 repetitions\n123456\n......\n' self.check_line(output, re.escape(line)) @@ -977,9 +1020,9 @@ def test_crashed(self): crash_test = self.create_test(name="crash", code=code) tests = [crash_test] - output = self.run_tests("-j2", *tests, exitcode=2) + output = self.run_tests("-j2", *tests, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, tests, failed=crash_test, - randomize=True) + randomize=True, stats=0) def parse_methods(self, output): regex = re.compile("^(test[^ ]+).*ok$", flags=re.MULTILINE) @@ -1074,12 +1117,14 @@ def test_env_changed(self): # don't fail by default output = self.run_tests(testname) - self.check_executed_tests(output, [testname], env_changed=testname) + self.check_executed_tests(output, [testname], + env_changed=testname, stats=1) # fail with --fail-env-changed - output = self.run_tests("--fail-env-changed", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=testname, - fail_env_changed=True) + fail_env_changed=True, stats=1) def test_rerun_fail(self): # FAILURE then FAILURE @@ -1096,9 +1141,11 @@ def test_fail_always(self): """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=2) + output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [testname], - failed=testname, rerun={testname: "test_fail_always"}) + failed=testname, + rerun={testname: "test_fail_always"}, + stats=TestStats(1, 1)) def test_rerun_success(self): # FAILURE then SUCCESS @@ -1119,7 +1166,8 @@ def test_fail_once(self): output = self.run_tests("-w", testname, exitcode=0) self.check_executed_tests(output, [testname], - rerun={testname: "test_fail_once"}) + rerun={testname: "test_fail_once"}, + stats=1) def test_rerun_setup_class_hook_failure(self): # FAILURE then FAILURE @@ -1139,7 +1187,8 @@ def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "ExampleTests"}) + rerun={testname: "ExampleTests"}, + stats=0) def test_rerun_teardown_class_hook_failure(self): # FAILURE then FAILURE @@ -1159,7 +1208,8 @@ def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "ExampleTests"}) + rerun={testname: "ExampleTests"}, + stats=1) def test_rerun_setup_module_hook_failure(self): # FAILURE then FAILURE @@ -1178,7 +1228,8 @@ def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: testname}) + rerun={testname: testname}, + stats=0) def test_rerun_teardown_module_hook_failure(self): # FAILURE then FAILURE @@ -1197,7 +1248,8 @@ def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: testname}) + rerun={testname: testname}, + stats=1) def test_rerun_setup_hook_failure(self): # FAILURE then FAILURE @@ -1216,7 +1268,8 @@ def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "test_success"}) + rerun={testname: "test_success"}, + stats=1) def test_rerun_teardown_hook_failure(self): # FAILURE then FAILURE @@ -1235,7 +1288,8 @@ def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "test_success"}) + rerun={testname: "test_success"}, + stats=1) def test_rerun_async_setup_hook_failure(self): # FAILURE then FAILURE @@ -1254,7 +1308,8 @@ async def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "test_success"}) + rerun={testname: "test_success"}, + stats=1) def test_rerun_async_teardown_hook_failure(self): # FAILURE then FAILURE @@ -1273,7 +1328,8 @@ async def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "test_success"}) + rerun={testname: "test_success"}, + stats=1) def test_no_tests_ran(self): code = textwrap.dedent(""" @@ -1285,8 +1341,11 @@ def test_bug(self): """) testname = self.create_test(code=code) - output = self.run_tests(testname, "-m", "nosuchtest", exitcode=0) - self.check_executed_tests(output, [testname], no_test_ran=testname) + output = self.run_tests(testname, "-m", "nosuchtest", + exitcode=EXITCODE_NO_TESTS_RAN) + self.check_executed_tests(output, [testname], + run_no_tests=testname, + stats=0) def test_no_tests_ran_skip(self): code = textwrap.dedent(""" @@ -1298,8 +1357,9 @@ def test_skipped(self): """) testname = self.create_test(code=code) - output = self.run_tests(testname, exitcode=0) - self.check_executed_tests(output, [testname]) + output = self.run_tests(testname) + self.check_executed_tests(output, [testname], + stats=TestStats(1, skipped=1)) def test_no_tests_ran_multiple_tests_nonexistent(self): code = textwrap.dedent(""" @@ -1312,9 +1372,11 @@ def test_bug(self): testname = self.create_test(code=code) testname2 = self.create_test(code=code) - output = self.run_tests(testname, testname2, "-m", "nosuchtest", exitcode=0) + output = self.run_tests(testname, testname2, "-m", "nosuchtest", + exitcode=EXITCODE_NO_TESTS_RAN) self.check_executed_tests(output, [testname, testname2], - no_test_ran=[testname, testname2]) + run_no_tests=[testname, testname2], + stats=0) def test_no_test_ran_some_test_exist_some_not(self): code = textwrap.dedent(""" @@ -1337,7 +1399,8 @@ def test_other_bug(self): output = self.run_tests(testname, testname2, "-m", "nosuchtest", "-m", "test_other_bug", exitcode=0) self.check_executed_tests(output, [testname, testname2], - no_test_ran=[testname]) + run_no_tests=[testname], + stats=1) @support.cpython_only def test_uncollectable(self): @@ -1360,10 +1423,12 @@ def test_garbage(self): """) testname = self.create_test(code=code) - output = self.run_tests("--fail-env-changed", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) def test_multiprocessing_timeout(self): code = textwrap.dedent(r""" @@ -1386,9 +1451,10 @@ def test_sleep(self): """) testname = self.create_test(code=code) - output = self.run_tests("-j2", "--timeout=1.0", testname, exitcode=2) + output = self.run_tests("-j2", "--timeout=1.0", testname, + exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [testname], - failed=testname) + failed=testname, stats=0) self.assertRegex(output, re.compile('%s timed out' % testname, re.MULTILINE)) @@ -1418,10 +1484,12 @@ def test_unraisable_exc(self): """) testname = self.create_test(code=code) - output = self.run_tests("--fail-env-changed", "-v", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", "-v", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) self.assertIn("Warning -- Unraisable exception", output) self.assertIn("Exception: weakref callback bug", output) @@ -1449,10 +1517,12 @@ def test_threading_excepthook(self): """) testname = self.create_test(code=code) - output = self.run_tests("--fail-env-changed", "-v", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", "-v", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) self.assertIn("Warning -- Uncaught thread exception", output) self.assertIn("Exception: bug in thread", output) @@ -1490,10 +1560,11 @@ def test_print_warning(self): for option in ("-v", "-W"): with self.subTest(option=option): cmd = ["--fail-env-changed", option, testname] - output = self.run_tests(*cmd, exitcode=3) + output = self.run_tests(*cmd, exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) self.assertRegex(output, regex) def test_unicode_guard_env(self): @@ -1519,6 +1590,34 @@ def test_cleanup(self): for name in names: self.assertFalse(os.path.exists(name), name) + @unittest.skipIf(support.is_wasi, + 'checking temp files is not implemented on WASI') + def test_leak_tmp_file(self): + code = textwrap.dedent(r""" + import os.path + import tempfile + import unittest + + class FileTests(unittest.TestCase): + def test_leak_tmp_file(self): + filename = os.path.join(tempfile.gettempdir(), 'mytmpfile') + with open(filename, "wb") as fp: + fp.write(b'content') + """) + testnames = [self.create_test(code=code) for _ in range(3)] + + output = self.run_tests("--fail-env-changed", "-v", "-j2", *testnames, + exitcode=EXITCODE_ENV_CHANGED) + self.check_executed_tests(output, testnames, + env_changed=testnames, + fail_env_changed=True, + randomize=True, + stats=len(testnames)) + for testname in testnames: + self.assertIn(f"Warning -- {testname} leaked temporary " + f"files (1): mytmpfile", + output) + def test_mp_decode_error(self): # gh-101634: If a worker stdout cannot be decoded, report a failed test # and a non-zero exit code. @@ -1552,7 +1651,47 @@ def test_mp_decode_error(self): exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [testname], failed=[testname], - randomize=True) + randomize=True, + stats=0) + + def test_doctest(self): + code = textwrap.dedent(fr''' + import doctest + import sys + from test import support + + def my_function(): + """ + Pass: + + >>> 1 + 1 + 2 + + Failure: + + >>> 2 + 3 + 23 + >>> 1 + 1 + 11 + + Skipped test (ignored): + + >>> id(1.0) # doctest: +SKIP + 7948648 + """ + + def load_tests(loader, tests, pattern): + tests.addTest(doctest.DocTestSuite()) + return tests + ''') + testname = self.create_test(code=code) + + output = self.run_tests("--fail-env-changed", "-v", "-j1", testname, + exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, [testname], + failed=[testname], + randomize=True, + stats=TestStats(1, 1, 0)) class TestUtils(unittest.TestCase): diff --git a/mingw32/lib/python3.11/test/test_runpy.py b/mingw32/lib/python3.11/test/test_runpy.py index 6aaa288c14e..628c8cae38a 100644 --- a/mingw32/lib/python3.11/test/test_runpy.py +++ b/mingw32/lib/python3.11/test/test_runpy.py @@ -12,7 +12,7 @@ import textwrap import unittest import warnings -from test.support import no_tracing, verbose, requires_subprocess +from test.support import no_tracing, verbose, requires_subprocess, requires_resource from test.support.import_helper import forget, make_legacy_pyc, unload from test.support.os_helper import create_empty_file, temp_dir from test.support.script_helper import make_script, make_zip_script @@ -733,6 +733,7 @@ def test_zipfile_error(self): self._check_import_error(zip_name, msg) @no_tracing + @requires_resource('cpu') def test_main_recursion_error(self): with temp_dir() as script_dir, temp_dir() as dummy_dir: mod_name = '__main__' diff --git a/mingw32/lib/python3.11/test/test_selectors.py b/mingw32/lib/python3.11/test/test_selectors.py index c2db88c2039..31757205ca3 100644 --- a/mingw32/lib/python3.11/test/test_selectors.py +++ b/mingw32/lib/python3.11/test/test_selectors.py @@ -279,6 +279,35 @@ def test_select(self): self.assertEqual([(wr_key, selectors.EVENT_WRITE)], result) + def test_select_read_write(self): + # gh-110038: when a file descriptor is registered for both read and + # write, the two events must be seen on a single call to select(). + s = self.SELECTOR() + self.addCleanup(s.close) + + sock1, sock2 = self.make_socketpair() + sock2.send(b"foo") + my_key = s.register(sock1, selectors.EVENT_READ | selectors.EVENT_WRITE) + + seen_read, seen_write = False, False + result = s.select() + # We get the read and write either in the same result entry or in two + # distinct entries with the same key. + self.assertLessEqual(len(result), 2) + for key, events in result: + self.assertTrue(isinstance(key, selectors.SelectorKey)) + self.assertEqual(key, my_key) + self.assertFalse(events & ~(selectors.EVENT_READ | + selectors.EVENT_WRITE)) + if events & selectors.EVENT_READ: + self.assertFalse(seen_read) + seen_read = True + if events & selectors.EVENT_WRITE: + self.assertFalse(seen_write) + seen_write = True + self.assertTrue(seen_read) + self.assertTrue(seen_write) + def test_context_manager(self): s = self.SELECTOR() self.addCleanup(s.close) @@ -449,6 +478,7 @@ class ScalableSelectorMixIn: # see issue #18963 for why it's skipped on older OS X versions @support.requires_mac_ver(10, 5) @unittest.skipUnless(resource, "Test needs resource module") + @support.requires_resource('cpu') def test_above_fd_setsize(self): # A scalable implementation should have no problem with more than # FD_SETSIZE file descriptors. Since we don't know the value, we just diff --git a/mingw32/lib/python3.11/test/test_signal.py b/mingw32/lib/python3.11/test/test_signal.py index ddd635197a7..f6632896100 100644 --- a/mingw32/lib/python3.11/test/test_signal.py +++ b/mingw32/lib/python3.11/test/test_signal.py @@ -745,6 +745,7 @@ def test_siginterrupt_on(self): interrupted = self.readpipe_interrupted(True) self.assertTrue(interrupted) + @support.requires_resource('walltime') def test_siginterrupt_off(self): # If a signal handler is installed and siginterrupt is called with # a false value for the second argument, when that signal arrives, it diff --git a/mingw32/lib/python3.11/test/test_site.py b/mingw32/lib/python3.11/test/test_site.py index b5dc381a2f3..613e946ba71 100644 --- a/mingw32/lib/python3.11/test/test_site.py +++ b/mingw32/lib/python3.11/test/test_site.py @@ -466,10 +466,10 @@ def test_sitecustomize_executed(self): else: self.fail("sitecustomize not imported automatically") - @test.support.requires_resource('network') - @test.support.system_must_validate_cert @unittest.skipUnless(hasattr(urllib.request, "HTTPSHandler"), 'need SSL support to download license') + @test.support.requires_resource('network') + @test.support.system_must_validate_cert def test_license_exists_at_url(self): # This test is a bit fragile since it depends on the format of the # string displayed by license in the absence of a LICENSE file. @@ -577,7 +577,7 @@ def _create_underpth_exe(self, lines, exe_pth=True): _pth_file = os.path.splitext(exe_file)[0] + '._pth' else: _pth_file = os.path.splitext(dll_file)[0] + '._pth' - with open(_pth_file, 'w') as f: + with open(_pth_file, 'w', encoding='utf8') as f: for line in lines: print(line, file=f) return exe_file @@ -614,7 +614,7 @@ def test_underpth_basic(self): os.path.dirname(exe_file), pth_lines) - output = subprocess.check_output([exe_file, '-c', + output = subprocess.check_output([exe_file, '-X', 'utf8', '-c', 'import sys; print("\\n".join(sys.path) if sys.flags.no_site else "")' ], encoding='utf-8', errors='surrogateescape') actual_sys_path = output.rstrip().split('\n') diff --git a/mingw32/lib/python3.11/test/test_smtpnet.py b/mingw32/lib/python3.11/test/test_smtpnet.py index 72f51cd8d81..2e0dc1aa276 100644 --- a/mingw32/lib/python3.11/test/test_smtpnet.py +++ b/mingw32/lib/python3.11/test/test_smtpnet.py @@ -61,6 +61,7 @@ def test_connect_default_port(self): server.ehlo() server.quit() + @support.requires_resource('walltime') def test_connect_using_sslcontext(self): context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) context.check_hostname = False diff --git a/mingw32/lib/python3.11/test/test_socket.py b/mingw32/lib/python3.11/test/test_socket.py index 13cb2a7945d..af0d2a4e6f6 100644 --- a/mingw32/lib/python3.11/test/test_socket.py +++ b/mingw32/lib/python3.11/test/test_socket.py @@ -5171,6 +5171,7 @@ def mocked_socket_module(self): finally: socket.socket = old_socket + @socket_helper.skip_if_tcp_blackhole def test_connect(self): port = socket_helper.find_unused_port() cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -5179,6 +5180,7 @@ def test_connect(self): cli.connect((HOST, port)) self.assertEqual(cm.exception.errno, errno.ECONNREFUSED) + @socket_helper.skip_if_tcp_blackhole def test_create_connection(self): # Issue #9792: errors raised by create_connection() should have # a proper errno attribute. @@ -6355,12 +6357,16 @@ def test_sha256(self): self.assertEqual(op.recv(512), expected) def test_hmac_sha1(self): - expected = bytes.fromhex("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79") + # gh-109396: In FIPS mode, Linux 6.5 requires a key + # of at least 112 bits. Use a key of 152 bits. + key = b"Python loves AF_ALG" + data = b"what do ya want for nothing?" + expected = bytes.fromhex("193dbb43c6297b47ea6277ec0ce67119a3f3aa66") with self.create_alg('hash', 'hmac(sha1)') as algo: - algo.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, b"Jefe") + algo.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, key) op, _ = algo.accept() with op: - op.sendall(b"what do ya want for nothing?") + op.sendall(data) self.assertEqual(op.recv(512), expected) # Although it should work with 3.19 and newer the test blocks on diff --git a/mingw32/lib/python3.11/test/test_source_encoding.py b/mingw32/lib/python3.11/test/test_source_encoding.py index 5fe0f312444..0c7f8ee861c 100644 --- a/mingw32/lib/python3.11/test/test_source_encoding.py +++ b/mingw32/lib/python3.11/test/test_source_encoding.py @@ -1,7 +1,7 @@ # -*- coding: koi8-r -*- import unittest -from test.support import script_helper, captured_stdout, requires_subprocess +from test.support import script_helper, captured_stdout, requires_subprocess, requires_resource from test.support.os_helper import TESTFN, unlink, rmtree from test.support.import_helper import unload import importlib @@ -69,6 +69,7 @@ def test_issue7820(self): def test_20731(self): sub = subprocess.Popen([sys.executable, os.path.join(os.path.dirname(__file__), + 'tokenizedata', 'coding20731.py')], stderr=subprocess.PIPE) err = sub.communicate()[1] @@ -101,10 +102,10 @@ def test_bad_coding2(self): self.verify_bad_module(module_name) def verify_bad_module(self, module_name): - self.assertRaises(SyntaxError, __import__, 'test.' + module_name) + self.assertRaises(SyntaxError, __import__, 'test.tokenizedata.' + module_name) path = os.path.dirname(__file__) - filename = os.path.join(path, module_name + '.py') + filename = os.path.join(path, 'tokenizedata', module_name + '.py') with open(filename, "rb") as fp: bytes = fp.read() self.assertRaises(SyntaxError, compile, bytes, filename, 'exec') @@ -251,6 +252,7 @@ def test_crcrcrlf2(self): class UTF8ValidatorTest(unittest.TestCase): @unittest.skipIf(not sys.platform.startswith("linux"), "Too slow to run on non-Linux platforms") + @requires_resource('cpu') def test_invalid_utf8(self): # This is a port of test_utf8_decode_invalid_sequences in # test_unicode.py to exercise the separate utf8 validator in diff --git a/mingw32/lib/python3.11/test/test_sqlite3/test_dbapi.py b/mingw32/lib/python3.11/test/test_sqlite3/test_dbapi.py index 899f5cfbd31..ff86291bc57 100644 --- a/mingw32/lib/python3.11/test/test_sqlite3/test_dbapi.py +++ b/mingw32/lib/python3.11/test/test_sqlite3/test_dbapi.py @@ -1837,7 +1837,7 @@ def test_on_conflict_replace(self): @requires_subprocess() class MultiprocessTests(unittest.TestCase): - CONNECTION_TIMEOUT = SHORT_TIMEOUT / 1000. # Defaults to 30 ms + CONNECTION_TIMEOUT = 0 # Disable the busy timeout. def tearDown(self): unlink(TESTFN) diff --git a/mingw32/lib/python3.11/test/test_sqlite3/test_dump.py b/mingw32/lib/python3.11/test/test_sqlite3/test_dump.py index d0c24b9c60e..c3ed3aefef0 100644 --- a/mingw32/lib/python3.11/test/test_sqlite3/test_dump.py +++ b/mingw32/lib/python3.11/test/test_sqlite3/test_dump.py @@ -117,6 +117,26 @@ def __getitem__(self, index): got = list(self.cx.iterdump()) self.assertEqual(expected, got) + def test_dump_virtual_tables(self): + # gh-64662 + expected = [ + "BEGIN TRANSACTION;", + "PRAGMA writable_schema=ON;", + ("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" + "VALUES('table','test','test',0,'CREATE VIRTUAL TABLE test USING fts4(example)');"), + "CREATE TABLE 'test_content'(docid INTEGER PRIMARY KEY, 'c0example');", + "CREATE TABLE 'test_docsize'(docid INTEGER PRIMARY KEY, size BLOB);", + ("CREATE TABLE 'test_segdir'(level INTEGER,idx INTEGER,start_block INTEGER," + "leaves_end_block INTEGER,end_block INTEGER,root BLOB,PRIMARY KEY(level, idx));"), + "CREATE TABLE 'test_segments'(blockid INTEGER PRIMARY KEY, block BLOB);", + "CREATE TABLE 'test_stat'(id INTEGER PRIMARY KEY, value BLOB);", + "PRAGMA writable_schema=OFF;", + "COMMIT;" + ] + self.cu.execute("CREATE VIRTUAL TABLE test USING fts4(example)") + actual = list(self.cx.iterdump()) + self.assertEqual(expected, actual) + if __name__ == "__main__": unittest.main() diff --git a/mingw32/lib/python3.11/test/test_sqlite3/test_factory.py b/mingw32/lib/python3.11/test/test_sqlite3/test_factory.py index 2b70093bd9b..67e81f77add 100644 --- a/mingw32/lib/python3.11/test/test_sqlite3/test_factory.py +++ b/mingw32/lib/python3.11/test/test_sqlite3/test_factory.py @@ -111,6 +111,7 @@ def tearDown(self): class RowFactoryTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") + self.con.row_factory = sqlite.Row def test_custom_factory(self): self.con.row_factory = lambda cur, row: list(row) @@ -118,7 +119,6 @@ def test_custom_factory(self): self.assertIsInstance(row, list) def test_sqlite_row_index(self): - self.con.row_factory = sqlite.Row row = self.con.execute("select 1 as a_1, 2 as b").fetchone() self.assertIsInstance(row, sqlite.Row) @@ -149,7 +149,6 @@ def test_sqlite_row_index(self): row[complex()] # index must be int or string def test_sqlite_row_index_unicode(self): - self.con.row_factory = sqlite.Row row = self.con.execute("select 1 as \xff").fetchone() self.assertEqual(row["\xff"], 1) with self.assertRaises(IndexError): @@ -159,7 +158,6 @@ def test_sqlite_row_index_unicode(self): def test_sqlite_row_slice(self): # A sqlite.Row can be sliced like a list. - self.con.row_factory = sqlite.Row row = self.con.execute("select 1, 2, 3, 4").fetchone() self.assertEqual(row[0:0], ()) self.assertEqual(row[0:1], (1,)) @@ -176,8 +174,7 @@ def test_sqlite_row_slice(self): self.assertEqual(row[3:0:-2], (4, 2)) def test_sqlite_row_iter(self): - """Checks if the row object is iterable""" - self.con.row_factory = sqlite.Row + # Checks if the row object is iterable. row = self.con.execute("select 1 as a, 2 as b").fetchone() # Is iterable in correct order and produces valid results: @@ -189,23 +186,20 @@ def test_sqlite_row_iter(self): self.assertEqual(items, [1, 2]) def test_sqlite_row_as_tuple(self): - """Checks if the row object can be converted to a tuple""" - self.con.row_factory = sqlite.Row + # Checks if the row object can be converted to a tuple. row = self.con.execute("select 1 as a, 2 as b").fetchone() t = tuple(row) self.assertEqual(t, (row['a'], row['b'])) def test_sqlite_row_as_dict(self): - """Checks if the row object can be correctly converted to a dictionary""" - self.con.row_factory = sqlite.Row + # Checks if the row object can be correctly converted to a dictionary. row = self.con.execute("select 1 as a, 2 as b").fetchone() d = dict(row) self.assertEqual(d["a"], row["a"]) self.assertEqual(d["b"], row["b"]) def test_sqlite_row_hash_cmp(self): - """Checks if the row object compares and hashes correctly""" - self.con.row_factory = sqlite.Row + # Checks if the row object compares and hashes correctly. row_1 = self.con.execute("select 1 as a, 2 as b").fetchone() row_2 = self.con.execute("select 1 as a, 2 as b").fetchone() row_3 = self.con.execute("select 1 as a, 3 as b").fetchone() @@ -238,21 +232,24 @@ def test_sqlite_row_hash_cmp(self): self.assertEqual(hash(row_1), hash(row_2)) def test_sqlite_row_as_sequence(self): - """ Checks if the row object can act like a sequence """ - self.con.row_factory = sqlite.Row + # Checks if the row object can act like a sequence. row = self.con.execute("select 1 as a, 2 as b").fetchone() as_tuple = tuple(row) self.assertEqual(list(reversed(row)), list(reversed(as_tuple))) self.assertIsInstance(row, Sequence) + def test_sqlite_row_keys(self): + # Checks if the row object can return a list of columns as strings. + row = self.con.execute("select 1 as a, 2 as b").fetchone() + self.assertEqual(row.keys(), ['a', 'b']) + def test_fake_cursor_class(self): # Issue #24257: Incorrect use of PyObject_IsInstance() caused # segmentation fault. # Issue #27861: Also applies for cursor factory. class FakeCursor(str): __class__ = sqlite.Cursor - self.con.row_factory = sqlite.Row self.assertRaises(TypeError, self.con.cursor, FakeCursor) self.assertRaises(TypeError, sqlite.Row, FakeCursor(), ()) diff --git a/mingw32/lib/python3.11/test/test_sqlite3/test_transactions.py b/mingw32/lib/python3.11/test/test_sqlite3/test_transactions.py index a67d72709d3..b8d786bbd71 100644 --- a/mingw32/lib/python3.11/test/test_sqlite3/test_transactions.py +++ b/mingw32/lib/python3.11/test/test_sqlite3/test_transactions.py @@ -23,21 +23,19 @@ import os, unittest import sqlite3 as sqlite -from test.support import LOOPBACK_TIMEOUT from test.support.os_helper import TESTFN, unlink from test.test_sqlite3.test_dbapi import memory_database -TIMEOUT = LOOPBACK_TIMEOUT / 10 - - class TransactionTests(unittest.TestCase): def setUp(self): - self.con1 = sqlite.connect(TESTFN, timeout=TIMEOUT) + # We can disable the busy handlers, since we control + # the order of SQLite C API operations. + self.con1 = sqlite.connect(TESTFN, timeout=0) self.cur1 = self.con1.cursor() - self.con2 = sqlite.connect(TESTFN, timeout=TIMEOUT) + self.con2 = sqlite.connect(TESTFN, timeout=0) self.cur2 = self.con2.cursor() def tearDown(self): @@ -117,10 +115,8 @@ def test_raise_timeout(self): self.cur2.execute("insert into test(i) values (5)") def test_locking(self): - """ - This tests the improved concurrency with pysqlite 2.3.4. You needed - to roll back con2 before you could commit con1. - """ + # This tests the improved concurrency with pysqlite 2.3.4. You needed + # to roll back con2 before you could commit con1. self.cur1.execute("create table test(i)") self.cur1.execute("insert into test(i) values (5)") with self.assertRaises(sqlite.OperationalError): diff --git a/mingw32/lib/python3.11/test/test_ssl.py b/mingw32/lib/python3.11/test/test_ssl.py index d6acbf36e6e..965c2728914 100644 --- a/mingw32/lib/python3.11/test/test_ssl.py +++ b/mingw32/lib/python3.11/test/test_ssl.py @@ -2398,6 +2398,7 @@ def test_timeout_connect_ex(self): self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK)) @unittest.skipUnless(socket_helper.IPV6_ENABLED, 'Needs IPv6') + @support.requires_resource('walltime') def test_get_server_certificate_ipv6(self): with socket_helper.transient_internet('ipv6.google.com'): _test_get_server_certificate(self, 'ipv6.google.com', 443) @@ -2956,6 +2957,7 @@ def try_protocol_combo(server_protocol, client_protocol, expect_success, class ThreadedTests(unittest.TestCase): + @support.requires_resource('walltime') def test_echo(self): """Basic test of an SSL client connecting to a server""" if support.verbose: diff --git a/mingw32/lib/python3.11/test/test_statistics.py b/mingw32/lib/python3.11/test/test_statistics.py index 3e172e974e1..9e69d918e37 100644 --- a/mingw32/lib/python3.11/test/test_statistics.py +++ b/mingw32/lib/python3.11/test/test_statistics.py @@ -2139,6 +2139,7 @@ def test_integer_sqrt_of_frac_rto(self): self.assertTrue(m * (r - 1)**2 < n < m * (r + 1)**2) @requires_IEEE_754 + @support.requires_resource('cpu') def test_float_sqrt_of_frac(self): def is_root_correctly_rounded(x: Fraction, root: float) -> bool: @@ -2744,6 +2745,7 @@ def test_cdf(self): self.assertTrue(math.isnan(X.cdf(float('NaN')))) @support.skip_if_pgo_task + @support.requires_resource('cpu') def test_inv_cdf(self): NormalDist = self.module.NormalDist diff --git a/mingw32/lib/python3.11/test/test_subprocess.py b/mingw32/lib/python3.11/test/test_subprocess.py index 8e9ad06c6eb..3142026ac53 100644 --- a/mingw32/lib/python3.11/test/test_subprocess.py +++ b/mingw32/lib/python3.11/test/test_subprocess.py @@ -268,6 +268,7 @@ def test_check_output_stdin_with_input_arg(self): self.assertIn('stdin', c.exception.args[0]) self.assertIn('input', c.exception.args[0]) + @support.requires_resource('walltime') def test_check_output_timeout(self): # check_output() function with timeout arg with self.assertRaises(subprocess.TimeoutExpired) as c: @@ -1290,6 +1291,7 @@ def test_bufsize_equal_one_binary_mode(self): with self.assertWarnsRegex(RuntimeWarning, 'line buffering'): self._test_bufsize_equal_one(line, b'', universal_newlines=False) + @support.requires_resource('cpu') def test_leaking_fds_on_error(self): # see bug #5179: Popen leaks file descriptors to PIPEs if # the child fails to execute; this will eventually exhaust @@ -1640,6 +1642,7 @@ def test_check_output_stdin_with_input_arg(self): self.assertIn('stdin', c.exception.args[0]) self.assertIn('input', c.exception.args[0]) + @support.requires_resource('walltime') def test_check_output_timeout(self): with self.assertRaises(subprocess.TimeoutExpired) as c: cp = self.run_python(( diff --git a/mingw32/lib/python3.11/test/test_support.py b/mingw32/lib/python3.11/test/test_support.py index 23bcceedd71..01ba88ce42c 100644 --- a/mingw32/lib/python3.11/test/test_support.py +++ b/mingw32/lib/python3.11/test/test_support.py @@ -7,6 +7,7 @@ import stat import subprocess import sys +import sysconfig import tempfile import textwrap import time @@ -510,6 +511,7 @@ def check_options(self, args, func, expected=None): self.assertEqual(proc.stdout.rstrip(), repr(expected)) self.assertEqual(proc.returncode, 0) + @support.requires_resource('cpu') def test_args_from_interpreter_flags(self): # Test test.support.args_from_interpreter_flags() for opts in ( @@ -697,6 +699,130 @@ def test_has_strftime_extensions(self): else: self.assertTrue(support.has_strftime_extensions) + def test_get_recursion_depth(self): + # test support.get_recursion_depth() + code = textwrap.dedent(""" + from test import support + import sys + try: + from _testcapi import USE_STACKCHECK + except ImportError: + USE_STACKCHECK = False + + def check(cond): + if not cond: + raise AssertionError("test failed") + + # depth 1 + check(support.get_recursion_depth() == 1) + + # depth 2 + def test_func(): + check(support.get_recursion_depth() == 2) + test_func() + + def test_recursive(depth, limit): + if depth >= limit: + # cannot call get_recursion_depth() at this depth, + # it can raise RecursionError + return + get_depth = support.get_recursion_depth() + print(f"test_recursive: {depth}/{limit}: " + f"get_recursion_depth() says {get_depth}") + check(get_depth == depth) + test_recursive(depth + 1, limit) + + if USE_STACKCHECK: + # f-string consumes 2 frames and -1 for USE_STACKCHECK + IGNORE = 3 + else: + # f-string consumes 2 frames + IGNORE = 2 + + # depth up to 25 + with support.infinite_recursion(max_depth=25): + limit = sys.getrecursionlimit() + print(f"test with sys.getrecursionlimit()={limit}") + test_recursive(2, limit - IGNORE) + + # depth up to 500 + with support.infinite_recursion(max_depth=500): + limit = sys.getrecursionlimit() + print(f"test with sys.getrecursionlimit()={limit}") + test_recursive(2, limit - IGNORE) + """) + script_helper.assert_python_ok("-c", code) + + def test_recursion(self): + # Test infinite_recursion() and get_recursion_available() functions. + def recursive_function(depth): + if depth: + recursive_function(depth - 1) + + for max_depth in (5, 25, 250): + with support.infinite_recursion(max_depth): + available = support.get_recursion_available() + + # Recursion up to 'available' additional frames should be OK. + recursive_function(available) + + # Recursion up to 'available+1' additional frames must raise + # RecursionError. Avoid self.assertRaises(RecursionError) which + # can consume more than 3 frames and so raises RecursionError. + try: + recursive_function(available + 1) + except RecursionError: + pass + else: + self.fail("RecursionError was not raised") + + # Test the bare minimumum: max_depth=4 + with support.infinite_recursion(4): + try: + recursive_function(4) + except RecursionError: + pass + else: + self.fail("RecursionError was not raised") + + #self.assertEqual(available, 2) + + def test_copy_python_src_ignore(self): + # Get source directory + src_dir = sysconfig.get_config_var('abs_srcdir') + if not src_dir: + src_dir = sysconfig.get_config_var('srcdir') + src_dir = os.path.abspath(src_dir) + + # Check that the source code is available + if not os.path.exists(src_dir): + self.skipTest(f"cannot access Python source code directory:" + f" {src_dir!r}") + # Check that the landmark copy_python_src_ignore() expects is available + # (Previously we looked for 'Lib\os.py', which is always present on Windows.) + landmark = os.path.join(src_dir, 'Modules') + if not os.path.exists(landmark): + self.skipTest(f"cannot access Python source code directory:" + f" {landmark!r} landmark is missing") + + # Test support.copy_python_src_ignore() + + # Source code directory + ignored = {'.git', '__pycache__'} + names = os.listdir(src_dir) + self.assertEqual(support.copy_python_src_ignore(src_dir, names), + ignored | {'build'}) + + # Doc/ directory + path = os.path.join(src_dir, 'Doc') + self.assertEqual(support.copy_python_src_ignore(path, os.listdir(path)), + ignored | {'build', 'venv'}) + + # Another directory + path = os.path.join(src_dir, 'Objects') + self.assertEqual(support.copy_python_src_ignore(path, os.listdir(path)), + ignored) + # XXX -follows a list of untested API # make_legacy_pyc # is_resource_enabled diff --git a/mingw32/lib/python3.11/test/test_symtable.py b/mingw32/lib/python3.11/test/test_symtable.py index 819354e4eee..f38d791c83d 100644 --- a/mingw32/lib/python3.11/test/test_symtable.py +++ b/mingw32/lib/python3.11/test/test_symtable.py @@ -252,6 +252,10 @@ def test_symtable_repr(self): self.assertEqual(str(self.top), "") self.assertEqual(str(self.spam), "") + def test_symtable_entry_repr(self): + expected = f"" + self.assertEqual(repr(self.top._table), expected) + if __name__ == '__main__': unittest.main() diff --git a/mingw32/lib/python3.11/test/test_sys.py b/mingw32/lib/python3.11/test/test_sys.py index 6f56c9ef97e..86cf1a794f9 100644 --- a/mingw32/lib/python3.11/test/test_sys.py +++ b/mingw32/lib/python3.11/test/test_sys.py @@ -269,20 +269,29 @@ def test_switchinterval(self): finally: sys.setswitchinterval(orig) - def test_recursionlimit(self): + def test_getrecursionlimit(self): + limit = sys.getrecursionlimit() + self.assertIsInstance(limit, int) + self.assertGreater(limit, 1) + self.assertRaises(TypeError, sys.getrecursionlimit, 42) - oldlimit = sys.getrecursionlimit() - self.assertRaises(TypeError, sys.setrecursionlimit) - self.assertRaises(ValueError, sys.setrecursionlimit, -42) - sys.setrecursionlimit(10000) - self.assertEqual(sys.getrecursionlimit(), 10000) - sys.setrecursionlimit(oldlimit) + + def test_setrecursionlimit(self): + old_limit = sys.getrecursionlimit() + try: + sys.setrecursionlimit(10_005) + self.assertEqual(sys.getrecursionlimit(), 10_005) + + self.assertRaises(TypeError, sys.setrecursionlimit) + self.assertRaises(ValueError, sys.setrecursionlimit, -42) + finally: + sys.setrecursionlimit(old_limit) def test_recursionlimit_recovery(self): if hasattr(sys, 'gettrace') and sys.gettrace(): self.skipTest('fatal error if run with a trace function') - oldlimit = sys.getrecursionlimit() + old_limit = sys.getrecursionlimit() def f(): f() try: @@ -301,35 +310,31 @@ def f(): with self.assertRaises(RecursionError): f() finally: - sys.setrecursionlimit(oldlimit) + sys.setrecursionlimit(old_limit) @test.support.cpython_only - def test_setrecursionlimit_recursion_depth(self): + def test_setrecursionlimit_to_depth(self): # Issue #25274: Setting a low recursion limit must be blocked if the # current recursion depth is already higher than limit. - from _testinternalcapi import get_recursion_depth - - def set_recursion_limit_at_depth(depth, limit): - recursion_depth = get_recursion_depth() - if recursion_depth >= depth: + old_limit = sys.getrecursionlimit() + try: + depth = support.get_recursion_depth() + with self.subTest(limit=sys.getrecursionlimit(), depth=depth): + # depth + 2 is OK + sys.setrecursionlimit(depth + 2) + + # reset the limit to be able to call self.assertRaises() + # context manager + sys.setrecursionlimit(old_limit) with self.assertRaises(RecursionError) as cm: - sys.setrecursionlimit(limit) + sys.setrecursionlimit(depth + 1) self.assertRegex(str(cm.exception), "cannot set the recursion limit to [0-9]+ " "at the recursion depth [0-9]+: " "the limit is too low") - else: - set_recursion_limit_at_depth(depth, limit) - - oldlimit = sys.getrecursionlimit() - try: - sys.setrecursionlimit(1000) - - for limit in (10, 25, 50, 75, 100, 150, 200): - set_recursion_limit_at_depth(limit, limit) finally: - sys.setrecursionlimit(oldlimit) + sys.setrecursionlimit(old_limit) def test_getwindowsversion(self): # Raise SkipTest if sys doesn't have getwindowsversion attribute diff --git a/mingw32/lib/python3.11/test/test_sys_settrace.py b/mingw32/lib/python3.11/test/test_sys_settrace.py index 96242bb260a..3540192b5bb 100644 --- a/mingw32/lib/python3.11/test/test_sys_settrace.py +++ b/mingw32/lib/python3.11/test/test_sys_settrace.py @@ -41,6 +41,20 @@ async def asynciter(iterable): for x in iterable: yield x +def clean_asynciter(test): + @wraps(test) + async def wrapper(*args, **kwargs): + cleanups = [] + def wrapped_asynciter(iterable): + it = asynciter(iterable) + cleanups.append(it.aclose) + return it + try: + return await test(*args, **kwargs, asynciter=wrapped_asynciter) + finally: + while cleanups: + await cleanups.pop()() + return wrapper # A very basic example. If this fails, we're in deep trouble. def basic(): @@ -1588,7 +1602,6 @@ def error_once(frame, event, arg): except Exception as ex: count = 0 tb = ex.__traceback__ - print(tb) while tb: if tb.tb_frame.f_code.co_name == "test_settrace_error": count += 1 @@ -1869,7 +1882,11 @@ def compare_jump_output(self, expected, received): def run_test(self, func, jumpFrom, jumpTo, expected, error=None, event='line', decorated=False): - tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated) + wrapped = func + while hasattr(wrapped, '__wrapped__'): + wrapped = wrapped.__wrapped__ + + tracer = JumpTracer(wrapped, jumpFrom, jumpTo, event, decorated) sys.settrace(tracer.trace) output = [] if error is None: @@ -1882,7 +1899,11 @@ def run_test(self, func, jumpFrom, jumpTo, expected, error=None, def run_async_test(self, func, jumpFrom, jumpTo, expected, error=None, event='line', decorated=False): - tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated) + wrapped = func + while hasattr(wrapped, '__wrapped__'): + wrapped = wrapped.__wrapped__ + + tracer = JumpTracer(wrapped, jumpFrom, jumpTo, event, decorated) sys.settrace(tracer.trace) output = [] if error is None: @@ -1950,7 +1971,8 @@ def test_jump_out_of_block_backwards(output): output.append(7) @async_jump_test(4, 5, [3, 5]) - async def test_jump_out_of_async_for_block_forwards(output): + @clean_asynciter + async def test_jump_out_of_async_for_block_forwards(output, asynciter): for i in [1]: async for i in asynciter([1, 2]): output.append(3) @@ -1958,7 +1980,8 @@ async def test_jump_out_of_async_for_block_forwards(output): output.append(5) @async_jump_test(5, 2, [2, 4, 2, 4, 5, 6]) - async def test_jump_out_of_async_for_block_backwards(output): + @clean_asynciter + async def test_jump_out_of_async_for_block_backwards(output, asynciter): for i in [1]: output.append(2) async for i in asynciter([1]): @@ -2769,6 +2792,7 @@ def test_jump_extended_args_unpack_ex_tricky(output): ) = output.append(4) or "Spam" output.append(5) + @support.requires_resource('cpu') def test_jump_extended_args_for_iter(self): # In addition to failing when extended arg handling is broken, this can # also hang for a *very* long time: diff --git a/mingw32/lib/python3.11/test/test_tarfile.py b/mingw32/lib/python3.11/test/test_tarfile.py index 13a75f39f9b..cad13a9e071 100644 --- a/mingw32/lib/python3.11/test/test_tarfile.py +++ b/mingw32/lib/python3.11/test/test_tarfile.py @@ -1,3 +1,4 @@ +import errno import sys import os import io @@ -2493,16 +2494,17 @@ def tarfilecmd_failure(self, *args): return script_helper.assert_python_failure('-m', 'tarfile', *args) def make_simple_tarfile(self, tar_name): - files = [support.findfile('tokenize_tests.txt'), + files = [support.findfile('tokenize_tests.txt', + subdir='tokenizedata'), support.findfile('tokenize_tests-no-coding-cookie-' - 'and-utf8-bom-sig-only.txt')] + 'and-utf8-bom-sig-only.txt', + subdir='tokenizedata')] self.addCleanup(os_helper.unlink, tar_name) with tarfile.open(tar_name, 'w') as tf: for tardata in files: tf.add(tardata, arcname=os.path.basename(tardata)) def make_evil_tarfile(self, tar_name): - files = [support.findfile('tokenize_tests.txt')] self.addCleanup(os_helper.unlink, tar_name) with tarfile.open(tar_name, 'w') as tf: benign = tarfile.TarInfo('benign') @@ -2583,9 +2585,11 @@ def test_list_command_invalid_file(self): self.assertEqual(rc, 1) def test_create_command(self): - files = [support.findfile('tokenize_tests.txt'), + files = [support.findfile('tokenize_tests.txt', + subdir='tokenizedata'), support.findfile('tokenize_tests-no-coding-cookie-' - 'and-utf8-bom-sig-only.txt')] + 'and-utf8-bom-sig-only.txt', + subdir='tokenizedata')] for opt in '-c', '--create': try: out = self.tarfilecmd(opt, tmpname, *files) @@ -2596,9 +2600,11 @@ def test_create_command(self): os_helper.unlink(tmpname) def test_create_command_verbose(self): - files = [support.findfile('tokenize_tests.txt'), + files = [support.findfile('tokenize_tests.txt', + subdir='tokenizedata'), support.findfile('tokenize_tests-no-coding-cookie-' - 'and-utf8-bom-sig-only.txt')] + 'and-utf8-bom-sig-only.txt', + subdir='tokenizedata')] for opt in '-v', '--verbose': try: out = self.tarfilecmd(opt, '-c', tmpname, *files, @@ -2610,7 +2616,7 @@ def test_create_command_verbose(self): os_helper.unlink(tmpname) def test_create_command_dotless_filename(self): - files = [support.findfile('tokenize_tests.txt')] + files = [support.findfile('tokenize_tests.txt', subdir='tokenizedata')] try: out = self.tarfilecmd('-c', dotlessname, *files) self.assertEqual(out, b'') @@ -2621,7 +2627,7 @@ def test_create_command_dotless_filename(self): def test_create_command_dot_started_filename(self): tar_name = os.path.join(TEMPDIR, ".testtar") - files = [support.findfile('tokenize_tests.txt')] + files = [support.findfile('tokenize_tests.txt', subdir='tokenizedata')] try: out = self.tarfilecmd('-c', tar_name, *files) self.assertEqual(out, b'') @@ -2631,9 +2637,11 @@ def test_create_command_dot_started_filename(self): os_helper.unlink(tar_name) def test_create_command_compressed(self): - files = [support.findfile('tokenize_tests.txt'), + files = [support.findfile('tokenize_tests.txt', + subdir='tokenizedata'), support.findfile('tokenize_tests-no-coding-cookie-' - 'and-utf8-bom-sig-only.txt')] + 'and-utf8-bom-sig-only.txt', + subdir='tokenizedata')] for filetype in (GzipTest, Bz2Test, LzmaTest): if not filetype.open: continue @@ -3716,9 +3724,21 @@ def test_modes(self): tmp_filename = os.path.join(TEMPDIR, "tmp.file") with open(tmp_filename, 'w'): pass - os.chmod(tmp_filename, os.stat(tmp_filename).st_mode | stat.S_ISVTX) - have_sticky_files = (os.stat(tmp_filename).st_mode & stat.S_ISVTX) - os.unlink(tmp_filename) + try: + try: + os.chmod(tmp_filename, + os.stat(tmp_filename).st_mode | stat.S_ISVTX) + except OSError as exc: + if exc.errno == getattr(errno, "EFTYPE", 0): + # gh-108948: On FreeBSD, regular users cannot set + # the sticky bit. + self.skipTest("chmod() failed with EFTYPE: " + "regular users cannot set sticky bit") + else: + raise + have_sticky_files = (os.stat(tmp_filename).st_mode & stat.S_ISVTX) + finally: + os.unlink(tmp_filename) os.mkdir(tmp_filename) os.chmod(tmp_filename, os.stat(tmp_filename).st_mode | stat.S_ISVTX) diff --git a/mingw32/lib/python3.11/test/test_tempfile.py b/mingw32/lib/python3.11/test/test_tempfile.py index ccf7ea072de..2632e77fc82 100644 --- a/mingw32/lib/python3.11/test/test_tempfile.py +++ b/mingw32/lib/python3.11/test/test_tempfile.py @@ -1726,9 +1726,25 @@ def test_modes(self): d.cleanup() self.assertFalse(os.path.exists(d.name)) - @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.lchflags') + @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.chflags') def test_flags(self): flags = stat.UF_IMMUTABLE | stat.UF_NOUNLINK + + # skip the test if these flags are not supported (ex: FreeBSD 13) + filename = os_helper.TESTFN + try: + open(filename, "w").close() + try: + os.chflags(filename, flags) + except OSError as exc: + # "OSError: [Errno 45] Operation not supported" + self.skipTest(f"chflags() doesn't support " + f"UF_IMMUTABLE|UF_NOUNLINK: {exc}") + else: + os.chflags(filename, 0) + finally: + os_helper.unlink(filename) + d = self.do_create(recurse=3, dirs=2, files=2) with d: # Change files and directories flags recursively. diff --git a/mingw32/lib/python3.11/test/test_threading.py b/mingw32/lib/python3.11/test/test_threading.py index 9c6561c099f..a4192acd6db 100644 --- a/mingw32/lib/python3.11/test/test_threading.py +++ b/mingw32/lib/python3.11/test/test_threading.py @@ -37,6 +37,23 @@ Py_DEBUG = hasattr(sys, 'gettotalrefcount') +# gh-89363: Skip fork() test if Python is built with Address Sanitizer (ASAN) +# to work around a libasan race condition, dead lock in pthread_create(). +skip_if_asan_fork = support.skip_if_sanitizer( + "libasan has a pthread_create() dead lock", + address=True) + + +def skip_unless_reliable_fork(test): + if not support.has_fork_support: + return unittest.skip("requires working os.fork()")(test) + if sys.platform in platforms_to_skip: + return unittest.skip("due to known OS bug related to thread+fork")(test) + if support.check_sanitizer(address=True): + return unittest.skip("libasan has a pthread_create() dead lock related to thread+fork")(test) + return test + + def restore_default_excepthook(testcase): testcase.addCleanup(setattr, threading, 'excepthook', threading.excepthook) threading.excepthook = threading.__excepthook__ @@ -533,7 +550,7 @@ def test_daemon_param(self): t = threading.Thread(daemon=True) self.assertTrue(t.daemon) - @support.requires_fork() + @skip_unless_reliable_fork def test_fork_at_exit(self): # bpo-42350: Calling os.fork() after threading._shutdown() must # not log an error. @@ -561,7 +578,7 @@ def exit_handler(): self.assertEqual(out, b'') self.assertEqual(err.rstrip(), b'child process ok') - @support.requires_fork() + @skip_unless_reliable_fork def test_dummy_thread_after_fork(self): # Issue #14308: a dummy thread in the active list doesn't mess up # the after-fork mechanism. @@ -588,7 +605,7 @@ def background_thread(evt): self.assertEqual(out, b'') self.assertEqual(err, b'') - @support.requires_fork() + @skip_unless_reliable_fork def test_is_alive_after_fork(self): # Try hard to trigger #18418: is_alive() could sometimes be True on # threads that vanished after a fork. @@ -622,7 +639,7 @@ def f(): th.start() th.join() - @support.requires_fork() + @skip_unless_reliable_fork @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()") def test_main_thread_after_fork(self): code = """if 1: @@ -643,8 +660,7 @@ def test_main_thread_after_fork(self): self.assertEqual(err, b"") self.assertEqual(data, "MainThread\nTrue\nTrue\n") - @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") - @support.requires_fork() + @skip_unless_reliable_fork @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()") def test_main_thread_after_fork_from_nonmain_thread(self): code = """if 1: @@ -1021,8 +1037,7 @@ def test_1_join_on_shutdown(self): """ self._run_and_join(script) - @support.requires_fork() - @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") + @skip_unless_reliable_fork def test_2_join_in_forked_process(self): # Like the test above, but from a forked interpreter script = """if 1: @@ -1042,8 +1057,7 @@ def test_2_join_in_forked_process(self): """ self._run_and_join(script) - @support.requires_fork() - @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") + @skip_unless_reliable_fork def test_3_join_in_forked_from_thread(self): # Like the test above, but fork() was called from a worker thread # In the forked process, the main Thread object must be marked as stopped. @@ -1113,8 +1127,7 @@ def main(): rc, out, err = assert_python_ok('-c', script) self.assertFalse(err) - @support.requires_fork() - @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") + @skip_unless_reliable_fork def test_reinit_tls_after_fork(self): # Issue #13817: fork() would deadlock in a multithreaded program with # the ad-hoc TLS implementation. @@ -1137,7 +1150,7 @@ def do_fork_and_wait(): for t in threads: t.join() - @support.requires_fork() + @skip_unless_reliable_fork def test_clear_threads_states_after_fork(self): # Issue #17094: check that threads states are cleared after fork() @@ -1603,6 +1616,9 @@ class ConditionAsRLockTests(lock_tests.RLockTests): # Condition uses an RLock by default and exports its API. locktype = staticmethod(threading.Condition) + def test_recursion_count(self): + self.skipTest("Condition does not expose _recursion_count()") + class ConditionTests(lock_tests.ConditionTests): condtype = staticmethod(threading.Condition) diff --git a/mingw32/lib/python3.11/test/test_timeout.py b/mingw32/lib/python3.11/test/test_timeout.py index fa85c7e6cd8..b4b0dd09a41 100644 --- a/mingw32/lib/python3.11/test/test_timeout.py +++ b/mingw32/lib/python3.11/test/test_timeout.py @@ -148,13 +148,12 @@ def setUp(self): def tearDown(self): self.sock.close() - @unittest.skipIf(True, 'need to replace these hosts; see bpo-35518') def testConnectTimeout(self): # Testing connect timeout is tricky: we need to have IP connectivity # to a host that silently drops our packets. We can't simulate this # from Python because it's a function of the underlying TCP/IP stack. - # So, the following Snakebite host has been defined: - blackhole = resolve_address('blackhole.snakebite.net', 56666) + # So, the following port on the pythontest.net host has been defined: + blackhole = resolve_address('pythontest.net', 56666) # Blackhole has been configured to silently drop any incoming packets. # No RSTs (for TCP) or ICMP UNREACH (for UDP/ICMP) will be sent back @@ -166,7 +165,7 @@ def testConnectTimeout(self): # to firewalling or general network configuration. In order to improve # our confidence in testing the blackhole, a corresponding 'whitehole' # has also been set up using one port higher: - whitehole = resolve_address('whitehole.snakebite.net', 56667) + whitehole = resolve_address('pythontest.net', 56667) # This address has been configured to immediately drop any incoming # packets as well, but it does it respectfully with regards to the @@ -180,20 +179,15 @@ def testConnectTimeout(self): # timeframe). # For the records, the whitehole/blackhole configuration has been set - # up using the 'pf' firewall (available on BSDs), using the following: + # up using the 'iptables' firewall, using the following rules: # - # ext_if="bge0" - # - # blackhole_ip="35.8.247.6" - # whitehole_ip="35.8.247.6" - # blackhole_port="56666" - # whitehole_port="56667" - # - # block return in log quick on $ext_if proto { tcp udp } \ - # from any to $whitehole_ip port $whitehole_port - # block drop in log quick on $ext_if proto { tcp udp } \ - # from any to $blackhole_ip port $blackhole_port + # -A INPUT -p tcp --destination-port 56666 -j DROP + # -A INPUT -p udp --destination-port 56666 -j DROP + # -A INPUT -p tcp --destination-port 56667 -j REJECT + # -A INPUT -p udp --destination-port 56667 -j REJECT # + # See https://github.com/python/psf-salt/blob/main/pillar/base/firewall/snakebite.sls + # for the current configuration. skip = True sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) diff --git a/mingw32/lib/python3.11/test/test_tokenize.py b/mingw32/lib/python3.11/test/test_tokenize.py index 63c2501cfe2..62f152fe431 100644 --- a/mingw32/lib/python3.11/test/test_tokenize.py +++ b/mingw32/lib/python3.11/test/test_tokenize.py @@ -999,7 +999,7 @@ class TestTokenizerAdheresToPep0263(TestCase): """ def _testFile(self, filename): - path = os.path.join(os.path.dirname(__file__), filename) + path = os.path.join(os.path.dirname(__file__), 'tokenizedata', filename) TestRoundtrip.check_roundtrip(self, open(path, 'rb')) def test_utf8_coding_cookie_and_no_utf8_bom(self): @@ -1560,7 +1560,7 @@ def test_roundtrip(self): self.check_roundtrip("if x == 1 : \n" " print(x)\n") - fn = support.findfile("tokenize_tests.txt") + fn = support.findfile("tokenize_tests.txt", subdir="tokenizedata") with open(fn, 'rb') as f: self.check_roundtrip(f) self.check_roundtrip("if x == 1:\n" @@ -1615,8 +1615,7 @@ def test_random_files(self): # pass the '-ucpu' option to process the full directory. import glob, random - fn = support.findfile("tokenize_tests.txt") - tempdir = os.path.dirname(fn) or os.curdir + tempdir = os.path.dirname(__file__) or os.curdir testfiles = glob.glob(os.path.join(glob.escape(tempdir), "test*.py")) # Tokenize is broken on test_pep3131.py because regular expressions are diff --git a/mingw32/lib/python3.11/test/test_tomllib/test_misc.py b/mingw32/lib/python3.11/test/test_tomllib/test_misc.py index a477a219fd9..9e677a337a2 100644 --- a/mingw32/lib/python3.11/test/test_tomllib/test_misc.py +++ b/mingw32/lib/python3.11/test/test_tomllib/test_misc.py @@ -9,6 +9,7 @@ import sys import tempfile import unittest +from test import support from . import tomllib @@ -92,13 +93,23 @@ def test_deepcopy(self): self.assertEqual(obj_copy, expected_obj) def test_inline_array_recursion_limit(self): - # 465 with default recursion limit - nest_count = int(sys.getrecursionlimit() * 0.465) - recursive_array_toml = "arr = " + nest_count * "[" + nest_count * "]" - tomllib.loads(recursive_array_toml) + with support.infinite_recursion(max_depth=100): + available = support.get_recursion_available() + nest_count = (available // 2) - 2 + # Add details if the test fails + with self.subTest(limit=sys.getrecursionlimit(), + available=available, + nest_count=nest_count): + recursive_array_toml = "arr = " + nest_count * "[" + nest_count * "]" + tomllib.loads(recursive_array_toml) def test_inline_table_recursion_limit(self): - # 310 with default recursion limit - nest_count = int(sys.getrecursionlimit() * 0.31) - recursive_table_toml = nest_count * "key = {" + nest_count * "}" - tomllib.loads(recursive_table_toml) + with support.infinite_recursion(max_depth=100): + available = support.get_recursion_available() + nest_count = (available // 3) - 1 + # Add details if the test fails + with self.subTest(limit=sys.getrecursionlimit(), + available=available, + nest_count=nest_count): + recursive_table_toml = nest_count * "key = {" + nest_count * "}" + tomllib.loads(recursive_table_toml) diff --git a/mingw32/lib/python3.11/test/test_tools/test_freeze.py b/mingw32/lib/python3.11/test/test_tools/test_freeze.py index 2ba36ca208f..671ec2961e7 100644 --- a/mingw32/lib/python3.11/test/test_tools/test_freeze.py +++ b/mingw32/lib/python3.11/test/test_tools/test_freeze.py @@ -15,8 +15,13 @@ @support.requires_zlib() @unittest.skipIf(sys.platform.startswith('win'), 'not supported on Windows') @support.skip_if_buildbot('not all buildbots have enough space') +# gh-103053: Skip test if Python is built with Profile Guided Optimization +# (PGO), since the test is just too slow in this case. +@unittest.skipIf(support.check_cflags_pgo(), + 'test is too slow with PGO') class TestFreeze(unittest.TestCase): + @support.requires_resource('cpu') # Building Python is slow def test_freeze_simple_script(self): script = textwrap.dedent(""" import sys diff --git a/mingw32/lib/python3.11/test/test_tools/test_reindent.py b/mingw32/lib/python3.11/test/test_tools/test_reindent.py index 34df0c5d511..3aa09130a5c 100644 --- a/mingw32/lib/python3.11/test/test_tools/test_reindent.py +++ b/mingw32/lib/python3.11/test/test_tools/test_reindent.py @@ -25,7 +25,7 @@ def test_help(self): self.assertGreater(err, b'') def test_reindent_file_with_bad_encoding(self): - bad_coding_path = findfile('bad_coding.py') + bad_coding_path = findfile('bad_coding.py', subdir='tokenizedata') rc, out, err = assert_python_ok(self.script, '-r', bad_coding_path) self.assertEqual(out, b'') self.assertNotEqual(err, b'') diff --git a/mingw32/lib/python3.11/test/test_trace.py b/mingw32/lib/python3.11/test/test_trace.py index fad2b3b8379..8be89eb0245 100644 --- a/mingw32/lib/python3.11/test/test_trace.py +++ b/mingw32/lib/python3.11/test/test_trace.py @@ -1,7 +1,7 @@ import os from pickle import dump import sys -from test.support import captured_stdout +from test.support import captured_stdout, requires_resource from test.support.os_helper import (TESTFN, rmtree, unlink) from test.support.script_helper import assert_python_ok, assert_python_failure import textwrap @@ -362,13 +362,19 @@ def tearDown(self): rmtree(TESTFN) unlink(TESTFN) - def _coverage(self, tracer, - cmd='import test.support, test.test_pprint;' - 'test.support.run_unittest(test.test_pprint.QueryTestCase)'): + DEFAULT_SCRIPT = '''if True: + import unittest + from test.test_pprint import QueryTestCase + loader = unittest.TestLoader() + tests = loader.loadTestsFromTestCase(QueryTestCase) + tests(unittest.TestResult()) + ''' + def _coverage(self, tracer, cmd=DEFAULT_SCRIPT): tracer.run(cmd) r = tracer.results() r.write_results(show_missing=True, summary=True, coverdir=TESTFN) + @requires_resource('cpu') def test_coverage(self): tracer = trace.Trace(trace=0, count=1) with captured_stdout() as stdout: diff --git a/mingw32/lib/python3.11/test/test_traceback.py b/mingw32/lib/python3.11/test/test_traceback.py index eadc9c440e3..ccc59870c2a 100644 --- a/mingw32/lib/python3.11/test/test_traceback.py +++ b/mingw32/lib/python3.11/test/test_traceback.py @@ -566,6 +566,24 @@ def f_with_binary_operator(): result_lines = self.get_exception(f_with_binary_operator) self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_binary_operators_with_spaces_and_parenthesis(self): + def f_with_binary_operator(): + a = 1 + b = "" + return ( a ) + b + + lineno_f = f_with_binary_operator.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n' + ' return ( a ) + b\n' + ' ~~~~~~~~~~^~~\n' + ) + result_lines = self.get_exception(f_with_binary_operator) + self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_subscript(self): def f_with_subscript(): some_dict = {'x': {'y': None}} @@ -600,6 +618,24 @@ def f_with_subscript(): result_lines = self.get_exception(f_with_subscript) self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_subscript_with_spaces_and_parenthesis(self): + def f_with_binary_operator(): + a = [] + b = c = 1 + return b [ a ] + c + + lineno_f = f_with_binary_operator.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n' + ' return b [ a ] + c\n' + ' ~~~~~~^^^^^^^^^\n' + ) + result_lines = self.get_exception(f_with_binary_operator) + self.assertEqual(result_lines, expected_error.splitlines()) + def test_traceback_specialization_with_syntax_error(self): bytecode = compile("1 / 0 / 1 / 2\n", TESTFN, "exec") @@ -1510,27 +1546,28 @@ def __repr__(self): err_msg = '' self.assertEqual(self.get_report(e), vanilla + err_msg + '\nFinal Note\n') - def test_exception_with_note_with_multiple_notes(self): - e = ValueError(42) - vanilla = self.get_report(e) + def test_exception_with_multiple_notes(self): + for e in [ValueError(42), SyntaxError('bad syntax')]: + with self.subTest(e=e): + vanilla = self.get_report(e) - e.add_note('Note 1') - e.add_note('Note 2') - e.add_note('Note 3') + e.add_note('Note 1') + e.add_note('Note 2') + e.add_note('Note 3') - self.assertEqual( - self.get_report(e), - vanilla + 'Note 1\n' + 'Note 2\n' + 'Note 3\n') + self.assertEqual( + self.get_report(e), + vanilla + 'Note 1\n' + 'Note 2\n' + 'Note 3\n') - del e.__notes__ - e.add_note('Note 4') - del e.__notes__ - e.add_note('Note 5') - e.add_note('Note 6') + del e.__notes__ + e.add_note('Note 4') + del e.__notes__ + e.add_note('Note 5') + e.add_note('Note 6') - self.assertEqual( - self.get_report(e), - vanilla + 'Note 5\n' + 'Note 6\n') + self.assertEqual( + self.get_report(e), + vanilla + 'Note 5\n' + 'Note 6\n') def test_exception_qualname(self): class A: diff --git a/mingw32/lib/python3.11/test/test_type_cache.py b/mingw32/lib/python3.11/test/test_type_cache.py index 8502f6b0584..9dc91dc9344 100644 --- a/mingw32/lib/python3.11/test/test_type_cache.py +++ b/mingw32/lib/python3.11/test/test_type_cache.py @@ -44,4 +44,4 @@ def test_tp_version_tag_unique(self): if __name__ == "__main__": - support.run_unittest(TypeCacheTests) + unittest.main() diff --git a/mingw32/lib/python3.11/test/test_typing.py b/mingw32/lib/python3.11/test/test_typing.py index 03988758541..149c29283d4 100644 --- a/mingw32/lib/python3.11/test/test_typing.py +++ b/mingw32/lib/python3.11/test/test_typing.py @@ -4641,7 +4641,7 @@ def test_errors(self): # We need this to make sure that `@no_type_check` respects `__module__` attr: -from test import ann_module8 +from test.typinganndata import ann_module8 @no_type_check class NoTypeCheck_Outer: @@ -5228,7 +5228,9 @@ def test_overload_registry_repeated(self): # Definitions needed for features introduced in Python 3.6 -from test import ann_module, ann_module2, ann_module3, ann_module5, ann_module6 +from test.typinganndata import ( + ann_module, ann_module2, ann_module3, ann_module5, ann_module6, +) T_a = TypeVar('T_a') diff --git a/mingw32/lib/python3.11/test/test_unicode_identifiers.py b/mingw32/lib/python3.11/test/test_unicode_identifiers.py index 5b9ced5d1cb..63c6c055824 100644 --- a/mingw32/lib/python3.11/test/test_unicode_identifiers.py +++ b/mingw32/lib/python3.11/test/test_unicode_identifiers.py @@ -19,7 +19,7 @@ def test_non_bmp_normalized(self): def test_invalid(self): try: - from test import badsyntax_3131 + from test.tokenizedata import badsyntax_3131 except SyntaxError as err: self.assertEqual(str(err), "invalid character '€' (U+20AC) (badsyntax_3131.py, line 2)") diff --git a/mingw32/lib/python3.11/test/test_unicodedata.py b/mingw32/lib/python3.11/test/test_unicodedata.py index 9e0097c892e..c02d15d54b5 100644 --- a/mingw32/lib/python3.11/test/test_unicodedata.py +++ b/mingw32/lib/python3.11/test/test_unicodedata.py @@ -295,6 +295,7 @@ def test_ucd_510(self): self.assertTrue("\u1d79".upper()=='\ua77d') self.assertTrue(".".upper()=='.') + @requires_resource('cpu') def test_bug_5828(self): self.assertEqual("\u1d79".lower(), "\u1d79") # Only U+0000 should have U+0000 as its upper/lower/titlecase variant @@ -335,6 +336,7 @@ def unistr(data): return "".join([chr(x) for x in data]) @requires_resource('network') + @requires_resource('cpu') def test_normalization(self): TESTDATAFILE = "NormalizationTest.txt" TESTDATAURL = f"http://www.pythontest.net/unicode/{unicodedata.unidata_version}/{TESTDATAFILE}" diff --git a/mingw32/lib/python3.11/test/test_unpack.py b/mingw32/lib/python3.11/test/test_unpack.py index f5ca1d455b5..515ec128a08 100644 --- a/mingw32/lib/python3.11/test/test_unpack.py +++ b/mingw32/lib/python3.11/test/test_unpack.py @@ -162,7 +162,7 @@ def test_extended_oparg_not_ignored(self): ns = {} exec(code, ns) unpack_400 = ns["unpack_400"] - # Warm up the the function for quickening (PEP 659) + # Warm up the function for quickening (PEP 659) for _ in range(30): y = unpack_400(range(400)) self.assertEqual(y, 399) diff --git a/mingw32/lib/python3.11/test/test_unparse.py b/mingw32/lib/python3.11/test/test_unparse.py index f1f1dd5dc26..d8f0060b3a4 100644 --- a/mingw32/lib/python3.11/test/test_unparse.py +++ b/mingw32/lib/python3.11/test/test_unparse.py @@ -662,6 +662,11 @@ def test_star_expr_assign_target_multiple(self): self.check_src_roundtrip("[a, b] = [c, d] = [e, f] = g") self.check_src_roundtrip("a, b = [c, d] = e, f = g") + def test_multiquote_joined_string(self): + self.check_ast_roundtrip("f\"'''{1}\\\"\\\"\\\"\" ") + self.check_ast_roundtrip("""f"'''{1}""\\"" """) + self.check_ast_roundtrip("""f'""\"{1}''' """) + self.check_ast_roundtrip("""f'""\"{1}""\\"' """) class DirectoryTestCase(ASTTestCase): diff --git a/mingw32/lib/python3.11/test/test_urllib2net.py b/mingw32/lib/python3.11/test/test_urllib2net.py index d8d882b2d33..f0874d8d3ce 100644 --- a/mingw32/lib/python3.11/test/test_urllib2net.py +++ b/mingw32/lib/python3.11/test/test_urllib2net.py @@ -133,6 +133,7 @@ def setUp(self): # XXX The rest of these tests aren't very good -- they don't check much. # They do sometimes catch some major disasters, though. + @support.requires_resource('walltime') def test_ftp(self): # Testing the same URL twice exercises the caching in CacheFTPHandler urls = [ @@ -196,6 +197,7 @@ def test_urlwithfrag(self): self.assertEqual(res.geturl(), "http://www.pythontest.net/index.html#frag") + @support.requires_resource('walltime') def test_redirect_url_withfrag(self): redirect_url_with_frag = "http://www.pythontest.net/redir/with_frag/" with socket_helper.transient_internet(redirect_url_with_frag): @@ -334,6 +336,7 @@ def test_http_timeout(self): FTP_HOST = 'ftp://www.pythontest.net/' + @support.requires_resource('walltime') def test_ftp_basic(self): self.assertIsNone(socket.getdefaulttimeout()) with socket_helper.transient_internet(self.FTP_HOST, timeout=None): @@ -352,6 +355,7 @@ def test_ftp_default_timeout(self): socket.setdefaulttimeout(None) self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) + @support.requires_resource('walltime') def test_ftp_no_timeout(self): self.assertIsNone(socket.getdefaulttimeout()) with socket_helper.transient_internet(self.FTP_HOST): @@ -363,6 +367,7 @@ def test_ftp_no_timeout(self): socket.setdefaulttimeout(None) self.assertIsNone(u.fp.fp.raw._sock.gettimeout()) + @support.requires_resource('walltime') def test_ftp_timeout(self): with socket_helper.transient_internet(self.FTP_HOST): u = _urlopen_with_retry(self.FTP_HOST, timeout=60) diff --git a/mingw32/lib/python3.11/test/test_urllibnet.py b/mingw32/lib/python3.11/test/test_urllibnet.py index 773101ce41f..49a3b5afdeb 100644 --- a/mingw32/lib/python3.11/test/test_urllibnet.py +++ b/mingw32/lib/python3.11/test/test_urllibnet.py @@ -109,6 +109,7 @@ def test_getcode(self): open_url.close() self.assertEqual(code, 404) + @support.requires_resource('walltime') def test_bad_address(self): # Make sure proper exception is raised when connecting to a bogus # address. @@ -191,6 +192,7 @@ def test_header(self): logo = "http://www.pythontest.net/" + @support.requires_resource('walltime') def test_data_header(self): with self.urlretrieve(self.logo) as (file_location, fileheaders): datevalue = fileheaders.get('Date') diff --git a/mingw32/lib/python3.11/test/test_utf8source.py b/mingw32/lib/python3.11/test/test_utf8source.py index 97dced8a622..c42b6aaaab5 100644 --- a/mingw32/lib/python3.11/test/test_utf8source.py +++ b/mingw32/lib/python3.11/test/test_utf8source.py @@ -1,5 +1,3 @@ -# This file is marked as binary in the CVS, to prevent MacCVS from recoding it. - import unittest class PEP3120Test(unittest.TestCase): @@ -16,7 +14,7 @@ def test_pep3120(self): def test_badsyntax(self): try: - import test.badsyntax_pep3120 + import test.tokenizedata.badsyntax_pep3120 except SyntaxError as msg: msg = str(msg).lower() self.assertTrue('utf-8' in msg) diff --git a/mingw32/lib/python3.11/test/test_venv.py b/mingw32/lib/python3.11/test/test_venv.py index 86ce60fef13..eb9227a3b70 100644 --- a/mingw32/lib/python3.11/test/test_venv.py +++ b/mingw32/lib/python3.11/test/test_venv.py @@ -20,7 +20,8 @@ from test.support import (captured_stdout, captured_stderr, requires_zlib, skip_if_broken_multiprocessing_synchronize, verbose, requires_subprocess, is_emscripten, is_wasi, - requires_venv_with_pip, TEST_HOME_DIR) + requires_venv_with_pip, TEST_HOME_DIR, + requires_resource, copy_python_src_ignore) from test.support.os_helper import (can_symlink, EnvironmentVarGuard, rmtree) import unittest import venv @@ -561,6 +562,7 @@ def test_zippath_from_non_installed_posix(self): platlibdir, stdlib_zip) additional_pythonpath_for_non_installed = [] + # Copy stdlib files to the non-installed python so venv can # correctly calculate the prefix. for eachpath in sys.path: @@ -570,14 +572,19 @@ def test_zippath_from_non_installed_posix(self): eachpath, os.path.join(non_installed_dir, platlibdir)) elif os.path.isfile(os.path.join(eachpath, "os.py")): - for name in os.listdir(eachpath): + names = os.listdir(eachpath) + ignored_names = copy_python_src_ignore(eachpath, names) + for name in names: + if name in ignored_names: + continue if name == "site-packages": continue fn = os.path.join(eachpath, name) if os.path.isfile(fn): shutil.copy(fn, libdir) elif os.path.isdir(fn): - shutil.copytree(fn, os.path.join(libdir, name)) + shutil.copytree(fn, os.path.join(libdir, name), + ignore=copy_python_src_ignore) else: additional_pythonpath_for_non_installed.append( eachpath) @@ -756,6 +763,7 @@ def nicer_error(self): ) @requires_venv_with_pip() + @requires_resource('cpu') def test_with_pip(self): self.do_test_with_pip(False) self.do_test_with_pip(True) diff --git a/mingw32/lib/python3.11/test/test_weakref.py b/mingw32/lib/python3.11/test/test_weakref.py index 1bc1d05f7da..4cdd66d3769 100644 --- a/mingw32/lib/python3.11/test/test_weakref.py +++ b/mingw32/lib/python3.11/test/test_weakref.py @@ -1933,6 +1933,7 @@ def test_threaded_weak_key_dict_copy(self): self.check_threaded_weak_dict_copy(weakref.WeakKeyDictionary, False) @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threaded_weak_key_dict_deepcopy(self): # Issue #35615: Weakref keys or values getting GC'ed during dict # copying should not result in a crash. @@ -1945,6 +1946,7 @@ def test_threaded_weak_value_dict_copy(self): self.check_threaded_weak_dict_copy(weakref.WeakValueDictionary, False) @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threaded_weak_value_dict_deepcopy(self): # Issue #35615: Weakref keys or values getting GC'ed during dict # copying should not result in a crash. diff --git a/mingw32/lib/python3.11/test/test_xml_etree.py b/mingw32/lib/python3.11/test/test_xml_etree.py index abf3c62156a..c095dd0b593 100644 --- a/mingw32/lib/python3.11/test/test_xml_etree.py +++ b/mingw32/lib/python3.11/test/test_xml_etree.py @@ -365,6 +365,7 @@ def test_path_cache(self): from xml.etree import ElementPath elem = ET.XML(SAMPLE_XML) + ElementPath._cache.clear() for i in range(10): ET.ElementTree(elem).find('./'+str(i)) cache_len_10 = len(ElementPath._cache) for i in range(10): ET.ElementTree(elem).find('./'+str(i)) @@ -3955,8 +3956,9 @@ def test_issue14818(self): # -------------------------------------------------------------------- class NoAcceleratorTest(unittest.TestCase): - def setUp(self): - if not pyET: + @classmethod + def setUpClass(cls): + if ET is not pyET: raise unittest.SkipTest('only for the Python version') # Test that the C accelerator was not imported for pyET @@ -4202,8 +4204,7 @@ def get_option(config, option_name, default=None): # -------------------------------------------------------------------- - -def test_main(module=None): +def setUpModule(module=None): # When invoked without a module, runs the Python ET tests by loading pyET. # Otherwise, uses the given module as the ET. global pyET @@ -4215,62 +4216,30 @@ def test_main(module=None): global ET ET = module - test_classes = [ - ModuleTest, - ElementSlicingTest, - BasicElementTest, - BadElementTest, - BadElementPathTest, - ElementTreeTest, - IOTest, - ParseErrorTest, - XIncludeTest, - ElementTreeTypeTest, - ElementFindTest, - ElementIterTest, - TreeBuilderTest, - XMLParserTest, - XMLPullParserTest, - BugsTest, - KeywordArgsTest, - C14NTest, - ] - - # These tests will only run for the pure-Python version that doesn't import - # _elementtree. We can't use skipUnless here, because pyET is filled in only - # after the module is loaded. - if pyET is not ET: - test_classes.extend([ - NoAcceleratorTest, - ]) + # don't interfere with subsequent tests + def cleanup(): + global ET, pyET + ET = pyET = None + unittest.addModuleCleanup(cleanup) # Provide default namespace mapping and path cache. from xml.etree import ElementPath nsmap = ET.register_namespace._namespace_map # Copy the default namespace mapping nsmap_copy = nsmap.copy() + unittest.addModuleCleanup(nsmap.update, nsmap_copy) + unittest.addModuleCleanup(nsmap.clear) + # Copy the path cache (should be empty) path_cache = ElementPath._cache + unittest.addModuleCleanup(setattr, ElementPath, "_cache", path_cache) ElementPath._cache = path_cache.copy() + # Align the Comment/PI factories. if hasattr(ET, '_set_factories'): old_factories = ET._set_factories(ET.Comment, ET.PI) - else: - old_factories = None - - try: - support.run_unittest(*test_classes) - finally: - from xml.etree import ElementPath - # Restore mapping and path cache - nsmap.clear() - nsmap.update(nsmap_copy) - ElementPath._cache = path_cache - if old_factories is not None: - ET._set_factories(*old_factories) - # don't interfere with subsequent tests - ET = pyET = None + unittest.addModuleCleanup(ET._set_factories, *old_factories) if __name__ == '__main__': - test_main() + unittest.main() diff --git a/mingw32/lib/python3.11/test/test_xml_etree_c.py b/mingw32/lib/python3.11/test/test_xml_etree_c.py index bec82085719..e7dee3efe3c 100644 --- a/mingw32/lib/python3.11/test/test_xml_etree_c.py +++ b/mingw32/lib/python3.11/test/test_xml_etree_c.py @@ -234,20 +234,25 @@ def test_element_with_children(self): self.check_sizeof(e, self.elementsize + self.extra + struct.calcsize('8P')) -def test_main(): - from test import test_xml_etree - - # Run the tests specific to the C implementation - support.run_unittest( - MiscTests, - TestAliasWorking, - TestAcceleratorImported, - SizeofTest, - ) - # Run the same test suite as the Python module - test_xml_etree.test_main(module=cET) +def install_tests(): + # Test classes should have __module__ referring to this module. + from test import test_xml_etree + for name, base in vars(test_xml_etree).items(): + if isinstance(base, type) and issubclass(base, unittest.TestCase): + class Temp(base): + pass + Temp.__name__ = Temp.__qualname__ = name + Temp.__module__ = __name__ + assert name not in globals() + globals()[name] = Temp + +install_tests() + +def setUpModule(): + from test import test_xml_etree + test_xml_etree.setUpModule(module=cET) if __name__ == '__main__': - test_main() + unittest.main() diff --git a/mingw32/lib/python3.11/test/test_xmlrpc.py b/mingw32/lib/python3.11/test/test_xmlrpc.py index 9ff5545f786..7f517dc7c13 100644 --- a/mingw32/lib/python3.11/test/test_xmlrpc.py +++ b/mingw32/lib/python3.11/test/test_xmlrpc.py @@ -1031,38 +1031,47 @@ def test_path2(self): self.assertEqual(p.add(6,8), 6+8) self.assertRaises(xmlrpclib.Fault, p.pow, 6, 8) + @support.requires_resource('walltime') def test_path3(self): p = xmlrpclib.ServerProxy(URL+"/is/broken") self.assertRaises(xmlrpclib.Fault, p.add, 6, 8) + @support.requires_resource('walltime') def test_invalid_path(self): p = xmlrpclib.ServerProxy(URL+"/invalid") self.assertRaises(xmlrpclib.Fault, p.add, 6, 8) + @support.requires_resource('walltime') def test_path_query_fragment(self): p = xmlrpclib.ServerProxy(URL+"/foo?k=v#frag") self.assertEqual(p.test(), "/foo?k=v#frag") + @support.requires_resource('walltime') def test_path_fragment(self): p = xmlrpclib.ServerProxy(URL+"/foo#frag") self.assertEqual(p.test(), "/foo#frag") + @support.requires_resource('walltime') def test_path_query(self): p = xmlrpclib.ServerProxy(URL+"/foo?k=v") self.assertEqual(p.test(), "/foo?k=v") + @support.requires_resource('walltime') def test_empty_path(self): p = xmlrpclib.ServerProxy(URL) self.assertEqual(p.test(), "/RPC2") + @support.requires_resource('walltime') def test_root_path(self): p = xmlrpclib.ServerProxy(URL + "/") self.assertEqual(p.test(), "/") + @support.requires_resource('walltime') def test_empty_path_query(self): p = xmlrpclib.ServerProxy(URL + "?k=v") self.assertEqual(p.test(), "?k=v") + @support.requires_resource('walltime') def test_empty_path_fragment(self): p = xmlrpclib.ServerProxy(URL + "#frag") self.assertEqual(p.test(), "#frag") diff --git a/mingw32/lib/python3.11/test/tokenizedata/__init__.py b/mingw32/lib/python3.11/test/tokenizedata/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/mingw32/lib/python3.11/test/bad_coding.py b/mingw32/lib/python3.11/test/tokenizedata/bad_coding.py similarity index 100% rename from mingw32/lib/python3.11/test/bad_coding.py rename to mingw32/lib/python3.11/test/tokenizedata/bad_coding.py diff --git a/mingw32/lib/python3.11/test/bad_coding2.py b/mingw32/lib/python3.11/test/tokenizedata/bad_coding2.py similarity index 100% rename from mingw32/lib/python3.11/test/bad_coding2.py rename to mingw32/lib/python3.11/test/tokenizedata/bad_coding2.py diff --git a/mingw32/lib/python3.11/test/badsyntax_3131.py b/mingw32/lib/python3.11/test/tokenizedata/badsyntax_3131.py similarity index 100% rename from mingw32/lib/python3.11/test/badsyntax_3131.py rename to mingw32/lib/python3.11/test/tokenizedata/badsyntax_3131.py diff --git a/mingw32/lib/python3.11/test/badsyntax_pep3120.py b/mingw32/lib/python3.11/test/tokenizedata/badsyntax_pep3120.py similarity index 100% rename from mingw32/lib/python3.11/test/badsyntax_pep3120.py rename to mingw32/lib/python3.11/test/tokenizedata/badsyntax_pep3120.py diff --git a/mingw32/lib/python3.11/test/coding20731.py b/mingw32/lib/python3.11/test/tokenizedata/coding20731.py similarity index 100% rename from mingw32/lib/python3.11/test/coding20731.py rename to mingw32/lib/python3.11/test/tokenizedata/coding20731.py diff --git a/mingw32/lib/python3.11/test/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt b/mingw32/lib/python3.11/test/tokenizedata/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt similarity index 100% rename from mingw32/lib/python3.11/test/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt rename to mingw32/lib/python3.11/test/tokenizedata/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt diff --git a/mingw32/lib/python3.11/test/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt b/mingw32/lib/python3.11/test/tokenizedata/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt similarity index 100% rename from mingw32/lib/python3.11/test/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt rename to mingw32/lib/python3.11/test/tokenizedata/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt diff --git a/mingw32/lib/python3.11/test/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt b/mingw32/lib/python3.11/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt similarity index 100% rename from mingw32/lib/python3.11/test/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt rename to mingw32/lib/python3.11/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt diff --git a/mingw32/lib/python3.11/test/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt b/mingw32/lib/python3.11/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt similarity index 100% rename from mingw32/lib/python3.11/test/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt rename to mingw32/lib/python3.11/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt diff --git a/mingw32/lib/python3.11/test/tokenize_tests.txt b/mingw32/lib/python3.11/test/tokenizedata/tokenize_tests.txt similarity index 100% rename from mingw32/lib/python3.11/test/tokenize_tests.txt rename to mingw32/lib/python3.11/test/tokenizedata/tokenize_tests.txt diff --git a/mingw32/lib/python3.11/test/ann_module.py b/mingw32/lib/python3.11/test/typinganndata/ann_module.py similarity index 100% rename from mingw32/lib/python3.11/test/ann_module.py rename to mingw32/lib/python3.11/test/typinganndata/ann_module.py diff --git a/mingw32/lib/python3.11/test/ann_module2.py b/mingw32/lib/python3.11/test/typinganndata/ann_module2.py similarity index 100% rename from mingw32/lib/python3.11/test/ann_module2.py rename to mingw32/lib/python3.11/test/typinganndata/ann_module2.py diff --git a/mingw32/lib/python3.11/test/ann_module3.py b/mingw32/lib/python3.11/test/typinganndata/ann_module3.py similarity index 100% rename from mingw32/lib/python3.11/test/ann_module3.py rename to mingw32/lib/python3.11/test/typinganndata/ann_module3.py diff --git a/mingw32/lib/python3.11/test/ann_module4.py b/mingw32/lib/python3.11/test/typinganndata/ann_module4.py similarity index 100% rename from mingw32/lib/python3.11/test/ann_module4.py rename to mingw32/lib/python3.11/test/typinganndata/ann_module4.py diff --git a/mingw32/lib/python3.11/test/ann_module5.py b/mingw32/lib/python3.11/test/typinganndata/ann_module5.py similarity index 100% rename from mingw32/lib/python3.11/test/ann_module5.py rename to mingw32/lib/python3.11/test/typinganndata/ann_module5.py diff --git a/mingw32/lib/python3.11/test/ann_module6.py b/mingw32/lib/python3.11/test/typinganndata/ann_module6.py similarity index 100% rename from mingw32/lib/python3.11/test/ann_module6.py rename to mingw32/lib/python3.11/test/typinganndata/ann_module6.py diff --git a/mingw32/lib/python3.11/test/ann_module7.py b/mingw32/lib/python3.11/test/typinganndata/ann_module7.py similarity index 100% rename from mingw32/lib/python3.11/test/ann_module7.py rename to mingw32/lib/python3.11/test/typinganndata/ann_module7.py diff --git a/mingw32/lib/python3.11/test/ann_module8.py b/mingw32/lib/python3.11/test/typinganndata/ann_module8.py similarity index 100% rename from mingw32/lib/python3.11/test/ann_module8.py rename to mingw32/lib/python3.11/test/typinganndata/ann_module8.py diff --git a/mingw32/lib/python3.11/threading.py b/mingw32/lib/python3.11/threading.py index 4f72938551d..70601fc0d5f 100644 --- a/mingw32/lib/python3.11/threading.py +++ b/mingw32/lib/python3.11/threading.py @@ -218,6 +218,13 @@ def _release_save(self): def _is_owned(self): return self._owner == get_ident() + # Internal method used for reentrancy checks + + def _recursion_count(self): + if self._owner != get_ident(): + return 0 + return self._count + _PyRLock = _RLock diff --git a/mingw32/lib/python3.11/timeit.py b/mingw32/lib/python3.11/timeit.py index 9dfd454936e..3250563f422 100644 --- a/mingw32/lib/python3.11/timeit.py +++ b/mingw32/lib/python3.11/timeit.py @@ -50,9 +50,9 @@ """ import gc +import itertools import sys import time -import itertools __all__ = ["Timer", "timeit", "repeat", "default_timer"] @@ -77,9 +77,11 @@ def inner(_it, _timer{init}): return _t1 - _t0 """ + def reindent(src, indent): """Helper to reindent a multi-line statement.""" - return src.replace("\n", "\n" + " "*indent) + return src.replace("\n", "\n" + " " * indent) + class Timer: """Class for timing execution speed of small code snippets. @@ -166,7 +168,7 @@ def timeit(self, number=default_number): To be precise, this executes the setup statement once, and then returns the time it takes to execute the main statement - a number of times, as a float measured in seconds. The + a number of times, as float seconds if using the default timer. The argument is the number of times through the loop, defaulting to one million. The main statement, the setup statement and the timer function to be used are passed to the constructor. @@ -228,16 +230,19 @@ def autorange(self, callback=None): return (number, time_taken) i *= 10 + def timeit(stmt="pass", setup="pass", timer=default_timer, number=default_number, globals=None): """Convenience function to create Timer object and call timeit method.""" return Timer(stmt, setup, timer, globals).timeit(number) + def repeat(stmt="pass", setup="pass", timer=default_timer, repeat=default_repeat, number=default_number, globals=None): """Convenience function to create Timer object and call repeat method.""" return Timer(stmt, setup, timer, globals).repeat(repeat, number) + def main(args=None, *, _wrap_timer=None): """Main program, used when run as a script. @@ -270,7 +275,7 @@ def main(args=None, *, _wrap_timer=None): timer = default_timer stmt = "\n".join(args) or "pass" - number = 0 # auto-determine + number = 0 # auto-determine setup = [] repeat = default_repeat verbose = 0 @@ -287,7 +292,7 @@ def main(args=None, *, _wrap_timer=None): time_unit = a else: print("Unrecognized unit. Please select nsec, usec, msec, or sec.", - file=sys.stderr) + file=sys.stderr) return 2 if o in ("-r", "--repeat"): repeat = int(a) @@ -321,7 +326,7 @@ def callback(number, time_taken): msg = "{num} loop{s} -> {secs:.{prec}g} secs" plural = (number != 1) print(msg.format(num=number, s='s' if plural else '', - secs=time_taken, prec=precision)) + secs=time_taken, prec=precision)) try: number, _ = t.autorange(callback) except: @@ -372,5 +377,6 @@ def format_time(dt): UserWarning, '', 0) return None + if __name__ == "__main__": sys.exit(main()) diff --git a/mingw32/lib/python3.11/traceback.py b/mingw32/lib/python3.11/traceback.py index 09950a8b55e..d3edd3a63ef 100644 --- a/mingw32/lib/python3.11/traceback.py +++ b/mingw32/lib/python3.11/traceback.py @@ -603,11 +603,21 @@ def _extract_caret_anchors_from_line_segment(segment): and not operator_str[operator_offset + 1].isspace() ): right_anchor += 1 + + while left_anchor < len(segment) and ((ch := segment[left_anchor]).isspace() or ch in ")#"): + left_anchor += 1 + right_anchor += 1 return _Anchors(normalize(left_anchor), normalize(right_anchor)) case ast.Subscript(): - subscript_start = normalize(expr.value.end_col_offset) - subscript_end = normalize(expr.slice.end_col_offset + 1) - return _Anchors(subscript_start, subscript_end) + left_anchor = normalize(expr.value.end_col_offset) + right_anchor = normalize(expr.slice.end_col_offset + 1) + while left_anchor < len(segment) and ((ch := segment[left_anchor]).isspace() or ch != "["): + left_anchor += 1 + while right_anchor < len(segment) and ((ch := segment[right_anchor]).isspace() or ch != "]"): + right_anchor += 1 + if right_anchor < len(segment): + right_anchor += 1 + return _Anchors(left_anchor, right_anchor) return None diff --git a/mingw32/lib/python3.11/unittest/loader.py b/mingw32/lib/python3.11/unittest/loader.py index 7e6ce2f224b..f4e3d6e8f27 100644 --- a/mingw32/lib/python3.11/unittest/loader.py +++ b/mingw32/lib/python3.11/unittest/loader.py @@ -87,9 +87,13 @@ def loadTestsFromTestCase(self, testCaseClass): raise TypeError("Test cases should not be derived from " "TestSuite. Maybe you meant to derive from " "TestCase?") - testCaseNames = self.getTestCaseNames(testCaseClass) - if not testCaseNames and hasattr(testCaseClass, 'runTest'): - testCaseNames = ['runTest'] + if testCaseClass in (case.TestCase, case.FunctionTestCase): + # We don't load any tests from base types that should not be loaded. + testCaseNames = [] + else: + testCaseNames = self.getTestCaseNames(testCaseClass) + if not testCaseNames and hasattr(testCaseClass, 'runTest'): + testCaseNames = ['runTest'] loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames)) return loaded_suite @@ -120,7 +124,11 @@ def loadTestsFromModule(self, module, *args, pattern=None, **kws): tests = [] for name in dir(module): obj = getattr(module, name) - if isinstance(obj, type) and issubclass(obj, case.TestCase): + if ( + isinstance(obj, type) + and issubclass(obj, case.TestCase) + and obj not in (case.TestCase, case.FunctionTestCase) + ): tests.append(self.loadTestsFromTestCase(obj)) load_tests = getattr(module, 'load_tests', None) @@ -189,7 +197,11 @@ def loadTestsFromName(self, name, module=None): if isinstance(obj, types.ModuleType): return self.loadTestsFromModule(obj) - elif isinstance(obj, type) and issubclass(obj, case.TestCase): + elif ( + isinstance(obj, type) + and issubclass(obj, case.TestCase) + and obj not in (case.TestCase, case.FunctionTestCase) + ): return self.loadTestsFromTestCase(obj) elif (isinstance(obj, types.FunctionType) and isinstance(parent, type) and diff --git a/mingw32/lib/python3.11/unittest/test/test_loader.py b/mingw32/lib/python3.11/unittest/test/test_loader.py index de2268cda90..24001822b2f 100644 --- a/mingw32/lib/python3.11/unittest/test/test_loader.py +++ b/mingw32/lib/python3.11/unittest/test/test_loader.py @@ -102,6 +102,22 @@ def runTest(self): self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), [Foo('runTest')]) + # "Do not load any tests from `TestCase` class itself." + def test_loadTestsFromTestCase__from_TestCase(self): + loader = unittest.TestLoader() + + suite = loader.loadTestsFromTestCase(unittest.TestCase) + self.assertIsInstance(suite, loader.suiteClass) + self.assertEqual(list(suite), []) + + # "Do not load any tests from `FunctionTestCase` class." + def test_loadTestsFromTestCase__from_FunctionTestCase(self): + loader = unittest.TestLoader() + + suite = loader.loadTestsFromTestCase(unittest.FunctionTestCase) + self.assertIsInstance(suite, loader.suiteClass) + self.assertEqual(list(suite), []) + ################################################################ ### /Tests for TestLoader.loadTestsFromTestCase @@ -123,6 +139,19 @@ def test(self): expected = [loader.suiteClass([MyTestCase('test')])] self.assertEqual(list(suite), expected) + # "This test ensures that internal `TestCase` subclasses are not loaded" + def test_loadTestsFromModule__TestCase_subclass_internals(self): + # See https://github.com/python/cpython/issues/84867 + m = types.ModuleType('m') + # Simulate imported names: + m.TestCase = unittest.TestCase + m.FunctionTestCase = unittest.FunctionTestCase + + loader = unittest.TestLoader() + suite = loader.loadTestsFromModule(m) + self.assertIsInstance(suite, loader.suiteClass) + self.assertEqual(list(suite), []) + # "This method searches `module` for classes derived from TestCase" # # What happens if no tests are found (no TestCase instances)? diff --git a/mingw32/lib/python3.11/venv/scripts/nt/python.exe b/mingw32/lib/python3.11/venv/scripts/nt/python.exe index ab4c1fb8b79..80dd3cfc024 100644 Binary files a/mingw32/lib/python3.11/venv/scripts/nt/python.exe and b/mingw32/lib/python3.11/venv/scripts/nt/python.exe differ diff --git a/mingw32/lib/python3.11/venv/scripts/nt/pythonw.exe b/mingw32/lib/python3.11/venv/scripts/nt/pythonw.exe index 947f305124c..96242fbd738 100644 Binary files a/mingw32/lib/python3.11/venv/scripts/nt/pythonw.exe and b/mingw32/lib/python3.11/venv/scripts/nt/pythonw.exe differ diff --git a/mingw64/bin/libpython3.11.dll b/mingw64/bin/libpython3.11.dll index 1f5b0229c82..d724046beca 100644 Binary files a/mingw64/bin/libpython3.11.dll and b/mingw64/bin/libpython3.11.dll differ diff --git a/mingw64/bin/libpython3.dll b/mingw64/bin/libpython3.dll index 36d7fad93f8..20ae429740f 100644 Binary files a/mingw64/bin/libpython3.dll and b/mingw64/bin/libpython3.dll differ diff --git a/mingw64/bin/python.exe b/mingw64/bin/python.exe index 38032da61e3..7d7d307bcd3 100755 Binary files a/mingw64/bin/python.exe and b/mingw64/bin/python.exe differ diff --git a/mingw64/bin/python3.11.exe b/mingw64/bin/python3.11.exe index 38032da61e3..7d7d307bcd3 100644 Binary files a/mingw64/bin/python3.11.exe and b/mingw64/bin/python3.11.exe differ diff --git a/mingw64/bin/python3.exe b/mingw64/bin/python3.exe index 38032da61e3..7d7d307bcd3 100644 Binary files a/mingw64/bin/python3.exe and b/mingw64/bin/python3.exe differ diff --git a/mingw64/bin/python3w.exe b/mingw64/bin/python3w.exe index 0082a79276b..66d8d38d464 100644 Binary files a/mingw64/bin/python3w.exe and b/mingw64/bin/python3w.exe differ diff --git a/mingw64/bin/pythonw.exe b/mingw64/bin/pythonw.exe index 0082a79276b..66d8d38d464 100644 Binary files a/mingw64/bin/pythonw.exe and b/mingw64/bin/pythonw.exe differ diff --git a/mingw64/include/python3.11/internal/pycore_pystate.h b/mingw64/include/python3.11/internal/pycore_pystate.h index cb8f115768a..7c5aba12d52 100644 --- a/mingw64/include/python3.11/internal/pycore_pystate.h +++ b/mingw64/include/python3.11/internal/pycore_pystate.h @@ -61,6 +61,12 @@ _Py_ThreadCanHandlePendingCalls(void) } +#ifndef NDEBUG +extern int _PyThreadState_CheckConsistency(PyThreadState *tstate); +#endif + +int _PyThreadState_MustExit(PyThreadState *tstate); + /* Variable and macro for in-line access to current thread and interpreter state */ diff --git a/mingw64/include/python3.11/patchlevel.h b/mingw64/include/python3.11/patchlevel.h index 7023a3f6c36..70d71c11377 100644 --- a/mingw64/include/python3.11/patchlevel.h +++ b/mingw64/include/python3.11/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 11 -#define PY_MICRO_VERSION 5 +#define PY_MICRO_VERSION 6 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.11.5" +#define PY_VERSION "3.11.6" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/mingw64/include/python3.11/pyport.h b/mingw64/include/python3.11/pyport.h index b816c90e038..9bbdbc92fdf 100644 --- a/mingw64/include/python3.11/pyport.h +++ b/mingw64/include/python3.11/pyport.h @@ -454,11 +454,6 @@ Please be conservative with adding new ones, document them and enclose them in platform-specific #ifdefs. **************************************************************************/ -#ifdef SOLARIS -/* Unchecked */ -extern int gethostname(char *, int); -#endif - #ifdef HAVE__GETPTY #include /* we need to import mode_t */ extern char * _getpty(int *, int, mode_t, int); diff --git a/mingw64/lib/python3.11/Tools/scripts/freeze_modules.py b/mingw64/lib/python3.11/Tools/scripts/freeze_modules.py index dd208c78471..0e41d96d462 100644 --- a/mingw64/lib/python3.11/Tools/scripts/freeze_modules.py +++ b/mingw64/lib/python3.11/Tools/scripts/freeze_modules.py @@ -581,7 +581,7 @@ def regen_makefile(modules): pyfiles = [] frozenfiles = [] rules = [''] - deepfreezerules = ["Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS)", + deepfreezerules = ["$(DEEPFREEZE_C): $(DEEPFREEZE_DEPS)", "\t$(PYTHON_FOR_FREEZE) $(srcdir)/Tools/scripts/deepfreeze.py \\"] for src in _iter_sources(modules): frozen_header = relpath_for_posix_display(src.frozenfile, ROOT_DIR) diff --git a/mingw64/lib/python3.11/Tools/scripts/patchcheck.py b/mingw64/lib/python3.11/Tools/scripts/patchcheck.py index a324eafc52b..c2dceea2a2c 100644 --- a/mingw64/lib/python3.11/Tools/scripts/patchcheck.py +++ b/mingw64/lib/python3.11/Tools/scripts/patchcheck.py @@ -11,6 +11,13 @@ import untabify +def get_python_source_dir(): + src_dir = sysconfig.get_config_var('abs_srcdir') + if not src_dir: + src_dir = sysconfig.get_config_var('srcdir') + return os.path.abspath(src_dir) + + # Excluded directories which are copies of external libraries: # don't check their coding style EXCLUDE_DIRS = [os.path.join('Modules', '_ctypes', 'libffi_osx'), @@ -18,7 +25,7 @@ os.path.join('Modules', '_decimal', 'libmpdec'), os.path.join('Modules', 'expat'), os.path.join('Modules', 'zlib')] -SRCDIR = sysconfig.get_config_var('srcdir') +SRCDIR = get_python_source_dir() def n_files_str(count): diff --git a/mingw64/lib/python3.11/Tools/scripts/verify_ensurepip_wheels.py b/mingw64/lib/python3.11/Tools/scripts/verify_ensurepip_wheels.py index 044d1fd6b3c..434a0b4c538 100644 --- a/mingw64/lib/python3.11/Tools/scripts/verify_ensurepip_wheels.py +++ b/mingw64/lib/python3.11/Tools/scripts/verify_ensurepip_wheels.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python3 +#!/usr/bin/env python3 """ Compare checksums for wheels in :mod:`ensurepip` against the Cheeseshop. @@ -35,11 +35,17 @@ def print_error(file_path: str, message: str) -> None: def verify_wheel(package_name: str) -> bool: # Find the package on disk - package_path = next(WHEEL_DIR.glob(f"{package_name}*.whl"), None) - if not package_path: - print_error("", f"Could not find a {package_name} wheel on disk.") + package_paths = list(WHEEL_DIR.glob(f"{package_name}*.whl")) + if len(package_paths) != 1: + if package_paths: + for p in package_paths: + print_error(p, f"Found more than one wheel for package {package_name}.") + else: + print_error("", f"Could not find a {package_name} wheel on disk.") return False + package_path = package_paths[0] + print(f"Verifying checksum for {package_path}.") # Find the version of the package used by ensurepip diff --git a/mingw64/lib/python3.11/_sysconfigdata__win32_.py b/mingw64/lib/python3.11/_sysconfigdata__win32_.py index 34de144c91a..afe4faee13a 100644 --- a/mingw64/lib/python3.11/_sysconfigdata__win32_.py +++ b/mingw64/lib/python3.11/_sysconfigdata__win32_.py @@ -44,7 +44,7 @@ '-fvisibility=hidden -D_WIN32_WINNT=0x0602 ' '-DPY3_DLLNAME=\'L"libpython3.11.dll"\' ' '-DMS_DLL_ID=\'"3.11"\'', - 'CONFIGURE_CPPFLAGS': '-I../Python-3.11.5/PC -D__USE_MINGW_ANSI_STDIO=1 -I.', + 'CONFIGURE_CPPFLAGS': '-I../Python-3.11.6/PC -D__USE_MINGW_ANSI_STDIO=1 -I.', 'CONFIGURE_LDFLAGS': '-pipe', 'CONFIGURE_LDFLAGS_NODIST': '-fno-semantic-interposition', 'CONFIGURE_LDFLAGS_NOLTO': '', @@ -69,15 +69,16 @@ 'COVERAGE_REPORT_OPTIONS': '--rc lcov_branch_coverage=1 --branch-coverage ' '--title "CPython 3.11 LCOV report [commit $(shell ' ')]"', - 'CPPFLAGS': '-IObjects -IInclude -IPython -I. -I../Python-3.11.5/Include ' - '-I../Python-3.11.5/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' + 'CPPFLAGS': '-IObjects -IInclude -IPython -I. -I../Python-3.11.6/Include ' + '-I../Python-3.11.6/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' '-D__USE_MINGW_ANSI_STDIO=1', 'CXX': 'g++', 'DECIMAL_CFLAGS': '-DCONFIG_64=1 -DANSI=1 -DHAVE_UINT128_T=1', 'DECIMAL_LDFLAGS': '-lmpdec', - 'DEEPFREEZE_DEPS': '../Python-3.11.5/Tools/scripts/deepfreeze.py ' + 'DEEPFREEZE_C': 'Python/deepfreeze/deepfreeze.c', + 'DEEPFREEZE_DEPS': '../Python-3.11.6/Tools/scripts/deepfreeze.py ' '_bootstrap_python ' - '../Python-3.11.5/Programs/_freeze_module.py \\', + '../Python-3.11.6/Programs/_freeze_module.py \\', 'DEEPFREEZE_OBJS': 'Python/deepfreeze/deepfreeze.o', 'DESTDIR': '', 'DESTDIRFINAL': '/', @@ -117,11 +118,11 @@ 'FILEMODE': 644, 'FLOAT_WORDS_BIGENDIAN': 0, 'FREEZE_MODULE': './_bootstrap_python ' - '../Python-3.11.5/Programs/_freeze_module.py', + '../Python-3.11.6/Programs/_freeze_module.py', 'FREEZE_MODULE_BOOTSTRAP': './Programs/_freeze_module', 'FREEZE_MODULE_BOOTSTRAP_DEPS': 'Programs/_freeze_module', 'FREEZE_MODULE_DEPS': '_bootstrap_python ' - '../Python-3.11.5/Programs/_freeze_module.py', + '../Python-3.11.6/Programs/_freeze_module.py', 'FROZEN_FILES_IN': '\\', 'FROZEN_FILES_OUT': '\\', 'GETPGRP_HAVE_ARG': 0, @@ -643,9 +644,9 @@ '-fvisibility=hidden -D_WIN32_WINNT=0x0602 ' '-DPY3_DLLNAME=\'L"libpython3.11.dll"\' ' '-DMS_DLL_ID=\'"3.11"\' -fprofile-use -fprofile-correction ' - '-I../Python-3.11.5/Include/internal -IObjects -IInclude ' - '-IPython -I. -I../Python-3.11.5/Include ' - '-I../Python-3.11.5/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' + '-I../Python-3.11.6/Include/internal -IObjects -IInclude ' + '-IPython -I. -I../Python-3.11.6/Include ' + '-I../Python-3.11.6/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' '-D__USE_MINGW_ANSI_STDIO=1', 'LIBEXPAT_HEADERS': '\\', 'LIBEXPAT_OBJS': '\\', @@ -662,9 +663,9 @@ '-D_WIN32_WINNT=0x0602 ' '-DPY3_DLLNAME=\'L"libpython3.11.dll"\' ' '-DMS_DLL_ID=\'"3.11"\' -fprofile-use -fprofile-correction ' - '-I../Python-3.11.5/Include/internal -IObjects -IInclude ' - '-IPython -I. -I../Python-3.11.5/Include ' - '-I../Python-3.11.5/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' + '-I../Python-3.11.6/Include/internal -IObjects -IInclude ' + '-IPython -I. -I../Python-3.11.6/Include ' + '-I../Python-3.11.6/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' '-D__USE_MINGW_ANSI_STDIO=1', 'LIBMPDEC_HEADERS': '\\', 'LIBMPDEC_OBJS': '\\', @@ -697,7 +698,7 @@ 'MAINCC': 'gcc', 'MAJOR_IN_MKDEV': 0, 'MAJOR_IN_SYSMACROS': 0, - 'MAKESETUP': '../Python-3.11.5/Modules/makesetup', + 'MAKESETUP': '../Python-3.11.6/Modules/makesetup', 'MANDIR': '/mingw64/share/man', 'MKDIR_P': '/usr/bin/mkdir -p', 'MODBUILT_NAMES': 'atexit faulthandler nt _signal _tracemalloc _codecs ' @@ -728,7 +729,7 @@ 'MODULE_BINASCII_CFLAGS': '-DUSE_ZLIB_CRC32', 'MODULE_BINASCII_LDFLAGS': '-lz', 'MODULE_BINASCII_STATE': 'yes', - 'MODULE_CMATH_DEPS': '../Python-3.11.5/Modules/_math.h', + 'MODULE_CMATH_DEPS': '../Python-3.11.6/Modules/_math.h', 'MODULE_CMATH_LDFLAGS': '-lm', 'MODULE_CMATH_STATE': 'yes', 'MODULE_ERRNO_LDFLAGS': '', @@ -736,7 +737,7 @@ 'MODULE_FCNTL_STATE': 'missing', 'MODULE_GRP_STATE': 'missing', 'MODULE_ITERTOOLS_LDFLAGS': '', - 'MODULE_MATH_DEPS': '../Python-3.11.5/Modules/_math.h', + 'MODULE_MATH_DEPS': '../Python-3.11.6/Modules/_math.h', 'MODULE_MATH_LDFLAGS': '-lm', 'MODULE_MATH_STATE': 'yes', 'MODULE_MMAP_STATE': 'yes', @@ -757,8 +758,8 @@ 'MODULE_TERMIOS_STATE': 'missing', 'MODULE_TIME_LDFLAGS': '', 'MODULE_TIME_STATE': 'yes', - 'MODULE_UNICODEDATA_DEPS': '../Python-3.11.5/Modules/unicodedata_db.h ' - '../Python-3.11.5/Modules/unicodename_db.h', + 'MODULE_UNICODEDATA_DEPS': '../Python-3.11.6/Modules/unicodedata_db.h ' + '../Python-3.11.6/Modules/unicodename_db.h', 'MODULE_UNICODEDATA_STATE': 'yes', 'MODULE_WINREG_LDFLAGS': '', 'MODULE_WINSOUND_LDFLAGS': '-lwinmm', @@ -773,22 +774,22 @@ 'MODULE__ASYNCIO_STATE': 'yes', 'MODULE__BISECT_STATE': 'yes', 'MODULE__BLAKE2_CFLAGS': '', - 'MODULE__BLAKE2_DEPS': '../Python-3.11.5/Modules/_blake2/impl/blake2-config.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2-impl.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2b-load-sse2.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2b-load-sse41.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2b-ref.c ' - '../Python-3.11.5/Modules/_blake2/impl/blake2b-round.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2b.c ' - '../Python-3.11.5/Modules/_blake2/impl/blake2s-load-sse2.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2s-load-sse41.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2s-load-xop.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2s-ref.c ' - '../Python-3.11.5/Modules/_blake2/impl/blake2s-round.h ' - '../Python-3.11.5/Modules/_blake2/impl/blake2s.c ' - '../Python-3.11.5/Modules/_blake2/blake2module.h ' - '../Python-3.11.5/Modules/hashlib.h', + 'MODULE__BLAKE2_DEPS': '../Python-3.11.6/Modules/_blake2/impl/blake2-config.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2-impl.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2b-load-sse2.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2b-load-sse41.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2b-ref.c ' + '../Python-3.11.6/Modules/_blake2/impl/blake2b-round.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2b.c ' + '../Python-3.11.6/Modules/_blake2/impl/blake2s-load-sse2.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2s-load-sse41.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2s-load-xop.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2s-ref.c ' + '../Python-3.11.6/Modules/_blake2/impl/blake2s-round.h ' + '../Python-3.11.6/Modules/_blake2/impl/blake2s.c ' + '../Python-3.11.6/Modules/_blake2/blake2module.h ' + '../Python-3.11.6/Modules/hashlib.h', 'MODULE__BLAKE2_LDFLAGS': '', 'MODULE__BLAKE2_STATE': 'yes', 'MODULE__BZ2_CFLAGS': '', @@ -805,27 +806,27 @@ 'MODULE__CONTEXTVARS_STATE': 'yes', 'MODULE__CRYPT_STATE': 'missing', 'MODULE__CSV_STATE': 'yes', - 'MODULE__CTYPES_DEPS': '../Python-3.11.5/Modules/_ctypes/ctypes.h', + 'MODULE__CTYPES_DEPS': '../Python-3.11.6/Modules/_ctypes/ctypes.h', 'MODULE__CTYPES_TEST_LDFLAGS': '-lm', 'MODULE__CTYPES_TEST_STATE': 'yes', 'MODULE__DATETIME_LDFLAGS': '-lm', 'MODULE__DATETIME_STATE': 'yes', 'MODULE__DECIMAL_CFLAGS': '-DCONFIG_64=1 -DANSI=1 -DHAVE_UINT128_T=1', - 'MODULE__DECIMAL_DEPS': '../Python-3.11.5/Modules/_decimal/docstrings.h', + 'MODULE__DECIMAL_DEPS': '../Python-3.11.6/Modules/_decimal/docstrings.h', 'MODULE__DECIMAL_LDFLAGS': '-lmpdec', 'MODULE__DECIMAL_STATE': 'yes', 'MODULE__ELEMENTTREE_CFLAGS': '', - 'MODULE__ELEMENTTREE_DEPS': '../Python-3.11.5/Modules/pyexpat.c', + 'MODULE__ELEMENTTREE_DEPS': '../Python-3.11.6/Modules/pyexpat.c', 'MODULE__ELEMENTTREE_STATE': 'yes', 'MODULE__FUNCTOOLS_LDFLAGS': '', 'MODULE__GDBM_STATE': 'missing', 'MODULE__HASHLIB_CFLAGS': '', - 'MODULE__HASHLIB_DEPS': '../Python-3.11.5/Modules/hashlib.h', + 'MODULE__HASHLIB_DEPS': '../Python-3.11.6/Modules/hashlib.h', 'MODULE__HASHLIB_LDFLAGS': '-lcrypto', 'MODULE__HASHLIB_STATE': 'yes', 'MODULE__HEAPQ_STATE': 'yes', - 'MODULE__IO_CFLAGS': '-I../Python-3.11.5/Modules/_io', - 'MODULE__IO_DEPS': '../Python-3.11.5/Modules/_io/_iomodule.h', + 'MODULE__IO_CFLAGS': '-I../Python-3.11.6/Modules/_io', + 'MODULE__IO_DEPS': '../Python-3.11.6/Modules/_io/_iomodule.h', 'MODULE__IO_LDFLAGS': '', 'MODULE__IO_STATE': 'yes', 'MODULE__JSON_STATE': 'yes', @@ -834,12 +835,12 @@ 'MODULE__LZMA_CFLAGS': '', 'MODULE__LZMA_LDFLAGS': '-llzma', 'MODULE__LZMA_STATE': 'yes', - 'MODULE__MD5_DEPS': '../Python-3.11.5/Modules/hashlib.h', + 'MODULE__MD5_DEPS': '../Python-3.11.6/Modules/hashlib.h', 'MODULE__MD5_STATE': 'yes', 'MODULE__MSI_LDFLAGS': '-lmsi -lcabinet -lrpcrt4', 'MODULE__MSI_STATE': 'yes', 'MODULE__MULTIBYTECODEC_STATE': 'yes', - 'MODULE__MULTIPROCESSING_CFLAGS': '-I../Python-3.11.5/Modules/_multiprocessing', + 'MODULE__MULTIPROCESSING_CFLAGS': '-I../Python-3.11.6/Modules/_multiprocessing', 'MODULE__MULTIPROCESSING_STATE': 'yes', 'MODULE__OPCODE_STATE': 'yes', 'MODULE__OPERATOR_LDFLAGS': '', @@ -851,42 +852,42 @@ 'MODULE__QUEUE_STATE': 'yes', 'MODULE__RANDOM_STATE': 'yes', 'MODULE__SCPROXY_STATE': 'n/a', - 'MODULE__SHA1_DEPS': '../Python-3.11.5/Modules/hashlib.h', + 'MODULE__SHA1_DEPS': '../Python-3.11.6/Modules/hashlib.h', 'MODULE__SHA1_STATE': 'yes', - 'MODULE__SHA256_DEPS': '../Python-3.11.5/Modules/hashlib.h', + 'MODULE__SHA256_DEPS': '../Python-3.11.6/Modules/hashlib.h', 'MODULE__SHA256_STATE': 'yes', - 'MODULE__SHA3_DEPS': '../Python-3.11.5/Modules/_sha3/sha3.c ' - '../Python-3.11.5/Modules/_sha3/sha3.h ' - '../Python-3.11.5/Modules/hashlib.h', + 'MODULE__SHA3_DEPS': '../Python-3.11.6/Modules/_sha3/sha3.c ' + '../Python-3.11.6/Modules/_sha3/sha3.h ' + '../Python-3.11.6/Modules/hashlib.h', 'MODULE__SHA3_STATE': 'yes', - 'MODULE__SHA512_DEPS': '../Python-3.11.5/Modules/hashlib.h', + 'MODULE__SHA512_DEPS': '../Python-3.11.6/Modules/hashlib.h', 'MODULE__SHA512_STATE': 'yes', - 'MODULE__SOCKET_DEPS': '../Python-3.11.5/Modules/socketmodule.h ' - '../Python-3.11.5/Modules/addrinfo.h ' - '../Python-3.11.5/Modules/getaddrinfo.c ' - '../Python-3.11.5/Modules/getnameinfo.c', + 'MODULE__SOCKET_DEPS': '../Python-3.11.6/Modules/socketmodule.h ' + '../Python-3.11.6/Modules/addrinfo.h ' + '../Python-3.11.6/Modules/getaddrinfo.c ' + '../Python-3.11.6/Modules/getnameinfo.c', 'MODULE__SOCKET_LDFLAGS': '', 'MODULE__SOCKET_STATE': 'yes', - 'MODULE__SQLITE3_CFLAGS': '-I../Python-3.11.5/Modules/_sqlite', - 'MODULE__SQLITE3_DEPS': '../Python-3.11.5/Modules/_sqlite/connection.h ' - '../Python-3.11.5/Modules/_sqlite/cursor.h ' - '../Python-3.11.5/Modules/_sqlite/microprotocols.h ' - '../Python-3.11.5/Modules/_sqlite/module.h ' - '../Python-3.11.5/Modules/_sqlite/prepare_protocol.h ' - '../Python-3.11.5/Modules/_sqlite/row.h ' - '../Python-3.11.5/Modules/_sqlite/util.h', + 'MODULE__SQLITE3_CFLAGS': '-I../Python-3.11.6/Modules/_sqlite', + 'MODULE__SQLITE3_DEPS': '../Python-3.11.6/Modules/_sqlite/connection.h ' + '../Python-3.11.6/Modules/_sqlite/cursor.h ' + '../Python-3.11.6/Modules/_sqlite/microprotocols.h ' + '../Python-3.11.6/Modules/_sqlite/module.h ' + '../Python-3.11.6/Modules/_sqlite/prepare_protocol.h ' + '../Python-3.11.6/Modules/_sqlite/row.h ' + '../Python-3.11.6/Modules/_sqlite/util.h', 'MODULE__SQLITE3_LDFLAGS': '-lsqlite3', 'MODULE__SQLITE3_STATE': 'yes', 'MODULE__SRE_LDFLAGS': '', 'MODULE__SSL_CFLAGS': '', - 'MODULE__SSL_DEPS': '../Python-3.11.5/Modules/_ssl.h ' - '../Python-3.11.5/Modules/_ssl/cert.c ' - '../Python-3.11.5/Modules/_ssl/debughelpers.c ' - '../Python-3.11.5/Modules/_ssl/misc.c ' - '../Python-3.11.5/Modules/_ssl_data.h ' - '../Python-3.11.5/Modules/_ssl_data_111.h ' - '../Python-3.11.5/Modules/_ssl_data_300.h ' - '../Python-3.11.5/Modules/socketmodule.h', + 'MODULE__SSL_DEPS': '../Python-3.11.6/Modules/_ssl.h ' + '../Python-3.11.6/Modules/_ssl/cert.c ' + '../Python-3.11.6/Modules/_ssl/debughelpers.c ' + '../Python-3.11.6/Modules/_ssl/misc.c ' + '../Python-3.11.6/Modules/_ssl_data.h ' + '../Python-3.11.6/Modules/_ssl_data_111.h ' + '../Python-3.11.6/Modules/_ssl_data_300.h ' + '../Python-3.11.6/Modules/socketmodule.h', 'MODULE__SSL_LDFLAGS': '-lssl -lcrypto -lws2_32', 'MODULE__SSL_STATE': 'yes', 'MODULE__STATISTICS_LDFLAGS': '-lm', @@ -895,7 +896,7 @@ 'MODULE__STRUCT_STATE': 'yes', 'MODULE__SYMTABLE_LDFLAGS': '', 'MODULE__TESTBUFFER_STATE': 'yes', - 'MODULE__TESTCAPI_DEPS': '../Python-3.11.5/Modules/testcapi_long.h', + 'MODULE__TESTCAPI_DEPS': '../Python-3.11.6/Modules/testcapi_long.h', 'MODULE__TESTCAPI_STATE': 'yes', 'MODULE__TESTCLINIC_STATE': 'yes', 'MODULE__TESTIMPORTMULTIPLE_STATE': 'yes', @@ -975,9 +976,9 @@ '-DPY3_DLLNAME=\'L"libpython3.11.dll"\' ' '-DMS_DLL_ID=\'"3.11"\' -fprofile-use ' '-fprofile-correction ' - '-I../Python-3.11.5/Include/internal -IObjects ' + '-I../Python-3.11.6/Include/internal -IObjects ' '-IInclude -IPython -I. ' - '-I../Python-3.11.5/Include -I../Python-3.11.5/PC ' + '-I../Python-3.11.6/Include -I../Python-3.11.6/PC ' '-D__USE_MINGW_ANSI_STDIO=1 -I. ' '-D__USE_MINGW_ANSI_STDIO=1 ' '-DPy_BUILD_CORE_BUILTIN', @@ -991,7 +992,7 @@ '-fvisibility=hidden -D_WIN32_WINNT=0x0602 ' '-DPY3_DLLNAME=\'L"libpython3.11.dll"\' ' '-DMS_DLL_ID=\'"3.11"\' -fprofile-use ' - '-fprofile-correction -I../Python-3.11.5/Include/internal', + '-fprofile-correction -I../Python-3.11.6/Include/internal', 'PY_COERCE_C_LOCALE': 0, 'PY_CORE_CFLAGS': '-DNDEBUG -g -fwrapv -O3 -Wall -march=nocona -msahf ' '-mtune=generic -O2 -pipe -Wp,-D_FORTIFY_SOURCE=2 ' @@ -1002,13 +1003,13 @@ '-fvisibility=hidden -D_WIN32_WINNT=0x0602 ' '-DPY3_DLLNAME=\'L"libpython3.11.dll"\' ' '-DMS_DLL_ID=\'"3.11"\' -fprofile-use -fprofile-correction ' - '-I../Python-3.11.5/Include/internal -IObjects -IInclude ' - '-IPython -I. -I../Python-3.11.5/Include ' - '-I../Python-3.11.5/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' + '-I../Python-3.11.6/Include/internal -IObjects -IInclude ' + '-IPython -I. -I../Python-3.11.6/Include ' + '-I../Python-3.11.6/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' '-D__USE_MINGW_ANSI_STDIO=1 -DPy_BUILD_CORE', 'PY_CORE_LDFLAGS': '-pipe -pipe -fno-semantic-interposition', - 'PY_CPPFLAGS': '-IObjects -IInclude -IPython -I. -I../Python-3.11.5/Include ' - '-I../Python-3.11.5/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' + 'PY_CPPFLAGS': '-IObjects -IInclude -IPython -I. -I../Python-3.11.6/Include ' + '-I../Python-3.11.6/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' '-D__USE_MINGW_ANSI_STDIO=1', 'PY_ENABLE_SHARED': 1, 'PY_FORMAT_SIZE_T': '"z"', @@ -1030,9 +1031,9 @@ '-DPY3_DLLNAME=\'L"libpython3.11.dll"\' ' '-DMS_DLL_ID=\'"3.11"\' -fprofile-use ' '-fprofile-correction ' - '-I../Python-3.11.5/Include/internal -IObjects ' - '-IInclude -IPython -I. -I../Python-3.11.5/Include ' - '-I../Python-3.11.5/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' + '-I../Python-3.11.6/Include/internal -IObjects ' + '-IInclude -IPython -I. -I../Python-3.11.6/Include ' + '-I../Python-3.11.6/PC -D__USE_MINGW_ANSI_STDIO=1 -I. ' '-D__USE_MINGW_ANSI_STDIO=1', 'PY_SUPPORT_TIER': 0, 'Py_DEBUG': 0, @@ -1041,7 +1042,7 @@ 'Py_STATS': 0, 'Py_TRACE_REFS': 0, 'QUICKTESTOPTS': '-x test_subprocess test_io test_lib2to3 \\', - 'RCFLAGS': '-DFIELD3=5150 -O COFF --target=pe-x86-64', + 'RCFLAGS': '-DFIELD3=6150 -O COFF --target=pe-x86-64', 'READELF': 'readelf', 'RESSRCDIR': 'Mac/Resources/framework', 'RETSIGTYPE': 'void', @@ -1078,7 +1079,7 @@ 'Modules/_sre Modules/_xxtestfuzz Modules/cjkcodecs ' 'Modules/expat Objects Parser Programs Python ' 'Python/frozen_modules Python/deepfreeze PC', - 'SRC_GDB_HOOKS': '../Python-3.11.5/Tools/gdb/libpython.py', + 'SRC_GDB_HOOKS': '../Python-3.11.6/Tools/gdb/libpython.py', 'STATIC_LIBPYTHON': 1, 'STDC_HEADERS': 1, 'STRICT_SYSV_CURSES': "/* Don't use ncurses extensions */", @@ -1091,7 +1092,7 @@ 'TESTPATH': '', 'TESTPYTHON': './python.exe -E', 'TESTPYTHONOPTS': '', - 'TESTRUNNER': './python.exe -E ../Python-3.11.5/Tools/scripts/run_tests.py', + 'TESTRUNNER': './python.exe -E ../Python-3.11.6/Tools/scripts/run_tests.py', 'TESTSUBDIRS': 'ctypes/test \\', 'TESTTIMEOUT': 1200, 'TEST_MODULES': 'yes', @@ -1102,11 +1103,11 @@ 'TZPATH': '/mingw64/share/zoneinfo', 'UNICODE_DEPS': '\\', 'UNIVERSALSDK': '', - 'UPDATE_FILE': '../Python-3.11.5/Tools/scripts/update_file.py', + 'UPDATE_FILE': '../Python-3.11.6/Tools/scripts/update_file.py', 'USE_COMPUTED_GOTOS': 0, 'VENVLAUNCHERDIR': '/mingw64/lib/python3.11/venv/scripts/nt', 'VERSION': '3.11', - 'VPATH': '../Python-3.11.5', + 'VPATH': '../Python-3.11.6', 'WASM_ASSETS_DIR': './mingw64', 'WASM_STDLIB': './mingw64/lib/python3.11/os.py', 'WHEEL_PKG_DIR': '', @@ -1126,14 +1127,14 @@ 'XMLLIBSUBDIRS': 'xml xml/dom xml/etree xml/parsers xml/sax', 'abs_builddir': 'C:/M/B/src/build-MINGW64', 'abs_builddir_b2h': 'C:/M/B/src/build-MINGW64', - 'abs_srcdir': 'C:/M/B/src/Python-3.11.5', - 'abs_srcdir_b2h': 'C:/M/B/src/Python-3.11.5', + 'abs_srcdir': 'C:/M/B/src/Python-3.11.6', + 'abs_srcdir_b2h': 'C:/M/B/src/Python-3.11.6', 'datarootdir': '/mingw64/share', 'exec_prefix': '/mingw64', 'prefix': 'D:/a/msys64/mingw64', 'prefix_b2h': 'D:/a/msys64/mingw64', - 'srcdir': 'C:/M/B/src/Python-3.11.5', - 'srcdir_b2h': 'C:/M/B/src/Python-3.11.5'} + 'srcdir': 'C:/M/B/src/Python-3.11.6', + 'srcdir_b2h': 'C:/M/B/src/Python-3.11.6'} keys_to_replace = [ diff --git a/mingw64/lib/python3.11/ast.py b/mingw64/lib/python3.11/ast.py index 623b9a1b805..d84d75e1f3a 100644 --- a/mingw64/lib/python3.11/ast.py +++ b/mingw64/lib/python3.11/ast.py @@ -1175,13 +1175,29 @@ def visit_JoinedStr(self, node): new_fstring_parts = [] quote_types = list(_ALL_QUOTES) + fallback_to_repr = False for value, is_constant in fstring_parts: - value, quote_types = self._str_literal_helper( + value, new_quote_types = self._str_literal_helper( value, quote_types=quote_types, escape_special_whitespace=is_constant, ) new_fstring_parts.append(value) + if set(new_quote_types).isdisjoint(quote_types): + fallback_to_repr = True + break + quote_types = new_quote_types + + if fallback_to_repr: + # If we weren't able to find a quote type that works for all parts + # of the JoinedStr, fallback to using repr and triple single quotes. + quote_types = ["'''"] + new_fstring_parts.clear() + for value, is_constant in fstring_parts: + value = repr('"' + value) # force repr to use single quotes + expected_prefix = "'\"" + assert value.startswith(expected_prefix), repr(value) + new_fstring_parts.append(value[len(expected_prefix):-1]) value = "".join(new_fstring_parts) quote_type = quote_types[0] diff --git a/mingw64/lib/python3.11/asyncio/streams.py b/mingw64/lib/python3.11/asyncio/streams.py index 3d577f12704..19d9154b66d 100644 --- a/mingw64/lib/python3.11/asyncio/streams.py +++ b/mingw64/lib/python3.11/asyncio/streams.py @@ -67,9 +67,8 @@ async def start_server(client_connected_cb, host=None, port=None, *, positional host and port, with various optional keyword arguments following. The return value is the same as loop.create_server(). - Additional optional keyword arguments are loop (to set the event loop - instance to use) and limit (to set the buffer limit passed to the - StreamReader). + Additional optional keyword argument is limit (to set the buffer + limit passed to the StreamReader). The return value is the same as loop.create_server(), i.e. a Server object which can be used to stop the service. diff --git a/mingw64/lib/python3.11/asyncio/subprocess.py b/mingw64/lib/python3.11/asyncio/subprocess.py index c380bbb0ee9..da4f00a4a07 100644 --- a/mingw64/lib/python3.11/asyncio/subprocess.py +++ b/mingw64/lib/python3.11/asyncio/subprocess.py @@ -147,14 +147,16 @@ def kill(self): async def _feed_stdin(self, input): debug = self._loop.get_debug() - self.stdin.write(input) - if debug: - logger.debug( - '%r communicate: feed stdin (%s bytes)', self, len(input)) try: + self.stdin.write(input) + if debug: + logger.debug( + '%r communicate: feed stdin (%s bytes)', self, len(input)) + await self.stdin.drain() except (BrokenPipeError, ConnectionResetError) as exc: - # communicate() ignores BrokenPipeError and ConnectionResetError + # communicate() ignores BrokenPipeError and ConnectionResetError. + # write() and drain() can raise these exceptions. if debug: logger.debug('%r communicate: stdin got %r', self, exc) diff --git a/mingw64/lib/python3.11/asyncio/tasks.py b/mingw64/lib/python3.11/asyncio/tasks.py index 3e07ce5294c..6ca545e30ac 100644 --- a/mingw64/lib/python3.11/asyncio/tasks.py +++ b/mingw64/lib/python3.11/asyncio/tasks.py @@ -81,15 +81,25 @@ class Task(futures._PyFuture): # Inherit Python Task implementation """A coroutine wrapped in a Future.""" # An important invariant maintained while a Task not done: + # _fut_waiter is either None or a Future. The Future + # can be either done() or not done(). + # The task can be in any of 3 states: # - # - Either _fut_waiter is None, and _step() is scheduled; - # - or _fut_waiter is some Future, and _step() is *not* scheduled. + # - 1: _fut_waiter is not None and not _fut_waiter.done(): + # __step() is *not* scheduled and the Task is waiting for _fut_waiter. + # - 2: (_fut_waiter is None or _fut_waiter.done()) and __step() is scheduled: + # the Task is waiting for __step() to be executed. + # - 3: _fut_waiter is None and __step() is *not* scheduled: + # the Task is currently executing (in __step()). # - # The only transition from the latter to the former is through - # _wakeup(). When _fut_waiter is not None, one of its callbacks - # must be _wakeup(). - - # If False, don't log a message if the task is destroyed whereas its + # * In state 1, one of the callbacks of __fut_waiter must be __wakeup(). + # * The transition from 1 to 2 happens when _fut_waiter becomes done(), + # as it schedules __wakeup() to be called (which calls __step() so + # we way that __step() is scheduled). + # * It transitions from 2 to 3 when __step() is executed, and it clears + # _fut_waiter to None. + + # If False, don't log a message if the task is destroyed while its # status is still pending _log_destroy_pending = True diff --git a/mingw64/lib/python3.11/calendar.py b/mingw64/lib/python3.11/calendar.py index 657396439c9..7cdf9311b57 100644 --- a/mingw64/lib/python3.11/calendar.py +++ b/mingw64/lib/python3.11/calendar.py @@ -693,7 +693,7 @@ def main(args): parser.add_argument( "-L", "--locale", default=None, - help="locale to be used from month and weekday names" + help="locale to use for month and weekday names" ) parser.add_argument( "-e", "--encoding", diff --git a/mingw64/lib/python3.11/codecs.py b/mingw64/lib/python3.11/codecs.py index 3b173b61210..c6165fcb142 100644 --- a/mingw64/lib/python3.11/codecs.py +++ b/mingw64/lib/python3.11/codecs.py @@ -414,6 +414,9 @@ def __enter__(self): def __exit__(self, type, value, tb): self.stream.close() + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + ### class StreamReader(Codec): @@ -663,6 +666,9 @@ def __enter__(self): def __exit__(self, type, value, tb): self.stream.close() + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + ### class StreamReaderWriter: @@ -750,6 +756,9 @@ def __enter__(self): def __exit__(self, type, value, tb): self.stream.close() + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + ### class StreamRecoder: @@ -866,6 +875,9 @@ def __enter__(self): def __exit__(self, type, value, tb): self.stream.close() + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + ### Shortcuts def open(filename, mode='r', encoding=None, errors='strict', buffering=-1): diff --git a/mingw64/lib/python3.11/concurrent/futures/process.py b/mingw64/lib/python3.11/concurrent/futures/process.py index 321608ab174..952fa903457 100644 --- a/mingw64/lib/python3.11/concurrent/futures/process.py +++ b/mingw64/lib/python3.11/concurrent/futures/process.py @@ -69,6 +69,11 @@ def __init__(self): self._reader, self._writer = mp.Pipe(duplex=False) def close(self): + # Please note that we do not take the shutdown lock when + # calling clear() (to avoid deadlocking) so this method can + # only be called safely from the same thread as all calls to + # clear() even if you hold the shutdown lock. Otherwise we + # might try to read from the closed pipe. if not self._closed: self._closed = True self._writer.close() @@ -424,8 +429,12 @@ def wait_result_broken_or_wakeup(self): elif wakeup_reader in ready: is_broken = False - with self.shutdown_lock: - self.thread_wakeup.clear() + # No need to hold the _shutdown_lock here because: + # 1. we're the only thread to use the wakeup reader + # 2. we're also the only thread to call thread_wakeup.close() + # 3. we want to avoid a possible deadlock when both reader and writer + # would block (gh-105829) + self.thread_wakeup.clear() return result_item, is_broken, cause @@ -501,6 +510,11 @@ def terminate_broken(self, cause): # https://github.com/python/cpython/issues/94777 self.call_queue._reader.close() + # gh-107219: Close the connection writer which can unblock + # Queue._feed() if it was stuck in send_bytes(). + if sys.platform == 'win32': + self.call_queue._writer.close() + # clean up resources self.join_executor_internals() @@ -704,7 +718,10 @@ def __init__(self, max_workers=None, mp_context=None, # as it could result in a deadlock if a worker process dies with the # _result_queue write lock still acquired. # - # _shutdown_lock must be locked to access _ThreadWakeup. + # _shutdown_lock must be locked to access _ThreadWakeup.close() and + # .wakeup(). Care must also be taken to not call clear or close from + # more than one thread since _ThreadWakeup.clear() is not protected by + # the _shutdown_lock self._executor_manager_thread_wakeup = _ThreadWakeup() # Create communication channels for the executor diff --git a/mingw64/lib/python3.11/config-3.11/Makefile b/mingw64/lib/python3.11/config-3.11/Makefile index 46df9bfa8da..7b1aa635779 100644 --- a/mingw64/lib/python3.11/config-3.11/Makefile +++ b/mingw64/lib/python3.11/config-3.11/Makefile @@ -29,9 +29,9 @@ MODLIBS= $(LOCALMODLIBS) $(BASEMODLIBS) # === Variables set by configure VERSION= 3.11 -srcdir= ../Python-3.11.5 -VPATH= ../Python-3.11.5 -abs_srcdir= /c/M/B/src/build-MINGW64/../Python-3.11.5 +srcdir= ../Python-3.11.6 +VPATH= ../Python-3.11.6 +abs_srcdir= /c/M/B/src/build-MINGW64/../Python-3.11.6 abs_builddir= /c/M/B/src/build-MINGW64 @@ -125,7 +125,7 @@ PY_CORE_CFLAGS= $(PY_STDMODULE_CFLAGS) -DPy_BUILD_CORE PY_CORE_LDFLAGS=$(PY_LDFLAGS) $(PY_LDFLAGS_NODIST) # Strict or non-strict aliasing flags used to compile dtoa.c, see above CFLAGS_ALIASING= -RCFLAGS= -DFIELD3=5150 -O COFF --target=pe-x86-64 +RCFLAGS= -DFIELD3=6150 -O COFF --target=pe-x86-64 # Machine-dependent subdirectories @@ -145,8 +145,8 @@ exec_prefix= ${prefix} datarootdir= ${prefix}/share # Locations needed for semi-native fixup of sysconfig. -srcdir_b2h= C:/M/B/src/Python-3.11.5 -abs_srcdir_b2h= C:/M/B/src/Python-3.11.5 +srcdir_b2h= C:/M/B/src/Python-3.11.6 +abs_srcdir_b2h= C:/M/B/src/Python-3.11.6 abs_builddir_b2h= C:/M/B/src/build-MINGW64 prefix_b2h= D:/a/msys64/mingw64 @@ -636,6 +636,7 @@ OBJECT_OBJS= \ Objects/unionobject.o \ Objects/weakrefobject.o +DEEPFREEZE_C = Python/deepfreeze/deepfreeze.c DEEPFREEZE_OBJS = Python/deepfreeze/deepfreeze.o ########################################################################## @@ -1332,12 +1333,12 @@ regen-frozen: Tools/scripts/freeze_modules.py $(FROZEN_FILES_IN) # Deepfreeze targets .PHONY: regen-deepfreeze -regen-deepfreeze: $(DEEPFREEZE_OBJS) +regen-deepfreeze: $(DEEPFREEZE_C) DEEPFREEZE_DEPS=$(srcdir)/Tools/scripts/deepfreeze.py $(FREEZE_MODULE_DEPS) $(FROZEN_FILES_OUT) # BEGIN: deepfreeze modules -Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS) +$(DEEPFREEZE_C): $(DEEPFREEZE_DEPS) $(PYTHON_FOR_FREEZE) $(srcdir)/Tools/scripts/deepfreeze.py \ Python/frozen_modules/importlib._bootstrap.h:importlib._bootstrap \ Python/frozen_modules/importlib._bootstrap_external.h:importlib._bootstrap_external \ @@ -1364,8 +1365,6 @@ Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS) Python/frozen_modules/frozen_only.h:frozen_only \ -o Python/deepfreeze/deepfreeze.c # END: deepfreeze modules - @echo "Note: Deepfreeze may have added some global objects," - @echo " so run 'make regen-global-objects' if necessary." # We keep this renamed target around for folks with muscle memory. .PHONY: regen-importlib @@ -1374,11 +1373,12 @@ regen-importlib: regen-frozen ############################################################################ # Global objects +# Dependencies which can add and/or remove _Py_ID() identifiers: +# - deepfreeze.c +# - "make clinic" .PHONY: regen-global-objects -regen-global-objects: $(srcdir)/Tools/scripts/generate_global_objects.py +regen-global-objects: $(srcdir)/Tools/scripts/generate_global_objects.py $(DEEPFREEZE_C) clinic $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_global_objects.py - @echo "Note: Global objects can be added or removed by other tools (e.g. deepfreeze), " - @echo " so be sure to re-run regen-global-objects after those tools." ############################################################################ # ABI @@ -1397,8 +1397,10 @@ regen-limited-abi: all ############################################################################ # Regenerate all generated files +# "clinic" is regenerated implicitly via "regen-global-objects". +.PHONY: regen-all regen-all: regen-opcode regen-opcode-targets regen-typeslots \ - regen-token regen-ast regen-keyword regen-sre regen-frozen clinic \ + regen-token regen-ast regen-keyword regen-sre regen-frozen \ regen-pegen-metaparser regen-pegen regen-test-frozenmain \ regen-global-objects @echo @@ -2152,8 +2154,10 @@ TESTSUBDIRS= ctypes/test \ test/test_asyncio \ test/test_capi \ test/test_cppext \ + test/test_dataclasses \ test/test_email \ test/test_email/data \ + test/test_future_stmt \ test/test_import \ test/test_import/data \ test/test_import/data/circular_imports \ @@ -2231,6 +2235,7 @@ TESTSUBDIRS= ctypes/test \ test/test_warnings/data \ test/test_zoneinfo \ test/test_zoneinfo/data \ + test/tokenizedata \ test/tracedmodules \ test/typinganndata \ test/xmltestdata \ @@ -2589,6 +2594,7 @@ recheck: autoconf: (cd $(srcdir); autoreconf -ivf -Werror) +# See https://github.com/tiran/cpython_autoconf container .PHONY: regen-configure regen-configure: @if command -v podman >/dev/null; then RUNTIME="podman"; else RUNTIME="docker"; fi; \ diff --git a/mingw64/lib/python3.11/config-3.11/config.c b/mingw64/lib/python3.11/config-3.11/config.c index 159ef46dd8f..804b2ff68c8 100644 --- a/mingw64/lib/python3.11/config-3.11/config.c +++ b/mingw64/lib/python3.11/config-3.11/config.c @@ -1,4 +1,4 @@ -/* Generated automatically from ../Python-3.11.5/Modules/config.c.in by makesetup. */ +/* Generated automatically from ../Python-3.11.6/Modules/config.c.in by makesetup. */ /* -*- C -*- *********************************************** Copyright (c) 2000, BeOpen.com. Copyright (c) 1995-2000, Corporation for National Research Initiatives. diff --git a/mingw64/lib/python3.11/config-3.11/python.o b/mingw64/lib/python3.11/config-3.11/python.o index f2d7b28e808..45b02ffe5f3 100644 Binary files a/mingw64/lib/python3.11/config-3.11/python.o and b/mingw64/lib/python3.11/config-3.11/python.o differ diff --git a/mingw64/lib/python3.11/datetime.py b/mingw64/lib/python3.11/datetime.py index c3c2568f986..474b4e9ae53 100644 --- a/mingw64/lib/python3.11/datetime.py +++ b/mingw64/lib/python3.11/datetime.py @@ -1002,13 +1002,9 @@ def fromisocalendar(cls, year, week, day): def __repr__(self): """Convert to formal string, for repr(). - >>> dt = datetime(2010, 1, 1) - >>> repr(dt) - 'datetime.datetime(2010, 1, 1, 0, 0)' - - >>> dt = datetime(2010, 1, 1, tzinfo=timezone.utc) - >>> repr(dt) - 'datetime.datetime(2010, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)' + >>> d = date(2010, 1, 1) + >>> repr(d) + 'datetime.date(2010, 1, 1)' """ return "%s.%s(%d, %d, %d)" % (self.__class__.__module__, self.__class__.__qualname__, @@ -1223,7 +1219,7 @@ def __reduce__(self): class tzinfo: """Abstract base class for time zone info classes. - Subclasses must override the name(), utcoffset() and dst() methods. + Subclasses must override the tzname(), utcoffset() and dst() methods. """ __slots__ = () diff --git a/mingw64/lib/python3.11/enum.py b/mingw64/lib/python3.11/enum.py index 1f447c878c1..155cb13022f 100644 --- a/mingw64/lib/python3.11/enum.py +++ b/mingw64/lib/python3.11/enum.py @@ -863,6 +863,8 @@ def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, s value = first_enum._generate_next_value_(name, start, count, last_values[:]) last_values.append(value) names.append((name, value)) + if names is None: + names = () # Here, names is either an iterable of (name, value) or a mapping. for item in names: @@ -1107,6 +1109,11 @@ def __new__(cls, value): for member in cls._member_map_.values(): if member._value_ == value: return member + # still not found -- verify that members exist, in-case somebody got here mistakenly + # (such as via super when trying to override __new__) + if not cls._member_map_: + raise TypeError("%r has no members defined" % cls) + # # still not found -- try _missing_ hook try: exc = None diff --git a/mingw64/lib/python3.11/lib-dynload/_asyncio.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_asyncio.cp311-mingw_x86_64.pyd index ce174954266..35c54181d04 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_asyncio.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_asyncio.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_bisect.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_bisect.cp311-mingw_x86_64.pyd index a7dc8107612..780aff24636 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_bisect.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_bisect.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_blake2.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_blake2.cp311-mingw_x86_64.pyd index dbd2e738733..5267780eb1d 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_blake2.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_blake2.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_bz2.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_bz2.cp311-mingw_x86_64.pyd index 5049fe5d975..bec49adc97d 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_bz2.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_bz2.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_codecs_cn.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_codecs_cn.cp311-mingw_x86_64.pyd index 906fb72a5a2..1a245f01f08 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_codecs_cn.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_codecs_cn.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_codecs_hk.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_codecs_hk.cp311-mingw_x86_64.pyd index 8f858f08dca..f005a137f74 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_codecs_hk.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_codecs_hk.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_codecs_iso2022.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_codecs_iso2022.cp311-mingw_x86_64.pyd index 4f39a907a27..a3ca8bec753 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_codecs_iso2022.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_codecs_iso2022.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_codecs_jp.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_codecs_jp.cp311-mingw_x86_64.pyd index f6ed802c9a2..443c0d6fe54 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_codecs_jp.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_codecs_jp.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_codecs_kr.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_codecs_kr.cp311-mingw_x86_64.pyd index f8273a6f133..6f8ae898cdd 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_codecs_kr.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_codecs_kr.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_codecs_tw.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_codecs_tw.cp311-mingw_x86_64.pyd index 86fe30cb173..b5b42ae1385 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_codecs_tw.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_codecs_tw.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_contextvars.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_contextvars.cp311-mingw_x86_64.pyd index 76b69181050..1a02bf9997c 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_contextvars.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_contextvars.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_csv.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_csv.cp311-mingw_x86_64.pyd index c182bf18902..e275a7a44ed 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_csv.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_csv.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_ctypes.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_ctypes.cp311-mingw_x86_64.pyd index 29bfa39bce8..83978605459 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_ctypes.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_ctypes.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_ctypes_test.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_ctypes_test.cp311-mingw_x86_64.pyd index 96ecb6d20fd..2e8f5aa4953 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_ctypes_test.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_ctypes_test.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_curses.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_curses.cp311-mingw_x86_64.pyd index 9f9153eb262..e1a15f5ea49 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_curses.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_curses.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_curses_panel.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_curses_panel.cp311-mingw_x86_64.pyd index d2ed5eaaeb5..5216fe92569 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_curses_panel.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_curses_panel.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_datetime.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_datetime.cp311-mingw_x86_64.pyd index d78d4126ca2..2f0d7571c2d 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_datetime.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_datetime.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_decimal.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_decimal.cp311-mingw_x86_64.pyd index 68701624a96..3ccb7702282 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_decimal.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_decimal.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_elementtree.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_elementtree.cp311-mingw_x86_64.pyd index 71b93a8b398..43a808458c2 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_elementtree.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_elementtree.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_hashlib.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_hashlib.cp311-mingw_x86_64.pyd index 3f8656d18b1..edd70aefff6 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_hashlib.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_hashlib.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_heapq.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_heapq.cp311-mingw_x86_64.pyd index 324654378db..3870dcf7432 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_heapq.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_heapq.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_json.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_json.cp311-mingw_x86_64.pyd index 401880de3a6..80a17b79704 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_json.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_json.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_lsprof.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_lsprof.cp311-mingw_x86_64.pyd index f3ed24a490c..e3bb47ba15b 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_lsprof.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_lsprof.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_lzma.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_lzma.cp311-mingw_x86_64.pyd index dbd38706f4c..339b466d1e6 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_lzma.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_lzma.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_md5.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_md5.cp311-mingw_x86_64.pyd index f92d41b9828..a99f1f5eec7 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_md5.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_md5.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_msi.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_msi.cp311-mingw_x86_64.pyd index 4266eb84ea3..9665a107602 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_msi.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_msi.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_multibytecodec.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_multibytecodec.cp311-mingw_x86_64.pyd index cfcc299c85d..69b5bd5c9dc 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_multibytecodec.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_multibytecodec.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_multiprocessing.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_multiprocessing.cp311-mingw_x86_64.pyd index 2666622dee3..8ef5ee83966 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_multiprocessing.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_multiprocessing.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_opcode.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_opcode.cp311-mingw_x86_64.pyd index 50d3a87e0d1..43127e7f7f3 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_opcode.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_opcode.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_overlapped.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_overlapped.cp311-mingw_x86_64.pyd index 887e70e691c..c53124e122a 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_overlapped.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_overlapped.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_pickle.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_pickle.cp311-mingw_x86_64.pyd index 7eca564c56a..7fd0d5b7d89 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_pickle.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_pickle.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_queue.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_queue.cp311-mingw_x86_64.pyd index 054ef9fd460..fb17b69740a 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_queue.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_queue.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_random.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_random.cp311-mingw_x86_64.pyd index 6de9ebf8d0c..1fbd953901c 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_random.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_random.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_sha1.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_sha1.cp311-mingw_x86_64.pyd index d8b6ceb0dfa..bf6e969dc35 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_sha1.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_sha1.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_sha256.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_sha256.cp311-mingw_x86_64.pyd index 9d8f98f9763..61f0181bbcb 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_sha256.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_sha256.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_sha3.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_sha3.cp311-mingw_x86_64.pyd index f458032a05e..80f0d78f40d 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_sha3.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_sha3.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_sha512.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_sha512.cp311-mingw_x86_64.pyd index 302236a203f..f031b64164e 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_sha512.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_sha512.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_socket.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_socket.cp311-mingw_x86_64.pyd index d3147b42ac6..05a80d466e2 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_socket.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_socket.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_sqlite3.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_sqlite3.cp311-mingw_x86_64.pyd index 964cd0bd679..5bfee95c759 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_sqlite3.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_sqlite3.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_ssl.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_ssl.cp311-mingw_x86_64.pyd index d15aca74cd1..9a31e4585c6 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_ssl.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_ssl.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_statistics.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_statistics.cp311-mingw_x86_64.pyd index ca4e8665731..7fb4e53ddac 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_statistics.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_statistics.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_struct.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_struct.cp311-mingw_x86_64.pyd index 8fd61a750d1..bb20aeaecb3 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_struct.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_struct.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_testbuffer.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_testbuffer.cp311-mingw_x86_64.pyd index b8ec0c7cfcf..bc807dca1d0 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_testbuffer.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_testbuffer.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_testcapi.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_testcapi.cp311-mingw_x86_64.pyd index 812adb1d302..f9efa3e6efc 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_testcapi.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_testcapi.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_testclinic.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_testclinic.cp311-mingw_x86_64.pyd index aaa82c3fc18..a93a59b4daa 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_testclinic.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_testclinic.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_testconsole.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_testconsole.cp311-mingw_x86_64.pyd index dc6b47a9e0a..8b2a8df0bdc 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_testconsole.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_testconsole.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_testimportmultiple.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_testimportmultiple.cp311-mingw_x86_64.pyd index 831f10cdccf..31e2edd2828 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_testimportmultiple.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_testimportmultiple.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_testinternalcapi.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_testinternalcapi.cp311-mingw_x86_64.pyd index d719b6df799..ae05e97f841 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_testinternalcapi.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_testinternalcapi.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_testmultiphase.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_testmultiphase.cp311-mingw_x86_64.pyd index a6634e18167..b7842eb326d 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_testmultiphase.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_testmultiphase.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_tkinter.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_tkinter.cp311-mingw_x86_64.pyd index db33071cf59..3d080bdda71 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_tkinter.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_tkinter.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_typing.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_typing.cp311-mingw_x86_64.pyd index 08883bdd2ca..66abe4656a6 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_typing.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_typing.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_xxsubinterpreters.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_xxsubinterpreters.cp311-mingw_x86_64.pyd index 1228bf9fd9b..f2fa788203e 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_xxsubinterpreters.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_xxsubinterpreters.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_xxtestfuzz.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_xxtestfuzz.cp311-mingw_x86_64.pyd index c4dcd36fc44..9f7b40d5e7b 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_xxtestfuzz.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_xxtestfuzz.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/_zoneinfo.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/_zoneinfo.cp311-mingw_x86_64.pyd index 54138325304..5f203397a24 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/_zoneinfo.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/_zoneinfo.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/array.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/array.cp311-mingw_x86_64.pyd index af82a9f8077..dfd53b199b9 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/array.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/array.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/audioop.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/audioop.cp311-mingw_x86_64.pyd index 6d3c72482a9..533e13a365d 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/audioop.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/audioop.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/binascii.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/binascii.cp311-mingw_x86_64.pyd index f1348927669..af058202651 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/binascii.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/binascii.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/cmath.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/cmath.cp311-mingw_x86_64.pyd index d07be1150b5..5b4a8335de7 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/cmath.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/cmath.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/math.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/math.cp311-mingw_x86_64.pyd index 420e9a66cf0..84b7c2d28d0 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/math.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/math.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/mmap.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/mmap.cp311-mingw_x86_64.pyd index 2de2c8d6470..23c80c4bcb9 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/mmap.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/mmap.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/pyexpat.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/pyexpat.cp311-mingw_x86_64.pyd index 6114d2b839e..67d97efdab1 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/pyexpat.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/pyexpat.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/select.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/select.cp311-mingw_x86_64.pyd index ff4459a7089..4631489545b 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/select.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/select.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/unicodedata.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/unicodedata.cp311-mingw_x86_64.pyd index e3c89c723af..f111ef2774d 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/unicodedata.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/unicodedata.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/winsound.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/winsound.cp311-mingw_x86_64.pyd index 53aa50e2bae..3184da2fd27 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/winsound.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/winsound.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/xxlimited.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/xxlimited.cp311-mingw_x86_64.pyd index 63a04f6ecdc..ad8fc84e59f 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/xxlimited.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/xxlimited.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/xxlimited_35.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/xxlimited_35.cp311-mingw_x86_64.pyd index 8e66f85aefd..26ae3e8a404 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/xxlimited_35.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/xxlimited_35.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib-dynload/zlib.cp311-mingw_x86_64.pyd b/mingw64/lib/python3.11/lib-dynload/zlib.cp311-mingw_x86_64.pyd index 3cb3568130a..a26ee4ee955 100644 Binary files a/mingw64/lib/python3.11/lib-dynload/zlib.cp311-mingw_x86_64.pyd and b/mingw64/lib/python3.11/lib-dynload/zlib.cp311-mingw_x86_64.pyd differ diff --git a/mingw64/lib/python3.11/lib2to3/Grammar3.11.5.final.0.pickle b/mingw64/lib/python3.11/lib2to3/Grammar3.11.6.final.0.pickle similarity index 100% rename from mingw64/lib/python3.11/lib2to3/Grammar3.11.5.final.0.pickle rename to mingw64/lib/python3.11/lib2to3/Grammar3.11.6.final.0.pickle diff --git a/mingw64/lib/python3.11/lib2to3/PatternGrammar3.11.5.final.0.pickle b/mingw64/lib/python3.11/lib2to3/PatternGrammar3.11.6.final.0.pickle similarity index 100% rename from mingw64/lib/python3.11/lib2to3/PatternGrammar3.11.5.final.0.pickle rename to mingw64/lib/python3.11/lib2to3/PatternGrammar3.11.6.final.0.pickle diff --git a/mingw64/lib/python3.11/multiprocessing/connection.py b/mingw64/lib/python3.11/multiprocessing/connection.py index b08144f7a1a..8b81f9954e4 100644 --- a/mingw64/lib/python3.11/multiprocessing/connection.py +++ b/mingw64/lib/python3.11/multiprocessing/connection.py @@ -9,6 +9,7 @@ __all__ = [ 'Client', 'Listener', 'Pipe', 'wait' ] +import errno import io import os import sys @@ -271,12 +272,22 @@ class PipeConnection(_ConnectionBase): with FILE_FLAG_OVERLAPPED. """ _got_empty_message = False + _send_ov = None def _close(self, _CloseHandle=_winapi.CloseHandle): + ov = self._send_ov + if ov is not None: + # Interrupt WaitForMultipleObjects() in _send_bytes() + ov.cancel() _CloseHandle(self._handle) def _send_bytes(self, buf): + if self._send_ov is not None: + # A connection should only be used by a single thread + raise ValueError("concurrent send_bytes() calls " + "are not supported") ov, err = _winapi.WriteFile(self._handle, buf, overlapped=True) + self._send_ov = ov try: if err == _winapi.ERROR_IO_PENDING: waitres = _winapi.WaitForMultipleObjects( @@ -286,7 +297,13 @@ def _send_bytes(self, buf): ov.cancel() raise finally: + self._send_ov = None nwritten, err = ov.GetOverlappedResult(True) + if err == _winapi.ERROR_OPERATION_ABORTED: + # close() was called by another thread while + # WaitForMultipleObjects() was waiting for the overlapped + # operation. + raise OSError(errno.EPIPE, "handle is closed") assert err == 0 assert nwritten == len(buf) diff --git a/mingw64/lib/python3.11/multiprocessing/popen_spawn_win32.py b/mingw64/lib/python3.11/multiprocessing/popen_spawn_win32.py index 4d60ffc030b..af044305709 100644 --- a/mingw64/lib/python3.11/multiprocessing/popen_spawn_win32.py +++ b/mingw64/lib/python3.11/multiprocessing/popen_spawn_win32.py @@ -14,6 +14,7 @@ # # +# Exit code used by Popen.terminate() TERMINATE = 0x10000 WINEXE = (sys.platform == 'win32' and getattr(sys, 'frozen', False)) WINSERVICE = sys.executable.lower().endswith("pythonservice.exe") @@ -122,9 +123,15 @@ def terminate(self): if self.returncode is None: try: _winapi.TerminateProcess(int(self._handle), TERMINATE) - except OSError: - if self.wait(timeout=1.0) is None: + except PermissionError: + # ERROR_ACCESS_DENIED (winerror 5) is received when the + # process already died. + code = _winapi.GetExitCodeProcess(int(self._handle)) + if code == _winapi.STILL_ACTIVE: raise + self.returncode = code + else: + self.returncode = -signal.SIGTERM kill = terminate diff --git a/mingw64/lib/python3.11/multiprocessing/resource_tracker.py b/mingw64/lib/python3.11/multiprocessing/resource_tracker.py index ea369507297..79e96ecf324 100644 --- a/mingw64/lib/python3.11/multiprocessing/resource_tracker.py +++ b/mingw64/lib/python3.11/multiprocessing/resource_tracker.py @@ -51,15 +51,31 @@ }) +class ReentrantCallError(RuntimeError): + pass + + class ResourceTracker(object): def __init__(self): - self._lock = threading.Lock() + self._lock = threading.RLock() self._fd = None self._pid = None + def _reentrant_call_error(self): + # gh-109629: this happens if an explicit call to the ResourceTracker + # gets interrupted by a garbage collection, invoking a finalizer (*) + # that itself calls back into ResourceTracker. + # (*) for example the SemLock finalizer + raise ReentrantCallError( + "Reentrant call into the multiprocessing resource tracker") + def _stop(self): with self._lock: + # This should not happen (_stop() isn't called by a finalizer) + # but we check for it anyway. + if self._lock._recursion_count() > 1: + return self._reentrant_call_error() if self._fd is None: # not running return @@ -81,6 +97,9 @@ def ensure_running(self): This can be run from any process. Usually a child process will use the resource created by its parent.''' with self._lock: + if self._lock._recursion_count() > 1: + # The code below is certainly not reentrant-safe, so bail out + return self._reentrant_call_error() if self._fd is not None: # resource tracker was launched before, is it still running? if self._check_alive(): @@ -159,7 +178,17 @@ def unregister(self, name, rtype): self._send('UNREGISTER', name, rtype) def _send(self, cmd, name, rtype): - self.ensure_running() + try: + self.ensure_running() + except ReentrantCallError: + # The code below might or might not work, depending on whether + # the resource tracker was already running and still alive. + # Better warn the user. + # (XXX is warnings.warn itself reentrant-safe? :-) + warnings.warn( + f"ResourceTracker called reentrantly for resource cleanup, " + f"which is unsupported. " + f"The {rtype} object {name!r} might leak.") msg = '{0}:{1}:{2}\n'.format(cmd, name, rtype).encode('ascii') if len(msg) > 512: # posix guarantees that writes to a pipe of less than PIPE_BUF @@ -176,6 +205,7 @@ def _send(self, cmd, name, rtype): unregister = _resource_tracker.unregister getfd = _resource_tracker.getfd + def main(fd): '''Run resource tracker.''' # protect the process from ^C and "killall python" etc diff --git a/mingw64/lib/python3.11/multiprocessing/synchronize.py b/mingw64/lib/python3.11/multiprocessing/synchronize.py index 2328d332123..3ccbfe311c7 100644 --- a/mingw64/lib/python3.11/multiprocessing/synchronize.py +++ b/mingw64/lib/python3.11/multiprocessing/synchronize.py @@ -50,8 +50,8 @@ class SemLock(object): def __init__(self, kind, value, maxvalue, *, ctx): if ctx is None: ctx = context._default_context.get_context() - self.is_fork_ctx = ctx.get_start_method() == 'fork' - unlink_now = sys.platform == 'win32' or self.is_fork_ctx + self._is_fork_ctx = ctx.get_start_method() == 'fork' + unlink_now = sys.platform == 'win32' or self._is_fork_ctx for i in range(100): try: sl = self._semlock = _multiprocessing.SemLock( @@ -103,7 +103,7 @@ def __getstate__(self): if sys.platform == 'win32': h = context.get_spawning_popen().duplicate_for_child(sl.handle) else: - if self.is_fork_ctx: + if self._is_fork_ctx: raise RuntimeError('A SemLock created in a fork context is being ' 'shared with a process in a spawn context. This is ' 'not supported. Please use the same context to create ' @@ -115,6 +115,8 @@ def __setstate__(self, state): self._semlock = _multiprocessing.SemLock._rebuild(*state) util.debug('recreated blocker with handle %r' % state[0]) self._make_methods() + # Ensure that deserialized SemLock can be serialized again (gh-108520). + self._is_fork_ctx = False @staticmethod def _make_name(): diff --git a/mingw64/lib/python3.11/pdb.py b/mingw64/lib/python3.11/pdb.py index d3824e19fa8..fe9eab9b5e1 100644 --- a/mingw64/lib/python3.11/pdb.py +++ b/mingw64/lib/python3.11/pdb.py @@ -1505,8 +1505,11 @@ def do_alias(self, arg): for alias in keys: self.message("%s = %s" % (alias, self.aliases[alias])) return - if args[0] in self.aliases and len(args) == 1: - self.message("%s = %s" % (args[0], self.aliases[args[0]])) + if len(args) == 1: + if args[0] in self.aliases: + self.message("%s = %s" % (args[0], self.aliases[args[0]])) + else: + self.error(f"Unknown alias '{args[0]}'") else: self.aliases[args[0]] = ' '.join(args[1:]) diff --git a/mingw64/lib/python3.11/pydoc_data/topics.py b/mingw64/lib/python3.11/pydoc_data/topics.py index 1b1251b6909..06422d21c6b 100644 --- a/mingw64/lib/python3.11/pydoc_data/topics.py +++ b/mingw64/lib/python3.11/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Thu Aug 24 13:07:17 2023 +# Autogenerated by Sphinx on Mon Oct 2 14:27:48 2023 # as part of the release process. topics = {'assert': 'The "assert" statement\n' '**********************\n' @@ -1076,9 +1076,7 @@ 'for each\n' ' instance.\n' '\n' - '\n' - 'Notes on using *__slots__*\n' - '--------------------------\n' + 'Notes on using *__slots__*:\n' '\n' '* When inheriting from a class without *__slots__*, the ' '"__dict__" and\n' @@ -10003,9 +10001,7 @@ 'each\n' ' instance.\n' '\n' - '\n' - 'Notes on using *__slots__*\n' - '~~~~~~~~~~~~~~~~~~~~~~~~~~\n' + 'Notes on using *__slots__*:\n' '\n' '* When inheriting from a class without *__slots__*, the ' '"__dict__" and\n' @@ -12374,71 +12370,71 @@ 'those\n' 'used by Standard C. The recognized escape sequences are:\n' '\n' - '+-------------------+-----------------------------------+---------+\n' - '| Escape Sequence | Meaning | Notes ' - '|\n' - '|===================|===================================|=========|\n' - '| "\\" | Backslash and newline ignored | ' - '(1) |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\\\" | Backslash ("\\") ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\\'" | Single quote ("\'") ' + '+---------------------------+-----------------------------------+---------+\n' + '| Escape Sequence | Meaning | ' + 'Notes |\n' + '|===========================|===================================|=========|\n' + '| "\\" | Backslash and newline ignored ' + '| (1) |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\\\" | Backslash ' + '("\\") | |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\\'" | Single quote ' + '("\'") | |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\"" | Double quote (""") ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\"" | Double quote (""") ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\a" | ASCII Bell (BEL) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\a" | ASCII Bell (BEL) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\b" | ASCII Backspace (BS) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\b" | ASCII Backspace (BS) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\f" | ASCII Formfeed (FF) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\f" | ASCII Formfeed (FF) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\n" | ASCII Linefeed (LF) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\n" | ASCII Linefeed (LF) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\r" | ASCII Carriage Return (CR) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\r" | ASCII Carriage Return (CR) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\t" | ASCII Horizontal Tab (TAB) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\t" | ASCII Horizontal Tab (TAB) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\v" | ASCII Vertical Tab (VT) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\v" | ASCII Vertical Tab (VT) ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\ooo" | Character with octal value *ooo* | ' - '(2,4) |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\xhh" | Character with hex value *hh* | ' - '(3,4) |\n' - '+-------------------+-----------------------------------+---------+\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\*ooo*" | Character with octal value *ooo* ' + '| (2,4) |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\x*hh*" | Character with hex value *hh* ' + '| (3,4) |\n' + '+---------------------------+-----------------------------------+---------+\n' '\n' 'Escape sequences only recognized in string literals are:\n' '\n' - '+-------------------+-----------------------------------+---------+\n' - '| Escape Sequence | Meaning | Notes ' - '|\n' - '|===================|===================================|=========|\n' - '| "\\N{name}" | Character named *name* in the | ' - '(5) |\n' - '| | Unicode database | ' - '|\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\uxxxx" | Character with 16-bit hex value | ' - '(6) |\n' - '| | *xxxx* | ' - '|\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\Uxxxxxxxx" | Character with 32-bit hex value | ' - '(7) |\n' - '| | *xxxxxxxx* | ' - '|\n' - '+-------------------+-----------------------------------+---------+\n' + '+---------------------------+-----------------------------------+---------+\n' + '| Escape Sequence | Meaning | ' + 'Notes |\n' + '|===========================|===================================|=========|\n' + '| "\\N{*name*}" | Character named *name* in the ' + '| (5) |\n' + '| | Unicode database ' + '| |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\u*xxxx*" | Character with 16-bit hex value ' + '| (6) |\n' + '| | *xxxx* ' + '| |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\U*xxxxxxxx*" | Character with 32-bit hex value ' + '| (7) |\n' + '| | *xxxxxxxx* ' + '| |\n' + '+---------------------------+-----------------------------------+---------+\n' '\n' 'Notes:\n' '\n' @@ -12896,1145 +12892,1172 @@ 'definition\n' 'may change in the future.\n' '\n' + '\n' 'None\n' - ' This type has a single value. There is a single object with ' - 'this\n' - ' value. This object is accessed through the built-in name "None". ' - 'It\n' - ' is used to signify the absence of a value in many situations, ' - 'e.g.,\n' - ' it is returned from functions that don’t explicitly return\n' - ' anything. Its truth value is false.\n' + '====\n' + '\n' + 'This type has a single value. There is a single object with this\n' + 'value. This object is accessed through the built-in name "None". It ' + 'is\n' + 'used to signify the absence of a value in many situations, e.g., it ' + 'is\n' + 'returned from functions that don’t explicitly return anything. Its\n' + 'truth value is false.\n' + '\n' '\n' 'NotImplemented\n' - ' This type has a single value. There is a single object with ' - 'this\n' - ' value. This object is accessed through the built-in name\n' - ' "NotImplemented". Numeric methods and rich comparison methods\n' - ' should return this value if they do not implement the operation ' - 'for\n' - ' the operands provided. (The interpreter will then try the\n' - ' reflected operation, or some other fallback, depending on the\n' - ' operator.) It should not be evaluated in a boolean context.\n' + '==============\n' + '\n' + 'This type has a single value. There is a single object with this\n' + 'value. This object is accessed through the built-in name\n' + '"NotImplemented". Numeric methods and rich comparison methods ' + 'should\n' + 'return this value if they do not implement the operation for the\n' + 'operands provided. (The interpreter will then try the reflected\n' + 'operation, or some other fallback, depending on the operator.) It\n' + 'should not be evaluated in a boolean context.\n' '\n' - ' See Implementing the arithmetic operations for more details.\n' + 'See Implementing the arithmetic operations for more details.\n' + '\n' + 'Changed in version 3.9: Evaluating "NotImplemented" in a boolean\n' + 'context is deprecated. While it currently evaluates as true, it ' + 'will\n' + 'emit a "DeprecationWarning". It will raise a "TypeError" in a ' + 'future\n' + 'version of Python.\n' '\n' - ' Changed in version 3.9: Evaluating "NotImplemented" in a ' - 'boolean\n' - ' context is deprecated. While it currently evaluates as true, it\n' - ' will emit a "DeprecationWarning". It will raise a "TypeError" in ' - 'a\n' - ' future version of Python.\n' '\n' 'Ellipsis\n' - ' This type has a single value. There is a single object with ' - 'this\n' - ' value. This object is accessed through the literal "..." or the\n' - ' built-in name "Ellipsis". Its truth value is true.\n' + '========\n' + '\n' + 'This type has a single value. There is a single object with this\n' + 'value. This object is accessed through the literal "..." or the ' + 'built-\n' + 'in name "Ellipsis". Its truth value is true.\n' + '\n' '\n' '"numbers.Number"\n' - ' These are created by numeric literals and returned as results ' - 'by\n' - ' arithmetic operators and arithmetic built-in functions. ' - 'Numeric\n' - ' objects are immutable; once created their value never changes.\n' - ' Python numbers are of course strongly related to mathematical\n' - ' numbers, but subject to the limitations of numerical ' - 'representation\n' - ' in computers.\n' - '\n' - ' The string representations of the numeric classes, computed by\n' - ' "__repr__()" and "__str__()", have the following properties:\n' - '\n' - ' * They are valid numeric literals which, when passed to their ' + '================\n' + '\n' + 'These are created by numeric literals and returned as results by\n' + 'arithmetic operators and arithmetic built-in functions. Numeric\n' + 'objects are immutable; once created their value never changes. ' + 'Python\n' + 'numbers are of course strongly related to mathematical numbers, ' + 'but\n' + 'subject to the limitations of numerical representation in ' + 'computers.\n' + '\n' + 'The string representations of the numeric classes, computed by\n' + '"__repr__()" and "__str__()", have the following properties:\n' + '\n' + '* They are valid numeric literals which, when passed to their ' 'class\n' - ' constructor, produce an object having the value of the ' - 'original\n' - ' numeric.\n' + ' constructor, produce an object having the value of the original\n' + ' numeric.\n' '\n' - ' * The representation is in base 10, when possible.\n' + '* The representation is in base 10, when possible.\n' '\n' - ' * Leading zeros, possibly excepting a single zero before a ' - 'decimal\n' - ' point, are not shown.\n' + '* Leading zeros, possibly excepting a single zero before a decimal\n' + ' point, are not shown.\n' '\n' - ' * Trailing zeros, possibly excepting a single zero after a ' - 'decimal\n' - ' point, are not shown.\n' + '* Trailing zeros, possibly excepting a single zero after a decimal\n' + ' point, are not shown.\n' '\n' - ' * A sign is shown only when the number is negative.\n' + '* A sign is shown only when the number is negative.\n' '\n' - ' Python distinguishes between integers, floating point numbers, ' - 'and\n' - ' complex numbers:\n' + 'Python distinguishes between integers, floating point numbers, and\n' + 'complex numbers:\n' '\n' - ' "numbers.Integral"\n' - ' These represent elements from the mathematical set of ' - 'integers\n' - ' (positive and negative).\n' '\n' - ' There are two types of integers:\n' + '"numbers.Integral"\n' + '------------------\n' '\n' - ' Integers ("int")\n' - ' These represent numbers in an unlimited range, subject to\n' - ' available (virtual) memory only. For the purpose of ' - 'shift\n' - ' and mask operations, a binary representation is assumed, ' - 'and\n' - ' negative numbers are represented in a variant of 2’s\n' - ' complement which gives the illusion of an infinite string ' - 'of\n' - ' sign bits extending to the left.\n' + 'These represent elements from the mathematical set of integers\n' + '(positive and negative).\n' '\n' - ' Booleans ("bool")\n' - ' These represent the truth values False and True. The two\n' - ' objects representing the values "False" and "True" are ' - 'the\n' - ' only Boolean objects. The Boolean type is a subtype of ' + 'Note:\n' + '\n' + ' The rules for integer representation are intended to give the ' + 'most\n' + ' meaningful interpretation of shift and mask operations involving\n' + ' negative integers.\n' + '\n' + 'There are two types of integers:\n' + '\n' + 'Integers ("int")\n' + ' These represent numbers in an unlimited range, subject to ' + 'available\n' + ' (virtual) memory only. For the purpose of shift and mask\n' + ' operations, a binary representation is assumed, and negative\n' + ' numbers are represented in a variant of 2’s complement which ' + 'gives\n' + ' the illusion of an infinite string of sign bits extending to ' 'the\n' - ' integer type, and Boolean values behave like the values 0 ' - 'and\n' - ' 1, respectively, in almost all contexts, the exception ' - 'being\n' - ' that when converted to a string, the strings ""False"" or\n' - ' ""True"" are returned, respectively.\n' + ' left.\n' + '\n' + 'Booleans ("bool")\n' + ' These represent the truth values False and True. The two ' + 'objects\n' + ' representing the values "False" and "True" are the only Boolean\n' + ' objects. The Boolean type is a subtype of the integer type, and\n' + ' Boolean values behave like the values 0 and 1, respectively, in\n' + ' almost all contexts, the exception being that when converted to ' + 'a\n' + ' string, the strings ""False"" or ""True"" are returned,\n' + ' respectively.\n' + '\n' + '\n' + '"numbers.Real" ("float")\n' + '------------------------\n' '\n' - ' The rules for integer representation are intended to give ' + 'These represent machine-level double precision floating point ' + 'numbers.\n' + 'You are at the mercy of the underlying machine architecture (and C ' + 'or\n' + 'Java implementation) for the accepted range and handling of ' + 'overflow.\n' + 'Python does not support single-precision floating point numbers; ' 'the\n' - ' most meaningful interpretation of shift and mask operations\n' - ' involving negative integers.\n' - '\n' - ' "numbers.Real" ("float")\n' - ' These represent machine-level double precision floating ' - 'point\n' - ' numbers. You are at the mercy of the underlying machine\n' - ' architecture (and C or Java implementation) for the accepted\n' - ' range and handling of overflow. Python does not support ' - 'single-\n' - ' precision floating point numbers; the savings in processor ' - 'and\n' - ' memory usage that are usually the reason for using these are\n' - ' dwarfed by the overhead of using objects in Python, so there ' - 'is\n' - ' no reason to complicate the language with two kinds of ' - 'floating\n' - ' point numbers.\n' - '\n' - ' "numbers.Complex" ("complex")\n' - ' These represent complex numbers as a pair of machine-level\n' - ' double precision floating point numbers. The same caveats ' - 'apply\n' - ' as for floating point numbers. The real and imaginary parts ' - 'of a\n' - ' complex number "z" can be retrieved through the read-only\n' - ' attributes "z.real" and "z.imag".\n' + 'savings in processor and memory usage that are usually the reason ' + 'for\n' + 'using these are dwarfed by the overhead of using objects in Python, ' + 'so\n' + 'there is no reason to complicate the language with two kinds of\n' + 'floating point numbers.\n' + '\n' + '\n' + '"numbers.Complex" ("complex")\n' + '-----------------------------\n' + '\n' + 'These represent complex numbers as a pair of machine-level double\n' + 'precision floating point numbers. The same caveats apply as for\n' + 'floating point numbers. The real and imaginary parts of a complex\n' + 'number "z" can be retrieved through the read-only attributes ' + '"z.real"\n' + 'and "z.imag".\n' + '\n' '\n' 'Sequences\n' - ' These represent finite ordered sets indexed by non-negative\n' - ' numbers. The built-in function "len()" returns the number of ' - 'items\n' - ' of a sequence. When the length of a sequence is *n*, the index ' + '=========\n' + '\n' + 'These represent finite ordered sets indexed by non-negative ' + 'numbers.\n' + 'The built-in function "len()" returns the number of items of a\n' + 'sequence. When the length of a sequence is *n*, the index set ' + 'contains\n' + 'the numbers 0, 1, …, *n*-1. Item *i* of sequence *a* is selected ' + 'by\n' + '"a[i]".\n' + '\n' + 'Sequences also support slicing: "a[i:j]" selects all items with ' + 'index\n' + '*k* such that *i* "<=" *k* "<" *j*. When used as an expression, a\n' + 'slice is a sequence of the same type. This implies that the index ' 'set\n' - ' contains the numbers 0, 1, …, *n*-1. Item *i* of sequence *a* ' - 'is\n' - ' selected by "a[i]".\n' + 'is renumbered so that it starts at 0.\n' '\n' - ' Sequences also support slicing: "a[i:j]" selects all items with\n' - ' index *k* such that *i* "<=" *k* "<" *j*. When used as an\n' - ' expression, a slice is a sequence of the same type. This ' - 'implies\n' - ' that the index set is renumbered so that it starts at 0.\n' + 'Some sequences also support “extended slicing†with a third “stepâ€\n' + 'parameter: "a[i:j:k]" selects all items of *a* with index *x* where ' + '"x\n' + '= i + n*k", *n* ">=" "0" and *i* "<=" *x* "<" *j*.\n' '\n' - ' Some sequences also support “extended slicing†with a third ' - '“stepâ€\n' - ' parameter: "a[i:j:k]" selects all items of *a* with index *x* ' - 'where\n' - ' "x = i + n*k", *n* ">=" "0" and *i* "<=" *x* "<" *j*.\n' + 'Sequences are distinguished according to their mutability:\n' '\n' - ' Sequences are distinguished according to their mutability:\n' '\n' - ' Immutable sequences\n' - ' An object of an immutable sequence type cannot change once it ' - 'is\n' - ' created. (If the object contains references to other ' - 'objects,\n' - ' these other objects may be mutable and may be changed; ' - 'however,\n' - ' the collection of objects directly referenced by an ' - 'immutable\n' - ' object cannot change.)\n' + 'Immutable sequences\n' + '-------------------\n' '\n' - ' The following types are immutable sequences:\n' + 'An object of an immutable sequence type cannot change once it is\n' + 'created. (If the object contains references to other objects, ' + 'these\n' + 'other objects may be mutable and may be changed; however, the\n' + 'collection of objects directly referenced by an immutable object\n' + 'cannot change.)\n' '\n' - ' Strings\n' - ' A string is a sequence of values that represent Unicode ' - 'code\n' - ' points. All the code points in the range "U+0000 - ' - 'U+10FFFF"\n' - ' can be represented in a string. Python doesn’t have a ' - 'char\n' - ' type; instead, every code point in the string is ' - 'represented\n' - ' as a string object with length "1". The built-in ' - 'function\n' - ' "ord()" converts a code point from its string form to an\n' - ' integer in the range "0 - 10FFFF"; "chr()" converts an\n' - ' integer in the range "0 - 10FFFF" to the corresponding ' - 'length\n' - ' "1" string object. "str.encode()" can be used to convert ' - 'a\n' - ' "str" to "bytes" using the given text encoding, and\n' - ' "bytes.decode()" can be used to achieve the opposite.\n' + 'The following types are immutable sequences:\n' '\n' - ' Tuples\n' - ' The items of a tuple are arbitrary Python objects. Tuples ' - 'of\n' - ' two or more items are formed by comma-separated lists of\n' - ' expressions. A tuple of one item (a ‘singleton’) can be\n' - ' formed by affixing a comma to an expression (an expression ' - 'by\n' - ' itself does not create a tuple, since parentheses must be\n' - ' usable for grouping of expressions). An empty tuple can ' + 'Strings\n' + ' A string is a sequence of values that represent Unicode code\n' + ' points. All the code points in the range "U+0000 - U+10FFFF" can ' 'be\n' - ' formed by an empty pair of parentheses.\n' - '\n' - ' Bytes\n' - ' A bytes object is an immutable array. The items are ' - '8-bit\n' - ' bytes, represented by integers in the range 0 <= x < 256.\n' - ' Bytes literals (like "b\'abc\'") and the built-in ' - '"bytes()"\n' - ' constructor can be used to create bytes objects. Also, ' - 'bytes\n' - ' objects can be decoded to strings via the "decode()" ' - 'method.\n' + ' represented in a string. Python doesn’t have a char type; ' + 'instead,\n' + ' every code point in the string is represented as a string ' + 'object\n' + ' with length "1". The built-in function "ord()" converts a code\n' + ' point from its string form to an integer in the range "0 - ' + '10FFFF";\n' + ' "chr()" converts an integer in the range "0 - 10FFFF" to the\n' + ' corresponding length "1" string object. "str.encode()" can be ' + 'used\n' + ' to convert a "str" to "bytes" using the given text encoding, ' + 'and\n' + ' "bytes.decode()" can be used to achieve the opposite.\n' '\n' - ' Mutable sequences\n' - ' Mutable sequences can be changed after they are created. ' - 'The\n' - ' subscription and slicing notations can be used as the target ' + 'Tuples\n' + ' The items of a tuple are arbitrary Python objects. Tuples of two ' + 'or\n' + ' more items are formed by comma-separated lists of expressions. ' + 'A\n' + ' tuple of one item (a ‘singleton’) can be formed by affixing a ' + 'comma\n' + ' to an expression (an expression by itself does not create a ' + 'tuple,\n' + ' since parentheses must be usable for grouping of expressions). ' + 'An\n' + ' empty tuple can be formed by an empty pair of parentheses.\n' + '\n' + 'Bytes\n' + ' A bytes object is an immutable array. The items are 8-bit ' + 'bytes,\n' + ' represented by integers in the range 0 <= x < 256. Bytes ' + 'literals\n' + ' (like "b\'abc\'") and the built-in "bytes()" constructor can be ' + 'used\n' + ' to create bytes objects. Also, bytes objects can be decoded to\n' + ' strings via the "decode()" method.\n' + '\n' + '\n' + 'Mutable sequences\n' + '-----------------\n' + '\n' + 'Mutable sequences can be changed after they are created. The\n' + 'subscription and slicing notations can be used as the target of\n' + 'assignment and "del" (delete) statements.\n' + '\n' + 'Note:\n' + '\n' + ' The "collections" and "array" module provide additional examples ' 'of\n' - ' assignment and "del" (delete) statements.\n' + ' mutable sequence types.\n' '\n' - ' There are currently two intrinsic mutable sequence types:\n' + 'There are currently two intrinsic mutable sequence types:\n' '\n' - ' Lists\n' - ' The items of a list are arbitrary Python objects. Lists ' - 'are\n' - ' formed by placing a comma-separated list of expressions ' - 'in\n' - ' square brackets. (Note that there are no special cases ' - 'needed\n' - ' to form lists of length 0 or 1.)\n' + 'Lists\n' + ' The items of a list are arbitrary Python objects. Lists are ' + 'formed\n' + ' by placing a comma-separated list of expressions in square\n' + ' brackets. (Note that there are no special cases needed to form\n' + ' lists of length 0 or 1.)\n' '\n' - ' Byte Arrays\n' - ' A bytearray object is a mutable array. They are created ' - 'by\n' - ' the built-in "bytearray()" constructor. Aside from being\n' - ' mutable (and hence unhashable), byte arrays otherwise ' - 'provide\n' - ' the same interface and functionality as immutable "bytes"\n' - ' objects.\n' + 'Byte Arrays\n' + ' A bytearray object is a mutable array. They are created by the\n' + ' built-in "bytearray()" constructor. Aside from being mutable ' + '(and\n' + ' hence unhashable), byte arrays otherwise provide the same ' + 'interface\n' + ' and functionality as immutable "bytes" objects.\n' '\n' - ' The extension module "array" provides an additional example ' - 'of a\n' - ' mutable sequence type, as does the "collections" module.\n' '\n' 'Set types\n' - ' These represent unordered, finite sets of unique, immutable\n' - ' objects. As such, they cannot be indexed by any subscript. ' - 'However,\n' - ' they can be iterated over, and the built-in function "len()"\n' - ' returns the number of items in a set. Common uses for sets are ' - 'fast\n' - ' membership testing, removing duplicates from a sequence, and\n' - ' computing mathematical operations such as intersection, union,\n' - ' difference, and symmetric difference.\n' - '\n' - ' For set elements, the same immutability rules apply as for\n' - ' dictionary keys. Note that numeric types obey the normal rules ' - 'for\n' - ' numeric comparison: if two numbers compare equal (e.g., "1" and\n' - ' "1.0"), only one of them can be contained in a set.\n' + '=========\n' + '\n' + 'These represent unordered, finite sets of unique, immutable ' + 'objects.\n' + 'As such, they cannot be indexed by any subscript. However, they can ' + 'be\n' + 'iterated over, and the built-in function "len()" returns the number ' + 'of\n' + 'items in a set. Common uses for sets are fast membership testing,\n' + 'removing duplicates from a sequence, and computing mathematical\n' + 'operations such as intersection, union, difference, and symmetric\n' + 'difference.\n' + '\n' + 'For set elements, the same immutability rules apply as for ' + 'dictionary\n' + 'keys. Note that numeric types obey the normal rules for numeric\n' + 'comparison: if two numbers compare equal (e.g., "1" and "1.0"), ' + 'only\n' + 'one of them can be contained in a set.\n' + '\n' + 'There are currently two intrinsic set types:\n' '\n' - ' There are currently two intrinsic set types:\n' + 'Sets\n' + ' These represent a mutable set. They are created by the built-in\n' + ' "set()" constructor and can be modified afterwards by several\n' + ' methods, such as "add()".\n' '\n' - ' Sets\n' - ' These represent a mutable set. They are created by the ' + 'Frozen sets\n' + ' These represent an immutable set. They are created by the ' 'built-in\n' - ' "set()" constructor and can be modified afterwards by ' - 'several\n' - ' methods, such as "add()".\n' - '\n' - ' Frozen sets\n' - ' These represent an immutable set. They are created by the\n' - ' built-in "frozenset()" constructor. As a frozenset is ' - 'immutable\n' - ' and *hashable*, it can be used again as an element of ' - 'another\n' - ' set, or as a dictionary key.\n' + ' "frozenset()" constructor. As a frozenset is immutable and\n' + ' *hashable*, it can be used again as an element of another set, ' + 'or\n' + ' as a dictionary key.\n' + '\n' '\n' 'Mappings\n' - ' These represent finite sets of objects indexed by arbitrary ' - 'index\n' - ' sets. The subscript notation "a[k]" selects the item indexed by ' + '========\n' + '\n' + 'These represent finite sets of objects indexed by arbitrary index\n' + 'sets. The subscript notation "a[k]" selects the item indexed by ' '"k"\n' - ' from the mapping "a"; this can be used in expressions and as ' - 'the\n' - ' target of assignments or "del" statements. The built-in ' - 'function\n' - ' "len()" returns the number of items in a mapping.\n' + 'from the mapping "a"; this can be used in expressions and as the\n' + 'target of assignments or "del" statements. The built-in function\n' + '"len()" returns the number of items in a mapping.\n' '\n' - ' There is currently a single intrinsic mapping type:\n' + 'There is currently a single intrinsic mapping type:\n' '\n' - ' Dictionaries\n' - ' These represent finite sets of objects indexed by nearly\n' - ' arbitrary values. The only types of values not acceptable ' - 'as\n' - ' keys are values containing lists or dictionaries or other\n' - ' mutable types that are compared by value rather than by ' - 'object\n' - ' identity, the reason being that the efficient implementation ' - 'of\n' - ' dictionaries requires a key’s hash value to remain constant.\n' - ' Numeric types used for keys obey the normal rules for ' - 'numeric\n' - ' comparison: if two numbers compare equal (e.g., "1" and ' - '"1.0")\n' - ' then they can be used interchangeably to index the same\n' - ' dictionary entry.\n' - '\n' - ' Dictionaries preserve insertion order, meaning that keys will ' - 'be\n' - ' produced in the same order they were added sequentially over ' - 'the\n' - ' dictionary. Replacing an existing key does not change the ' - 'order,\n' - ' however removing a key and re-inserting it will add it to ' + '\n' + 'Dictionaries\n' + '------------\n' + '\n' + 'These represent finite sets of objects indexed by nearly arbitrary\n' + 'values. The only types of values not acceptable as keys are ' + 'values\n' + 'containing lists or dictionaries or other mutable types that are\n' + 'compared by value rather than by object identity, the reason being\n' + 'that the efficient implementation of dictionaries requires a key’s\n' + 'hash value to remain constant. Numeric types used for keys obey ' 'the\n' - ' end instead of keeping its old place.\n' + 'normal rules for numeric comparison: if two numbers compare equal\n' + '(e.g., "1" and "1.0") then they can be used interchangeably to ' + 'index\n' + 'the same dictionary entry.\n' '\n' - ' Dictionaries are mutable; they can be created by the "{...}"\n' - ' notation (see section Dictionary displays).\n' + 'Dictionaries preserve insertion order, meaning that keys will be\n' + 'produced in the same order they were added sequentially over the\n' + 'dictionary. Replacing an existing key does not change the order,\n' + 'however removing a key and re-inserting it will add it to the end\n' + 'instead of keeping its old place.\n' '\n' - ' The extension modules "dbm.ndbm" and "dbm.gnu" provide\n' - ' additional examples of mapping types, as does the ' - '"collections"\n' - ' module.\n' + 'Dictionaries are mutable; they can be created by the "{...}" ' + 'notation\n' + '(see section Dictionary displays).\n' + '\n' + 'The extension modules "dbm.ndbm" and "dbm.gnu" provide additional\n' + 'examples of mapping types, as does the "collections" module.\n' + '\n' + 'Changed in version 3.7: Dictionaries did not preserve insertion ' + 'order\n' + 'in versions of Python before 3.6. In CPython 3.6, insertion order ' + 'was\n' + 'preserved, but it was considered an implementation detail at that ' + 'time\n' + 'rather than a language guarantee.\n' '\n' - ' Changed in version 3.7: Dictionaries did not preserve ' - 'insertion\n' - ' order in versions of Python before 3.6. In CPython 3.6,\n' - ' insertion order was preserved, but it was considered an\n' - ' implementation detail at that time rather than a language\n' - ' guarantee.\n' '\n' 'Callable types\n' - ' These are the types to which the function call operation (see\n' - ' section Calls) can be applied:\n' + '==============\n' '\n' - ' User-defined functions\n' - ' A user-defined function object is created by a function\n' - ' definition (see section Function definitions). It should be\n' - ' called with an argument list containing the same number of ' - 'items\n' - ' as the function’s formal parameter list.\n' + 'These are the types to which the function call operation (see ' + 'section\n' + 'Calls) can be applied:\n' '\n' - ' Special attributes:\n' '\n' - ' ' + 'User-defined functions\n' + '----------------------\n' + '\n' + 'A user-defined function object is created by a function definition\n' + '(see section Function definitions). It should be called with an\n' + 'argument list containing the same number of items as the ' + 'function’s\n' + 'formal parameter list.\n' + '\n' + 'Special attributes:\n' + '\n' '+---------------------------+---------------------------------+-------------+\n' - ' | Attribute | Meaning ' + '| Attribute | Meaning ' '| |\n' - ' ' '|===========================|=================================|=============|\n' - ' | "__doc__" | The function’s documentation ' - '| Writable |\n' - ' | | string, or "None" if ' + '| "__doc__" | The function’s documentation | ' + 'Writable |\n' + '| | string, or "None" if ' '| |\n' - ' | | unavailable; not inherited by ' + '| | unavailable; not inherited by ' '| |\n' - ' | | subclasses. ' + '| | subclasses. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__name__" | The function’s name. ' - '| Writable |\n' - ' ' + '| "__name__" | The function’s name. | ' + 'Writable |\n' '+---------------------------+---------------------------------+-------------+\n' - ' | "__qualname__" | The function’s *qualified ' - '| Writable |\n' - ' | | name*. New in version 3.3. ' + '| "__qualname__" | The function’s *qualified | ' + 'Writable |\n' + '| | name*. New in version 3.3. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__module__" | The name of the module the ' - '| Writable |\n' - ' | | function was defined in, or ' + '| "__module__" | The name of the module the | ' + 'Writable |\n' + '| | function was defined in, or ' '| |\n' - ' | | "None" if unavailable. ' + '| | "None" if unavailable. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__defaults__" | A tuple containing default ' - '| Writable |\n' - ' | | argument values for those ' + '| "__defaults__" | A tuple containing default | ' + 'Writable |\n' + '| | argument values for those ' '| |\n' - ' | | arguments that have defaults, ' + '| | arguments that have defaults, ' '| |\n' - ' | | or "None" if no arguments have ' + '| | or "None" if no arguments have ' '| |\n' - ' | | a default value. ' + '| | a default value. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__code__" | The code object representing ' - '| Writable |\n' - ' | | the compiled function body. ' + '| "__code__" | The code object representing | ' + 'Writable |\n' + '| | the compiled function body. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__globals__" | A reference to the dictionary ' - '| Read-only |\n' - ' | | that holds the function’s ' + '| "__globals__" | A reference to the dictionary | ' + 'Read-only |\n' + '| | that holds the function’s ' '| |\n' - ' | | global variables — the global ' + '| | global variables — the global ' '| |\n' - ' | | namespace of the module in ' + '| | namespace of the module in ' '| |\n' - ' | | which the function was defined. ' + '| | which the function was defined. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__dict__" | The namespace supporting ' - '| Writable |\n' - ' | | arbitrary function attributes. ' + '| "__dict__" | The namespace supporting | ' + 'Writable |\n' + '| | arbitrary function attributes. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__closure__" | "None" or a tuple of cells that ' - '| Read-only |\n' - ' | | contain bindings for the ' + '| "__closure__" | "None" or a tuple of cells that | ' + 'Read-only |\n' + '| | contain bindings for the ' '| |\n' - ' | | function’s free variables. See ' + '| | function’s free variables. See ' '| |\n' - ' | | below for information on the ' + '| | below for information on the ' '| |\n' - ' | | "cell_contents" attribute. ' + '| | "cell_contents" attribute. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__annotations__" | A dict containing annotations ' - '| Writable |\n' - ' | | of parameters. The keys of the ' + '| "__annotations__" | A dict containing annotations | ' + 'Writable |\n' + '| | of parameters. The keys of the ' + '| |\n' + '| | dict are the parameter names, ' '| |\n' - ' | | dict are the parameter names, ' + '| | and "\'return\'" for the return ' '| |\n' - ' | | and "\'return\'" for the ' - 'return | |\n' - ' | | annotation, if provided. For ' + '| | annotation, if provided. For ' '| |\n' - ' | | more information on working ' + '| | more information on working ' '| |\n' - ' | | with this attribute, see ' + '| | with this attribute, see ' '| |\n' - ' | | Annotations Best Practices. ' + '| | Annotations Best Practices. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__kwdefaults__" | A dict containing defaults for ' - '| Writable |\n' - ' | | keyword-only parameters. ' + '| "__kwdefaults__" | A dict containing defaults for | ' + 'Writable |\n' + '| | keyword-only parameters. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' '\n' - ' Most of the attributes labelled “Writable†check the type of ' - 'the\n' - ' assigned value.\n' + 'Most of the attributes labelled “Writable†check the type of the\n' + 'assigned value.\n' '\n' - ' Function objects also support getting and setting arbitrary\n' - ' attributes, which can be used, for example, to attach ' - 'metadata\n' - ' to functions. Regular attribute dot-notation is used to get ' - 'and\n' - ' set such attributes. *Note that the current implementation ' - 'only\n' - ' supports function attributes on user-defined functions. ' - 'Function\n' - ' attributes on built-in functions may be supported in the\n' - ' future.*\n' - '\n' - ' A cell object has the attribute "cell_contents". This can be\n' - ' used to get the value of the cell, as well as set the value.\n' - '\n' - ' Additional information about a function’s definition can be\n' - ' retrieved from its code object; see the description of ' - 'internal\n' - ' types below. The "cell" type can be accessed in the "types"\n' - ' module.\n' - '\n' - ' Instance methods\n' - ' An instance method object combines a class, a class instance ' - 'and\n' - ' any callable object (normally a user-defined function).\n' - '\n' - ' Special read-only attributes: "__self__" is the class ' - 'instance\n' - ' object, "__func__" is the function object; "__doc__" is the\n' - ' method’s documentation (same as "__func__.__doc__"); ' - '"__name__"\n' - ' is the method name (same as "__func__.__name__"); ' - '"__module__"\n' - ' is the name of the module the method was defined in, or ' - '"None"\n' - ' if unavailable.\n' + 'Function objects also support getting and setting arbitrary\n' + 'attributes, which can be used, for example, to attach metadata to\n' + 'functions. Regular attribute dot-notation is used to get and set ' + 'such\n' + 'attributes. *Note that the current implementation only supports\n' + 'function attributes on user-defined functions. Function attributes ' + 'on\n' + 'built-in functions may be supported in the future.*\n' '\n' - ' Methods also support accessing (but not setting) the ' - 'arbitrary\n' - ' function attributes on the underlying function object.\n' + 'A cell object has the attribute "cell_contents". This can be used ' + 'to\n' + 'get the value of the cell, as well as set the value.\n' '\n' - ' User-defined method objects may be created when getting an\n' - ' attribute of a class (perhaps via an instance of that class), ' - 'if\n' - ' that attribute is a user-defined function object or a class\n' - ' method object.\n' - '\n' - ' When an instance method object is created by retrieving a ' - 'user-\n' - ' defined function object from a class via one of its ' - 'instances,\n' - ' its "__self__" attribute is the instance, and the method ' - 'object\n' - ' is said to be bound. The new method’s "__func__" attribute ' - 'is\n' - ' the original function object.\n' + 'Additional information about a function’s definition can be ' + 'retrieved\n' + 'from its code object; see the description of internal types below. ' + 'The\n' + '"cell" type can be accessed in the "types" module.\n' '\n' - ' When an instance method object is created by retrieving a ' - 'class\n' - ' method object from a class or instance, its "__self__" ' - 'attribute\n' - ' is the class itself, and its "__func__" attribute is the\n' - ' function object underlying the class method.\n' '\n' - ' When an instance method object is called, the underlying\n' - ' function ("__func__") is called, inserting the class ' - 'instance\n' - ' ("__self__") in front of the argument list. For instance, ' - 'when\n' - ' "C" is a class which contains a definition for a function ' - '"f()",\n' - ' and "x" is an instance of "C", calling "x.f(1)" is equivalent ' - 'to\n' - ' calling "C.f(x, 1)".\n' + 'Instance methods\n' + '----------------\n' + '\n' + 'An instance method object combines a class, a class instance and ' + 'any\n' + 'callable object (normally a user-defined function).\n' '\n' - ' When an instance method object is derived from a class ' + 'Special read-only attributes: "__self__" is the class instance ' + 'object,\n' + '"__func__" is the function object; "__doc__" is the method’s\n' + 'documentation (same as "__func__.__doc__"); "__name__" is the ' 'method\n' - ' object, the “class instance†stored in "__self__" will ' - 'actually\n' - ' be the class itself, so that calling either "x.f(1)" or ' - '"C.f(1)"\n' - ' is equivalent to calling "f(C,1)" where "f" is the ' - 'underlying\n' - ' function.\n' - '\n' - ' Note that the transformation from function object to ' - 'instance\n' - ' method object happens each time the attribute is retrieved ' - 'from\n' - ' the instance. In some cases, a fruitful optimization is to\n' - ' assign the attribute to a local variable and call that local\n' - ' variable. Also notice that this transformation only happens ' - 'for\n' - ' user-defined functions; other callable objects (and all non-\n' - ' callable objects) are retrieved without transformation. It ' - 'is\n' - ' also important to note that user-defined functions which are\n' - ' attributes of a class instance are not converted to bound\n' - ' methods; this *only* happens when the function is an ' + 'name (same as "__func__.__name__"); "__module__" is the name of ' + 'the\n' + 'module the method was defined in, or "None" if unavailable.\n' + '\n' + 'Methods also support accessing (but not setting) the arbitrary\n' + 'function attributes on the underlying function object.\n' + '\n' + 'User-defined method objects may be created when getting an ' + 'attribute\n' + 'of a class (perhaps via an instance of that class), if that ' 'attribute\n' - ' of the class.\n' + 'is a user-defined function object or a class method object.\n' '\n' - ' Generator functions\n' - ' A function or method which uses the "yield" statement (see\n' - ' section The yield statement) is called a *generator ' - 'function*.\n' - ' Such a function, when called, always returns an *iterator*\n' - ' object which can be used to execute the body of the ' - 'function:\n' - ' calling the iterator’s "iterator.__next__()" method will ' - 'cause\n' - ' the function to execute until it provides a value using the\n' - ' "yield" statement. When the function executes a "return"\n' - ' statement or falls off the end, a "StopIteration" exception ' - 'is\n' - ' raised and the iterator will have reached the end of the set ' + 'When an instance method object is created by retrieving a ' + 'user-defined\n' + 'function object from a class via one of its instances, its ' + '"__self__"\n' + 'attribute is the instance, and the method object is said to be ' + 'bound.\n' + 'The new method’s "__func__" attribute is the original function ' + 'object.\n' + '\n' + 'When an instance method object is created by retrieving a class ' + 'method\n' + 'object from a class or instance, its "__self__" attribute is the ' + 'class\n' + 'itself, and its "__func__" attribute is the function object ' + 'underlying\n' + 'the class method.\n' + '\n' + 'When an instance method object is called, the underlying function\n' + '("__func__") is called, inserting the class instance ("__self__") ' + 'in\n' + 'front of the argument list. For instance, when "C" is a class ' + 'which\n' + 'contains a definition for a function "f()", and "x" is an instance ' 'of\n' - ' values to be returned.\n' - '\n' - ' Coroutine functions\n' - ' A function or method which is defined using "async def" is\n' - ' called a *coroutine function*. Such a function, when ' - 'called,\n' - ' returns a *coroutine* object. It may contain "await"\n' - ' expressions, as well as "async with" and "async for" ' - 'statements.\n' - ' See also the Coroutine Objects section.\n' - '\n' - ' Asynchronous generator functions\n' - ' A function or method which is defined using "async def" and\n' - ' which uses the "yield" statement is called a *asynchronous\n' - ' generator function*. Such a function, when called, returns ' - 'an\n' - ' *asynchronous iterator* object which can be used in an ' - '"async\n' - ' for" statement to execute the body of the function.\n' + '"C", calling "x.f(1)" is equivalent to calling "C.f(x, 1)".\n' '\n' - ' Calling the asynchronous iterator’s "aiterator.__anext__" ' + 'When an instance method object is derived from a class method ' + 'object,\n' + 'the “class instance†stored in "__self__" will actually be the ' + 'class\n' + 'itself, so that calling either "x.f(1)" or "C.f(1)" is equivalent ' + 'to\n' + 'calling "f(C,1)" where "f" is the underlying function.\n' + '\n' + 'Note that the transformation from function object to instance ' 'method\n' - ' will return an *awaitable* which when awaited will execute ' + 'object happens each time the attribute is retrieved from the ' + 'instance.\n' + 'In some cases, a fruitful optimization is to assign the attribute ' + 'to a\n' + 'local variable and call that local variable. Also notice that this\n' + 'transformation only happens for user-defined functions; other ' + 'callable\n' + 'objects (and all non-callable objects) are retrieved without\n' + 'transformation. It is also important to note that user-defined\n' + 'functions which are attributes of a class instance are not ' + 'converted\n' + 'to bound methods; this *only* happens when the function is an\n' + 'attribute of the class.\n' + '\n' + '\n' + 'Generator functions\n' + '-------------------\n' + '\n' + 'A function or method which uses the "yield" statement (see section ' + 'The\n' + 'yield statement) is called a *generator function*. Such a ' + 'function,\n' + 'when called, always returns an *iterator* object which can be used ' + 'to\n' + 'execute the body of the function: calling the iterator’s\n' + '"iterator.__next__()" method will cause the function to execute ' 'until\n' - ' it provides a value using the "yield" expression. When the\n' - ' function executes an empty "return" statement or falls off ' + 'it provides a value using the "yield" statement. When the ' + 'function\n' + 'executes a "return" statement or falls off the end, a ' + '"StopIteration"\n' + 'exception is raised and the iterator will have reached the end of ' 'the\n' - ' end, a "StopAsyncIteration" exception is raised and the\n' - ' asynchronous iterator will have reached the end of the set ' - 'of\n' - ' values to be yielded.\n' + 'set of values to be returned.\n' '\n' - ' Built-in functions\n' - ' A built-in function object is a wrapper around a C function.\n' - ' Examples of built-in functions are "len()" and "math.sin()"\n' - ' ("math" is a standard built-in module). The number and type ' - 'of\n' - ' the arguments are determined by the C function. Special ' - 'read-\n' - ' only attributes: "__doc__" is the function’s documentation\n' - ' string, or "None" if unavailable; "__name__" is the ' - 'function’s\n' - ' name; "__self__" is set to "None" (but see the next item);\n' - ' "__module__" is the name of the module the function was ' - 'defined\n' - ' in or "None" if unavailable.\n' '\n' - ' Built-in methods\n' - ' This is really a different disguise of a built-in function, ' - 'this\n' - ' time containing an object passed to the C function as an\n' - ' implicit extra argument. An example of a built-in method is\n' - ' "alist.append()", assuming *alist* is a list object. In this\n' - ' case, the special read-only attribute "__self__" is set to ' + 'Coroutine functions\n' + '-------------------\n' + '\n' + 'A function or method which is defined using "async def" is called ' + 'a\n' + '*coroutine function*. Such a function, when called, returns a\n' + '*coroutine* object. It may contain "await" expressions, as well ' + 'as\n' + '"async with" and "async for" statements. See also the Coroutine\n' + 'Objects section.\n' + '\n' + '\n' + 'Asynchronous generator functions\n' + '--------------------------------\n' + '\n' + 'A function or method which is defined using "async def" and which ' + 'uses\n' + 'the "yield" statement is called a *asynchronous generator ' + 'function*.\n' + 'Such a function, when called, returns an *asynchronous iterator*\n' + 'object which can be used in an "async for" statement to execute ' 'the\n' - ' object denoted by *alist*.\n' + 'body of the function.\n' + '\n' + 'Calling the asynchronous iterator’s "aiterator.__anext__" method ' + 'will\n' + 'return an *awaitable* which when awaited will execute until it\n' + 'provides a value using the "yield" expression. When the function\n' + 'executes an empty "return" statement or falls off the end, a\n' + '"StopAsyncIteration" exception is raised and the asynchronous ' + 'iterator\n' + 'will have reached the end of the set of values to be yielded.\n' + '\n' + '\n' + 'Built-in functions\n' + '------------------\n' + '\n' + 'A built-in function object is a wrapper around a C function. ' + 'Examples\n' + 'of built-in functions are "len()" and "math.sin()" ("math" is a\n' + 'standard built-in module). The number and type of the arguments ' + 'are\n' + 'determined by the C function. Special read-only attributes: ' + '"__doc__"\n' + 'is the function’s documentation string, or "None" if unavailable;\n' + '"__name__" is the function’s name; "__self__" is set to "None" ' + '(but\n' + 'see the next item); "__module__" is the name of the module the\n' + 'function was defined in or "None" if unavailable.\n' + '\n' + '\n' + 'Built-in methods\n' + '----------------\n' + '\n' + 'This is really a different disguise of a built-in function, this ' + 'time\n' + 'containing an object passed to the C function as an implicit extra\n' + 'argument. An example of a built-in method is "alist.append()",\n' + 'assuming *alist* is a list object. In this case, the special ' + 'read-only\n' + 'attribute "__self__" is set to the object denoted by *alist*.\n' + '\n' + '\n' + 'Classes\n' + '-------\n' + '\n' + 'Classes are callable. These objects normally act as factories for ' + 'new\n' + 'instances of themselves, but variations are possible for class ' + 'types\n' + 'that override "__new__()". The arguments of the call are passed ' + 'to\n' + '"__new__()" and, in the typical case, to "__init__()" to ' + 'initialize\n' + 'the new instance.\n' '\n' - ' Classes\n' - ' Classes are callable. These objects normally act as ' - 'factories\n' - ' for new instances of themselves, but variations are possible ' - 'for\n' - ' class types that override "__new__()". The arguments of the\n' - ' call are passed to "__new__()" and, in the typical case, to\n' - ' "__init__()" to initialize the new instance.\n' '\n' - ' Class Instances\n' - ' Instances of arbitrary classes can be made callable by ' - 'defining\n' - ' a "__call__()" method in their class.\n' + 'Class Instances\n' + '---------------\n' + '\n' + 'Instances of arbitrary classes can be made callable by defining a\n' + '"__call__()" method in their class.\n' + '\n' '\n' 'Modules\n' - ' Modules are a basic organizational unit of Python code, and are\n' - ' created by the import system as invoked either by the "import"\n' - ' statement, or by calling functions such as\n' - ' "importlib.import_module()" and built-in "__import__()". A ' - 'module\n' - ' object has a namespace implemented by a dictionary object (this ' - 'is\n' - ' the dictionary referenced by the "__globals__" attribute of\n' - ' functions defined in the module). Attribute references are\n' - ' translated to lookups in this dictionary, e.g., "m.x" is ' - 'equivalent\n' - ' to "m.__dict__["x"]". A module object does not contain the code\n' - ' object used to initialize the module (since it isn’t needed ' - 'once\n' - ' the initialization is done).\n' + '=======\n' + '\n' + 'Modules are a basic organizational unit of Python code, and are\n' + 'created by the import system as invoked either by the "import"\n' + 'statement, or by calling functions such as ' + '"importlib.import_module()"\n' + 'and built-in "__import__()". A module object has a namespace\n' + 'implemented by a dictionary object (this is the dictionary ' + 'referenced\n' + 'by the "__globals__" attribute of functions defined in the ' + 'module).\n' + 'Attribute references are translated to lookups in this dictionary,\n' + 'e.g., "m.x" is equivalent to "m.__dict__["x"]". A module object ' + 'does\n' + 'not contain the code object used to initialize the module (since ' + 'it\n' + 'isn’t needed once the initialization is done).\n' + '\n' + 'Attribute assignment updates the module’s namespace dictionary, ' + 'e.g.,\n' + '"m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n' '\n' - ' Attribute assignment updates the module’s namespace dictionary,\n' - ' e.g., "m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n' + 'Predefined (writable) attributes:\n' '\n' - ' Predefined (writable) attributes:\n' + ' "__name__"\n' + ' The module’s name.\n' '\n' - ' "__name__"\n' - ' The module’s name.\n' + ' "__doc__"\n' + ' The module’s documentation string, or "None" if unavailable.\n' '\n' - ' "__doc__"\n' - ' The module’s documentation string, or "None" if ' - 'unavailable.\n' + ' "__file__"\n' + ' The pathname of the file from which the module was loaded, if ' + 'it\n' + ' was loaded from a file. The "__file__" attribute may be ' + 'missing\n' + ' for certain types of modules, such as C modules that are\n' + ' statically linked into the interpreter. For extension ' + 'modules\n' + ' loaded dynamically from a shared library, it’s the pathname ' + 'of\n' + ' the shared library file.\n' '\n' - ' "__file__"\n' - ' The pathname of the file from which the module was loaded, ' - 'if\n' - ' it was loaded from a file. The "__file__" attribute may ' - 'be\n' - ' missing for certain types of modules, such as C modules ' - 'that\n' - ' are statically linked into the interpreter. For ' - 'extension\n' - ' modules loaded dynamically from a shared library, it’s ' - 'the\n' - ' pathname of the shared library file.\n' - '\n' - ' "__annotations__"\n' - ' A dictionary containing *variable annotations* collected\n' - ' during module body execution. For best practices on ' - 'working\n' - ' with "__annotations__", please see Annotations Best\n' - ' Practices.\n' - '\n' - ' Special read-only attribute: "__dict__" is the module’s ' - 'namespace\n' - ' as a dictionary object.\n' - '\n' - ' **CPython implementation detail:** Because of the way CPython\n' - ' clears module dictionaries, the module dictionary will be ' - 'cleared\n' - ' when the module falls out of scope even if the dictionary still ' - 'has\n' - ' live references. To avoid this, copy the dictionary or keep ' + ' "__annotations__"\n' + ' A dictionary containing *variable annotations* collected ' + 'during\n' + ' module body execution. For best practices on working with\n' + ' "__annotations__", please see Annotations Best Practices.\n' + '\n' + 'Special read-only attribute: "__dict__" is the module’s namespace ' + 'as a\n' + 'dictionary object.\n' + '\n' + '**CPython implementation detail:** Because of the way CPython ' + 'clears\n' + 'module dictionaries, the module dictionary will be cleared when ' 'the\n' - ' module around while using its dictionary directly.\n' + 'module falls out of scope even if the dictionary still has live\n' + 'references. To avoid this, copy the dictionary or keep the module\n' + 'around while using its dictionary directly.\n' + '\n' '\n' 'Custom classes\n' - ' Custom class types are typically created by class definitions ' - '(see\n' - ' section Class definitions). A class has a namespace implemented ' - 'by\n' - ' a dictionary object. Class attribute references are translated ' - 'to\n' - ' lookups in this dictionary, e.g., "C.x" is translated to\n' - ' "C.__dict__["x"]" (although there are a number of hooks which ' + '==============\n' + '\n' + 'Custom class types are typically created by class definitions (see\n' + 'section Class definitions). A class has a namespace implemented by ' + 'a\n' + 'dictionary object. Class attribute references are translated to\n' + 'lookups in this dictionary, e.g., "C.x" is translated to\n' + '"C.__dict__["x"]" (although there are a number of hooks which ' 'allow\n' - ' for other means of locating attributes). When the attribute name ' + 'for other means of locating attributes). When the attribute name ' 'is\n' - ' not found there, the attribute search continues in the base\n' - ' classes. This search of the base classes uses the C3 method\n' - ' resolution order which behaves correctly even in the presence ' - 'of\n' - ' ‘diamond’ inheritance structures where there are multiple\n' - ' inheritance paths leading back to a common ancestor. Additional\n' - ' details on the C3 MRO used by Python can be found in the\n' - ' documentation accompanying the 2.3 release at\n' - ' https://www.python.org/download/releases/2.3/mro/.\n' - '\n' - ' When a class attribute reference (for class "C", say) would ' - 'yield a\n' - ' class method object, it is transformed into an instance method\n' - ' object whose "__self__" attribute is "C". When it would yield ' + 'not found there, the attribute search continues in the base ' + 'classes.\n' + 'This search of the base classes uses the C3 method resolution ' + 'order\n' + 'which behaves correctly even in the presence of ‘diamond’ ' + 'inheritance\n' + 'structures where there are multiple inheritance paths leading back ' + 'to\n' + 'a common ancestor. Additional details on the C3 MRO used by Python ' + 'can\n' + 'be found in the documentation accompanying the 2.3 release at\n' + 'https://www.python.org/download/releases/2.3/mro/.\n' + '\n' + 'When a class attribute reference (for class "C", say) would yield ' 'a\n' - ' static method object, it is transformed into the object wrapped ' - 'by\n' - ' the static method object. See section Implementing Descriptors ' - 'for\n' - ' another way in which attributes retrieved from a class may ' - 'differ\n' - ' from those actually contained in its "__dict__".\n' + 'class method object, it is transformed into an instance method ' + 'object\n' + 'whose "__self__" attribute is "C". When it would yield a static\n' + 'method object, it is transformed into the object wrapped by the ' + 'static\n' + 'method object. See section Implementing Descriptors for another way ' + 'in\n' + 'which attributes retrieved from a class may differ from those ' + 'actually\n' + 'contained in its "__dict__".\n' '\n' - ' Class attribute assignments update the class’s dictionary, ' - 'never\n' - ' the dictionary of a base class.\n' + 'Class attribute assignments update the class’s dictionary, never ' + 'the\n' + 'dictionary of a base class.\n' + '\n' + 'A class object can be called (see above) to yield a class instance\n' + '(see below).\n' '\n' - ' A class object can be called (see above) to yield a class ' - 'instance\n' - ' (see below).\n' + 'Special attributes:\n' '\n' - ' Special attributes:\n' + ' "__name__"\n' + ' The class name.\n' '\n' - ' "__name__"\n' - ' The class name.\n' + ' "__module__"\n' + ' The name of the module in which the class was defined.\n' '\n' - ' "__module__"\n' - ' The name of the module in which the class was defined.\n' + ' "__dict__"\n' + ' The dictionary containing the class’s namespace.\n' '\n' - ' "__dict__"\n' - ' The dictionary containing the class’s namespace.\n' + ' "__bases__"\n' + ' A tuple containing the base classes, in the order of their\n' + ' occurrence in the base class list.\n' '\n' - ' "__bases__"\n' - ' A tuple containing the base classes, in the order of ' - 'their\n' - ' occurrence in the base class list.\n' + ' "__doc__"\n' + ' The class’s documentation string, or "None" if undefined.\n' '\n' - ' "__doc__"\n' - ' The class’s documentation string, or "None" if undefined.\n' + ' "__annotations__"\n' + ' A dictionary containing *variable annotations* collected ' + 'during\n' + ' class body execution. For best practices on working with\n' + ' "__annotations__", please see Annotations Best Practices.\n' '\n' - ' "__annotations__"\n' - ' A dictionary containing *variable annotations* collected\n' - ' during class body execution. For best practices on ' - 'working\n' - ' with "__annotations__", please see Annotations Best\n' - ' Practices.\n' '\n' 'Class instances\n' - ' A class instance is created by calling a class object (see ' - 'above).\n' - ' A class instance has a namespace implemented as a dictionary ' - 'which\n' - ' is the first place in which attribute references are searched.\n' - ' When an attribute is not found there, and the instance’s class ' - 'has\n' - ' an attribute by that name, the search continues with the class\n' - ' attributes. If a class attribute is found that is a ' - 'user-defined\n' - ' function object, it is transformed into an instance method ' - 'object\n' - ' whose "__self__" attribute is the instance. Static method and\n' - ' class method objects are also transformed; see above under\n' - ' “Classesâ€. See section Implementing Descriptors for another way ' - 'in\n' - ' which attributes of a class retrieved via its instances may ' - 'differ\n' - ' from the objects actually stored in the class’s "__dict__". If ' - 'no\n' - ' class attribute is found, and the object’s class has a\n' - ' "__getattr__()" method, that is called to satisfy the lookup.\n' + '===============\n' '\n' - ' Attribute assignments and deletions update the instance’s\n' - ' dictionary, never a class’s dictionary. If the class has a\n' - ' "__setattr__()" or "__delattr__()" method, this is called ' - 'instead\n' - ' of updating the instance dictionary directly.\n' + 'A class instance is created by calling a class object (see above). ' + 'A\n' + 'class instance has a namespace implemented as a dictionary which ' + 'is\n' + 'the first place in which attribute references are searched. When ' + 'an\n' + 'attribute is not found there, and the instance’s class has an\n' + 'attribute by that name, the search continues with the class\n' + 'attributes. If a class attribute is found that is a user-defined\n' + 'function object, it is transformed into an instance method object\n' + 'whose "__self__" attribute is the instance. Static method and ' + 'class\n' + 'method objects are also transformed; see above under “Classesâ€. ' + 'See\n' + 'section Implementing Descriptors for another way in which ' + 'attributes\n' + 'of a class retrieved via its instances may differ from the objects\n' + 'actually stored in the class’s "__dict__". If no class attribute ' + 'is\n' + 'found, and the object’s class has a "__getattr__()" method, that ' + 'is\n' + 'called to satisfy the lookup.\n' '\n' - ' Class instances can pretend to be numbers, sequences, or ' - 'mappings\n' - ' if they have methods with certain special names. See section\n' - ' Special method names.\n' + 'Attribute assignments and deletions update the instance’s ' + 'dictionary,\n' + 'never a class’s dictionary. If the class has a "__setattr__()" or\n' + '"__delattr__()" method, this is called instead of updating the\n' + 'instance dictionary directly.\n' + '\n' + 'Class instances can pretend to be numbers, sequences, or mappings ' + 'if\n' + 'they have methods with certain special names. See section Special\n' + 'method names.\n' + '\n' + 'Special attributes: "__dict__" is the attribute dictionary;\n' + '"__class__" is the instance’s class.\n' '\n' - ' Special attributes: "__dict__" is the attribute dictionary;\n' - ' "__class__" is the instance’s class.\n' '\n' 'I/O objects (also known as file objects)\n' - ' A *file object* represents an open file. Various shortcuts are\n' - ' available to create file objects: the "open()" built-in ' - 'function,\n' - ' and also "os.popen()", "os.fdopen()", and the "makefile()" ' - 'method\n' - ' of socket objects (and perhaps by other functions or methods\n' - ' provided by extension modules).\n' + '========================================\n' + '\n' + 'A *file object* represents an open file. Various shortcuts are\n' + 'available to create file objects: the "open()" built-in function, ' + 'and\n' + 'also "os.popen()", "os.fdopen()", and the "makefile()" method of\n' + 'socket objects (and perhaps by other functions or methods provided ' + 'by\n' + 'extension modules).\n' + '\n' + 'The objects "sys.stdin", "sys.stdout" and "sys.stderr" are ' + 'initialized\n' + 'to file objects corresponding to the interpreter’s standard input,\n' + 'output and error streams; they are all open in text mode and ' + 'therefore\n' + 'follow the interface defined by the "io.TextIOBase" abstract ' + 'class.\n' '\n' - ' The objects "sys.stdin", "sys.stdout" and "sys.stderr" are\n' - ' initialized to file objects corresponding to the interpreter’s\n' - ' standard input, output and error streams; they are all open in ' - 'text\n' - ' mode and therefore follow the interface defined by the\n' - ' "io.TextIOBase" abstract class.\n' '\n' 'Internal types\n' - ' A few types used internally by the interpreter are exposed to ' - 'the\n' - ' user. Their definitions may change with future versions of the\n' - ' interpreter, but they are mentioned here for completeness.\n' - '\n' - ' Code objects\n' - ' Code objects represent *byte-compiled* executable Python ' - 'code,\n' - ' or *bytecode*. The difference between a code object and a\n' - ' function object is that the function object contains an ' - 'explicit\n' - ' reference to the function’s globals (the module in which it ' - 'was\n' - ' defined), while a code object contains no context; also the\n' - ' default argument values are stored in the function object, ' - 'not\n' - ' in the code object (because they represent values calculated ' - 'at\n' - ' run-time). Unlike function objects, code objects are ' - 'immutable\n' - ' and contain no references (directly or indirectly) to ' - 'mutable\n' - ' objects.\n' - '\n' - ' Special read-only attributes: "co_name" gives the function ' - 'name;\n' - ' "co_qualname" gives the fully qualified function name;\n' - ' "co_argcount" is the total number of positional arguments\n' - ' (including positional-only arguments and arguments with ' - 'default\n' - ' values); "co_posonlyargcount" is the number of ' - 'positional-only\n' - ' arguments (including arguments with default values);\n' - ' "co_kwonlyargcount" is the number of keyword-only arguments\n' - ' (including arguments with default values); "co_nlocals" is ' - 'the\n' - ' number of local variables used by the function (including\n' - ' arguments); "co_varnames" is a tuple containing the names of ' - 'the\n' - ' local variables (starting with the argument names);\n' - ' "co_cellvars" is a tuple containing the names of local ' - 'variables\n' - ' that are referenced by nested functions; "co_freevars" is a\n' - ' tuple containing the names of free variables; "co_code" is a\n' - ' string representing the sequence of bytecode instructions;\n' - ' "co_consts" is a tuple containing the literals used by the\n' - ' bytecode; "co_names" is a tuple containing the names used by ' - 'the\n' - ' bytecode; "co_filename" is the filename from which the code ' - 'was\n' - ' compiled; "co_firstlineno" is the first line number of the\n' - ' function; "co_lnotab" is a string encoding the mapping from\n' - ' bytecode offsets to line numbers (for details see the source\n' - ' code of the interpreter); "co_stacksize" is the required ' - 'stack\n' - ' size; "co_flags" is an integer encoding a number of flags ' - 'for\n' - ' the interpreter.\n' + '==============\n' + '\n' + 'A few types used internally by the interpreter are exposed to the\n' + 'user. Their definitions may change with future versions of the\n' + 'interpreter, but they are mentioned here for completeness.\n' '\n' - ' The following flag bits are defined for "co_flags": bit ' - '"0x04"\n' - ' is set if the function uses the "*arguments" syntax to accept ' - 'an\n' - ' arbitrary number of positional arguments; bit "0x08" is set ' - 'if\n' - ' the function uses the "**keywords" syntax to accept ' - 'arbitrary\n' - ' keyword arguments; bit "0x20" is set if the function is a\n' - ' generator.\n' '\n' - ' Future feature declarations ("from __future__ import ' - 'division")\n' - ' also use bits in "co_flags" to indicate whether a code ' + 'Code objects\n' + '------------\n' + '\n' + 'Code objects represent *byte-compiled* executable Python code, or\n' + '*bytecode*. The difference between a code object and a function ' 'object\n' - ' was compiled with a particular feature enabled: bit "0x2000" ' + 'is that the function object contains an explicit reference to the\n' + 'function’s globals (the module in which it was defined), while a ' + 'code\n' + 'object contains no context; also the default argument values are\n' + 'stored in the function object, not in the code object (because ' + 'they\n' + 'represent values calculated at run-time). Unlike function ' + 'objects,\n' + 'code objects are immutable and contain no references (directly or\n' + 'indirectly) to mutable objects.\n' + '\n' + 'Special read-only attributes: "co_name" gives the function name;\n' + '"co_qualname" gives the fully qualified function name; ' + '"co_argcount"\n' + 'is the total number of positional arguments (including ' + 'positional-only\n' + 'arguments and arguments with default values); "co_posonlyargcount" ' 'is\n' - ' set if the function was compiled with future division ' - 'enabled;\n' - ' bits "0x10" and "0x1000" were used in earlier versions of\n' - ' Python.\n' + 'the number of positional-only arguments (including arguments with\n' + 'default values); "co_kwonlyargcount" is the number of keyword-only\n' + 'arguments (including arguments with default values); "co_nlocals" ' + 'is\n' + 'the number of local variables used by the function (including\n' + 'arguments); "co_varnames" is a tuple containing the names of the ' + 'local\n' + 'variables (starting with the argument names); "co_cellvars" is a ' + 'tuple\n' + 'containing the names of local variables that are referenced by ' + 'nested\n' + 'functions; "co_freevars" is a tuple containing the names of free\n' + 'variables; "co_code" is a string representing the sequence of ' + 'bytecode\n' + 'instructions; "co_consts" is a tuple containing the literals used ' + 'by\n' + 'the bytecode; "co_names" is a tuple containing the names used by ' + 'the\n' + 'bytecode; "co_filename" is the filename from which the code was\n' + 'compiled; "co_firstlineno" is the first line number of the ' + 'function;\n' + '"co_lnotab" is a string encoding the mapping from bytecode offsets ' + 'to\n' + 'line numbers (for details see the source code of the interpreter);\n' + '"co_stacksize" is the required stack size; "co_flags" is an ' + 'integer\n' + 'encoding a number of flags for the interpreter.\n' '\n' - ' Other bits in "co_flags" are reserved for internal use.\n' + 'The following flag bits are defined for "co_flags": bit "0x04" is ' + 'set\n' + 'if the function uses the "*arguments" syntax to accept an ' + 'arbitrary\n' + 'number of positional arguments; bit "0x08" is set if the function ' + 'uses\n' + 'the "**keywords" syntax to accept arbitrary keyword arguments; bit\n' + '"0x20" is set if the function is a generator.\n' + '\n' + 'Future feature declarations ("from __future__ import division") ' + 'also\n' + 'use bits in "co_flags" to indicate whether a code object was ' + 'compiled\n' + 'with a particular feature enabled: bit "0x2000" is set if the ' + 'function\n' + 'was compiled with future division enabled; bits "0x10" and ' + '"0x1000"\n' + 'were used in earlier versions of Python.\n' '\n' - ' If a code object represents a function, the first item in\n' - ' "co_consts" is the documentation string of the function, or\n' - ' "None" if undefined.\n' + 'Other bits in "co_flags" are reserved for internal use.\n' '\n' - ' codeobject.co_positions()\n' + 'If a code object represents a function, the first item in ' + '"co_consts"\n' + 'is the documentation string of the function, or "None" if ' + 'undefined.\n' '\n' - ' Returns an iterable over the source code positions of ' - 'each\n' - ' bytecode instruction in the code object.\n' + 'codeobject.co_positions()\n' '\n' - ' The iterator returns tuples containing the "(start_line,\n' - ' end_line, start_column, end_column)". The *i-th* tuple\n' - ' corresponds to the position of the source code that ' - 'compiled\n' - ' to the *i-th* instruction. Column information is ' - '0-indexed\n' - ' utf-8 byte offsets on the given source line.\n' + ' Returns an iterable over the source code positions of each ' + 'bytecode\n' + ' instruction in the code object.\n' '\n' - ' This positional information can be missing. A ' - 'non-exhaustive\n' - ' lists of cases where this may happen:\n' + ' The iterator returns tuples containing the "(start_line, ' + 'end_line,\n' + ' start_column, end_column)". The *i-th* tuple corresponds to the\n' + ' position of the source code that compiled to the *i-th*\n' + ' instruction. Column information is 0-indexed utf-8 byte offsets ' + 'on\n' + ' the given source line.\n' '\n' - ' * Running the interpreter with "-X" "no_debug_ranges".\n' + ' This positional information can be missing. A non-exhaustive ' + 'lists\n' + ' of cases where this may happen:\n' '\n' - ' * Loading a pyc file compiled while using "-X"\n' - ' "no_debug_ranges".\n' + ' * Running the interpreter with "-X" "no_debug_ranges".\n' '\n' - ' * Position tuples corresponding to artificial ' - 'instructions.\n' + ' * Loading a pyc file compiled while using "-X" ' + '"no_debug_ranges".\n' '\n' - ' * Line and column numbers that can’t be represented due ' - 'to\n' - ' implementation specific limitations.\n' + ' * Position tuples corresponding to artificial instructions.\n' '\n' - ' When this occurs, some or all of the tuple elements can ' - 'be\n' - ' "None".\n' + ' * Line and column numbers that can’t be represented due to\n' + ' implementation specific limitations.\n' '\n' - ' New in version 3.11.\n' + ' When this occurs, some or all of the tuple elements can be ' + '"None".\n' '\n' - ' Note:\n' + ' New in version 3.11.\n' '\n' - ' This feature requires storing column positions in code\n' - ' objects which may result in a small increase of disk ' - 'usage\n' - ' of compiled Python files or interpreter memory usage. ' - 'To\n' - ' avoid storing the extra information and/or deactivate\n' - ' printing the extra traceback information, the "-X"\n' - ' "no_debug_ranges" command line flag or the\n' - ' "PYTHONNODEBUGRANGES" environment variable can be used.\n' + ' Note:\n' '\n' - ' Frame objects\n' - ' Frame objects represent execution frames. They may occur in\n' - ' traceback objects (see below), and are also passed to ' - 'registered\n' - ' trace functions.\n' + ' This feature requires storing column positions in code ' + 'objects\n' + ' which may result in a small increase of disk usage of ' + 'compiled\n' + ' Python files or interpreter memory usage. To avoid storing ' + 'the\n' + ' extra information and/or deactivate printing the extra ' + 'traceback\n' + ' information, the "-X" "no_debug_ranges" command line flag or ' + 'the\n' + ' "PYTHONNODEBUGRANGES" environment variable can be used.\n' + '\n' + '\n' + 'Frame objects\n' + '-------------\n' + '\n' + 'Frame objects represent execution frames. They may occur in ' + 'traceback\n' + 'objects (see below), and are also passed to registered trace\n' + 'functions.\n' + '\n' + 'Special read-only attributes: "f_back" is to the previous stack ' + 'frame\n' + '(towards the caller), or "None" if this is the bottom stack frame;\n' + '"f_code" is the code object being executed in this frame; ' + '"f_locals"\n' + 'is the dictionary used to look up local variables; "f_globals" is ' + 'used\n' + 'for global variables; "f_builtins" is used for built-in ' + '(intrinsic)\n' + 'names; "f_lasti" gives the precise instruction (this is an index ' + 'into\n' + 'the bytecode string of the code object).\n' + '\n' + 'Accessing "f_code" raises an auditing event "object.__getattr__" ' + 'with\n' + 'arguments "obj" and ""f_code"".\n' + '\n' + 'Special writable attributes: "f_trace", if not "None", is a ' + 'function\n' + 'called for various events during code execution (this is used by ' + 'the\n' + 'debugger). Normally an event is triggered for each new source line ' + '-\n' + 'this can be disabled by setting "f_trace_lines" to "False".\n' '\n' - ' Special read-only attributes: "f_back" is to the previous ' - 'stack\n' - ' frame (towards the caller), or "None" if this is the bottom\n' - ' stack frame; "f_code" is the code object being executed in ' + 'Implementations *may* allow per-opcode events to be requested by\n' + 'setting "f_trace_opcodes" to "True". Note that this may lead to\n' + 'undefined interpreter behaviour if exceptions raised by the trace\n' + 'function escape to the function being traced.\n' + '\n' + '"f_lineno" is the current line number of the frame — writing to ' 'this\n' - ' frame; "f_locals" is the dictionary used to look up local\n' - ' variables; "f_globals" is used for global variables;\n' - ' "f_builtins" is used for built-in (intrinsic) names; ' - '"f_lasti"\n' - ' gives the precise instruction (this is an index into the\n' - ' bytecode string of the code object).\n' - '\n' - ' Accessing "f_code" raises an auditing event ' - '"object.__getattr__"\n' - ' with arguments "obj" and ""f_code"".\n' - '\n' - ' Special writable attributes: "f_trace", if not "None", is a\n' - ' function called for various events during code execution ' - '(this\n' - ' is used by the debugger). Normally an event is triggered for\n' - ' each new source line - this can be disabled by setting\n' - ' "f_trace_lines" to "False".\n' - '\n' - ' Implementations *may* allow per-opcode events to be requested ' - 'by\n' - ' setting "f_trace_opcodes" to "True". Note that this may lead ' - 'to\n' - ' undefined interpreter behaviour if exceptions raised by the\n' - ' trace function escape to the function being traced.\n' + 'from within a trace function jumps to the given line (only for the\n' + 'bottom-most frame). A debugger can implement a Jump command (aka ' + 'Set\n' + 'Next Statement) by writing to f_lineno.\n' '\n' - ' "f_lineno" is the current line number of the frame — writing ' - 'to\n' - ' this from within a trace function jumps to the given line ' - '(only\n' - ' for the bottom-most frame). A debugger can implement a Jump\n' - ' command (aka Set Next Statement) by writing to f_lineno.\n' + 'Frame objects support one method:\n' '\n' - ' Frame objects support one method:\n' + 'frame.clear()\n' '\n' - ' frame.clear()\n' + ' This method clears all references to local variables held by ' + 'the\n' + ' frame. Also, if the frame belonged to a generator, the ' + 'generator\n' + ' is finalized. This helps break reference cycles involving ' + 'frame\n' + ' objects (for example when catching an exception and storing its\n' + ' traceback for later use).\n' '\n' - ' This method clears all references to local variables held ' - 'by\n' - ' the frame. Also, if the frame belonged to a generator, ' + ' "RuntimeError" is raised if the frame is currently executing.\n' + '\n' + ' New in version 3.4.\n' + '\n' + '\n' + 'Traceback objects\n' + '-----------------\n' + '\n' + 'Traceback objects represent a stack trace of an exception. A\n' + 'traceback object is implicitly created when an exception occurs, ' + 'and\n' + 'may also be explicitly created by calling "types.TracebackType".\n' + '\n' + 'For implicitly created tracebacks, when the search for an ' + 'exception\n' + 'handler unwinds the execution stack, at each unwound level a ' + 'traceback\n' + 'object is inserted in front of the current traceback. When an\n' + 'exception handler is entered, the stack trace is made available to ' 'the\n' - ' generator is finalized. This helps break reference ' - 'cycles\n' - ' involving frame objects (for example when catching an\n' - ' exception and storing its traceback for later use).\n' + 'program. (See section The try statement.) It is accessible as the\n' + 'third item of the tuple returned by "sys.exc_info()", and as the\n' + '"__traceback__" attribute of the caught exception.\n' '\n' - ' "RuntimeError" is raised if the frame is currently ' - 'executing.\n' + 'When the program contains no suitable handler, the stack trace is\n' + 'written (nicely formatted) to the standard error stream; if the\n' + 'interpreter is interactive, it is also made available to the user ' + 'as\n' + '"sys.last_traceback".\n' '\n' - ' New in version 3.4.\n' + 'For explicitly created tracebacks, it is up to the creator of the\n' + 'traceback to determine how the "tb_next" attributes should be ' + 'linked\n' + 'to form a full stack trace.\n' '\n' - ' Traceback objects\n' - ' Traceback objects represent a stack trace of an exception. ' - 'A\n' - ' traceback object is implicitly created when an exception ' - 'occurs,\n' - ' and may also be explicitly created by calling\n' - ' "types.TracebackType".\n' - '\n' - ' For implicitly created tracebacks, when the search for an\n' - ' exception handler unwinds the execution stack, at each ' - 'unwound\n' - ' level a traceback object is inserted in front of the current\n' - ' traceback. When an exception handler is entered, the stack\n' - ' trace is made available to the program. (See section The try\n' - ' statement.) It is accessible as the third item of the tuple\n' - ' returned by "sys.exc_info()", and as the "__traceback__"\n' - ' attribute of the caught exception.\n' - '\n' - ' When the program contains no suitable handler, the stack ' - 'trace\n' - ' is written (nicely formatted) to the standard error stream; ' - 'if\n' - ' the interpreter is interactive, it is also made available to ' + 'Special read-only attributes: "tb_frame" points to the execution ' + 'frame\n' + 'of the current level; "tb_lineno" gives the line number where the\n' + 'exception occurred; "tb_lasti" indicates the precise instruction. ' + 'The\n' + 'line number and last instruction in the traceback may differ from ' 'the\n' - ' user as "sys.last_traceback".\n' + 'line number of its frame object if the exception occurred in a ' + '"try"\n' + 'statement with no matching except clause or with a finally clause.\n' '\n' - ' For explicitly created tracebacks, it is up to the creator ' - 'of\n' - ' the traceback to determine how the "tb_next" attributes ' - 'should\n' - ' be linked to form a full stack trace.\n' - '\n' - ' Special read-only attributes: "tb_frame" points to the ' - 'execution\n' - ' frame of the current level; "tb_lineno" gives the line ' - 'number\n' - ' where the exception occurred; "tb_lasti" indicates the ' - 'precise\n' - ' instruction. The line number and last instruction in the\n' - ' traceback may differ from the line number of its frame object ' + 'Accessing "tb_frame" raises an auditing event "object.__getattr__"\n' + 'with arguments "obj" and ""tb_frame"".\n' + '\n' + 'Special writable attribute: "tb_next" is the next level in the ' + 'stack\n' + 'trace (towards the frame where the exception occurred), or "None" ' 'if\n' - ' the exception occurred in a "try" statement with no matching\n' - ' except clause or with a finally clause.\n' + 'there is no next level.\n' '\n' - ' Accessing "tb_frame" raises an auditing event\n' - ' "object.__getattr__" with arguments "obj" and ""tb_frame"".\n' + 'Changed in version 3.7: Traceback objects can now be explicitly\n' + 'instantiated from Python code, and the "tb_next" attribute of ' + 'existing\n' + 'instances can be updated.\n' '\n' - ' Special writable attribute: "tb_next" is the next level in ' - 'the\n' - ' stack trace (towards the frame where the exception occurred), ' - 'or\n' - ' "None" if there is no next level.\n' '\n' - ' Changed in version 3.7: Traceback objects can now be ' - 'explicitly\n' - ' instantiated from Python code, and the "tb_next" attribute ' - 'of\n' - ' existing instances can be updated.\n' + 'Slice objects\n' + '-------------\n' '\n' - ' Slice objects\n' - ' Slice objects are used to represent slices for ' - '"__getitem__()"\n' - ' methods. They are also created by the built-in "slice()"\n' - ' function.\n' + 'Slice objects are used to represent slices for "__getitem__()"\n' + 'methods. They are also created by the built-in "slice()" ' + 'function.\n' '\n' - ' Special read-only attributes: "start" is the lower bound; ' - '"stop"\n' - ' is the upper bound; "step" is the step value; each is "None" ' - 'if\n' - ' omitted. These attributes can have any type.\n' + 'Special read-only attributes: "start" is the lower bound; "stop" ' + 'is\n' + 'the upper bound; "step" is the step value; each is "None" if ' + 'omitted.\n' + 'These attributes can have any type.\n' '\n' - ' Slice objects support one method:\n' + 'Slice objects support one method:\n' '\n' - ' slice.indices(self, length)\n' + 'slice.indices(self, length)\n' '\n' - ' This method takes a single integer argument *length* and\n' - ' computes information about the slice that the slice ' - 'object\n' - ' would describe if applied to a sequence of *length* ' - 'items.\n' - ' It returns a tuple of three integers; respectively these ' - 'are\n' - ' the *start* and *stop* indices and the *step* or stride\n' - ' length of the slice. Missing or out-of-bounds indices are\n' - ' handled in a manner consistent with regular slices.\n' - '\n' - ' Static method objects\n' - ' Static method objects provide a way of defeating the\n' - ' transformation of function objects to method objects ' - 'described\n' - ' above. A static method object is a wrapper around any other\n' - ' object, usually a user-defined method object. When a static\n' - ' method object is retrieved from a class or a class instance, ' - 'the\n' - ' object actually returned is the wrapped object, which is not\n' - ' subject to any further transformation. Static method objects ' - 'are\n' - ' also callable. Static method objects are created by the ' - 'built-in\n' - ' "staticmethod()" constructor.\n' + ' This method takes a single integer argument *length* and ' + 'computes\n' + ' information about the slice that the slice object would describe ' + 'if\n' + ' applied to a sequence of *length* items. It returns a tuple of\n' + ' three integers; respectively these are the *start* and *stop*\n' + ' indices and the *step* or stride length of the slice. Missing ' + 'or\n' + ' out-of-bounds indices are handled in a manner consistent with\n' + ' regular slices.\n' '\n' - ' Class method objects\n' - ' A class method object, like a static method object, is a ' - 'wrapper\n' - ' around another object that alters the way in which that ' - 'object\n' - ' is retrieved from classes and class instances. The behaviour ' + '\n' + 'Static method objects\n' + '---------------------\n' + '\n' + 'Static method objects provide a way of defeating the transformation ' 'of\n' - ' class method objects upon such retrieval is described above,\n' - ' under “User-defined methodsâ€. Class method objects are ' - 'created\n' - ' by the built-in "classmethod()" constructor.\n', + 'function objects to method objects described above. A static ' + 'method\n' + 'object is a wrapper around any other object, usually a ' + 'user-defined\n' + 'method object. When a static method object is retrieved from a ' + 'class\n' + 'or a class instance, the object actually returned is the wrapped\n' + 'object, which is not subject to any further transformation. Static\n' + 'method objects are also callable. Static method objects are created ' + 'by\n' + 'the built-in "staticmethod()" constructor.\n' + '\n' + '\n' + 'Class method objects\n' + '--------------------\n' + '\n' + 'A class method object, like a static method object, is a wrapper\n' + 'around another object that alters the way in which that object is\n' + 'retrieved from classes and class instances. The behaviour of class\n' + 'method objects upon such retrieval is described above, under ' + '“User-\n' + 'defined methodsâ€. Class method objects are created by the built-in\n' + '"classmethod()" constructor.\n', 'typesfunctions': 'Functions\n' '*********\n' '\n' diff --git a/mingw64/lib/python3.11/selectors.py b/mingw64/lib/python3.11/selectors.py index af6a4f94b50..c3b065b5226 100644 --- a/mingw64/lib/python3.11/selectors.py +++ b/mingw64/lib/python3.11/selectors.py @@ -509,6 +509,7 @@ class KqueueSelector(_BaseSelectorImpl): def __init__(self): super().__init__() self._selector = select.kqueue() + self._max_events = 0 def fileno(self): return self._selector.fileno() @@ -520,10 +521,12 @@ def register(self, fileobj, events, data=None): kev = select.kevent(key.fd, select.KQ_FILTER_READ, select.KQ_EV_ADD) self._selector.control([kev], 0, 0) + self._max_events += 1 if events & EVENT_WRITE: kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, select.KQ_EV_ADD) self._selector.control([kev], 0, 0) + self._max_events += 1 except: super().unregister(fileobj) raise @@ -534,6 +537,7 @@ def unregister(self, fileobj): if key.events & EVENT_READ: kev = select.kevent(key.fd, select.KQ_FILTER_READ, select.KQ_EV_DELETE) + self._max_events -= 1 try: self._selector.control([kev], 0, 0) except OSError: @@ -543,6 +547,7 @@ def unregister(self, fileobj): if key.events & EVENT_WRITE: kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, select.KQ_EV_DELETE) + self._max_events -= 1 try: self._selector.control([kev], 0, 0) except OSError: @@ -555,7 +560,7 @@ def select(self, timeout=None): # If max_ev is 0, kqueue will ignore the timeout. For consistent # behavior with the other selector classes, we prevent that here # (using max). See https://bugs.python.org/issue29255 - max_ev = max(len(self._fd_to_key), 1) + max_ev = self._max_events or 1 ready = [] try: kev_list = self._selector.control(None, max_ev, timeout) diff --git a/mingw64/lib/python3.11/shutil.py b/mingw64/lib/python3.11/shutil.py index 1c3a75da55b..d108986d130 100644 --- a/mingw64/lib/python3.11/shutil.py +++ b/mingw64/lib/python3.11/shutil.py @@ -454,7 +454,7 @@ def _copytree(entries, src, dst, symlinks, ignore, copy_function, if ignore is not None: ignored_names = ignore(os.fspath(src), [x.name for x in entries]) else: - ignored_names = set() + ignored_names = () os.makedirs(dst, exist_ok=dirs_exist_ok) errors = [] diff --git a/mingw64/lib/python3.11/sqlite3/dump.py b/mingw64/lib/python3.11/sqlite3/dump.py index 07b9da10b92..1cf8759f897 100644 --- a/mingw64/lib/python3.11/sqlite3/dump.py +++ b/mingw64/lib/python3.11/sqlite3/dump.py @@ -16,6 +16,7 @@ def _iterdump(connection): directly but instead called from the Connection method, iterdump(). """ + writeable_schema = False cu = connection.cursor() yield('BEGIN TRANSACTION;') @@ -42,13 +43,15 @@ def _iterdump(connection): yield('ANALYZE "sqlite_master";') elif table_name.startswith('sqlite_'): continue - # NOTE: Virtual table support not implemented - #elif sql.startswith('CREATE VIRTUAL TABLE'): - # qtable = table_name.replace("'", "''") - # yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"\ - # "VALUES('table','{0}','{0}',0,'{1}');".format( - # qtable, - # sql.replace("''"))) + elif sql.startswith('CREATE VIRTUAL TABLE'): + if not writeable_schema: + writeable_schema = True + yield('PRAGMA writable_schema=ON;') + yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" + "VALUES('table','{0}','{0}',0,'{1}');".format( + table_name.replace("'", "''"), + sql.replace("'", "''"), + )) else: yield('{0};'.format(sql)) @@ -74,6 +77,9 @@ def _iterdump(connection): for name, type, sql in schema_res.fetchall(): yield('{0};'.format(sql)) + if writeable_schema: + yield('PRAGMA writable_schema=OFF;') + # gh-79009: Yield statements concerning the sqlite_sequence table at the # end of the transaction. for row in sqlite_sequence: diff --git a/mingw64/lib/python3.11/test/_test_eintr.py b/mingw64/lib/python3.11/test/_test_eintr.py index e43b59d064f..54a5412f828 100644 --- a/mingw64/lib/python3.11/test/_test_eintr.py +++ b/mingw64/lib/python3.11/test/_test_eintr.py @@ -25,6 +25,12 @@ from test.support import os_helper from test.support import socket_helper + +# gh-109592: Tolerate a difference of 20 ms when comparing timings +# (clock resolution) +CLOCK_RES = 0.020 + + @contextlib.contextmanager def kill_on_error(proc): """Context manager killing the subprocess if a Python exception is raised.""" @@ -75,6 +81,9 @@ def subprocess(self, *args, **kw): cmd_args = (sys.executable, '-c') + args return subprocess.Popen(cmd_args, **kw) + def check_elapsed_time(self, elapsed): + self.assertGreaterEqual(elapsed, self.sleep_time - CLOCK_RES) + @unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") class OSEINTRTest(EINTRBaseTest): @@ -373,7 +382,7 @@ def test_sleep(self): time.sleep(self.sleep_time) self.stop_alarm() dt = time.monotonic() - t0 - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) @unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") @@ -437,7 +446,7 @@ def test_select(self): select.select([], [], [], self.sleep_time) dt = time.monotonic() - t0 self.stop_alarm() - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) @unittest.skipIf(sys.platform == "darwin", "poll may fail on macOS; see issue #28087") @@ -449,7 +458,7 @@ def test_poll(self): poller.poll(self.sleep_time * 1e3) dt = time.monotonic() - t0 self.stop_alarm() - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) @unittest.skipUnless(hasattr(select, 'epoll'), 'need select.epoll') def test_epoll(self): @@ -460,7 +469,7 @@ def test_epoll(self): poller.poll(self.sleep_time) dt = time.monotonic() - t0 self.stop_alarm() - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) @unittest.skipUnless(hasattr(select, 'kqueue'), 'need select.kqueue') def test_kqueue(self): @@ -471,7 +480,7 @@ def test_kqueue(self): kqueue.control(None, 1, self.sleep_time) dt = time.monotonic() - t0 self.stop_alarm() - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) @unittest.skipUnless(hasattr(select, 'devpoll'), 'need select.devpoll') def test_devpoll(self): @@ -482,7 +491,7 @@ def test_devpoll(self): poller.poll(self.sleep_time * 1e3) dt = time.monotonic() - t0 self.stop_alarm() - self.assertGreaterEqual(dt, self.sleep_time) + self.check_elapsed_time(dt) class FNTLEINTRTest(EINTRBaseTest): @@ -512,8 +521,8 @@ def _lock(self, lock_func, lock_name): # potential context switch delay lock_func(f, fcntl.LOCK_EX) dt = time.monotonic() - start_time - self.assertGreaterEqual(dt, self.sleep_time) self.stop_alarm() + self.check_elapsed_time(dt) proc.wait() # Issue 35633: See https://bugs.python.org/issue35633#msg333662 diff --git a/mingw64/lib/python3.11/test/_test_multiprocessing.py b/mingw64/lib/python3.11/test/_test_multiprocessing.py index 9bc8242cbfa..6249062639b 100644 --- a/mingw64/lib/python3.11/test/_test_multiprocessing.py +++ b/mingw64/lib/python3.11/test/_test_multiprocessing.py @@ -78,7 +78,7 @@ if support.check_sanitizer(address=True): - # bpo-45200: Skip multiprocessing tests if Python is built with ASAN to + # gh-89363: Skip multiprocessing tests if Python is built with ASAN to # work around a libasan race condition: dead lock in pthread_create(). raise unittest.SkipTest("libasan has a pthread_create() dead lock") @@ -328,6 +328,7 @@ def test_set_executable(self): p.join() self.assertEqual(p.exitcode, 0) + @support.requires_resource('cpu') def test_args_argument(self): # bpo-45735: Using list or tuple as *args* in constructor could # achieve the same effect. @@ -555,13 +556,14 @@ def handler(*args): def test_terminate(self): exitcode = self._kill_process(multiprocessing.Process.terminate) - if os.name != 'nt': - self.assertEqual(exitcode, -signal.SIGTERM) + self.assertEqual(exitcode, -signal.SIGTERM) def test_kill(self): exitcode = self._kill_process(multiprocessing.Process.kill) if os.name != 'nt': self.assertEqual(exitcode, -signal.SIGKILL) + else: + self.assertEqual(exitcode, -signal.SIGTERM) def test_cpu_count(self): try: @@ -673,6 +675,7 @@ def test_close(self): close_queue(q) + @support.requires_resource('walltime') def test_many_processes(self): if self.TYPE == 'threads': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -4470,6 +4473,7 @@ def test_finalize(self): result = [obj for obj in iter(conn.recv, 'STOP')] self.assertEqual(result, ['a', 'b', 'd10', 'd03', 'd02', 'd01', 'e']) + @support.requires_resource('cpu') def test_thread_safety(self): # bpo-24484: _run_finalizers() should be thread-safe def cb(): @@ -4917,6 +4921,7 @@ def test_wait_slow(self): def test_wait_socket_slow(self): self.test_wait_socket(True) + @support.requires_resource('walltime') def test_wait_timeout(self): from multiprocessing.connection import wait @@ -4945,6 +4950,7 @@ def signal_and_sleep(cls, sem, period): sem.release() time.sleep(period) + @support.requires_resource('walltime') def test_wait_integer(self): from multiprocessing.connection import wait @@ -5367,6 +5373,34 @@ def test_mixed_startmethod(self): p.start() p.join() + @classmethod + def _put_one_in_queue(cls, queue): + queue.put(1) + + @classmethod + def _put_two_and_nest_once(cls, queue): + queue.put(2) + process = multiprocessing.Process(target=cls._put_one_in_queue, args=(queue,)) + process.start() + process.join() + + def test_nested_startmethod(self): + # gh-108520: Regression test to ensure that child process can send its + # arguments to another process + queue = multiprocessing.Queue() + + process = multiprocessing.Process(target=self._put_two_and_nest_once, args=(queue,)) + process.start() + process.join() + + results = [] + while not queue.empty(): + results.append(queue.get()) + + # gh-109706: queue.put(1) can write into the queue before queue.put(2), + # there is no synchronization in the test. + self.assertSetEqual(set(results), set([2, 1])) + @unittest.skipIf(sys.platform == "win32", "test semantics don't make sense on Windows") @@ -6049,7 +6083,8 @@ class ThreadsMixin(BaseMixin): # Functions used to create test cases from the base ones in this module # -def install_tests_in_module_dict(remote_globs, start_method): +def install_tests_in_module_dict(remote_globs, start_method, + only_type=None, exclude_types=False): __module__ = remote_globs['__name__'] local_globs = globals() ALL_TYPES = {'processes', 'threads', 'manager'} @@ -6062,6 +6097,10 @@ def install_tests_in_module_dict(remote_globs, start_method): continue assert set(base.ALLOWED_TYPES) <= ALL_TYPES, base.ALLOWED_TYPES for type_ in base.ALLOWED_TYPES: + if only_type and type_ != only_type: + continue + if exclude_types: + continue newname = 'With' + type_.capitalize() + name[1:] Mixin = local_globs[type_.capitalize() + 'Mixin'] class Temp(base, Mixin, unittest.TestCase): @@ -6072,6 +6111,9 @@ class Temp(base, Mixin, unittest.TestCase): Temp.__module__ = __module__ remote_globs[newname] = Temp elif issubclass(base, unittest.TestCase): + if only_type: + continue + class Temp(base, object): pass Temp.__name__ = Temp.__qualname__ = name diff --git a/mingw64/lib/python3.11/test/libregrtest/cmdline.py b/mingw64/lib/python3.11/test/libregrtest/cmdline.py index ebe57920d91..40ae8fc46e9 100644 --- a/mingw64/lib/python3.11/test/libregrtest/cmdline.py +++ b/mingw64/lib/python3.11/test/libregrtest/cmdline.py @@ -107,6 +107,8 @@ cpu - Used for certain CPU-heavy tests. + walltime - Long running but not CPU-bound tests. + subprocess Run all tests for the subprocess module. urlfetch - It is okay to download files required on testing. @@ -129,7 +131,7 @@ ALL_RESOURCES = ('audio', 'curses', 'largefile', 'network', - 'decimal', 'cpu', 'subprocess', 'urlfetch', 'gui') + 'decimal', 'cpu', 'subprocess', 'urlfetch', 'gui', 'walltime') # Other resources excluded from --use=all: # diff --git a/mingw64/lib/python3.11/test/libregrtest/main.py b/mingw64/lib/python3.11/test/libregrtest/main.py index 0125227bf11..7192244c69c 100644 --- a/mingw64/lib/python3.11/test/libregrtest/main.py +++ b/mingw64/lib/python3.11/test/libregrtest/main.py @@ -11,14 +11,14 @@ import unittest from test.libregrtest.cmdline import _parse_args from test.libregrtest.runtest import ( - findtests, runtest, get_abs_module, is_failed, - STDTESTS, NOTTESTS, PROGRESS_MIN_TIME, - Passed, Failed, EnvChanged, Skipped, ResourceDenied, Interrupted, - ChildError, DidNotRun) + findtests, split_test_packages, runtest, get_abs_module, + PROGRESS_MIN_TIME, State) from test.libregrtest.setup import setup_tests from test.libregrtest.pgo import setup_pgo_tests -from test.libregrtest.utils import removepy, count, format_duration, printlist +from test.libregrtest.utils import (removepy, count, format_duration, + printlist, get_build_info) from test import support +from test.support import TestStats from test.support import os_helper from test.support import threading_helper @@ -77,13 +77,14 @@ def __init__(self): self.good = [] self.bad = [] self.skipped = [] - self.resource_denieds = [] + self.resource_denied = [] self.environment_changed = [] self.run_no_tests = [] self.need_rerun = [] self.rerun = [] self.first_result = None self.interrupted = False + self.stats_dict: dict[str, TestStats] = {} # used by --slow self.test_times = [] @@ -92,7 +93,7 @@ def __init__(self): self.tracer = None # used to display the progress bar "[ 3/100]" - self.start_time = time.monotonic() + self.start_time = time.perf_counter() self.test_count = '' self.test_count_width = 1 @@ -110,36 +111,41 @@ def __init__(self): def get_executed(self): return (set(self.good) | set(self.bad) | set(self.skipped) - | set(self.resource_denieds) | set(self.environment_changed) + | set(self.resource_denied) | set(self.environment_changed) | set(self.run_no_tests)) def accumulate_result(self, result, rerun=False): - test_name = result.name - - if not isinstance(result, (ChildError, Interrupted)) and not rerun: - self.test_times.append((result.duration_sec, test_name)) - - if isinstance(result, Passed): - self.good.append(test_name) - elif isinstance(result, ResourceDenied): - self.skipped.append(test_name) - self.resource_denieds.append(test_name) - elif isinstance(result, Skipped): - self.skipped.append(test_name) - elif isinstance(result, EnvChanged): - self.environment_changed.append(test_name) - elif isinstance(result, Failed): - if not rerun: - self.bad.append(test_name) - self.need_rerun.append(result) - elif isinstance(result, DidNotRun): - self.run_no_tests.append(test_name) - elif isinstance(result, Interrupted): - self.interrupted = True - else: - raise ValueError("invalid test result: %r" % result) + test_name = result.test_name + + if result.has_meaningful_duration() and not rerun: + self.test_times.append((result.duration, test_name)) - if rerun and not isinstance(result, (Failed, Interrupted)): + match result.state: + case State.PASSED: + self.good.append(test_name) + case State.ENV_CHANGED: + self.environment_changed.append(test_name) + case State.SKIPPED: + self.skipped.append(test_name) + case State.RESOURCE_DENIED: + self.skipped.append(test_name) + self.resource_denied.append(test_name) + case State.INTERRUPTED: + self.interrupted = True + case State.DID_NOT_RUN: + self.run_no_tests.append(test_name) + case _: + if result.is_failed(self.ns.fail_env_changed): + if not rerun: + self.bad.append(test_name) + self.need_rerun.append(result) + else: + raise ValueError(f"invalid test state: {state!r}") + + if result.stats is not None: + self.stats_dict[result.test_name] = result.stats + + if rerun and not(result.is_failed(False) or result.state == State.INTERRUPTED): self.bad.remove(test_name) xml_data = result.xml_data @@ -161,7 +167,7 @@ def log(self, line=''): line = f"load avg: {load_avg:.2f} {line}" # add the timestamp prefix: "0:01:05 " - test_time = time.monotonic() - self.start_time + test_time = time.perf_counter() - self.start_time mins, secs = divmod(int(test_time), 60) hours, mins = divmod(mins, 60) @@ -245,26 +251,23 @@ def find_tests(self, tests): # add default PGO tests if no tests are specified setup_pgo_tests(self.ns) - stdtests = STDTESTS[:] - nottests = NOTTESTS.copy() + exclude = set() if self.ns.exclude: for arg in self.ns.args: - if arg in stdtests: - stdtests.remove(arg) - nottests.add(arg) + exclude.add(arg) self.ns.args = [] - # if testdir is set, then we are not running the python tests suite, so - # don't add default tests to be executed or skipped (pass empty values) - if self.ns.testdir: - alltests = findtests(self.ns.testdir, list(), set()) - else: - alltests = findtests(self.ns.testdir, stdtests, nottests) + alltests = findtests(testdir=self.ns.testdir, exclude=exclude) if not self.ns.fromfile: - self.selected = self.tests or self.ns.args or alltests + self.selected = self.tests or self.ns.args + if self.selected: + self.selected = split_test_packages(self.selected) + else: + self.selected = alltests else: self.selected = self.tests + if self.ns.single: self.selected = self.selected[:1] try: @@ -339,7 +342,7 @@ def rerun_failed_tests(self): rerun_list = list(self.need_rerun) self.need_rerun.clear() for result in rerun_list: - test_name = result.name + test_name = result.test_name self.rerun.append(test_name) errors = result.errors or [] @@ -366,7 +369,7 @@ def rerun_failed_tests(self): self.accumulate_result(result, rerun=True) - if isinstance(result, Interrupted): + if result.state == State.INTERRUPTED: break if self.bad: @@ -463,7 +466,7 @@ def run_tests_sequential(self): previous_test = None for test_index, test_name in enumerate(self.tests, 1): - start_time = time.monotonic() + start_time = time.perf_counter() text = test_name if previous_test: @@ -482,14 +485,14 @@ def run_tests_sequential(self): result = runtest(self.ns, test_name) self.accumulate_result(result) - if isinstance(result, Interrupted): + if result.state == State.INTERRUPTED: break previous_test = str(result) - test_time = time.monotonic() - start_time + test_time = time.perf_counter() - start_time if test_time >= PROGRESS_MIN_TIME: previous_test = "%s in %s" % (previous_test, format_duration(test_time)) - elif isinstance(result, Passed): + elif result.state == State.PASSED: # be quiet: say nothing if the test passed shortly previous_test = None @@ -498,7 +501,7 @@ def run_tests_sequential(self): if module not in save_modules and module.startswith("test."): support.unload(module) - if self.ns.failfast and is_failed(result, self.ns): + if self.ns.failfast and result.is_failed(self.ns.fail_env_changed): break if previous_test: @@ -518,12 +521,44 @@ def display_header(self): print("==", platform.python_implementation(), *sys.version.split()) print("==", platform.platform(aliased=True), "%s-endian" % sys.byteorder) + print("== Python build:", ' '.join(get_build_info())) print("== cwd:", os.getcwd()) cpu_count = os.cpu_count() if cpu_count: print("== CPU count:", cpu_count) print("== encodings: locale=%s, FS=%s" % (locale.getencoding(), sys.getfilesystemencoding())) + self.display_sanitizers() + + def display_sanitizers(self): + # This makes it easier to remember what to set in your local + # environment when trying to reproduce a sanitizer failure. + asan = support.check_sanitizer(address=True) + msan = support.check_sanitizer(memory=True) + ubsan = support.check_sanitizer(ub=True) + sanitizers = [] + if asan: + sanitizers.append("address") + if msan: + sanitizers.append("memory") + if ubsan: + sanitizers.append("undefined behavior") + if not sanitizers: + return + + print(f"== sanitizers: {', '.join(sanitizers)}") + for sanitizer, env_var in ( + (asan, "ASAN_OPTIONS"), + (msan, "MSAN_OPTIONS"), + (ubsan, "UBSAN_OPTIONS"), + ): + options= os.environ.get(env_var) + if sanitizer and options is not None: + print(f"== {env_var}={options!r}") + + def no_tests_run(self): + return not any((self.good, self.bad, self.skipped, self.interrupted, + self.environment_changed)) def get_tests_result(self): result = [] @@ -531,9 +566,8 @@ def get_tests_result(self): result.append("FAILURE") elif self.ns.fail_env_changed and self.environment_changed: result.append("ENV CHANGED") - elif not any((self.good, self.bad, self.skipped, self.interrupted, - self.environment_changed)): - result.append("NO TEST RUN") + elif self.no_tests_run(): + result.append("NO TESTS RAN") if self.interrupted: result.append("INTERRUPTED") @@ -609,13 +643,48 @@ def finalize(self): coverdir=self.ns.coverdir) print() - duration = time.monotonic() - self.start_time - print("Total duration: %s" % format_duration(duration)) - print("Tests result: %s" % self.get_tests_result()) + self.display_summary() if self.ns.runleaks: os.system("leaks %d" % os.getpid()) + def display_summary(self): + duration = time.perf_counter() - self.start_time + + # Total duration + print("Total duration: %s" % format_duration(duration)) + + # Total tests + total = TestStats() + for stats in self.stats_dict.values(): + total.accumulate(stats) + stats = [f'run={total.tests_run:,}'] + if total.failures: + stats.append(f'failures={total.failures:,}') + if total.skipped: + stats.append(f'skipped={total.skipped:,}') + print(f"Total tests: {' '.join(stats)}") + + # Total test files + report = [f'success={len(self.good)}'] + if self.bad: + report.append(f'failed={len(self.bad)}') + if self.environment_changed: + report.append(f'env_changed={len(self.environment_changed)}') + if self.skipped: + report.append(f'skipped={len(self.skipped)}') + if self.resource_denied: + report.append(f'resource_denied={len(self.resource_denied)}') + if self.rerun: + report.append(f'rerun={len(self.rerun)}') + if self.run_no_tests: + report.append(f'run_no_tests={len(self.run_no_tests)}') + print(f"Total test files: {' '.join(report)}") + + # Result + result = self.get_tests_result() + print(f"Result: {result}") + def save_xml_result(self): if not self.ns.xmlpath and not self.testsuite_xml: return @@ -662,11 +731,13 @@ def set_temp_dir(self): if sysconfig.is_python_build(): self.tmp_dir = sysconfig.get_config_var('abs_builddir') if self.tmp_dir is None: - # bpo-30284: On Windows, only srcdir is available. Using - # abs_builddir mostly matters on UNIX when building Python - # out of the source tree, especially when the source tree - # is read only. - self.tmp_dir = sysconfig.get_config_var('srcdir') + self.tmp_dir = sysconfig.get_config_var('abs_srcdir') + if not self.tmp_dir: + # gh-74470: On Windows, only srcdir is available. Using + # abs_builddir mostly matters on UNIX when building + # Python out of the source tree, especially when the + # source tree is read only. + self.tmp_dir = sysconfig.get_config_var('srcdir') self.tmp_dir = os.path.join(self.tmp_dir, 'build') else: self.tmp_dir = tempfile.gettempdir() @@ -782,11 +853,13 @@ def _main(self, tests, kwargs): self.save_xml_result() if self.bad: - sys.exit(2) + sys.exit(EXITCODE_BAD_TEST) if self.interrupted: - sys.exit(130) + sys.exit(EXITCODE_INTERRUPTED) if self.ns.fail_env_changed and self.environment_changed: - sys.exit(3) + sys.exit(EXITCODE_ENV_CHANGED) + if self.no_tests_run(): + sys.exit(EXITCODE_NO_TESTS_RAN) sys.exit(0) diff --git a/mingw64/lib/python3.11/test/libregrtest/refleak.py b/mingw64/lib/python3.11/test/libregrtest/refleak.py index a0538cbb3c3..58a1419e050 100644 --- a/mingw64/lib/python3.11/test/libregrtest/refleak.py +++ b/mingw64/lib/python3.11/test/libregrtest/refleak.py @@ -83,11 +83,12 @@ def get_pooled_int(value): print(("1234567890"*(repcount//10 + 1))[:repcount], file=sys.stderr, flush=True) + results = None dash_R_cleanup(fs, ps, pic, zdc, abcs) support.gc_collect() for i in rep_range: - test_func() + results = test_func() dash_R_cleanup(fs, ps, pic, zdc, abcs) support.gc_collect() @@ -146,7 +147,7 @@ def check_fd_deltas(deltas): print(msg, file=refrep) refrep.flush() failed = True - return failed + return (failed, results) def dash_R_cleanup(fs, ps, pic, zdc, abcs): diff --git a/mingw64/lib/python3.11/test/libregrtest/runtest.py b/mingw64/lib/python3.11/test/libregrtest/runtest.py index 62cf1a3f117..000a4aa75c4 100644 --- a/mingw64/lib/python3.11/test/libregrtest/runtest.py +++ b/mingw64/lib/python3.11/test/libregrtest/runtest.py @@ -1,3 +1,5 @@ +import dataclasses +import doctest import faulthandler import functools import gc @@ -10,6 +12,7 @@ import unittest from test import support +from test.support import TestStats from test.support import os_helper from test.support import threading_helper from test.libregrtest.cmdline import Namespace @@ -17,153 +20,174 @@ from test.libregrtest.utils import clear_caches, format_duration, print_warning +# Avoid enum.Enum to reduce the number of imports when tests are run +class State: + PASSED = "PASSED" + FAILED = "FAILED" + SKIPPED = "SKIPPED" + UNCAUGHT_EXC = "UNCAUGHT_EXC" + REFLEAK = "REFLEAK" + ENV_CHANGED = "ENV_CHANGED" + RESOURCE_DENIED = "RESOURCE_DENIED" + INTERRUPTED = "INTERRUPTED" + MULTIPROCESSING_ERROR = "MULTIPROCESSING_ERROR" + DID_NOT_RUN = "DID_NOT_RUN" + TIMEOUT = "TIMEOUT" + + @staticmethod + def is_failed(state): + return state in { + State.FAILED, + State.UNCAUGHT_EXC, + State.REFLEAK, + State.MULTIPROCESSING_ERROR, + State.TIMEOUT} + + @staticmethod + def has_meaningful_duration(state): + # Consider that the duration is meaningless for these cases. + # For example, if a whole test file is skipped, its duration + # is unlikely to be the duration of executing its tests, + # but just the duration to execute code which skips the test. + return state not in { + State.SKIPPED, + State.RESOURCE_DENIED, + State.INTERRUPTED, + State.MULTIPROCESSING_ERROR, + State.DID_NOT_RUN} + + +@dataclasses.dataclass(slots=True) class TestResult: - def __init__( - self, - name: str, - duration_sec: float = 0.0, - xml_data: list[str] | None = None, - ) -> None: - self.name = name - self.duration_sec = duration_sec - self.xml_data = xml_data - - def __str__(self) -> str: - return f"{self.name} finished" - - -class Passed(TestResult): - def __str__(self) -> str: - return f"{self.name} passed" - - -class Failed(TestResult): - def __init__( - self, - name: str, - duration_sec: float = 0.0, - xml_data: list[str] | None = None, - errors: list[tuple[str, str]] | None = None, - failures: list[tuple[str, str]] | None = None, - ) -> None: - super().__init__(name, duration_sec=duration_sec, xml_data=xml_data) - self.errors = errors - self.failures = failures - - def __str__(self) -> str: + test_name: str + state: str | None = None + # Test duration in seconds + duration: float | None = None + xml_data: list[str] | None = None + stats: TestStats | None = None + + # errors and failures copied from support.TestFailedWithDetails + errors: list[tuple[str, str]] | None = None + failures: list[tuple[str, str]] | None = None + + def is_failed(self, fail_env_changed: bool) -> bool: + if self.state == State.ENV_CHANGED: + return fail_env_changed + return State.is_failed(self.state) + + def _format_failed(self): if self.errors and self.failures: le = len(self.errors) lf = len(self.failures) error_s = "error" + ("s" if le > 1 else "") failure_s = "failure" + ("s" if lf > 1 else "") - return f"{self.name} failed ({le} {error_s}, {lf} {failure_s})" + return f"{self.test_name} failed ({le} {error_s}, {lf} {failure_s})" if self.errors: le = len(self.errors) error_s = "error" + ("s" if le > 1 else "") - return f"{self.name} failed ({le} {error_s})" + return f"{self.test_name} failed ({le} {error_s})" if self.failures: lf = len(self.failures) failure_s = "failure" + ("s" if lf > 1 else "") - return f"{self.name} failed ({lf} {failure_s})" - - return f"{self.name} failed" - - -class UncaughtException(Failed): - def __str__(self) -> str: - return f"{self.name} failed (uncaught exception)" - - -class EnvChanged(Failed): - def __str__(self) -> str: - return f"{self.name} failed (env changed)" - - -class RefLeak(Failed): - def __str__(self) -> str: - return f"{self.name} failed (reference leak)" - - -class Skipped(TestResult): - def __str__(self) -> str: - return f"{self.name} skipped" - - -class ResourceDenied(Skipped): - def __str__(self) -> str: - return f"{self.name} skipped (resource denied)" - - -class Interrupted(TestResult): - def __str__(self) -> str: - return f"{self.name} interrupted" - - -class ChildError(Failed): - def __str__(self) -> str: - return f"{self.name} crashed" - - -class DidNotRun(TestResult): - def __str__(self) -> str: - return f"{self.name} ran no tests" + return f"{self.test_name} failed ({lf} {failure_s})" + return f"{self.test_name} failed" -class Timeout(Failed): def __str__(self) -> str: - return f"{self.name} timed out ({format_duration(self.duration_sec)})" + match self.state: + case State.PASSED: + return f"{self.test_name} passed" + case State.FAILED: + return self._format_failed() + case State.SKIPPED: + return f"{self.test_name} skipped" + case State.UNCAUGHT_EXC: + return f"{self.test_name} failed (uncaught exception)" + case State.REFLEAK: + return f"{self.test_name} failed (reference leak)" + case State.ENV_CHANGED: + return f"{self.test_name} failed (env changed)" + case State.RESOURCE_DENIED: + return f"{self.test_name} skipped (resource denied)" + case State.INTERRUPTED: + return f"{self.test_name} interrupted" + case State.MULTIPROCESSING_ERROR: + return f"{self.test_name} process crashed" + case State.DID_NOT_RUN: + return f"{self.test_name} ran no tests" + case State.TIMEOUT: + return f"{self.test_name} timed out ({format_duration(self.duration)})" + case _: + raise ValueError("unknown result state: {state!r}") + + def has_meaningful_duration(self): + return State.has_meaningful_duration(self.state) + + def set_env_changed(self): + if self.state is None or self.state == State.PASSED: + self.state = State.ENV_CHANGED # Minimum duration of a test to display its duration or to mention that # the test is running in background PROGRESS_MIN_TIME = 30.0 # seconds -# small set of tests to determine if we have a basically functioning interpreter -# (i.e. if any of these fail, then anything else is likely to follow) -STDTESTS = [ - 'test_grammar', - 'test_opcodes', - 'test_dict', - 'test_builtin', - 'test_exceptions', - 'test_types', - 'test_unittest', - 'test_doctest', - 'test_doctest2', - 'test_support' -] - -# set of tests that we don't want to be executed when using regrtest -NOTTESTS = set() +#If these test directories are encountered recurse into them and treat each +# test_ .py or dir as a separate test module. This can increase parallelism. +# Beware this can't generally be done for any directory with sub-tests as the +# __init__.py may do things which alter what tests are to be run. +SPLITTESTDIRS = { + "test_asyncio", + "test_concurrent_futures", + "test_future_stmt", + "test_multiprocessing_fork", + "test_multiprocessing_forkserver", + "test_multiprocessing_spawn", +} # Storage of uncollectable objects FOUND_GARBAGE = [] -def is_failed(result: TestResult, ns: Namespace) -> bool: - if isinstance(result, EnvChanged): - return ns.fail_env_changed - return isinstance(result, Failed) - - def findtestdir(path=None): return path or os.path.dirname(os.path.dirname(__file__)) or os.curdir -def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS): +def findtests(*, testdir=None, exclude=(), + split_test_dirs=SPLITTESTDIRS, base_mod=""): """Return a list of all applicable test modules.""" testdir = findtestdir(testdir) - names = os.listdir(testdir) tests = [] - others = set(stdtests) | nottests - for name in names: + for name in os.listdir(testdir): mod, ext = os.path.splitext(name) - if mod[:5] == "test_" and ext in (".py", "") and mod not in others: - tests.append(mod) - return stdtests + sorted(tests) + if (not mod.startswith("test_")) or (mod in exclude): + continue + if mod in split_test_dirs: + subdir = os.path.join(testdir, mod) + mod = f"{base_mod or 'test'}.{mod}" + tests.extend(findtests(testdir=subdir, exclude=exclude, + split_test_dirs=split_test_dirs, base_mod=mod)) + elif ext in (".py", ""): + tests.append(f"{base_mod}.{mod}" if base_mod else mod) + return sorted(tests) + + +def split_test_packages(tests, *, testdir=None, exclude=(), + split_test_dirs=SPLITTESTDIRS): + testdir = findtestdir(testdir) + splitted = [] + for name in tests: + if name in split_test_dirs: + subdir = os.path.join(testdir, name) + splitted.extend(findtests(testdir=subdir, exclude=exclude, + split_test_dirs=split_test_dirs, + base_mod=name)) + else: + splitted.append(name) + return splitted def get_abs_module(ns: Namespace, test_name: str) -> str: @@ -174,9 +198,9 @@ def get_abs_module(ns: Namespace, test_name: str) -> str: return 'test.' + test_name -def _runtest(ns: Namespace, test_name: str) -> TestResult: - # Handle faulthandler timeout, capture stdout+stderr, XML serialization - # and measure time. +def _runtest_capture_output_timeout_junit(result: TestResult, ns: Namespace) -> None: + # Capture stdout and stderr, set faulthandler timeout, + # and create JUnit XML report. output_on_failure = ns.verbose3 @@ -186,7 +210,6 @@ def _runtest(ns: Namespace, test_name: str) -> TestResult: if use_timeout: faulthandler.dump_traceback_later(ns.timeout, exit=True) - start_time = time.perf_counter() try: support.set_match_tests(ns.match_tests, ns.ignore_tests) support.junit_xml_list = xml_list = [] if ns.xmlpath else None @@ -211,9 +234,9 @@ def _runtest(ns: Namespace, test_name: str) -> TestResult: # warnings will be written to sys.stderr below. print_warning.orig_stderr = stream - result = _runtest_inner(ns, test_name, - display_failure=False) - if not isinstance(result, Passed): + _runtest_env_changed_exc(result, ns, display_failure=False) + # Ignore output if the test passed successfully + if result.state != State.PASSED: output = stream.getvalue() finally: sys.stdout = orig_stdout @@ -227,18 +250,13 @@ def _runtest(ns: Namespace, test_name: str) -> TestResult: # Tell tests to be moderately quiet support.verbose = ns.verbose - result = _runtest_inner(ns, test_name, - display_failure=not ns.verbose) + _runtest_env_changed_exc(result, ns, + display_failure=not ns.verbose) if xml_list: import xml.etree.ElementTree as ET - result.xml_data = [ - ET.tostring(x).decode('us-ascii') - for x in xml_list - ] - - result.duration_sec = time.perf_counter() - start_time - return result + result.xml_data = [ET.tostring(x).decode('us-ascii') + for x in xml_list] finally: if use_timeout: faulthandler.cancel_dump_traceback_later() @@ -251,19 +269,23 @@ def runtest(ns: Namespace, test_name: str) -> TestResult: ns -- regrtest namespace of options test_name -- the name of the test - Returns a TestResult sub-class depending on the kind of result received. + Returns a TestResult. If ns.xmlpath is not None, xml_data is a list containing each generated testsuite element. """ + start_time = time.perf_counter() + result = TestResult(test_name) try: - return _runtest(ns, test_name) + _runtest_capture_output_timeout_junit(result, ns) except: if not ns.pgo: msg = traceback.format_exc() print(f"test {test_name} crashed -- {msg}", file=sys.stderr, flush=True) - return Failed(test_name) + result.state = State.UNCAUGHT_EXC + result.duration = time.perf_counter() - start_time + return result def _test_module(the_module): @@ -273,18 +295,48 @@ def _test_module(the_module): print(error, file=sys.stderr) if loader.errors: raise Exception("errors while loading tests") - support.run_unittest(tests) + return support.run_unittest(tests) def save_env(ns: Namespace, test_name: str): return saved_test_environment(test_name, ns.verbose, ns.quiet, pgo=ns.pgo) -def _runtest_inner2(ns: Namespace, test_name: str) -> bool: - # Load the test function, run the test function, handle huntrleaks - # to detect leaks. +def regrtest_runner(result, test_func, ns) -> None: + # Run test_func(), collect statistics, and detect reference and memory + # leaks. + + if ns.huntrleaks: + from test.libregrtest.refleak import dash_R + refleak, test_result = dash_R(ns, result.test_name, test_func) + else: + test_result = test_func() + refleak = False + + if refleak: + result.state = State.REFLEAK + + match test_result: + case TestStats(): + stats = test_result + case unittest.TestResult(): + stats = TestStats.from_unittest(test_result) + case doctest.TestResults(): + stats = TestStats.from_doctest(test_result) + case None: + print_warning(f"{result.test_name} test runner returned None: {test_func}") + stats = None + case _: + print_warning(f"Unknown test result type: {type(test_result)}") + stats = None + + result.stats = stats + - abstest = get_abs_module(ns, test_name) +def _load_run_test(result: TestResult, ns: Namespace) -> None: + # Load the test function, run the test function. + + abstest = get_abs_module(ns, result.test_name) # remove the module from sys.module to reload it if it was already imported try: @@ -294,23 +346,14 @@ def _runtest_inner2(ns: Namespace, test_name: str) -> bool: the_module = importlib.import_module(abstest) - if ns.huntrleaks: - from test.libregrtest.refleak import dash_R - - # If the test has a test_main, that will run the appropriate - # tests. If not, use normal unittest test loading. - test_runner = getattr(the_module, "test_main", None) - if test_runner is None: - test_runner = functools.partial(_test_module, the_module) + if hasattr(the_module, "test_main"): + # https://github.com/python/cpython/issues/89392 + raise Exception(f"Module {result.test_name} defines test_main() which is no longer supported by regrtest") + test_func = functools.partial(_test_module, the_module) try: - with save_env(ns, test_name): - if ns.huntrleaks: - # Return True if the test leaked references - refleak = dash_R(ns, test_name, test_runner) - else: - test_runner() - refleak = False + with save_env(ns, result.test_name): + regrtest_runner(result, test_func, ns) finally: # First kill any dangling references to open files etc. # This can also issue some ResourceWarnings which would otherwise get @@ -318,11 +361,11 @@ def _runtest_inner2(ns: Namespace, test_name: str) -> bool: # failures. support.gc_collect() - cleanup_test_droppings(test_name, ns.verbose) + cleanup_test_droppings(result.test_name, ns.verbose) if gc.garbage: support.environment_altered = True - print_warning(f"{test_name} created {len(gc.garbage)} " + print_warning(f"{result.test_name} created {len(gc.garbage)} " f"uncollectable object(s).") # move the uncollectable objects somewhere, @@ -332,12 +375,9 @@ def _runtest_inner2(ns: Namespace, test_name: str) -> bool: support.reap_children() - return refleak - -def _runtest_inner( - ns: Namespace, test_name: str, display_failure: bool = True -) -> TestResult: +def _runtest_env_changed_exc(result: TestResult, ns: Namespace, + display_failure: bool = True) -> None: # Detect environment changes, handle exceptions. # Reset the environment_altered flag to detect if a test altered @@ -347,49 +387,61 @@ def _runtest_inner( if ns.pgo: display_failure = False + test_name = result.test_name try: clear_caches() support.gc_collect() with save_env(ns, test_name): - refleak = _runtest_inner2(ns, test_name) + _load_run_test(result, ns) except support.ResourceDenied as msg: if not ns.quiet and not ns.pgo: print(f"{test_name} skipped -- {msg}", flush=True) - return ResourceDenied(test_name) + result.state = State.RESOURCE_DENIED + return except unittest.SkipTest as msg: if not ns.quiet and not ns.pgo: print(f"{test_name} skipped -- {msg}", flush=True) - return Skipped(test_name) + result.state = State.SKIPPED + return except support.TestFailedWithDetails as exc: msg = f"test {test_name} failed" if display_failure: msg = f"{msg} -- {exc}" print(msg, file=sys.stderr, flush=True) - return Failed(test_name, errors=exc.errors, failures=exc.failures) + result.state = State.FAILED + result.errors = exc.errors + result.failures = exc.failures + result.stats = exc.stats + return except support.TestFailed as exc: msg = f"test {test_name} failed" if display_failure: msg = f"{msg} -- {exc}" print(msg, file=sys.stderr, flush=True) - return Failed(test_name) + result.state = State.FAILED + result.stats = exc.stats + return except support.TestDidNotRun: - return DidNotRun(test_name) + result.state = State.DID_NOT_RUN + return except KeyboardInterrupt: print() - return Interrupted(test_name) + result.state = State.INTERRUPTED + return except: if not ns.pgo: msg = traceback.format_exc() print(f"test {test_name} crashed -- {msg}", file=sys.stderr, flush=True) - return UncaughtException(test_name) + result.state = State.UNCAUGHT_EXC + return - if refleak: - return RefLeak(test_name) if support.environment_altered: - return EnvChanged(test_name) - return Passed(test_name) + result.set_env_changed() + # Don't override the state if it was already set (REFLEAK or ENV_CHANGED) + if result.state is None: + result.state = State.PASSED def cleanup_test_droppings(test_name: str, verbose: int) -> None: diff --git a/mingw64/lib/python3.11/test/libregrtest/runtest_mp.py b/mingw64/lib/python3.11/test/libregrtest/runtest_mp.py index 8587e64e515..fb1f80b0c05 100644 --- a/mingw64/lib/python3.11/test/libregrtest/runtest_mp.py +++ b/mingw64/lib/python3.11/test/libregrtest/runtest_mp.py @@ -1,6 +1,7 @@ +import dataclasses import faulthandler import json -import os +import os.path import queue import signal import subprocess @@ -13,11 +14,13 @@ from test import support from test.support import os_helper +from test.support import TestStats from test.libregrtest.cmdline import Namespace from test.libregrtest.main import Regrtest from test.libregrtest.runtest import ( - runtest, is_failed, TestResult, Interrupted, Timeout, ChildError, PROGRESS_MIN_TIME) + runtest, TestResult, State, + PROGRESS_MIN_TIME) from test.libregrtest.setup import setup_tests from test.libregrtest.utils import format_duration, print_warning @@ -42,9 +45,9 @@ def must_stop(result: TestResult, ns: Namespace) -> bool: - if isinstance(result, Interrupted): + if result.state == State.INTERRUPTED: return True - if ns.failfast and is_failed(result, ns): + if ns.failfast and result.is_failed(ns.fail_env_changed): return True return False @@ -55,7 +58,7 @@ def parse_worker_args(worker_args) -> tuple[Namespace, str]: return (ns, test_name) -def run_test_in_subprocess(testname: str, ns: Namespace, stdout_fh: TextIO) -> subprocess.Popen: +def run_test_in_subprocess(testname: str, ns: Namespace, tmp_dir: str, stdout_fh: TextIO) -> subprocess.Popen: ns_dict = vars(ns) worker_args = (ns_dict, testname) worker_args = json.dumps(worker_args) @@ -68,10 +71,17 @@ def run_test_in_subprocess(testname: str, ns: Namespace, stdout_fh: TextIO) -> s '-m', 'test.regrtest', '--worker-args', worker_args] + env = dict(os.environ) + if tmp_dir is not None: + env['TMPDIR'] = tmp_dir + env['TEMP'] = tmp_dir + env['TMP'] = tmp_dir + # Running the child from the same working directory as regrtest's original # invocation ensures that TEMPDIR for the child is the same when # sysconfig.is_python_build() is true. See issue 15300. kw = dict( + env=env, stdout=stdout_fh, # bpo-45410: Write stderr into stdout to keep messages order stderr=stdout_fh, @@ -122,8 +132,8 @@ def stop(self): class MultiprocessResult(NamedTuple): result: TestResult # bpo-45410: stderr is written into stdout to keep messages order - stdout: str - error_msg: str + worker_stdout: str | None = None + err_msg: str | None = None ExcStr = str @@ -201,18 +211,15 @@ def stop(self) -> None: def mp_result_error( self, test_result: TestResult, - stdout: str = '', + stdout: str | None = None, err_msg=None ) -> MultiprocessResult: - test_result.duration_sec = time.monotonic() - self.start_time return MultiprocessResult(test_result, stdout, err_msg) - def _run_process(self, test_name: str, stdout_fh: TextIO) -> int: - self.start_time = time.monotonic() - + def _run_process(self, test_name: str, tmp_dir: str, stdout_fh: TextIO) -> int: self.current_test_name = test_name try: - popen = run_test_in_subprocess(test_name, self.ns, stdout_fh) + popen = run_test_in_subprocess(test_name, self.ns, tmp_dir, stdout_fh) self._killed = False self._popen = popen @@ -276,7 +283,20 @@ def _runtest(self, test_name: str) -> MultiprocessResult: # gh-93353: Check for leaked temporary files in the parent process, # since the deletion of temporary files can happen late during # Python finalization: too late for libregrtest. - retcode = self._run_process(test_name, stdout_fh) + if not support.is_wasi: + # Don't check for leaked temporary files and directories if Python is + # run on WASI. WASI don't pass environment variables like TMPDIR to + # worker processes. + tmp_dir = tempfile.mkdtemp(prefix="test_python_") + tmp_dir = os.path.abspath(tmp_dir) + try: + retcode = self._run_process(test_name, tmp_dir, stdout_fh) + finally: + tmp_files = os.listdir(tmp_dir) + os_helper.rmtree(tmp_dir) + else: + retcode = self._run_process(test_name, None, stdout_fh) + tmp_files = () stdout_fh.seek(0) try: @@ -285,30 +305,41 @@ def _runtest(self, test_name: str) -> MultiprocessResult: # gh-101634: Catch UnicodeDecodeError if stdout cannot be # decoded from encoding err_msg = f"Cannot read process stdout: {exc}" - return self.mp_result_error(ChildError(test_name), '', err_msg) + result = TestResult(test_name, state=State.MULTIPROCESSING_ERROR) + return self.mp_result_error(result, err_msg=err_msg) if retcode is None: - return self.mp_result_error(Timeout(test_name), stdout) + result = TestResult(test_name, state=State.TIMEOUT) + return self.mp_result_error(result, stdout) err_msg = None if retcode != 0: err_msg = "Exit code %s" % retcode else: - stdout, _, result = stdout.rpartition("\n") + stdout, _, worker_json = stdout.rpartition("\n") stdout = stdout.rstrip() - if not result: + if not worker_json: err_msg = "Failed to parse worker stdout" else: try: # deserialize run_tests_worker() output - result = json.loads(result, object_hook=decode_test_result) + result = json.loads(worker_json, + object_hook=decode_test_result) except Exception as exc: err_msg = "Failed to parse worker JSON: %s" % exc - if err_msg is not None: - return self.mp_result_error(ChildError(test_name), stdout, err_msg) + if err_msg: + result = TestResult(test_name, state=State.MULTIPROCESSING_ERROR) + return self.mp_result_error(result, stdout, err_msg) + + if tmp_files: + msg = (f'\n\n' + f'Warning -- {test_name} leaked temporary files ' + f'({len(tmp_files)}): {", ".join(sorted(tmp_files))}') + stdout += msg + result.set_env_changed() - return MultiprocessResult(result, stdout, err_msg) + return MultiprocessResult(result, stdout) def run(self) -> None: while not self._stopped: @@ -318,7 +349,9 @@ def run(self) -> None: except StopIteration: break + self.start_time = time.monotonic() mp_result = self._runtest(test_name) + mp_result.result.duration = time.monotonic() - self.start_time self.output.put((False, mp_result)) if must_stop(mp_result.result, self.ns): @@ -444,11 +477,11 @@ def display_result(self, mp_result: MultiprocessResult) -> None: result = mp_result.result text = str(result) - if mp_result.error_msg is not None: - # CHILD_ERROR - text += ' (%s)' % mp_result.error_msg - elif (result.duration_sec >= PROGRESS_MIN_TIME and not self.ns.pgo): - text += ' (%s)' % format_duration(result.duration_sec) + if mp_result.err_msg: + # MULTIPROCESSING_ERROR + text += ' (%s)' % mp_result.err_msg + elif (result.duration >= PROGRESS_MIN_TIME and not self.ns.pgo): + text += ' (%s)' % format_duration(result.duration) running = get_running(self.workers) if running and not self.ns.pgo: text += ' -- running: %s' % ', '.join(running) @@ -460,7 +493,7 @@ def _process_result(self, item: QueueOutput) -> bool: # Thread got an exception format_exc = item[1] print_warning(f"regrtest worker thread failed: {format_exc}") - result = ChildError("") + result = TestResult("", state=State.MULTIPROCESSING_ERROR) self.regrtest.accumulate_result(result) return True @@ -469,8 +502,8 @@ def _process_result(self, item: QueueOutput) -> bool: self.regrtest.accumulate_result(mp_result.result) self.display_result(mp_result) - if mp_result.stdout: - print(mp_result.stdout, flush=True) + if mp_result.worker_stdout: + print(mp_result.worker_stdout, flush=True) if must_stop(mp_result.result, self.ns): return True @@ -512,32 +545,20 @@ class EncodeTestResult(json.JSONEncoder): def default(self, o: Any) -> dict[str, Any]: if isinstance(o, TestResult): - result = vars(o) + result = dataclasses.asdict(o) result["__test_result__"] = o.__class__.__name__ return result return super().default(o) -def decode_test_result(d: dict[str, Any]) -> TestResult | dict[str, Any]: +def decode_test_result(d: dict[str, Any]) -> TestResult | TestStats | dict[str, Any]: """Decode a TestResult (sub)class object from a JSON dict.""" if "__test_result__" not in d: return d - cls_name = d.pop("__test_result__") - for cls in get_all_test_result_classes(): - if cls.__name__ == cls_name: - return cls(**d) - - -def get_all_test_result_classes() -> set[type[TestResult]]: - prev_count = 0 - classes = {TestResult} - while len(classes) > prev_count: - prev_count = len(classes) - to_add = [] - for cls in classes: - to_add.extend(cls.__subclasses__()) - classes.update(to_add) - return classes + d.pop('__test_result__') + if d['stats'] is not None: + d['stats'] = TestStats(**d['stats']) + return TestResult(**d) diff --git a/mingw64/lib/python3.11/test/libregrtest/save_env.py b/mingw64/lib/python3.11/test/libregrtest/save_env.py index 60c9be24617..7e801a59132 100644 --- a/mingw64/lib/python3.11/test/libregrtest/save_env.py +++ b/mingw64/lib/python3.11/test/libregrtest/save_env.py @@ -23,7 +23,7 @@ class SkipTestEnvironment(Exception): class saved_test_environment: """Save bits of the test environment and restore them at block exit. - with saved_test_environment(testname, verbose, quiet): + with saved_test_environment(test_name, verbose, quiet): #stuff Unless quiet is True, a warning is printed to stderr if any of @@ -34,8 +34,8 @@ class saved_test_environment: items is also printed. """ - def __init__(self, testname, verbose=0, quiet=False, *, pgo=False): - self.testname = testname + def __init__(self, test_name, verbose=0, quiet=False, *, pgo=False): + self.test_name = test_name self.verbose = verbose self.quiet = quiet self.pgo = pgo @@ -321,7 +321,7 @@ def __exit__(self, exc_type, exc_val, exc_tb): restore(original) if not self.quiet and not self.pgo: print_warning( - f"{name} was modified by {self.testname}\n" + f"{name} was modified by {self.test_name}\n" f" Before: {original}\n" f" After: {current} ") return False diff --git a/mingw64/lib/python3.11/test/libregrtest/utils.py b/mingw64/lib/python3.11/test/libregrtest/utils.py index 8578a028c78..49f3a236f3d 100644 --- a/mingw64/lib/python3.11/test/libregrtest/utils.py +++ b/mingw64/lib/python3.11/test/libregrtest/utils.py @@ -1,6 +1,7 @@ import math import os.path import sys +import sysconfig import textwrap from test import support @@ -210,3 +211,84 @@ def clear_caches(): else: for f in typing._cleanups: f() + + +def get_build_info(): + # Get most important configure and build options as a list of strings. + # Example: ['debug', 'ASAN+MSAN'] or ['release', 'LTO+PGO']. + + config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' + cflags = sysconfig.get_config_var('PY_CFLAGS') or '' + cflags_nodist = sysconfig.get_config_var('PY_CFLAGS_NODIST') or '' + ldflags_nodist = sysconfig.get_config_var('PY_LDFLAGS_NODIST') or '' + + build = [] + + # --disable-gil + if sysconfig.get_config_var('Py_NOGIL'): + build.append("nogil") + + if hasattr(sys, 'gettotalrefcount'): + # --with-pydebug + build.append('debug') + + if '-DNDEBUG' in (cflags + cflags_nodist): + build.append('without_assert') + else: + build.append('release') + + if '--with-assertions' in config_args: + build.append('with_assert') + elif '-DNDEBUG' not in (cflags + cflags_nodist): + build.append('with_assert') + + # --enable-framework=name + framework = sysconfig.get_config_var('PYTHONFRAMEWORK') + if framework: + build.append(f'framework={framework}') + + # --enable-shared + shared = int(sysconfig.get_config_var('PY_ENABLE_SHARED') or '0') + if shared: + build.append('shared') + + # --with-lto + optimizations = [] + if '-flto=thin' in ldflags_nodist: + optimizations.append('ThinLTO') + elif '-flto' in ldflags_nodist: + optimizations.append('LTO') + + if support.check_cflags_pgo(): + # PGO (--enable-optimizations) + optimizations.append('PGO') + if optimizations: + build.append('+'.join(optimizations)) + + # --with-address-sanitizer + sanitizers = [] + if support.check_sanitizer(address=True): + sanitizers.append("ASAN") + # --with-memory-sanitizer + if support.check_sanitizer(memory=True): + sanitizers.append("MSAN") + # --with-undefined-behavior-sanitizer + if support.check_sanitizer(ub=True): + sanitizers.append("UBSAN") + if sanitizers: + build.append('+'.join(sanitizers)) + + # --with-trace-refs + if hasattr(sys, 'getobjects'): + build.append("TraceRefs") + # --enable-pystats + if hasattr(sys, '_stats_on'): + build.append("pystats") + # --with-valgrind + if sysconfig.get_config_var('WITH_VALGRIND'): + build.append("valgrind") + # --with-dtrace + if sysconfig.get_config_var('WITH_DTRACE'): + build.append("dtrace") + + return build diff --git a/mingw64/lib/python3.11/test/lock_tests.py b/mingw64/lib/python3.11/test/lock_tests.py index f16c7ed952c..d5ac1319064 100644 --- a/mingw64/lib/python3.11/test/lock_tests.py +++ b/mingw64/lib/python3.11/test/lock_tests.py @@ -331,6 +331,42 @@ def test_release_save_unacquired(self): lock.release() self.assertRaises(RuntimeError, lock._release_save) + def test_recursion_count(self): + lock = self.locktype() + self.assertEqual(0, lock._recursion_count()) + lock.acquire() + self.assertEqual(1, lock._recursion_count()) + lock.acquire() + lock.acquire() + self.assertEqual(3, lock._recursion_count()) + lock.release() + self.assertEqual(2, lock._recursion_count()) + lock.release() + lock.release() + self.assertEqual(0, lock._recursion_count()) + + phase = [] + + def f(): + lock.acquire() + phase.append(None) + while len(phase) == 1: + _wait() + lock.release() + phase.append(None) + + with threading_helper.wait_threads_exit(): + start_new_thread(f, ()) + while len(phase) == 0: + _wait() + self.assertEqual(len(phase), 1) + self.assertEqual(0, lock._recursion_count()) + phase.append(None) + while len(phase) == 2: + _wait() + self.assertEqual(len(phase), 3) + self.assertEqual(0, lock._recursion_count()) + def test_different_thread(self): # Cannot release from a different thread lock = self.locktype() @@ -1015,13 +1051,15 @@ def test_default_timeout(self): """ Test the barrier's default timeout """ - # create a barrier with a low default timeout - barrier = self.barriertype(self.N, timeout=0.3) + # gh-109401: Barrier timeout should be long enough + # to create 4 threads on a slow CI. + timeout = 1.0 + barrier = self.barriertype(self.N, timeout=timeout) def f(): i = barrier.wait() if i == self.N // 2: - # One thread is later than the default timeout of 0.3s. - time.sleep(1.0) + # One thread is later than the default timeout. + time.sleep(timeout * 2) self.assertRaises(threading.BrokenBarrierError, barrier.wait) self.run_threads(f) diff --git a/mingw64/lib/python3.11/test/pickletester.py b/mingw64/lib/python3.11/test/pickletester.py index 6e87370c206..a687fe06290 100644 --- a/mingw64/lib/python3.11/test/pickletester.py +++ b/mingw64/lib/python3.11/test/pickletester.py @@ -2576,6 +2576,7 @@ def check_frame_opcodes(self, pickled): self.assertLess(pos - frameless_start, self.FRAME_SIZE_MIN) @support.skip_if_pgo_task + @support.requires_resource('cpu') def test_framing_many_objects(self): obj = list(range(10**5)) for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): diff --git a/mingw64/lib/python3.11/test/pythoninfo.py b/mingw64/lib/python3.11/test/pythoninfo.py index 61fd734d4c6..db8dfe247cc 100644 --- a/mingw64/lib/python3.11/test/pythoninfo.py +++ b/mingw64/lib/python3.11/test/pythoninfo.py @@ -112,6 +112,7 @@ def collect_sys(info_add): call_func(info_add, 'sys.androidapilevel', sys, 'getandroidapilevel') call_func(info_add, 'sys.windowsversion', sys, 'getwindowsversion') + call_func(info_add, 'sys.getrecursionlimit', sys, 'getrecursionlimit') encoding = sys.getfilesystemencoding() if hasattr(sys, 'getfilesystemencodeerrors'): @@ -163,6 +164,26 @@ def collect_platform(info_add): if libc_ver: info_add('platform.libc_ver', libc_ver) + try: + os_release = platform.freedesktop_os_release() + except OSError: + pass + else: + for key in ( + 'ID', + 'NAME', + 'PRETTY_NAME' + 'VARIANT', + 'VARIANT_ID', + 'VERSION', + 'VERSION_CODENAME', + 'VERSION_ID', + ): + if key not in os_release: + continue + info_add(f'platform.freedesktop_os_release[{key}]', + os_release[key]) + def collect_locale(info_add): import locale @@ -309,6 +330,13 @@ def format_groups(groups): "_PYTHON_PROJECT_BASE", "_PYTHON_SYSCONFIGDATA_NAME", "__PYVENV_LAUNCHER__", + + # Sanitizer options + "ASAN_OPTIONS", + "LSAN_OPTIONS", + "MSAN_OPTIONS", + "TSAN_OPTIONS", + "UBSAN_OPTIONS", )) for name, value in os.environ.items(): uname = name.upper() @@ -493,9 +521,13 @@ def collect_sysconfig(info_add): 'PY_STDMODULE_CFLAGS', 'Py_DEBUG', 'Py_ENABLE_SHARED', + 'Py_NOGIL', 'SHELL', 'SOABI', + 'abs_builddir', + 'abs_srcdir', 'prefix', + 'srcdir', ): value = sysconfig.get_config_var(name) if name == 'ANDROID_API_LEVEL' and not value: @@ -846,6 +878,15 @@ def collect_fips(info_add): pass +def collect_libregrtest_utils(info_add): + try: + from test.libregrtest import utils + except ImportError: + return + + info_add('libregrtests.build_info', ' '.join(utils.get_build_info())) + + def collect_info(info): error = False info_add = info.add @@ -883,6 +924,7 @@ def collect_info(info): collect_tkinter, collect_windows, collect_zlib, + collect_libregrtest_utils, # Collecting from tests should be last as they have side effects. collect_test_socket, @@ -912,7 +954,6 @@ def dump_info(info, file=None): for key, value in infos: value = value.replace("\n", " ") print("%s: %s" % (key, value)) - print() def main(): @@ -921,6 +962,7 @@ def main(): dump_info(info) if error: + print() print("Collection failed: exit with error", file=sys.stderr) sys.exit(1) diff --git a/mingw64/lib/python3.11/test/sgml_input.html b/mingw64/lib/python3.11/test/sgml_input.html deleted file mode 100644 index f4d2e6cc805..00000000000 --- a/mingw64/lib/python3.11/test/sgml_input.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - - - -
- - - - - -
-
- - - - - -
- - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - -
  MetalCristalDeuterioEnergía  
160.6363.40639.230-80/3.965
-
-
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Flotas (max. 9)
Num.MisiónCantidadComienzoSalidaObjetivoLlegadaOrden
1 - Espionaje - (F) - 3[2:250:6]Wed Aug 9 18:00:02[2:242:5]Wed Aug 9 18:01:02 -
- - -
-
2 - Espionaje - (V) - 3[2:250:6]Wed Aug 9 17:59:55[2:242:1]Wed Aug 9 18:01:55 -
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Nueva misión: elegir naves
NavesDisponibles--
Nave pequeña de carga10máx
Nave grande de carga19máx
Crucero6máx
Reciclador1máx
Sonda de espionaje139máx
Ninguna naveTodas las naves
- -

-
- - diff --git a/mingw64/lib/python3.11/test/signalinterproctester.py b/mingw64/lib/python3.11/test/signalinterproctester.py index bc60b747f71..5dafc029005 100644 --- a/mingw64/lib/python3.11/test/signalinterproctester.py +++ b/mingw64/lib/python3.11/test/signalinterproctester.py @@ -1,3 +1,4 @@ +import gc import os import signal import subprocess @@ -60,6 +61,13 @@ def test_interprocess_signal(self): self.assertEqual(self.got_signals, {'SIGHUP': 1, 'SIGUSR1': 0, 'SIGALRM': 0}) + # gh-110033: Make sure that the subprocess.Popen is deleted before + # the next test which raises an exception. Otherwise, the exception + # may be raised when Popen.__del__() is executed and so be logged + # as "Exception ignored in: ". + child = None + gc.collect() + with self.assertRaises(SIGUSR1Exception): with self.subprocess_send_signal(pid, "SIGUSR1") as child: self.wait_signal(child, 'SIGUSR1') diff --git a/mingw64/lib/python3.11/test/string_tests.py b/mingw64/lib/python3.11/test/string_tests.py index d69edd7bf45..fdced1c26cf 100644 --- a/mingw64/lib/python3.11/test/string_tests.py +++ b/mingw64/lib/python3.11/test/string_tests.py @@ -327,11 +327,12 @@ def reference_find(p, s): for i in range(len(s)): if s.startswith(p, i): return i + if p == '' and s == '': + return 0 return -1 - rr = random.randrange - choices = random.choices - for _ in range(1000): + def check_pattern(rr): + choices = random.choices p0 = ''.join(choices('abcde', k=rr(10))) * rr(10, 20) p = p0[:len(p0) - rr(10)] # pop off some characters left = ''.join(choices('abcdef', k=rr(2000))) @@ -341,6 +342,13 @@ def reference_find(p, s): self.checkequal(reference_find(p, text), text, 'find', p) + rr = random.randrange + for _ in range(1000): + check_pattern(rr) + + # Test that empty string always work: + check_pattern(lambda *args: 0) + def test_find_shift_table_overflow(self): """When the table of 8-bit shifts overflows.""" N = 2**8 + 100 diff --git a/mingw64/lib/python3.11/test/support/__init__.py b/mingw64/lib/python3.11/test/support/__init__.py index 98be9cdd0e1..2e6518cf241 100644 --- a/mingw64/lib/python3.11/test/support/__init__.py +++ b/mingw64/lib/python3.11/test/support/__init__.py @@ -4,6 +4,7 @@ raise ImportError('support must be imported from the test package') import contextlib +import dataclasses import functools import getpass import os @@ -116,17 +117,20 @@ class Error(Exception): class TestFailed(Error): """Test failed.""" + def __init__(self, msg, *args, stats=None): + self.msg = msg + self.stats = stats + super().__init__(msg, *args) + + def __str__(self): + return self.msg class TestFailedWithDetails(TestFailed): """Test failed.""" - def __init__(self, msg, errors, failures): - self.msg = msg + def __init__(self, msg, errors, failures, stats): self.errors = errors self.failures = failures - super().__init__(msg, errors, failures) - - def __str__(self): - return self.msg + super().__init__(msg, errors, failures, stats=stats) class TestDidNotRun(Error): """Test did not run any subtests.""" @@ -400,19 +404,19 @@ def check_sanitizer(*, address=False, memory=False, ub=False): raise ValueError('At least one of address, memory, or ub must be True') - _cflags = sysconfig.get_config_var('CFLAGS') or '' - _config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' + cflags = sysconfig.get_config_var('CFLAGS') or '' + config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' memory_sanitizer = ( - '-fsanitize=memory' in _cflags or - '--with-memory-sanitizer' in _config_args + '-fsanitize=memory' in cflags or + '--with-memory-sanitizer' in config_args ) address_sanitizer = ( - '-fsanitize=address' in _cflags or - '--with-memory-sanitizer' in _config_args + '-fsanitize=address' in cflags or + '--with-address-sanitizer' in config_args ) ub_sanitizer = ( - '-fsanitize=undefined' in _cflags or - '--with-undefined-behavior-sanitizer' in _config_args + '-fsanitize=undefined' in cflags or + '--with-undefined-behavior-sanitizer' in config_args ) return ( (memory and memory_sanitizer) or @@ -761,6 +765,21 @@ def python_is_optimized(): return final_opt not in ('', '-O0', '-Og') +def check_cflags_pgo(): + # Check if Python was built with ./configure --enable-optimizations: + # with Profile Guided Optimization (PGO). + cflags_nodist = sysconfig.get_config_var('PY_CFLAGS_NODIST') or '' + pgo_options = ( + # GCC + '-fprofile-use', + # clang: -fprofile-instr-use=code.profclangd + '-fprofile-instr-use', + # ICC + "-prof-use", + ) + return any(option in cflags_nodist for option in pgo_options) + + _header = 'nP' _align = '0n' if hasattr(sys, "getobjects"): @@ -1086,6 +1105,29 @@ def _filter_suite(suite, pred): newtests.append(test) suite._tests = newtests +@dataclasses.dataclass(slots=True) +class TestStats: + tests_run: int = 0 + failures: int = 0 + skipped: int = 0 + + @staticmethod + def from_unittest(result): + return TestStats(result.testsRun, + len(result.failures), + len(result.skipped)) + + @staticmethod + def from_doctest(results): + return TestStats(results.attempted, + results.failed) + + def accumulate(self, stats): + self.tests_run += stats.tests_run + self.failures += stats.failures + self.skipped += stats.skipped + + def _run_suite(suite): """Run tests from a unittest.TestSuite-derived class.""" runner = get_test_runner(sys.stdout, @@ -1100,6 +1142,7 @@ def _run_suite(suite): if not result.testsRun and not result.skipped and not result.errors: raise TestDidNotRun if not result.wasSuccessful(): + stats = TestStats.from_unittest(result) if len(result.errors) == 1 and not result.failures: err = result.errors[0][1] elif len(result.failures) == 1 and not result.errors: @@ -1109,7 +1152,8 @@ def _run_suite(suite): if not verbose: err += "; run in verbose mode for details" errors = [(str(tc), exc_str) for tc, exc_str in result.errors] failures = [(str(tc), exc_str) for tc, exc_str in result.failures] - raise TestFailedWithDetails(err, errors, failures) + raise TestFailedWithDetails(err, errors, failures, stats=stats) + return result # By default, don't filter tests @@ -1218,7 +1262,7 @@ def run_unittest(*classes): else: suite.addTest(loader.loadTestsFromTestCase(cls)) _filter_suite(suite, match_test) - _run_suite(suite) + return _run_suite(suite) #======================================================================= # Check for the presence of docstrings. @@ -1258,13 +1302,18 @@ def run_doctest(module, verbosity=None, optionflags=0): else: verbosity = None - f, t = doctest.testmod(module, verbose=verbosity, optionflags=optionflags) - if f: - raise TestFailed("%d of %d doctests failed" % (f, t)) + results = doctest.testmod(module, + verbose=verbosity, + optionflags=optionflags) + if results.failed: + stats = TestStats.from_doctest(results) + raise TestFailed(f"{results.failed} of {results.attempted} " + f"doctests failed", + stats=stats) if verbose: print('doctest (%s) ... %d tests with zero failures' % - (module.__name__, t)) - return f, t + (module.__name__, results.attempted)) + return results #======================================================================= @@ -2163,20 +2212,70 @@ def check_disallow_instantiation(testcase, tp, *args, **kwds): msg = f"cannot create '{re.escape(qualname)}' instances" testcase.assertRaisesRegex(TypeError, msg, tp, *args, **kwds) +def get_recursion_depth(): + """Get the recursion depth of the caller function. + + In the __main__ module, at the module level, it should be 1. + """ + try: + import _testinternalcapi + depth = _testinternalcapi.get_recursion_depth() + except (ImportError, RecursionError) as exc: + # sys._getframe() + frame.f_back implementation. + try: + depth = 0 + frame = sys._getframe() + while frame is not None: + depth += 1 + frame = frame.f_back + finally: + # Break any reference cycles. + frame = None + + # Ignore get_recursion_depth() frame. + return max(depth - 1, 1) + +def get_recursion_available(): + """Get the number of available frames before RecursionError. + + It depends on the current recursion depth of the caller function and + sys.getrecursionlimit(). + """ + limit = sys.getrecursionlimit() + depth = get_recursion_depth() + + try: + from _testcapi import USE_STACKCHECK + except ImportError: + USE_STACKCHECK = False + + if USE_STACKCHECK: + return max(limit - depth - 1, 0) + else: + return limit - depth + @contextlib.contextmanager -def infinite_recursion(max_depth=75): +def set_recursion_limit(limit): + """Temporarily change the recursion limit.""" + original_limit = sys.getrecursionlimit() + try: + sys.setrecursionlimit(limit) + yield + finally: + sys.setrecursionlimit(original_limit) + +def infinite_recursion(max_depth=100): """Set a lower limit for tests that interact with infinite recursions (e.g test_ast.ASTHelpers_Test.test_recursion_direct) since on some debug windows builds, due to not enough functions being inlined the stack size might not handle the default recursion limit (1000). See bpo-11105 for details.""" - - original_depth = sys.getrecursionlimit() - try: - sys.setrecursionlimit(max_depth) - yield - finally: - sys.setrecursionlimit(original_depth) + if max_depth < 4: + raise ValueError("max_depth must be at least 4, got {max_depth}") + depth = get_recursion_depth() + depth = max(depth - 1, 1) # Ignore infinite_recursion() frame. + limit = depth + max_depth + return set_recursion_limit(limit) def ignore_deprecations_from(module: str, *, like: str) -> object: token = object() @@ -2234,3 +2333,29 @@ def adjust_int_max_str_digits(max_digits): yield finally: sys.set_int_max_str_digits(current) + +_BASE_COPY_SRC_DIR_IGNORED_NAMES = frozenset({ + # SRC_DIR/.git + '.git', + # ignore all __pycache__/ sub-directories + '__pycache__', +}) + +# Ignore function for shutil.copytree() to copy the Python source code. +def copy_python_src_ignore(path, names): + ignored = _BASE_COPY_SRC_DIR_IGNORED_NAMES + if os.path.basename(path) == 'Doc': + ignored |= { + # SRC_DIR/Doc/build/ + 'build', + # SRC_DIR/Doc/venv/ + 'venv', + } + + # check if we are at the root of the source code + elif 'Modules' in names: + ignored |= { + # SRC_DIR/build/ + 'build', + } + return ignored diff --git a/mingw64/lib/python3.11/test/support/import_helper.py b/mingw64/lib/python3.11/test/support/import_helper.py index 5201dc84cf6..a803d9f1b40 100644 --- a/mingw64/lib/python3.11/test/support/import_helper.py +++ b/mingw64/lib/python3.11/test/support/import_helper.py @@ -8,7 +8,7 @@ import unittest import warnings -from .os_helper import unlink +from .os_helper import unlink, temp_dir @contextlib.contextmanager @@ -246,3 +246,26 @@ def modules_cleanup(oldmodules): # do currently). Implicitly imported *real* modules should be left alone # (see issue 10556). sys.modules.update(oldmodules) + + +@contextlib.contextmanager +def ready_to_import(name=None, source=""): + from test.support import script_helper + + # 1. Sets up a temporary directory and removes it afterwards + # 2. Creates the module file + # 3. Temporarily clears the module from sys.modules (if any) + # 4. Reverts or removes the module when cleaning up + name = name or "spam" + with temp_dir() as tempdir: + path = script_helper.make_script(tempdir, name, source) + old_module = sys.modules.pop(name, None) + try: + sys.path.insert(0, tempdir) + yield name, path + sys.path.remove(tempdir) + finally: + if old_module is not None: + sys.modules[name] = old_module + else: + sys.modules.pop(name, None) diff --git a/mingw64/lib/python3.11/test/support/socket_helper.py b/mingw64/lib/python3.11/test/support/socket_helper.py index 50e1d4d56c9..ec6d1dee4e9 100644 --- a/mingw64/lib/python3.11/test/support/socket_helper.py +++ b/mingw64/lib/python3.11/test/support/socket_helper.py @@ -1,8 +1,9 @@ import contextlib import errno import socket -import unittest +import subprocess import sys +import unittest from .. import support from . import warnings_helper @@ -270,3 +271,62 @@ def filter_error(err): # __cause__ or __context__? finally: socket.setdefaulttimeout(old_timeout) + + +# consider that sysctl values should not change while tests are running +_sysctl_cache = {} + +def _get_sysctl(name): + """Get a sysctl value as an integer.""" + try: + return _sysctl_cache[name] + except KeyError: + pass + + # At least Linux and FreeBSD support the "-n" option + cmd = ['sysctl', '-n', name] + proc = subprocess.run(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True) + if proc.returncode: + support.print_warning(f"{' '.join(cmd)!r} command failed with " + f"exit code {proc.returncode}") + # cache the error to only log the warning once + _sysctl_cache[name] = None + return None + output = proc.stdout + + # Parse '0\n' to get '0' + try: + value = int(output.strip()) + except Exception as exc: + support.print_warning(f"Failed to parse {' '.join(cmd)!r} " + f"command output {output!r}: {exc!r}") + # cache the error to only log the warning once + _sysctl_cache[name] = None + return None + + _sysctl_cache[name] = value + return value + + +def tcp_blackhole(): + if not sys.platform.startswith('freebsd'): + return False + + # gh-109015: test if FreeBSD TCP blackhole is enabled + value = _get_sysctl('net.inet.tcp.blackhole') + if value is None: + # don't skip if we fail to get the sysctl value + return False + return (value != 0) + + +def skip_if_tcp_blackhole(test): + """Decorator skipping test if TCP blackhole is enabled.""" + skip_if = unittest.skipIf( + tcp_blackhole(), + "TCP blackhole is enabled (sysctl net.inet.tcp.blackhole)" + ) + return skip_if(test) diff --git a/mingw64/lib/python3.11/test/test_ast.py b/mingw64/lib/python3.11/test/test_ast.py index 33c13ee29a2..c8d2f916dbd 100644 --- a/mingw64/lib/python3.11/test/test_ast.py +++ b/mingw64/lib/python3.11/test/test_ast.py @@ -1701,6 +1701,7 @@ def test_tuple(self): def test_nameconstant(self): self.expr(ast.NameConstant(4)) + @support.requires_resource('cpu') def test_stdlib_validates(self): stdlib = os.path.dirname(ast.__file__) tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")] diff --git a/mingw64/lib/python3.11/test/test_asyncgen.py b/mingw64/lib/python3.11/test/test_asyncgen.py index fb22f411c2e..2241b39f3b1 100644 --- a/mingw64/lib/python3.11/test/test_asyncgen.py +++ b/mingw64/lib/python3.11/test/test_asyncgen.py @@ -1037,8 +1037,7 @@ async def gen(): while True: yield 1 finally: - await asyncio.sleep(0.01) - await asyncio.sleep(0.01) + await asyncio.sleep(0) DONE = 1 async def run(): @@ -1048,7 +1047,10 @@ async def run(): del g gc_collect() # For PyPy or other GCs. - await asyncio.sleep(0.1) + # Starts running the aclose task + await asyncio.sleep(0) + # For asyncio.sleep(0) in finally block + await asyncio.sleep(0) self.loop.run_until_complete(run()) self.assertEqual(DONE, 1) diff --git a/mingw64/lib/python3.11/test/test_asyncio/test_base_events.py b/mingw64/lib/python3.11/test/test_asyncio/test_base_events.py index 6ba602dd619..f3f83ad318c 100644 --- a/mingw64/lib/python3.11/test/test_asyncio/test_base_events.py +++ b/mingw64/lib/python3.11/test/test_asyncio/test_base_events.py @@ -273,7 +273,7 @@ def cb(): self.loop.stop() self.loop._process_events = mock.Mock() - delay = 0.1 + delay = 0.100 when = self.loop.time() + delay self.loop.call_at(when, cb) @@ -282,10 +282,7 @@ def cb(): dt = self.loop.time() - t0 # 50 ms: maximum granularity of the event loop - self.assertGreaterEqual(dt, delay - 0.050, dt) - # tolerate a difference of +800 ms because some Python buildbots - # are really slow - self.assertLessEqual(dt, 0.9, dt) + self.assertGreaterEqual(dt, delay - test_utils.CLOCK_RES) with self.assertRaises(TypeError, msg="when cannot be None"): self.loop.call_at(None, cb) diff --git a/mingw64/lib/python3.11/test/test_asyncio/test_events.py b/mingw64/lib/python3.11/test/test_asyncio/test_events.py index 5728d25254f..d7871d3e538 100644 --- a/mingw64/lib/python3.11/test/test_asyncio/test_events.py +++ b/mingw64/lib/python3.11/test/test_asyncio/test_events.py @@ -31,6 +31,7 @@ from asyncio import events from asyncio import proactor_events from asyncio import selector_events +from multiprocessing.util import _cleanup_tests as multiprocessing_cleanup_tests from test.test_asyncio import utils as test_utils from test import support from test.support import socket_helper @@ -293,10 +294,11 @@ async def coro2(): # 15.6 msec, we use fairly long sleep times here (~100 msec). def test_run_until_complete(self): + delay = 0.100 t0 = self.loop.time() - self.loop.run_until_complete(asyncio.sleep(0.1)) - t1 = self.loop.time() - self.assertTrue(0.08 <= t1-t0 <= 0.8, t1-t0) + self.loop.run_until_complete(asyncio.sleep(delay)) + dt = self.loop.time() - t0 + self.assertGreaterEqual(dt, delay - test_utils.CLOCK_RES) def test_run_until_complete_stopped(self): @@ -671,6 +673,7 @@ def test_create_connection_local_addr(self): self.assertEqual(port, expected) tr.close() + @socket_helper.skip_if_tcp_blackhole def test_create_connection_local_addr_skip_different_family(self): # See https://github.com/python/cpython/issues/86508 port1 = socket_helper.find_unused_port() @@ -692,6 +695,7 @@ async def getaddrinfo(host, port, *args, **kwargs): with self.assertRaises(OSError): self.loop.run_until_complete(f) + @socket_helper.skip_if_tcp_blackhole def test_create_connection_local_addr_nomatch_family(self): # See https://github.com/python/cpython/issues/86508 port1 = socket_helper.find_unused_port() @@ -1248,6 +1252,7 @@ def connection_made(self, transport): server.close() + @socket_helper.skip_if_tcp_blackhole def test_server_close(self): f = self.loop.create_server(MyProto, '0.0.0.0', 0) server = self.loop.run_until_complete(f) @@ -1666,12 +1671,9 @@ async def main(): self.loop.stop() return res - start = time.monotonic() t = self.loop.create_task(main()) self.loop.run_forever() - elapsed = time.monotonic() - start - self.assertLess(elapsed, 0.1) self.assertEqual(t.result(), 'cancelled') self.assertRaises(asyncio.CancelledError, f.result) if ov is not None: @@ -1691,7 +1693,6 @@ def _run_once(): self.loop._run_once = _run_once async def wait(): - loop = self.loop await asyncio.sleep(1e-2) await asyncio.sleep(1e-4) await asyncio.sleep(1e-6) @@ -2727,6 +2728,8 @@ def test_get_event_loop_new_process(self): # multiprocessing.synchronize module cannot be imported. support.skip_if_broken_multiprocessing_synchronize() + self.addCleanup(multiprocessing_cleanup_tests) + async def main(): pool = concurrent.futures.ProcessPoolExecutor() result = await self.loop.run_in_executor( diff --git a/mingw64/lib/python3.11/test/test_asyncio/test_sock_lowlevel.py b/mingw64/lib/python3.11/test/test_asyncio/test_sock_lowlevel.py index db47616d183..1f8f4e2ddfc 100644 --- a/mingw64/lib/python3.11/test/test_asyncio/test_sock_lowlevel.py +++ b/mingw64/lib/python3.11/test/test_asyncio/test_sock_lowlevel.py @@ -10,6 +10,10 @@ from test import support from test.support import socket_helper +if socket_helper.tcp_blackhole(): + raise unittest.SkipTest('Not relevant to ProactorEventLoop') + + def tearDownModule(): asyncio.set_event_loop_policy(None) diff --git a/mingw64/lib/python3.11/test/test_asyncio/test_sslproto.py b/mingw64/lib/python3.11/test/test_asyncio/test_sslproto.py index 52a45f1c7c6..37d01533976 100644 --- a/mingw64/lib/python3.11/test/test_asyncio/test_sslproto.py +++ b/mingw64/lib/python3.11/test/test_asyncio/test_sslproto.py @@ -5,6 +5,7 @@ import unittest import weakref from test import support +from test.support import socket_helper from unittest import mock try: import ssl @@ -350,6 +351,7 @@ async def client(addr): support.gc_collect() self.assertIsNone(client_context()) + @socket_helper.skip_if_tcp_blackhole def test_start_tls_client_buf_proto_1(self): HELLO_MSG = b'1' * self.PAYLOAD_SIZE @@ -502,6 +504,7 @@ async def client(addr): asyncio.wait_for(client(srv.addr), timeout=support.SHORT_TIMEOUT)) + @socket_helper.skip_if_tcp_blackhole def test_start_tls_server_1(self): HELLO_MSG = b'1' * self.PAYLOAD_SIZE ANSWER = b'answer' diff --git a/mingw64/lib/python3.11/test/test_asyncio/test_subprocess.py b/mingw64/lib/python3.11/test/test_asyncio/test_subprocess.py index bea2314a528..8b4f14eb48d 100644 --- a/mingw64/lib/python3.11/test/test_asyncio/test_subprocess.py +++ b/mingw64/lib/python3.11/test/test_asyncio/test_subprocess.py @@ -2,6 +2,7 @@ import shutil import signal import sys +import textwrap import unittest import warnings from unittest import mock @@ -13,9 +14,14 @@ from test import support from test.support import os_helper -if sys.platform != 'win32': + +MS_WINDOWS = (sys.platform == 'win32') +if MS_WINDOWS: + import msvcrt +else: from asyncio import unix_events + if support.check_sanitizer(address=True): raise unittest.SkipTest("Exposes ASAN flakiness in GitHub CI") @@ -253,26 +259,43 @@ async def send_signal(proc): finally: signal.signal(signal.SIGHUP, old_handler) - def prepare_broken_pipe_test(self): + def test_stdin_broken_pipe(self): # buffer large enough to feed the whole pipe buffer large_data = b'x' * support.PIPE_MAX_SIZE + rfd, wfd = os.pipe() + self.addCleanup(os.close, rfd) + self.addCleanup(os.close, wfd) + if MS_WINDOWS: + handle = msvcrt.get_osfhandle(rfd) + os.set_handle_inheritable(handle, True) + code = textwrap.dedent(f''' + import os, msvcrt + handle = {handle} + fd = msvcrt.open_osfhandle(handle, os.O_RDONLY) + os.read(fd, 1) + ''') + from subprocess import STARTUPINFO + startupinfo = STARTUPINFO() + startupinfo.lpAttributeList = {"handle_list": [handle]} + kwargs = dict(startupinfo=startupinfo) + else: + code = f'import os; fd = {rfd}; os.read(fd, 1)' + kwargs = dict(pass_fds=(rfd,)) + # the program ends before the stdin can be fed proc = self.loop.run_until_complete( asyncio.create_subprocess_exec( - sys.executable, '-c', 'pass', + sys.executable, '-c', code, stdin=subprocess.PIPE, + **kwargs ) ) - return (proc, large_data) - - def test_stdin_broken_pipe(self): - proc, large_data = self.prepare_broken_pipe_test() - async def write_stdin(proc, data): - await asyncio.sleep(0.5) proc.stdin.write(data) + # Only exit the child process once the write buffer is filled + os.write(wfd, b'go') await proc.stdin.drain() coro = write_stdin(proc, large_data) @@ -283,7 +306,16 @@ async def write_stdin(proc, data): self.loop.run_until_complete(proc.wait()) def test_communicate_ignore_broken_pipe(self): - proc, large_data = self.prepare_broken_pipe_test() + # buffer large enough to feed the whole pipe buffer + large_data = b'x' * support.PIPE_MAX_SIZE + + # the program ends before the stdin can be fed + proc = self.loop.run_until_complete( + asyncio.create_subprocess_exec( + sys.executable, '-c', 'pass', + stdin=subprocess.PIPE, + ) + ) # communicate() must ignore BrokenPipeError when feeding stdin self.loop.set_exception_handler(lambda loop, msg: None) diff --git a/mingw64/lib/python3.11/test/test_asyncio/test_timeouts.py b/mingw64/lib/python3.11/test/test_asyncio/test_timeouts.py index cc8feb8d0c1..5a4093e9470 100644 --- a/mingw64/lib/python3.11/test/test_asyncio/test_timeouts.py +++ b/mingw64/lib/python3.11/test/test_asyncio/test_timeouts.py @@ -47,7 +47,6 @@ async def test_nested_timeouts(self): self.assertTrue(cm2.expired()) async def test_waiter_cancelled(self): - loop = asyncio.get_running_loop() cancelled = False with self.assertRaises(TimeoutError): async with asyncio.timeout(0.01): @@ -60,39 +59,26 @@ async def test_waiter_cancelled(self): async def test_timeout_not_called(self): loop = asyncio.get_running_loop() - t0 = loop.time() async with asyncio.timeout(10) as cm: await asyncio.sleep(0.01) t1 = loop.time() self.assertFalse(cm.expired()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) self.assertGreater(cm.when(), t1) async def test_timeout_disabled(self): - loop = asyncio.get_running_loop() - t0 = loop.time() async with asyncio.timeout(None) as cm: await asyncio.sleep(0.01) - t1 = loop.time() self.assertFalse(cm.expired()) self.assertIsNone(cm.when()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) async def test_timeout_at_disabled(self): - loop = asyncio.get_running_loop() - t0 = loop.time() async with asyncio.timeout_at(None) as cm: await asyncio.sleep(0.01) - t1 = loop.time() self.assertFalse(cm.expired()) self.assertIsNone(cm.when()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) async def test_timeout_zero(self): loop = asyncio.get_running_loop() @@ -102,8 +88,6 @@ async def test_timeout_zero(self): await asyncio.sleep(10) t1 = loop.time() self.assertTrue(cm.expired()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) self.assertTrue(t0 <= cm.when() <= t1) async def test_timeout_zero_sleep_zero(self): @@ -114,8 +98,6 @@ async def test_timeout_zero_sleep_zero(self): await asyncio.sleep(0) t1 = loop.time() self.assertTrue(cm.expired()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) self.assertTrue(t0 <= cm.when() <= t1) async def test_timeout_in_the_past_sleep_zero(self): @@ -126,8 +108,6 @@ async def test_timeout_in_the_past_sleep_zero(self): await asyncio.sleep(0) t1 = loop.time() self.assertTrue(cm.expired()) - # 2 sec for slow CI boxes - self.assertLess(t1-t0, 2) self.assertTrue(t0 >= cm.when() <= t1) async def test_foreign_exception_passed(self): diff --git a/mingw64/lib/python3.11/test/test_asyncio/test_waitfor.py b/mingw64/lib/python3.11/test/test_asyncio/test_waitfor.py index 45498fa097f..c0cc606825b 100644 --- a/mingw64/lib/python3.11/test/test_asyncio/test_waitfor.py +++ b/mingw64/lib/python3.11/test/test_asyncio/test_waitfor.py @@ -1,6 +1,7 @@ import asyncio import unittest import time +from test import support def tearDownModule(): @@ -65,17 +66,12 @@ async def test_wait_for_timeout_less_then_0_or_0_future_done(self): fut = loop.create_future() fut.set_result('done') - t0 = loop.time() ret = await asyncio.wait_for(fut, 0) - t1 = loop.time() self.assertEqual(ret, 'done') self.assertTrue(fut.done()) - self.assertLess(t1 - t0, 0.1) async def test_wait_for_timeout_less_then_0_or_0_coroutine_do_not_started(self): - loop = asyncio.get_running_loop() - foo_started = False async def foo(): @@ -83,12 +79,9 @@ async def foo(): foo_started = True with self.assertRaises(asyncio.TimeoutError): - t0 = loop.time() await asyncio.wait_for(foo(), 0) - t1 = loop.time() self.assertEqual(foo_started, False) - self.assertLess(t1 - t0, 0.1) async def test_wait_for_timeout_less_then_0_or_0(self): loop = asyncio.get_running_loop() @@ -112,25 +105,21 @@ async def foo(): await started with self.assertRaises(asyncio.TimeoutError): - t0 = loop.time() await asyncio.wait_for(fut, timeout) - t1 = loop.time() self.assertTrue(fut.done()) # it should have been cancelled due to the timeout self.assertTrue(fut.cancelled()) self.assertEqual(foo_running, False) - self.assertLess(t1 - t0, 0.1) async def test_wait_for(self): - loop = asyncio.get_running_loop() foo_running = None async def foo(): nonlocal foo_running foo_running = True try: - await asyncio.sleep(10) + await asyncio.sleep(support.LONG_TIMEOUT) finally: foo_running = False return 'done' @@ -138,13 +127,10 @@ async def foo(): fut = asyncio.create_task(foo()) with self.assertRaises(asyncio.TimeoutError): - t0 = loop.time() await asyncio.wait_for(fut, 0.1) - t1 = loop.time() self.assertTrue(fut.done()) # it should have been cancelled due to the timeout self.assertTrue(fut.cancelled()) - self.assertLess(t1 - t0, 0.5) self.assertEqual(foo_running, False) async def test_wait_for_blocking(self): diff --git a/mingw64/lib/python3.11/test/test_asyncio/test_windows_events.py b/mingw64/lib/python3.11/test/test_asyncio/test_windows_events.py index a36119a8004..6e6c90a247b 100644 --- a/mingw64/lib/python3.11/test/test_asyncio/test_windows_events.py +++ b/mingw64/lib/python3.11/test/test_asyncio/test_windows_events.py @@ -163,29 +163,25 @@ def test_wait_for_handle(self): # Wait for unset event with 0.5s timeout; # result should be False at timeout - fut = self.loop._proactor.wait_for_handle(event, 0.5) + timeout = 0.5 + fut = self.loop._proactor.wait_for_handle(event, timeout) start = self.loop.time() done = self.loop.run_until_complete(fut) elapsed = self.loop.time() - start self.assertEqual(done, False) self.assertFalse(fut.result()) - # bpo-31008: Tolerate only 450 ms (at least 500 ms expected), - # because of bad clock resolution on Windows - self.assertTrue(0.45 <= elapsed <= 0.9, elapsed) + self.assertGreaterEqual(elapsed, timeout - test_utils.CLOCK_RES) _overlapped.SetEvent(event) # Wait for set event; # result should be True immediately fut = self.loop._proactor.wait_for_handle(event, 10) - start = self.loop.time() done = self.loop.run_until_complete(fut) - elapsed = self.loop.time() - start self.assertEqual(done, True) self.assertTrue(fut.result()) - self.assertTrue(0 <= elapsed < 0.3, elapsed) # asyncio issue #195: cancelling a done _WaitHandleFuture # must not crash @@ -199,11 +195,8 @@ def test_wait_for_handle_cancel(self): # CancelledError should be raised immediately fut = self.loop._proactor.wait_for_handle(event, 10) fut.cancel() - start = self.loop.time() with self.assertRaises(asyncio.CancelledError): self.loop.run_until_complete(fut) - elapsed = self.loop.time() - start - self.assertTrue(0 <= elapsed < 0.1, elapsed) # asyncio issue #195: cancelling a _WaitHandleFuture twice # must not crash diff --git a/mingw64/lib/python3.11/test/test_asyncio/utils.py b/mingw64/lib/python3.11/test/test_asyncio/utils.py index c32494d40cc..19de8540fdb 100644 --- a/mingw64/lib/python3.11/test/test_asyncio/utils.py +++ b/mingw64/lib/python3.11/test/test_asyncio/utils.py @@ -37,6 +37,12 @@ from test.support import threading_helper +# Use the maximum known clock resolution (gh-75191, gh-110088): Windows +# GetTickCount64() has a resolution of 15.6 ms. Use 20 ms to tolerate rounding +# issues. +CLOCK_RES = 0.020 + + def data_file(filename): if hasattr(support, 'TEST_HOME_DIR'): fullname = os.path.join(support.TEST_HOME_DIR, filename) diff --git a/mingw64/lib/python3.11/test/test_buffer.py b/mingw64/lib/python3.11/test/test_buffer.py index 468c6ea9def..e9149d1ac49 100644 --- a/mingw64/lib/python3.11/test/test_buffer.py +++ b/mingw64/lib/python3.11/test/test_buffer.py @@ -1019,6 +1019,7 @@ def match(req, flag): ndim=ndim, shape=shape, strides=strides, lst=lst, sliced=sliced) + @support.requires_resource('cpu') def test_ndarray_getbuf(self): requests = ( # distinct flags @@ -2750,6 +2751,7 @@ def iter_roundtrip(ex, m, items, fmt): m = memoryview(ex) iter_roundtrip(ex, m, items, fmt) + @support.requires_resource('cpu') def test_memoryview_cast_1D_ND(self): # Cast between C-contiguous buffers. At least one buffer must # be 1D, at least one format must be 'c', 'b' or 'B'. diff --git a/mingw64/lib/python3.11/test/test_builtin.py b/mingw64/lib/python3.11/test/test_builtin.py index 9078c409cc4..2f561216166 100644 --- a/mingw64/lib/python3.11/test/test_builtin.py +++ b/mingw64/lib/python3.11/test/test_builtin.py @@ -918,6 +918,7 @@ def test_filter_pickle(self): f2 = filter(filter_char, "abcdeabcde") self.check_iter_pickle(f1, list(f2), proto) + @support.requires_resource('cpu') def test_filter_dealloc(self): # Tests recursive deallocation of nested filter objects using the # thrashcan mechanism. See gh-102356 for more details. diff --git a/mingw64/lib/python3.11/test/test_bz2.py b/mingw64/lib/python3.11/test/test_bz2.py index c97ed1cea0d..ba1c02c8338 100644 --- a/mingw64/lib/python3.11/test/test_bz2.py +++ b/mingw64/lib/python3.11/test/test_bz2.py @@ -721,10 +721,10 @@ def testEOFError(self): @bigmemtest(size=_4G + 100, memuse=3.3) def testDecompress4G(self, size): # "Test BZ2Decompressor.decompress() with >4GiB input" - blocksize = 10 * 1024 * 1024 + blocksize = min(10 * 1024 * 1024, size) block = random.randbytes(blocksize) try: - data = block * (size // blocksize + 1) + data = block * ((size-1) // blocksize + 1) compressed = bz2.compress(data) bz2d = BZ2Decompressor() decompressed = bz2d.decompress(compressed) diff --git a/mingw64/lib/python3.11/test/test_codecs.py b/mingw64/lib/python3.11/test/test_codecs.py index e170a30263f..684e6cf7515 100644 --- a/mingw64/lib/python3.11/test/test_codecs.py +++ b/mingw64/lib/python3.11/test/test_codecs.py @@ -1,7 +1,9 @@ import codecs import contextlib +import copy import io import locale +import pickle import sys import unittest import encodings @@ -1772,6 +1774,61 @@ def test_readlines(self): f = self.reader(self.stream) self.assertEqual(f.readlines(), ['\ud55c\n', '\uae00']) + def test_copy(self): + f = self.reader(Queue(b'\xed\x95\x9c\n\xea\xb8\x80')) + with self.assertRaisesRegex(TypeError, 'StreamReader'): + copy.copy(f) + with self.assertRaisesRegex(TypeError, 'StreamReader'): + copy.deepcopy(f) + + def test_pickle(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + f = self.reader(Queue(b'\xed\x95\x9c\n\xea\xb8\x80')) + with self.assertRaisesRegex(TypeError, 'StreamReader'): + pickle.dumps(f, proto) + + +class StreamWriterTest(unittest.TestCase): + + def setUp(self): + self.writer = codecs.getwriter('utf-8') + + def test_copy(self): + f = self.writer(Queue(b'')) + with self.assertRaisesRegex(TypeError, 'StreamWriter'): + copy.copy(f) + with self.assertRaisesRegex(TypeError, 'StreamWriter'): + copy.deepcopy(f) + + def test_pickle(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + f = self.writer(Queue(b'')) + with self.assertRaisesRegex(TypeError, 'StreamWriter'): + pickle.dumps(f, proto) + + +class StreamReaderWriterTest(unittest.TestCase): + + def setUp(self): + self.reader = codecs.getreader('latin1') + self.writer = codecs.getwriter('utf-8') + + def test_copy(self): + f = codecs.StreamReaderWriter(Queue(b''), self.reader, self.writer) + with self.assertRaisesRegex(TypeError, 'StreamReaderWriter'): + copy.copy(f) + with self.assertRaisesRegex(TypeError, 'StreamReaderWriter'): + copy.deepcopy(f) + + def test_pickle(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + f = codecs.StreamReaderWriter(Queue(b''), self.reader, self.writer) + with self.assertRaisesRegex(TypeError, 'StreamReaderWriter'): + pickle.dumps(f, proto) + class EncodedFileTest(unittest.TestCase): @@ -3369,6 +3426,28 @@ def test_seeking_write(self): self.assertEqual(sr.readline(), b'abc\n') self.assertEqual(sr.readline(), b'789\n') + def test_copy(self): + bio = io.BytesIO() + codec = codecs.lookup('ascii') + sr = codecs.StreamRecoder(bio, codec.encode, codec.decode, + encodings.ascii.StreamReader, encodings.ascii.StreamWriter) + + with self.assertRaisesRegex(TypeError, 'StreamRecoder'): + copy.copy(sr) + with self.assertRaisesRegex(TypeError, 'StreamRecoder'): + copy.deepcopy(sr) + + def test_pickle(self): + q = Queue(b'') + codec = codecs.lookup('ascii') + sr = codecs.StreamRecoder(q, codec.encode, codec.decode, + encodings.ascii.StreamReader, encodings.ascii.StreamWriter) + + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + with self.assertRaisesRegex(TypeError, 'StreamRecoder'): + pickle.dumps(sr, proto) + @unittest.skipIf(_testinternalcapi is None, 'need _testinternalcapi module') class LocaleCodecTest(unittest.TestCase): diff --git a/mingw64/lib/python3.11/test/test_compile.py b/mingw64/lib/python3.11/test/test_compile.py index c756d43a3cf..408064919b0 100644 --- a/mingw64/lib/python3.11/test/test_compile.py +++ b/mingw64/lib/python3.11/test/test_compile.py @@ -442,6 +442,33 @@ def f(): self.assertIn("_A__mangled_mod", A.f.__code__.co_varnames) self.assertIn("__package__", A.f.__code__.co_varnames) + def test_compile_invalid_namedexpr(self): + # gh-109351 + m = ast.Module( + body=[ + ast.Expr( + value=ast.ListComp( + elt=ast.NamedExpr( + target=ast.Constant(value=1), + value=ast.Constant(value=3), + ), + generators=[ + ast.comprehension( + target=ast.Name(id="x", ctx=ast.Store()), + iter=ast.Name(id="y", ctx=ast.Load()), + ifs=[], + is_async=0, + ) + ], + ) + ) + ], + type_ignores=[], + ) + + with self.assertRaisesRegex(TypeError, "NamedExpr target must be a Name"): + compile(ast.fix_missing_locations(m), "", "exec") + def test_compile_ast(self): fname = __file__ if fname.lower().endswith('pyc'): @@ -741,6 +768,7 @@ def test_path_like_objects(self): # An implicit test for PyUnicode_FSDecoder(). compile("42", FakePath("test_compile_pathlike"), "single") + @support.requires_resource('cpu') def test_stack_overflow(self): # bpo-31113: Stack overflow when compile a long sequence of # complex statements. diff --git a/mingw64/lib/python3.11/test/test_compileall.py b/mingw64/lib/python3.11/test/test_compileall.py index 05154c8f1c6..9cd92ad365c 100644 --- a/mingw64/lib/python3.11/test/test_compileall.py +++ b/mingw64/lib/python3.11/test/test_compileall.py @@ -18,6 +18,7 @@ try: # compileall relies on ProcessPoolExecutor if ProcessPoolExecutor exists # and it can function. + from multiprocessing.util import _cleanup_tests as multiprocessing_cleanup_tests from concurrent.futures import ProcessPoolExecutor from concurrent.futures.process import _check_system_limits _check_system_limits() @@ -54,6 +55,8 @@ class CompileallTestsBase: def setUp(self): self.directory = tempfile.mkdtemp() + self.addCleanup(shutil.rmtree, self.directory) + self.source_path = os.path.join(self.directory, '_test.py') self.bc_path = importlib.util.cache_from_source(self.source_path) with open(self.source_path, 'w', encoding="utf-8") as file: @@ -66,9 +69,6 @@ def setUp(self): self.source_path3 = os.path.join(self.subdirectory, '_test3.py') shutil.copyfile(self.source_path, self.source_path3) - def tearDown(self): - shutil.rmtree(self.directory) - def add_bad_source_file(self): self.bad_source_path = os.path.join(self.directory, '_test_bad.py') with open(self.bad_source_path, 'w', encoding="utf-8") as file: @@ -307,9 +307,13 @@ def _test_ddir_only(self, *, ddir, parallel=True): script_helper.make_script(path, "__init__", "") mods.append(script_helper.make_script(path, "mod", "def fn(): 1/0\nfn()\n")) + + if parallel: + self.addCleanup(multiprocessing_cleanup_tests) compileall.compile_dir( self.directory, quiet=True, ddir=ddir, workers=2 if parallel else 1) + self.assertTrue(mods) for mod in mods: self.assertTrue(mod.startswith(self.directory), mod) @@ -551,6 +555,7 @@ def test_no_args_compiles_path(self): self.assertNotCompiled(self.barfn) @without_source_date_epoch # timestamp invalidation test + @support.requires_resource('cpu') def test_no_args_respects_force_flag(self): bazfn = script_helper.make_script(self.directory, 'baz', '') with self.temporary_pycache_prefix() as env: @@ -568,6 +573,7 @@ def test_no_args_respects_force_flag(self): mtime2 = os.stat(pycpath).st_mtime self.assertNotEqual(mtime, mtime2) + @support.requires_resource('cpu') def test_no_args_respects_quiet_flag(self): script_helper.make_script(self.directory, 'baz', '') with self.temporary_pycache_prefix() as env: diff --git a/mingw64/lib/python3.11/test/test_concurrent_futures.py b/mingw64/lib/python3.11/test/test_concurrent_futures.py deleted file mode 100644 index 11d5001bc63..00000000000 --- a/mingw64/lib/python3.11/test/test_concurrent_futures.py +++ /dev/null @@ -1,1674 +0,0 @@ -from test import support -from test.support import import_helper -from test.support import threading_helper - -# Skip tests if _multiprocessing wasn't built. -import_helper.import_module('_multiprocessing') - -from test.support import hashlib_helper -from test.support.script_helper import assert_python_ok - -import contextlib -import itertools -import logging -from logging.handlers import QueueHandler -import os -import queue -import signal -import sys -import threading -import time -import unittest -import weakref -from pickle import PicklingError - -from concurrent import futures -from concurrent.futures._base import ( - PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED, Future, - BrokenExecutor) -from concurrent.futures.process import BrokenProcessPool, _check_system_limits - -import multiprocessing.process -import multiprocessing.util -import multiprocessing as mp - - -if support.check_sanitizer(address=True, memory=True): - # bpo-46633: Skip the test because it is too slow when Python is built - # with ASAN/MSAN: between 5 and 20 minutes on GitHub Actions. - raise unittest.SkipTest("test too slow on ASAN/MSAN build") - - -def create_future(state=PENDING, exception=None, result=None): - f = Future() - f._state = state - f._exception = exception - f._result = result - return f - - -PENDING_FUTURE = create_future(state=PENDING) -RUNNING_FUTURE = create_future(state=RUNNING) -CANCELLED_FUTURE = create_future(state=CANCELLED) -CANCELLED_AND_NOTIFIED_FUTURE = create_future(state=CANCELLED_AND_NOTIFIED) -EXCEPTION_FUTURE = create_future(state=FINISHED, exception=OSError()) -SUCCESSFUL_FUTURE = create_future(state=FINISHED, result=42) - -INITIALIZER_STATUS = 'uninitialized' - -def mul(x, y): - return x * y - -def capture(*args, **kwargs): - return args, kwargs - -def sleep_and_raise(t): - time.sleep(t) - raise Exception('this is an exception') - -def sleep_and_print(t, msg): - time.sleep(t) - print(msg) - sys.stdout.flush() - -def init(x): - global INITIALIZER_STATUS - INITIALIZER_STATUS = x - -def get_init_status(): - return INITIALIZER_STATUS - -def init_fail(log_queue=None): - if log_queue is not None: - logger = logging.getLogger('concurrent.futures') - logger.addHandler(QueueHandler(log_queue)) - logger.setLevel('CRITICAL') - logger.propagate = False - time.sleep(0.1) # let some futures be scheduled - raise ValueError('error in initializer') - - -class MyObject(object): - def my_method(self): - pass - - -class EventfulGCObj(): - def __init__(self, mgr): - self.event = mgr.Event() - - def __del__(self): - self.event.set() - - -def make_dummy_object(_): - return MyObject() - - -class BaseTestCase(unittest.TestCase): - def setUp(self): - self._thread_key = threading_helper.threading_setup() - - def tearDown(self): - support.reap_children() - threading_helper.threading_cleanup(*self._thread_key) - - -class ExecutorMixin: - worker_count = 5 - executor_kwargs = {} - - def setUp(self): - super().setUp() - - self.t1 = time.monotonic() - if hasattr(self, "ctx"): - self.executor = self.executor_type( - max_workers=self.worker_count, - mp_context=self.get_context(), - **self.executor_kwargs) - else: - self.executor = self.executor_type( - max_workers=self.worker_count, - **self.executor_kwargs) - - def tearDown(self): - self.executor.shutdown(wait=True) - self.executor = None - - dt = time.monotonic() - self.t1 - if support.verbose: - print("%.2fs" % dt, end=' ') - self.assertLess(dt, 300, "synchronization issue: test lasted too long") - - super().tearDown() - - def get_context(self): - return mp.get_context(self.ctx) - - -class ThreadPoolMixin(ExecutorMixin): - executor_type = futures.ThreadPoolExecutor - - -class ProcessPoolForkMixin(ExecutorMixin): - executor_type = futures.ProcessPoolExecutor - ctx = "fork" - - def get_context(self): - try: - _check_system_limits() - except NotImplementedError: - self.skipTest("ProcessPoolExecutor unavailable on this system") - if sys.platform == "win32": - self.skipTest("require unix system") - return super().get_context() - - -class ProcessPoolSpawnMixin(ExecutorMixin): - executor_type = futures.ProcessPoolExecutor - ctx = "spawn" - - def get_context(self): - try: - _check_system_limits() - except NotImplementedError: - self.skipTest("ProcessPoolExecutor unavailable on this system") - return super().get_context() - - -class ProcessPoolForkserverMixin(ExecutorMixin): - executor_type = futures.ProcessPoolExecutor - ctx = "forkserver" - - def get_context(self): - try: - _check_system_limits() - except NotImplementedError: - self.skipTest("ProcessPoolExecutor unavailable on this system") - if sys.platform == "win32": - self.skipTest("require unix system") - return super().get_context() - - -def create_executor_tests(mixin, bases=(BaseTestCase,), - executor_mixins=(ThreadPoolMixin, - ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)): - def strip_mixin(name): - if name.endswith(('Mixin', 'Tests')): - return name[:-5] - elif name.endswith('Test'): - return name[:-4] - else: - return name - - for exe in executor_mixins: - name = ("%s%sTest" - % (strip_mixin(exe.__name__), strip_mixin(mixin.__name__))) - cls = type(name, (mixin,) + (exe,) + bases, {}) - globals()[name] = cls - - -class InitializerMixin(ExecutorMixin): - worker_count = 2 - - def setUp(self): - global INITIALIZER_STATUS - INITIALIZER_STATUS = 'uninitialized' - self.executor_kwargs = dict(initializer=init, - initargs=('initialized',)) - super().setUp() - - def test_initializer(self): - futures = [self.executor.submit(get_init_status) - for _ in range(self.worker_count)] - - for f in futures: - self.assertEqual(f.result(), 'initialized') - - -class FailingInitializerMixin(ExecutorMixin): - worker_count = 2 - - def setUp(self): - if hasattr(self, "ctx"): - # Pass a queue to redirect the child's logging output - self.mp_context = self.get_context() - self.log_queue = self.mp_context.Queue() - self.executor_kwargs = dict(initializer=init_fail, - initargs=(self.log_queue,)) - else: - # In a thread pool, the child shares our logging setup - # (see _assert_logged()) - self.mp_context = None - self.log_queue = None - self.executor_kwargs = dict(initializer=init_fail) - super().setUp() - - def test_initializer(self): - with self._assert_logged('ValueError: error in initializer'): - try: - future = self.executor.submit(get_init_status) - except BrokenExecutor: - # Perhaps the executor is already broken - pass - else: - with self.assertRaises(BrokenExecutor): - future.result() - # At some point, the executor should break - t1 = time.monotonic() - while not self.executor._broken: - if time.monotonic() - t1 > 5: - self.fail("executor not broken after 5 s.") - time.sleep(0.01) - # ... and from this point submit() is guaranteed to fail - with self.assertRaises(BrokenExecutor): - self.executor.submit(get_init_status) - - @contextlib.contextmanager - def _assert_logged(self, msg): - if self.log_queue is not None: - yield - output = [] - try: - while True: - output.append(self.log_queue.get_nowait().getMessage()) - except queue.Empty: - pass - else: - with self.assertLogs('concurrent.futures', 'CRITICAL') as cm: - yield - output = cm.output - self.assertTrue(any(msg in line for line in output), - output) - - -create_executor_tests(InitializerMixin) -create_executor_tests(FailingInitializerMixin) - - -class ExecutorShutdownTest: - def test_run_after_shutdown(self): - self.executor.shutdown() - self.assertRaises(RuntimeError, - self.executor.submit, - pow, 2, 5) - - def test_interpreter_shutdown(self): - # Test the atexit hook for shutdown of worker threads and processes - rc, out, err = assert_python_ok('-c', """if 1: - from concurrent.futures import {executor_type} - from time import sleep - from test.test_concurrent_futures import sleep_and_print - if __name__ == "__main__": - context = '{context}' - if context == "": - t = {executor_type}(5) - else: - from multiprocessing import get_context - context = get_context(context) - t = {executor_type}(5, mp_context=context) - t.submit(sleep_and_print, 1.0, "apple") - """.format(executor_type=self.executor_type.__name__, - context=getattr(self, "ctx", ""))) - # Errors in atexit hooks don't change the process exit code, check - # stderr manually. - self.assertFalse(err) - self.assertEqual(out.strip(), b"apple") - - def test_submit_after_interpreter_shutdown(self): - # Test the atexit hook for shutdown of worker threads and processes - rc, out, err = assert_python_ok('-c', """if 1: - import atexit - @atexit.register - def run_last(): - try: - t.submit(id, None) - except RuntimeError: - print("runtime-error") - raise - from concurrent.futures import {executor_type} - if __name__ == "__main__": - context = '{context}' - if not context: - t = {executor_type}(5) - else: - from multiprocessing import get_context - context = get_context(context) - t = {executor_type}(5, mp_context=context) - t.submit(id, 42).result() - """.format(executor_type=self.executor_type.__name__, - context=getattr(self, "ctx", ""))) - # Errors in atexit hooks don't change the process exit code, check - # stderr manually. - self.assertIn("RuntimeError: cannot schedule new futures", err.decode()) - self.assertEqual(out.strip(), b"runtime-error") - - def test_hang_issue12364(self): - fs = [self.executor.submit(time.sleep, 0.1) for _ in range(50)] - self.executor.shutdown() - for f in fs: - f.result() - - def test_cancel_futures(self): - assert self.worker_count <= 5, "test needs few workers" - fs = [self.executor.submit(time.sleep, .1) for _ in range(50)] - self.executor.shutdown(cancel_futures=True) - # We can't guarantee the exact number of cancellations, but we can - # guarantee that *some* were cancelled. With few workers, many of - # the submitted futures should have been cancelled. - cancelled = [fut for fut in fs if fut.cancelled()] - self.assertGreater(len(cancelled), 20) - - # Ensure the other futures were able to finish. - # Use "not fut.cancelled()" instead of "fut.done()" to include futures - # that may have been left in a pending state. - others = [fut for fut in fs if not fut.cancelled()] - for fut in others: - self.assertTrue(fut.done(), msg=f"{fut._state=}") - self.assertIsNone(fut.exception()) - - # Similar to the number of cancelled futures, we can't guarantee the - # exact number that completed. But, we can guarantee that at least - # one finished. - self.assertGreater(len(others), 0) - - def test_hang_gh83386(self): - """shutdown(wait=False) doesn't hang at exit with running futures. - - See https://github.com/python/cpython/issues/83386. - """ - if self.executor_type == futures.ProcessPoolExecutor: - raise unittest.SkipTest( - "Hangs, see https://github.com/python/cpython/issues/83386") - - rc, out, err = assert_python_ok('-c', """if True: - from concurrent.futures import {executor_type} - from test.test_concurrent_futures import sleep_and_print - if __name__ == "__main__": - if {context!r}: multiprocessing.set_start_method({context!r}) - t = {executor_type}(max_workers=3) - t.submit(sleep_and_print, 1.0, "apple") - t.shutdown(wait=False) - """.format(executor_type=self.executor_type.__name__, - context=getattr(self, 'ctx', None))) - self.assertFalse(err) - self.assertEqual(out.strip(), b"apple") - - def test_hang_gh94440(self): - """shutdown(wait=True) doesn't hang when a future was submitted and - quickly canceled right before shutdown. - - See https://github.com/python/cpython/issues/94440. - """ - if not hasattr(signal, 'alarm'): - raise unittest.SkipTest( - "Tested platform does not support the alarm signal") - - def timeout(_signum, _frame): - raise RuntimeError("timed out waiting for shutdown") - - kwargs = {} - if getattr(self, 'ctx', None): - kwargs['mp_context'] = self.get_context() - executor = self.executor_type(max_workers=1, **kwargs) - executor.submit(int).result() - old_handler = signal.signal(signal.SIGALRM, timeout) - try: - signal.alarm(5) - executor.submit(int).cancel() - executor.shutdown(wait=True) - finally: - signal.alarm(0) - signal.signal(signal.SIGALRM, old_handler) - - -class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest, BaseTestCase): - def test_threads_terminate(self): - def acquire_lock(lock): - lock.acquire() - - sem = threading.Semaphore(0) - for i in range(3): - self.executor.submit(acquire_lock, sem) - self.assertEqual(len(self.executor._threads), 3) - for i in range(3): - sem.release() - self.executor.shutdown() - for t in self.executor._threads: - t.join() - - def test_context_manager_shutdown(self): - with futures.ThreadPoolExecutor(max_workers=5) as e: - executor = e - self.assertEqual(list(e.map(abs, range(-5, 5))), - [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) - - for t in executor._threads: - t.join() - - def test_del_shutdown(self): - executor = futures.ThreadPoolExecutor(max_workers=5) - res = executor.map(abs, range(-5, 5)) - threads = executor._threads - del executor - - for t in threads: - t.join() - - # Make sure the results were all computed before the - # executor got shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - def test_shutdown_no_wait(self): - # Ensure that the executor cleans up the threads when calling - # shutdown with wait=False - executor = futures.ThreadPoolExecutor(max_workers=5) - res = executor.map(abs, range(-5, 5)) - threads = executor._threads - executor.shutdown(wait=False) - for t in threads: - t.join() - - # Make sure the results were all computed before the - # executor got shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - - def test_thread_names_assigned(self): - executor = futures.ThreadPoolExecutor( - max_workers=5, thread_name_prefix='SpecialPool') - executor.map(abs, range(-5, 5)) - threads = executor._threads - del executor - support.gc_collect() # For PyPy or other GCs. - - for t in threads: - self.assertRegex(t.name, r'^SpecialPool_[0-4]$') - t.join() - - def test_thread_names_default(self): - executor = futures.ThreadPoolExecutor(max_workers=5) - executor.map(abs, range(-5, 5)) - threads = executor._threads - del executor - support.gc_collect() # For PyPy or other GCs. - - for t in threads: - # Ensure that our default name is reasonably sane and unique when - # no thread_name_prefix was supplied. - self.assertRegex(t.name, r'ThreadPoolExecutor-\d+_[0-4]$') - t.join() - - def test_cancel_futures_wait_false(self): - # Can only be reliably tested for TPE, since PPE often hangs with - # `wait=False` (even without *cancel_futures*). - rc, out, err = assert_python_ok('-c', """if True: - from concurrent.futures import ThreadPoolExecutor - from test.test_concurrent_futures import sleep_and_print - if __name__ == "__main__": - t = ThreadPoolExecutor() - t.submit(sleep_and_print, .1, "apple") - t.shutdown(wait=False, cancel_futures=True) - """) - # Errors in atexit hooks don't change the process exit code, check - # stderr manually. - self.assertFalse(err) - self.assertEqual(out.strip(), b"apple") - - -class ProcessPoolShutdownTest(ExecutorShutdownTest): - def test_processes_terminate(self): - def acquire_lock(lock): - lock.acquire() - - mp_context = self.get_context() - if mp_context.get_start_method(allow_none=False) == "fork": - # fork pre-spawns, not on demand. - expected_num_processes = self.worker_count - else: - expected_num_processes = 3 - - sem = mp_context.Semaphore(0) - for _ in range(3): - self.executor.submit(acquire_lock, sem) - self.assertEqual(len(self.executor._processes), expected_num_processes) - for _ in range(3): - sem.release() - processes = self.executor._processes - self.executor.shutdown() - - for p in processes.values(): - p.join() - - def test_context_manager_shutdown(self): - with futures.ProcessPoolExecutor( - max_workers=5, mp_context=self.get_context()) as e: - processes = e._processes - self.assertEqual(list(e.map(abs, range(-5, 5))), - [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) - - for p in processes.values(): - p.join() - - def test_del_shutdown(self): - executor = futures.ProcessPoolExecutor( - max_workers=5, mp_context=self.get_context()) - res = executor.map(abs, range(-5, 5)) - executor_manager_thread = executor._executor_manager_thread - processes = executor._processes - call_queue = executor._call_queue - executor_manager_thread = executor._executor_manager_thread - del executor - support.gc_collect() # For PyPy or other GCs. - - # Make sure that all the executor resources were properly cleaned by - # the shutdown process - executor_manager_thread.join() - for p in processes.values(): - p.join() - call_queue.join_thread() - - # Make sure the results were all computed before the - # executor got shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - def test_shutdown_no_wait(self): - # Ensure that the executor cleans up the processes when calling - # shutdown with wait=False - executor = futures.ProcessPoolExecutor( - max_workers=5, mp_context=self.get_context()) - res = executor.map(abs, range(-5, 5)) - processes = executor._processes - call_queue = executor._call_queue - executor_manager_thread = executor._executor_manager_thread - executor.shutdown(wait=False) - - # Make sure that all the executor resources were properly cleaned by - # the shutdown process - executor_manager_thread.join() - for p in processes.values(): - p.join() - call_queue.join_thread() - - # Make sure the results were all computed before the executor got - # shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - -create_executor_tests(ProcessPoolShutdownTest, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - - -class WaitTests: - def test_20369(self): - # See https://bugs.python.org/issue20369 - future = self.executor.submit(time.sleep, 1.5) - done, not_done = futures.wait([future, future], - return_when=futures.ALL_COMPLETED) - self.assertEqual({future}, done) - self.assertEqual(set(), not_done) - - - def test_first_completed(self): - future1 = self.executor.submit(mul, 21, 2) - future2 = self.executor.submit(time.sleep, 1.5) - - done, not_done = futures.wait( - [CANCELLED_FUTURE, future1, future2], - return_when=futures.FIRST_COMPLETED) - - self.assertEqual(set([future1]), done) - self.assertEqual(set([CANCELLED_FUTURE, future2]), not_done) - - def test_first_completed_some_already_completed(self): - future1 = self.executor.submit(time.sleep, 1.5) - - finished, pending = futures.wait( - [CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE, future1], - return_when=futures.FIRST_COMPLETED) - - self.assertEqual( - set([CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE]), - finished) - self.assertEqual(set([future1]), pending) - - def test_first_exception(self): - future1 = self.executor.submit(mul, 2, 21) - future2 = self.executor.submit(sleep_and_raise, 1.5) - future3 = self.executor.submit(time.sleep, 3) - - finished, pending = futures.wait( - [future1, future2, future3], - return_when=futures.FIRST_EXCEPTION) - - self.assertEqual(set([future1, future2]), finished) - self.assertEqual(set([future3]), pending) - - def test_first_exception_some_already_complete(self): - future1 = self.executor.submit(divmod, 21, 0) - future2 = self.executor.submit(time.sleep, 1.5) - - finished, pending = futures.wait( - [SUCCESSFUL_FUTURE, - CANCELLED_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - future1, future2], - return_when=futures.FIRST_EXCEPTION) - - self.assertEqual(set([SUCCESSFUL_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - future1]), finished) - self.assertEqual(set([CANCELLED_FUTURE, future2]), pending) - - def test_first_exception_one_already_failed(self): - future1 = self.executor.submit(time.sleep, 2) - - finished, pending = futures.wait( - [EXCEPTION_FUTURE, future1], - return_when=futures.FIRST_EXCEPTION) - - self.assertEqual(set([EXCEPTION_FUTURE]), finished) - self.assertEqual(set([future1]), pending) - - def test_all_completed(self): - future1 = self.executor.submit(divmod, 2, 0) - future2 = self.executor.submit(mul, 2, 21) - - finished, pending = futures.wait( - [SUCCESSFUL_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - future1, - future2], - return_when=futures.ALL_COMPLETED) - - self.assertEqual(set([SUCCESSFUL_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - future1, - future2]), finished) - self.assertEqual(set(), pending) - - def test_timeout(self): - future1 = self.executor.submit(mul, 6, 7) - future2 = self.executor.submit(time.sleep, 6) - - finished, pending = futures.wait( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1, future2], - timeout=5, - return_when=futures.ALL_COMPLETED) - - self.assertEqual(set([CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1]), finished) - self.assertEqual(set([future2]), pending) - - -class ThreadPoolWaitTests(ThreadPoolMixin, WaitTests, BaseTestCase): - - def test_pending_calls_race(self): - # Issue #14406: multi-threaded race condition when waiting on all - # futures. - event = threading.Event() - def future_func(): - event.wait() - oldswitchinterval = sys.getswitchinterval() - sys.setswitchinterval(1e-6) - try: - fs = {self.executor.submit(future_func) for i in range(100)} - event.set() - futures.wait(fs, return_when=futures.ALL_COMPLETED) - finally: - sys.setswitchinterval(oldswitchinterval) - - -create_executor_tests(WaitTests, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - - -class AsCompletedTests: - # TODO(brian@sweetapp.com): Should have a test with a non-zero timeout. - def test_no_timeout(self): - future1 = self.executor.submit(mul, 2, 21) - future2 = self.executor.submit(mul, 7, 6) - - completed = set(futures.as_completed( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1, future2])) - self.assertEqual(set( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1, future2]), - completed) - - def test_zero_timeout(self): - future1 = self.executor.submit(time.sleep, 2) - completed_futures = set() - try: - for future in futures.as_completed( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1], - timeout=0): - completed_futures.add(future) - except futures.TimeoutError: - pass - - self.assertEqual(set([CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE]), - completed_futures) - - def test_duplicate_futures(self): - # Issue 20367. Duplicate futures should not raise exceptions or give - # duplicate responses. - # Issue #31641: accept arbitrary iterables. - future1 = self.executor.submit(time.sleep, 2) - completed = [ - f for f in futures.as_completed(itertools.repeat(future1, 3)) - ] - self.assertEqual(len(completed), 1) - - def test_free_reference_yielded_future(self): - # Issue #14406: Generator should not keep references - # to finished futures. - futures_list = [Future() for _ in range(8)] - futures_list.append(create_future(state=CANCELLED_AND_NOTIFIED)) - futures_list.append(create_future(state=FINISHED, result=42)) - - with self.assertRaises(futures.TimeoutError): - for future in futures.as_completed(futures_list, timeout=0): - futures_list.remove(future) - wr = weakref.ref(future) - del future - support.gc_collect() # For PyPy or other GCs. - self.assertIsNone(wr()) - - futures_list[0].set_result("test") - for future in futures.as_completed(futures_list): - futures_list.remove(future) - wr = weakref.ref(future) - del future - support.gc_collect() # For PyPy or other GCs. - self.assertIsNone(wr()) - if futures_list: - futures_list[0].set_result("test") - - def test_correct_timeout_exception_msg(self): - futures_list = [CANCELLED_AND_NOTIFIED_FUTURE, PENDING_FUTURE, - RUNNING_FUTURE, SUCCESSFUL_FUTURE] - - with self.assertRaises(futures.TimeoutError) as cm: - list(futures.as_completed(futures_list, timeout=0)) - - self.assertEqual(str(cm.exception), '2 (of 4) futures unfinished') - - -create_executor_tests(AsCompletedTests) - - -class ExecutorTest: - # Executor.shutdown() and context manager usage is tested by - # ExecutorShutdownTest. - def test_submit(self): - future = self.executor.submit(pow, 2, 8) - self.assertEqual(256, future.result()) - - def test_submit_keyword(self): - future = self.executor.submit(mul, 2, y=8) - self.assertEqual(16, future.result()) - future = self.executor.submit(capture, 1, self=2, fn=3) - self.assertEqual(future.result(), ((1,), {'self': 2, 'fn': 3})) - with self.assertRaises(TypeError): - self.executor.submit(fn=capture, arg=1) - with self.assertRaises(TypeError): - self.executor.submit(arg=1) - - def test_map(self): - self.assertEqual( - list(self.executor.map(pow, range(10), range(10))), - list(map(pow, range(10), range(10)))) - - self.assertEqual( - list(self.executor.map(pow, range(10), range(10), chunksize=3)), - list(map(pow, range(10), range(10)))) - - def test_map_exception(self): - i = self.executor.map(divmod, [1, 1, 1, 1], [2, 3, 0, 5]) - self.assertEqual(i.__next__(), (0, 1)) - self.assertEqual(i.__next__(), (0, 1)) - self.assertRaises(ZeroDivisionError, i.__next__) - - def test_map_timeout(self): - results = [] - try: - for i in self.executor.map(time.sleep, - [0, 0, 6], - timeout=5): - results.append(i) - except futures.TimeoutError: - pass - else: - self.fail('expected TimeoutError') - - self.assertEqual([None, None], results) - - def test_shutdown_race_issue12456(self): - # Issue #12456: race condition at shutdown where trying to post a - # sentinel in the call queue blocks (the queue is full while processes - # have exited). - self.executor.map(str, [2] * (self.worker_count + 1)) - self.executor.shutdown() - - @support.cpython_only - def test_no_stale_references(self): - # Issue #16284: check that the executors don't unnecessarily hang onto - # references. - my_object = MyObject() - my_object_collected = threading.Event() - my_object_callback = weakref.ref( - my_object, lambda obj: my_object_collected.set()) - # Deliberately discarding the future. - self.executor.submit(my_object.my_method) - del my_object - - collected = my_object_collected.wait(timeout=support.SHORT_TIMEOUT) - self.assertTrue(collected, - "Stale reference not collected within timeout.") - - def test_max_workers_negative(self): - for number in (0, -1): - with self.assertRaisesRegex(ValueError, - "max_workers must be greater " - "than 0"): - self.executor_type(max_workers=number) - - def test_free_reference(self): - # Issue #14406: Result iterator should not keep an internal - # reference to result objects. - for obj in self.executor.map(make_dummy_object, range(10)): - wr = weakref.ref(obj) - del obj - support.gc_collect() # For PyPy or other GCs. - self.assertIsNone(wr()) - - -class ThreadPoolExecutorTest(ThreadPoolMixin, ExecutorTest, BaseTestCase): - def test_map_submits_without_iteration(self): - """Tests verifying issue 11777.""" - finished = [] - def record_finished(n): - finished.append(n) - - self.executor.map(record_finished, range(10)) - self.executor.shutdown(wait=True) - self.assertCountEqual(finished, range(10)) - - def test_default_workers(self): - executor = self.executor_type() - expected = min(32, (os.cpu_count() or 1) + 4) - self.assertEqual(executor._max_workers, expected) - - def test_saturation(self): - executor = self.executor_type(4) - def acquire_lock(lock): - lock.acquire() - - sem = threading.Semaphore(0) - for i in range(15 * executor._max_workers): - executor.submit(acquire_lock, sem) - self.assertEqual(len(executor._threads), executor._max_workers) - for i in range(15 * executor._max_workers): - sem.release() - executor.shutdown(wait=True) - - def test_idle_thread_reuse(self): - executor = self.executor_type() - executor.submit(mul, 21, 2).result() - executor.submit(mul, 6, 7).result() - executor.submit(mul, 3, 14).result() - self.assertEqual(len(executor._threads), 1) - executor.shutdown(wait=True) - - @unittest.skipUnless(hasattr(os, 'register_at_fork'), 'need os.register_at_fork') - def test_hang_global_shutdown_lock(self): - # bpo-45021: _global_shutdown_lock should be reinitialized in the child - # process, otherwise it will never exit - def submit(pool): - pool.submit(submit, pool) - - with futures.ThreadPoolExecutor(1) as pool: - pool.submit(submit, pool) - - for _ in range(50): - with futures.ProcessPoolExecutor(1, mp_context=mp.get_context('fork')) as workers: - workers.submit(tuple) - - def test_executor_map_current_future_cancel(self): - stop_event = threading.Event() - log = [] - - def log_n_wait(ident): - log.append(f"{ident=} started") - try: - stop_event.wait() - finally: - log.append(f"{ident=} stopped") - - with self.executor_type(max_workers=1) as pool: - # submit work to saturate the pool - fut = pool.submit(log_n_wait, ident="first") - try: - with contextlib.closing( - pool.map(log_n_wait, ["second", "third"], timeout=0) - ) as gen: - with self.assertRaises(TimeoutError): - next(gen) - finally: - stop_event.set() - fut.result() - # ident='second' is cancelled as a result of raising a TimeoutError - # ident='third' is cancelled because it remained in the collection of futures - self.assertListEqual(log, ["ident='first' started", "ident='first' stopped"]) - - -class ProcessPoolExecutorTest(ExecutorTest): - - @unittest.skipUnless(sys.platform=='win32', 'Windows-only process limit') - def test_max_workers_too_large(self): - with self.assertRaisesRegex(ValueError, - "max_workers must be <= 61"): - futures.ProcessPoolExecutor(max_workers=62) - - def test_killed_child(self): - # When a child process is abruptly terminated, the whole pool gets - # "broken". - futures = [self.executor.submit(time.sleep, 3)] - # Get one of the processes, and terminate (kill) it - p = next(iter(self.executor._processes.values())) - p.terminate() - for fut in futures: - self.assertRaises(BrokenProcessPool, fut.result) - # Submitting other jobs fails as well. - self.assertRaises(BrokenProcessPool, self.executor.submit, pow, 2, 8) - - def test_map_chunksize(self): - def bad_map(): - list(self.executor.map(pow, range(40), range(40), chunksize=-1)) - - ref = list(map(pow, range(40), range(40))) - self.assertEqual( - list(self.executor.map(pow, range(40), range(40), chunksize=6)), - ref) - self.assertEqual( - list(self.executor.map(pow, range(40), range(40), chunksize=50)), - ref) - self.assertEqual( - list(self.executor.map(pow, range(40), range(40), chunksize=40)), - ref) - self.assertRaises(ValueError, bad_map) - - @classmethod - def _test_traceback(cls): - raise RuntimeError(123) # some comment - - def test_traceback(self): - # We want ensure that the traceback from the child process is - # contained in the traceback raised in the main process. - future = self.executor.submit(self._test_traceback) - with self.assertRaises(Exception) as cm: - future.result() - - exc = cm.exception - self.assertIs(type(exc), RuntimeError) - self.assertEqual(exc.args, (123,)) - cause = exc.__cause__ - self.assertIs(type(cause), futures.process._RemoteTraceback) - self.assertIn('raise RuntimeError(123) # some comment', cause.tb) - - with support.captured_stderr() as f1: - try: - raise exc - except RuntimeError: - sys.excepthook(*sys.exc_info()) - self.assertIn('raise RuntimeError(123) # some comment', - f1.getvalue()) - - @hashlib_helper.requires_hashdigest('md5') - def test_ressources_gced_in_workers(self): - # Ensure that argument for a job are correctly gc-ed after the job - # is finished - mgr = self.get_context().Manager() - obj = EventfulGCObj(mgr) - future = self.executor.submit(id, obj) - future.result() - - self.assertTrue(obj.event.wait(timeout=1)) - - # explicitly destroy the object to ensure that EventfulGCObj.__del__() - # is called while manager is still running. - obj = None - support.gc_collect() - - mgr.shutdown() - mgr.join() - - def test_saturation(self): - executor = self.executor - mp_context = self.get_context() - sem = mp_context.Semaphore(0) - job_count = 15 * executor._max_workers - for _ in range(job_count): - executor.submit(sem.acquire) - self.assertEqual(len(executor._processes), executor._max_workers) - for _ in range(job_count): - sem.release() - - def test_idle_process_reuse_one(self): - executor = self.executor - assert executor._max_workers >= 4 - if self.get_context().get_start_method(allow_none=False) == "fork": - raise unittest.SkipTest("Incompatible with the fork start method.") - executor.submit(mul, 21, 2).result() - executor.submit(mul, 6, 7).result() - executor.submit(mul, 3, 14).result() - self.assertEqual(len(executor._processes), 1) - - def test_idle_process_reuse_multiple(self): - executor = self.executor - assert executor._max_workers <= 5 - if self.get_context().get_start_method(allow_none=False) == "fork": - raise unittest.SkipTest("Incompatible with the fork start method.") - executor.submit(mul, 12, 7).result() - executor.submit(mul, 33, 25) - executor.submit(mul, 25, 26).result() - executor.submit(mul, 18, 29) - executor.submit(mul, 1, 2).result() - executor.submit(mul, 0, 9) - self.assertLessEqual(len(executor._processes), 3) - executor.shutdown() - - def test_max_tasks_per_child(self): - context = self.get_context() - if context.get_start_method(allow_none=False) == "fork": - with self.assertRaises(ValueError): - self.executor_type(1, mp_context=context, max_tasks_per_child=3) - return - # not using self.executor as we need to control construction. - # arguably this could go in another class w/o that mixin. - executor = self.executor_type( - 1, mp_context=context, max_tasks_per_child=3) - f1 = executor.submit(os.getpid) - original_pid = f1.result() - # The worker pid remains the same as the worker could be reused - f2 = executor.submit(os.getpid) - self.assertEqual(f2.result(), original_pid) - self.assertEqual(len(executor._processes), 1) - f3 = executor.submit(os.getpid) - self.assertEqual(f3.result(), original_pid) - - # A new worker is spawned, with a statistically different pid, - # while the previous was reaped. - f4 = executor.submit(os.getpid) - new_pid = f4.result() - self.assertNotEqual(original_pid, new_pid) - self.assertEqual(len(executor._processes), 1) - - executor.shutdown() - - def test_max_tasks_per_child_defaults_to_spawn_context(self): - # not using self.executor as we need to control construction. - # arguably this could go in another class w/o that mixin. - executor = self.executor_type(1, max_tasks_per_child=3) - self.assertEqual(executor._mp_context.get_start_method(), "spawn") - - def test_max_tasks_early_shutdown(self): - context = self.get_context() - if context.get_start_method(allow_none=False) == "fork": - raise unittest.SkipTest("Incompatible with the fork start method.") - # not using self.executor as we need to control construction. - # arguably this could go in another class w/o that mixin. - executor = self.executor_type( - 3, mp_context=context, max_tasks_per_child=1) - futures = [] - for i in range(6): - futures.append(executor.submit(mul, i, i)) - executor.shutdown() - for i, future in enumerate(futures): - self.assertEqual(future.result(), mul(i, i)) - - -create_executor_tests(ProcessPoolExecutorTest, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - -def _crash(delay=None): - """Induces a segfault.""" - if delay: - time.sleep(delay) - import faulthandler - faulthandler.disable() - faulthandler._sigsegv() - - -def _crash_with_data(data): - """Induces a segfault with dummy data in input.""" - _crash() - - -def _exit(): - """Induces a sys exit with exitcode 1.""" - sys.exit(1) - - -def _raise_error(Err): - """Function that raises an Exception in process.""" - raise Err() - - -def _raise_error_ignore_stderr(Err): - """Function that raises an Exception in process and ignores stderr.""" - import io - sys.stderr = io.StringIO() - raise Err() - - -def _return_instance(cls): - """Function that returns a instance of cls.""" - return cls() - - -class CrashAtPickle(object): - """Bad object that triggers a segfault at pickling time.""" - def __reduce__(self): - _crash() - - -class CrashAtUnpickle(object): - """Bad object that triggers a segfault at unpickling time.""" - def __reduce__(self): - return _crash, () - - -class ExitAtPickle(object): - """Bad object that triggers a process exit at pickling time.""" - def __reduce__(self): - _exit() - - -class ExitAtUnpickle(object): - """Bad object that triggers a process exit at unpickling time.""" - def __reduce__(self): - return _exit, () - - -class ErrorAtPickle(object): - """Bad object that triggers an error at pickling time.""" - def __reduce__(self): - from pickle import PicklingError - raise PicklingError("Error in pickle") - - -class ErrorAtUnpickle(object): - """Bad object that triggers an error at unpickling time.""" - def __reduce__(self): - from pickle import UnpicklingError - return _raise_error_ignore_stderr, (UnpicklingError, ) - - -class ExecutorDeadlockTest: - TIMEOUT = support.SHORT_TIMEOUT - - def _fail_on_deadlock(self, executor): - # If we did not recover before TIMEOUT seconds, consider that the - # executor is in a deadlock state and forcefully clean all its - # composants. - import faulthandler - from tempfile import TemporaryFile - with TemporaryFile(mode="w+") as f: - faulthandler.dump_traceback(file=f) - f.seek(0) - tb = f.read() - for p in executor._processes.values(): - p.terminate() - # This should be safe to call executor.shutdown here as all possible - # deadlocks should have been broken. - executor.shutdown(wait=True) - print(f"\nTraceback:\n {tb}", file=sys.__stderr__) - self.fail(f"Executor deadlock:\n\n{tb}") - - - def _check_crash(self, error, func, *args, ignore_stderr=False): - # test for deadlock caused by crashes in a pool - self.executor.shutdown(wait=True) - - executor = self.executor_type( - max_workers=2, mp_context=self.get_context()) - res = executor.submit(func, *args) - - if ignore_stderr: - cm = support.captured_stderr() - else: - cm = contextlib.nullcontext() - - try: - with self.assertRaises(error): - with cm: - res.result(timeout=self.TIMEOUT) - except futures.TimeoutError: - # If we did not recover before TIMEOUT seconds, - # consider that the executor is in a deadlock state - self._fail_on_deadlock(executor) - executor.shutdown(wait=True) - - def test_error_at_task_pickle(self): - # Check problem occurring while pickling a task in - # the task_handler thread - self._check_crash(PicklingError, id, ErrorAtPickle()) - - def test_exit_at_task_unpickle(self): - # Check problem occurring while unpickling a task on workers - self._check_crash(BrokenProcessPool, id, ExitAtUnpickle()) - - def test_error_at_task_unpickle(self): - # Check problem occurring while unpickling a task on workers - self._check_crash(BrokenProcessPool, id, ErrorAtUnpickle()) - - def test_crash_at_task_unpickle(self): - # Check problem occurring while unpickling a task on workers - self._check_crash(BrokenProcessPool, id, CrashAtUnpickle()) - - def test_crash_during_func_exec_on_worker(self): - # Check problem occurring during func execution on workers - self._check_crash(BrokenProcessPool, _crash) - - def test_exit_during_func_exec_on_worker(self): - # Check problem occurring during func execution on workers - self._check_crash(SystemExit, _exit) - - def test_error_during_func_exec_on_worker(self): - # Check problem occurring during func execution on workers - self._check_crash(RuntimeError, _raise_error, RuntimeError) - - def test_crash_during_result_pickle_on_worker(self): - # Check problem occurring while pickling a task result - # on workers - self._check_crash(BrokenProcessPool, _return_instance, CrashAtPickle) - - def test_exit_during_result_pickle_on_worker(self): - # Check problem occurring while pickling a task result - # on workers - self._check_crash(SystemExit, _return_instance, ExitAtPickle) - - def test_error_during_result_pickle_on_worker(self): - # Check problem occurring while pickling a task result - # on workers - self._check_crash(PicklingError, _return_instance, ErrorAtPickle) - - def test_error_during_result_unpickle_in_result_handler(self): - # Check problem occurring while unpickling a task in - # the result_handler thread - self._check_crash(BrokenProcessPool, - _return_instance, ErrorAtUnpickle, - ignore_stderr=True) - - def test_exit_during_result_unpickle_in_result_handler(self): - # Check problem occurring while unpickling a task in - # the result_handler thread - self._check_crash(BrokenProcessPool, _return_instance, ExitAtUnpickle) - - def test_shutdown_deadlock(self): - # Test that the pool calling shutdown do not cause deadlock - # if a worker fails after the shutdown call. - self.executor.shutdown(wait=True) - with self.executor_type(max_workers=2, - mp_context=self.get_context()) as executor: - self.executor = executor # Allow clean up in fail_on_deadlock - f = executor.submit(_crash, delay=.1) - executor.shutdown(wait=True) - with self.assertRaises(BrokenProcessPool): - f.result() - - def test_shutdown_deadlock_pickle(self): - # Test that the pool calling shutdown with wait=False does not cause - # a deadlock if a task fails at pickle after the shutdown call. - # Reported in bpo-39104. - self.executor.shutdown(wait=True) - with self.executor_type(max_workers=2, - mp_context=self.get_context()) as executor: - self.executor = executor # Allow clean up in fail_on_deadlock - - # Start the executor and get the executor_manager_thread to collect - # the threads and avoid dangling thread that should be cleaned up - # asynchronously. - executor.submit(id, 42).result() - executor_manager = executor._executor_manager_thread - - # Submit a task that fails at pickle and shutdown the executor - # without waiting - f = executor.submit(id, ErrorAtPickle()) - executor.shutdown(wait=False) - with self.assertRaises(PicklingError): - f.result() - - # Make sure the executor is eventually shutdown and do not leave - # dangling threads - executor_manager.join() - - def test_crash_big_data(self): - # https://github.com/python/cpython/issues/107219 - return - # Test that there is a clean exception instad of a deadlock when a - # child process crashes while some data is being written into the - # queue. - # https://github.com/python/cpython/issues/94777 - self.executor.shutdown(wait=True) - data = "a" * support.PIPE_MAX_SIZE - with self.executor_type(max_workers=2, - mp_context=self.get_context()) as executor: - self.executor = executor # Allow clean up in fail_on_deadlock - with self.assertRaises(BrokenProcessPool): - list(executor.map(_crash_with_data, [data] * 10)) - - -create_executor_tests(ExecutorDeadlockTest, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - - -class FutureTests(BaseTestCase): - def test_done_callback_with_result(self): - callback_result = None - def fn(callback_future): - nonlocal callback_result - callback_result = callback_future.result() - - f = Future() - f.add_done_callback(fn) - f.set_result(5) - self.assertEqual(5, callback_result) - - def test_done_callback_with_exception(self): - callback_exception = None - def fn(callback_future): - nonlocal callback_exception - callback_exception = callback_future.exception() - - f = Future() - f.add_done_callback(fn) - f.set_exception(Exception('test')) - self.assertEqual(('test',), callback_exception.args) - - def test_done_callback_with_cancel(self): - was_cancelled = None - def fn(callback_future): - nonlocal was_cancelled - was_cancelled = callback_future.cancelled() - - f = Future() - f.add_done_callback(fn) - self.assertTrue(f.cancel()) - self.assertTrue(was_cancelled) - - def test_done_callback_raises(self): - with support.captured_stderr() as stderr: - raising_was_called = False - fn_was_called = False - - def raising_fn(callback_future): - nonlocal raising_was_called - raising_was_called = True - raise Exception('doh!') - - def fn(callback_future): - nonlocal fn_was_called - fn_was_called = True - - f = Future() - f.add_done_callback(raising_fn) - f.add_done_callback(fn) - f.set_result(5) - self.assertTrue(raising_was_called) - self.assertTrue(fn_was_called) - self.assertIn('Exception: doh!', stderr.getvalue()) - - def test_done_callback_already_successful(self): - callback_result = None - def fn(callback_future): - nonlocal callback_result - callback_result = callback_future.result() - - f = Future() - f.set_result(5) - f.add_done_callback(fn) - self.assertEqual(5, callback_result) - - def test_done_callback_already_failed(self): - callback_exception = None - def fn(callback_future): - nonlocal callback_exception - callback_exception = callback_future.exception() - - f = Future() - f.set_exception(Exception('test')) - f.add_done_callback(fn) - self.assertEqual(('test',), callback_exception.args) - - def test_done_callback_already_cancelled(self): - was_cancelled = None - def fn(callback_future): - nonlocal was_cancelled - was_cancelled = callback_future.cancelled() - - f = Future() - self.assertTrue(f.cancel()) - f.add_done_callback(fn) - self.assertTrue(was_cancelled) - - def test_done_callback_raises_already_succeeded(self): - with support.captured_stderr() as stderr: - def raising_fn(callback_future): - raise Exception('doh!') - - f = Future() - - # Set the result first to simulate a future that runs instantly, - # effectively allowing the callback to be run immediately. - f.set_result(5) - f.add_done_callback(raising_fn) - - self.assertIn('exception calling callback for', stderr.getvalue()) - self.assertIn('doh!', stderr.getvalue()) - - - def test_repr(self): - self.assertRegex(repr(PENDING_FUTURE), - '') - self.assertRegex(repr(RUNNING_FUTURE), - '') - self.assertRegex(repr(CANCELLED_FUTURE), - '') - self.assertRegex(repr(CANCELLED_AND_NOTIFIED_FUTURE), - '') - self.assertRegex( - repr(EXCEPTION_FUTURE), - '') - self.assertRegex( - repr(SUCCESSFUL_FUTURE), - '') - - - def test_cancel(self): - f1 = create_future(state=PENDING) - f2 = create_future(state=RUNNING) - f3 = create_future(state=CANCELLED) - f4 = create_future(state=CANCELLED_AND_NOTIFIED) - f5 = create_future(state=FINISHED, exception=OSError()) - f6 = create_future(state=FINISHED, result=5) - - self.assertTrue(f1.cancel()) - self.assertEqual(f1._state, CANCELLED) - - self.assertFalse(f2.cancel()) - self.assertEqual(f2._state, RUNNING) - - self.assertTrue(f3.cancel()) - self.assertEqual(f3._state, CANCELLED) - - self.assertTrue(f4.cancel()) - self.assertEqual(f4._state, CANCELLED_AND_NOTIFIED) - - self.assertFalse(f5.cancel()) - self.assertEqual(f5._state, FINISHED) - - self.assertFalse(f6.cancel()) - self.assertEqual(f6._state, FINISHED) - - def test_cancelled(self): - self.assertFalse(PENDING_FUTURE.cancelled()) - self.assertFalse(RUNNING_FUTURE.cancelled()) - self.assertTrue(CANCELLED_FUTURE.cancelled()) - self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.cancelled()) - self.assertFalse(EXCEPTION_FUTURE.cancelled()) - self.assertFalse(SUCCESSFUL_FUTURE.cancelled()) - - def test_done(self): - self.assertFalse(PENDING_FUTURE.done()) - self.assertFalse(RUNNING_FUTURE.done()) - self.assertTrue(CANCELLED_FUTURE.done()) - self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.done()) - self.assertTrue(EXCEPTION_FUTURE.done()) - self.assertTrue(SUCCESSFUL_FUTURE.done()) - - def test_running(self): - self.assertFalse(PENDING_FUTURE.running()) - self.assertTrue(RUNNING_FUTURE.running()) - self.assertFalse(CANCELLED_FUTURE.running()) - self.assertFalse(CANCELLED_AND_NOTIFIED_FUTURE.running()) - self.assertFalse(EXCEPTION_FUTURE.running()) - self.assertFalse(SUCCESSFUL_FUTURE.running()) - - def test_result_with_timeout(self): - self.assertRaises(futures.TimeoutError, - PENDING_FUTURE.result, timeout=0) - self.assertRaises(futures.TimeoutError, - RUNNING_FUTURE.result, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_FUTURE.result, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_AND_NOTIFIED_FUTURE.result, timeout=0) - self.assertRaises(OSError, EXCEPTION_FUTURE.result, timeout=0) - self.assertEqual(SUCCESSFUL_FUTURE.result(timeout=0), 42) - - def test_result_with_success(self): - # TODO(brian@sweetapp.com): This test is timing dependent. - def notification(): - # Wait until the main thread is waiting for the result. - time.sleep(1) - f1.set_result(42) - - f1 = create_future(state=PENDING) - t = threading.Thread(target=notification) - t.start() - - self.assertEqual(f1.result(timeout=5), 42) - t.join() - - def test_result_with_cancel(self): - # TODO(brian@sweetapp.com): This test is timing dependent. - def notification(): - # Wait until the main thread is waiting for the result. - time.sleep(1) - f1.cancel() - - f1 = create_future(state=PENDING) - t = threading.Thread(target=notification) - t.start() - - self.assertRaises(futures.CancelledError, - f1.result, timeout=support.SHORT_TIMEOUT) - t.join() - - def test_exception_with_timeout(self): - self.assertRaises(futures.TimeoutError, - PENDING_FUTURE.exception, timeout=0) - self.assertRaises(futures.TimeoutError, - RUNNING_FUTURE.exception, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_FUTURE.exception, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_AND_NOTIFIED_FUTURE.exception, timeout=0) - self.assertTrue(isinstance(EXCEPTION_FUTURE.exception(timeout=0), - OSError)) - self.assertEqual(SUCCESSFUL_FUTURE.exception(timeout=0), None) - - def test_exception_with_success(self): - def notification(): - # Wait until the main thread is waiting for the exception. - time.sleep(1) - with f1._condition: - f1._state = FINISHED - f1._exception = OSError() - f1._condition.notify_all() - - f1 = create_future(state=PENDING) - t = threading.Thread(target=notification) - t.start() - - self.assertTrue(isinstance(f1.exception(timeout=support.SHORT_TIMEOUT), OSError)) - t.join() - - def test_multiple_set_result(self): - f = create_future(state=PENDING) - f.set_result(1) - - with self.assertRaisesRegex( - futures.InvalidStateError, - 'FINISHED: ' - ): - f.set_result(2) - - self.assertTrue(f.done()) - self.assertEqual(f.result(), 1) - - def test_multiple_set_exception(self): - f = create_future(state=PENDING) - e = ValueError() - f.set_exception(e) - - with self.assertRaisesRegex( - futures.InvalidStateError, - 'FINISHED: ' - ): - f.set_exception(Exception()) - - self.assertEqual(f.exception(), e) - - -def setUpModule(): - unittest.addModuleCleanup(multiprocessing.util._cleanup_tests) - thread_info = threading_helper.threading_setup() - unittest.addModuleCleanup(threading_helper.threading_cleanup, *thread_info) - - -if __name__ == "__main__": - unittest.main() diff --git a/mingw64/lib/python3.11/test/test_context.py b/mingw64/lib/python3.11/test/test_context.py index b1aece4f5c9..dc6856509a4 100644 --- a/mingw64/lib/python3.11/test/test_context.py +++ b/mingw64/lib/python3.11/test/test_context.py @@ -6,6 +6,7 @@ import time import unittest import weakref +from test import support from test.support import threading_helper try: @@ -570,6 +571,7 @@ def test_hamt_collision_3(self): self.assertEqual({k.name for k in h.keys()}, {'C', 'D', 'E'}) + @support.requires_resource('cpu') def test_hamt_stress(self): COLLECTION_SIZE = 7000 TEST_ITERS_EVERY = 647 diff --git a/mingw64/lib/python3.11/test/test_cppext/__init__.py b/mingw64/lib/python3.11/test/test_cppext/__init__.py index 4ce29b7ff2c..37247e4ac01 100644 --- a/mingw64/lib/python3.11/test/test_cppext/__init__.py +++ b/mingw64/lib/python3.11/test/test_cppext/__init__.py @@ -15,9 +15,11 @@ @support.requires_subprocess() class TestCPPExt(unittest.TestCase): + @support.requires_resource('cpu') def test_build_cpp11(self): self.check_build(False, '_testcpp11ext') + @support.requires_resource('cpu') def test_build_cpp03(self): self.check_build(True, '_testcpp03ext') diff --git a/mingw32/lib/python3.11/test/test_dataclasses.py b/mingw64/lib/python3.11/test/test_dataclasses/__init__.py similarity index 99% rename from mingw32/lib/python3.11/test/test_dataclasses.py rename to mingw64/lib/python3.11/test/test_dataclasses/__init__.py index 4714d0bca86..682f351c6bd 100644 --- a/mingw32/lib/python3.11/test/test_dataclasses.py +++ b/mingw64/lib/python3.11/test/test_dataclasses/__init__.py @@ -3568,10 +3568,10 @@ class C: self.assertEqual(C(10).x, 10) def test_classvar_module_level_import(self): - from test import dataclass_module_1 - from test import dataclass_module_1_str - from test import dataclass_module_2 - from test import dataclass_module_2_str + from test.test_dataclasses import dataclass_module_1 + from test.test_dataclasses import dataclass_module_1_str + from test.test_dataclasses import dataclass_module_2 + from test.test_dataclasses import dataclass_module_2_str for m in (dataclass_module_1, dataclass_module_1_str, dataclass_module_2, dataclass_module_2_str, @@ -3609,7 +3609,7 @@ def test_classvar_module_level_import(self): self.assertNotIn('not_iv4', c.__dict__) def test_text_annotations(self): - from test import dataclass_textanno + from test.test_dataclasses import dataclass_textanno self.assertEqual( get_type_hints(dataclass_textanno.Bar), diff --git a/mingw64/lib/python3.11/test/dataclass_module_1.py b/mingw64/lib/python3.11/test/test_dataclasses/dataclass_module_1.py similarity index 100% rename from mingw64/lib/python3.11/test/dataclass_module_1.py rename to mingw64/lib/python3.11/test/test_dataclasses/dataclass_module_1.py diff --git a/mingw64/lib/python3.11/test/dataclass_module_1_str.py b/mingw64/lib/python3.11/test/test_dataclasses/dataclass_module_1_str.py similarity index 100% rename from mingw64/lib/python3.11/test/dataclass_module_1_str.py rename to mingw64/lib/python3.11/test/test_dataclasses/dataclass_module_1_str.py diff --git a/mingw64/lib/python3.11/test/dataclass_module_2.py b/mingw64/lib/python3.11/test/test_dataclasses/dataclass_module_2.py similarity index 100% rename from mingw64/lib/python3.11/test/dataclass_module_2.py rename to mingw64/lib/python3.11/test/test_dataclasses/dataclass_module_2.py diff --git a/mingw64/lib/python3.11/test/dataclass_module_2_str.py b/mingw64/lib/python3.11/test/test_dataclasses/dataclass_module_2_str.py similarity index 100% rename from mingw64/lib/python3.11/test/dataclass_module_2_str.py rename to mingw64/lib/python3.11/test/test_dataclasses/dataclass_module_2_str.py diff --git a/mingw64/lib/python3.11/test/dataclass_textanno.py b/mingw64/lib/python3.11/test/test_dataclasses/dataclass_textanno.py similarity index 100% rename from mingw64/lib/python3.11/test/dataclass_textanno.py rename to mingw64/lib/python3.11/test/test_dataclasses/dataclass_textanno.py diff --git a/mingw64/lib/python3.11/test/test_descr.py b/mingw64/lib/python3.11/test/test_descr.py index f07d7d45965..e356624af04 100644 --- a/mingw64/lib/python3.11/test/test_descr.py +++ b/mingw64/lib/python3.11/test/test_descr.py @@ -1980,7 +1980,7 @@ def __getattr__(self, attr): ns = {} exec(code, ns) number_attrs = ns["number_attrs"] - # Warm up the the function for quickening (PEP 659) + # Warm up the function for quickening (PEP 659) for _ in range(30): self.assertEqual(number_attrs(Numbers()), list(range(280))) @@ -4453,6 +4453,7 @@ class Oops(object): o.whatever = Provoker(o) del o + @support.requires_resource('cpu') def test_wrapper_segfault(self): # SF 927248: deeply nested wrappers could cause stack overflow f = lambda:None diff --git a/mingw64/lib/python3.11/test/test_doctest.py b/mingw64/lib/python3.11/test/test_doctest.py index 00aeacddc12..e48d91fafed 100644 --- a/mingw64/lib/python3.11/test/test_doctest.py +++ b/mingw64/lib/python3.11/test/test_doctest.py @@ -742,15 +742,13 @@ class TestDocTestFinder(unittest.TestCase): def test_issue35753(self): # This import of `call` should trigger issue35753 when - # `support.run_doctest` is called due to unwrap failing, + # DocTestFinder.find() is called due to inspect.unwrap() failing, # however with a patched doctest this should succeed. from unittest.mock import call dummy_module = types.ModuleType("dummy") dummy_module.__dict__['inject_call'] = call - try: - support.run_doctest(dummy_module, verbosity=True) - except ValueError as e: - raise support.TestFailed("Doctest unwrap failed") from e + finder = doctest.DocTestFinder() + self.assertEqual(finder.find(dummy_module), []) def test_empty_namespace_package(self): pkg_name = 'doctest_empty_pkg' diff --git a/mingw64/lib/python3.11/test/test_eintr.py b/mingw64/lib/python3.11/test/test_eintr.py index 528147802ba..49b15f1a2db 100644 --- a/mingw64/lib/python3.11/test/test_eintr.py +++ b/mingw64/lib/python3.11/test/test_eintr.py @@ -9,6 +9,7 @@ class EINTRTests(unittest.TestCase): @unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") + @support.requires_resource('walltime') def test_all(self): # Run the tester in a sub-process, to make sure there is only one # thread (for reliable signal delivery). diff --git a/mingw64/lib/python3.11/test/test_email/test_email.py b/mingw64/lib/python3.11/test/test_email/test_email.py index 2bb651609f5..677f2094b83 100644 --- a/mingw64/lib/python3.11/test/test_email/test_email.py +++ b/mingw64/lib/python3.11/test/test_email/test_email.py @@ -39,6 +39,7 @@ from email import quoprimime from email import utils +from test import support from test.support import threading_helper from test.support.os_helper import unlink from test.test_email import openfile, TestEmailBase @@ -3342,6 +3343,7 @@ def test_getaddresses_header_obj(self): self.assertEqual(addrs[0][1], 'aperson@dom.ain') @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_make_msgid_collisions(self): # Test make_msgid uniqueness, even with multiple threads class MsgidsThread(Thread): diff --git a/mingw64/lib/python3.11/test/test_enum.py b/mingw64/lib/python3.11/test/test_enum.py index cc66875bde0..ed1c3a59ce4 100644 --- a/mingw64/lib/python3.11/test/test_enum.py +++ b/mingw64/lib/python3.11/test/test_enum.py @@ -322,6 +322,17 @@ def spam(cls): with self.assertRaises(AttributeError): del Season.SPRING.name + def test_bad_new_super(self): + with self.assertRaisesRegex( + TypeError, + 'has no members defined', + ): + class BadSuper(self.enum_type): + def __new__(cls, value): + obj = super().__new__(cls, value) + return obj + failed = 1 + def test_basics(self): TE = self.MainEnum if self.is_flag: diff --git a/mingw64/lib/python3.11/test/test_exceptions.py b/mingw64/lib/python3.11/test/test_exceptions.py index d7133adf058..6f34e29e42f 100644 --- a/mingw64/lib/python3.11/test/test_exceptions.py +++ b/mingw64/lib/python3.11/test/test_exceptions.py @@ -1304,6 +1304,7 @@ def g(): @cpython_only + @support.requires_resource('cpu') def test_trashcan_recursion(self): # See bpo-33930 diff --git a/mingw64/lib/python3.11/test/test_faulthandler.py b/mingw64/lib/python3.11/test/test_faulthandler.py index 8d106daaf65..0e03ee21288 100644 --- a/mingw64/lib/python3.11/test/test_faulthandler.py +++ b/mingw64/lib/python3.11/test/test_faulthandler.py @@ -676,6 +676,7 @@ def test_dump_traceback_later_fd(self): with tempfile.TemporaryFile('wb+') as fp: self.check_dump_traceback_later(fd=fp.fileno()) + @support.requires_resource('walltime') def test_dump_traceback_later_twice(self): self.check_dump_traceback_later(loops=2) diff --git a/mingw64/lib/python3.11/test/test_float.py b/mingw64/lib/python3.11/test/test_float.py index 304388e1f78..c6af0b92a73 100644 --- a/mingw64/lib/python3.11/test/test_float.py +++ b/mingw64/lib/python3.11/test/test_float.py @@ -734,8 +734,13 @@ def test_format_testfile(self): lhs, rhs = map(str.strip, line.split('->')) fmt, arg = lhs.split() - self.assertEqual(fmt % float(arg), rhs) - self.assertEqual(fmt % -float(arg), '-' + rhs) + f = float(arg) + self.assertEqual(fmt % f, rhs) + self.assertEqual(fmt % -f, '-' + rhs) + if fmt != '%r': + fmt2 = fmt[1:] + self.assertEqual(format(f, fmt2), rhs) + self.assertEqual(format(-f, fmt2), '-' + rhs) def test_issue5864(self): self.assertEqual(format(123.456, '.4'), '123.5') diff --git a/mingw64/lib/python3.11/test/test_frame.py b/mingw64/lib/python3.11/test/test_frame.py index 9cb2686f175..1e52164a6ba 100644 --- a/mingw64/lib/python3.11/test/test_frame.py +++ b/mingw64/lib/python3.11/test/test_frame.py @@ -317,7 +317,7 @@ def f(): sneaky_frame_object = None gc.enable() next(g) - # g.gi_frame should be the the frame object from the callback (the + # g.gi_frame should be the frame object from the callback (the # one that was *requested* second, but *created* first): self.assertIs(g.gi_frame, sneaky_frame_object) finally: diff --git a/mingw64/lib/python3.11/test/test_ftplib.py b/mingw64/lib/python3.11/test/test_ftplib.py index 082a90d46ba..7d6b12ffadc 100644 --- a/mingw64/lib/python3.11/test/test_ftplib.py +++ b/mingw64/lib/python3.11/test/test_ftplib.py @@ -34,7 +34,7 @@ DEFAULT_ENCODING = 'utf-8' # the dummy data returned by server over the data channel when # RETR, LIST, NLST, MLSD commands are issued -RETR_DATA = 'abcde12345\r\n' * 1000 + 'non-ascii char \xAE\r\n' +RETR_DATA = 'abcde\xB9\xB2\xB3\xA4\xA6\r\n' * 1000 LIST_DATA = 'foo\r\nbar\r\n non-ascii char \xAE\r\n' NLST_DATA = 'foo\r\nbar\r\n non-ascii char \xAE\r\n' MLSD_DATA = ("type=cdir;perm=el;unique==keVO1+ZF4; test\r\n" @@ -69,11 +69,11 @@ class DummyDTPHandler(asynchat.async_chat): def __init__(self, conn, baseclass): asynchat.async_chat.__init__(self, conn) self.baseclass = baseclass - self.baseclass.last_received_data = '' + self.baseclass.last_received_data = bytearray() self.encoding = baseclass.encoding def handle_read(self): - new_data = self.recv(1024).decode(self.encoding, 'replace') + new_data = self.recv(1024) self.baseclass.last_received_data += new_data def handle_close(self): @@ -109,7 +109,7 @@ def __init__(self, conn, encoding=DEFAULT_ENCODING): self.in_buffer = [] self.dtp = None self.last_received_cmd = None - self.last_received_data = '' + self.last_received_data = bytearray() self.next_response = '' self.next_data = None self.rest = None @@ -592,19 +592,17 @@ def test_abort(self): self.client.abort() def test_retrbinary(self): - def callback(data): - received.append(data.decode(self.client.encoding)) received = [] - self.client.retrbinary('retr', callback) - self.check_data(''.join(received), RETR_DATA) + self.client.retrbinary('retr', received.append) + self.check_data(b''.join(received), + RETR_DATA.encode(self.client.encoding)) def test_retrbinary_rest(self): - def callback(data): - received.append(data.decode(self.client.encoding)) for rest in (0, 10, 20): received = [] - self.client.retrbinary('retr', callback, rest=rest) - self.check_data(''.join(received), RETR_DATA[rest:]) + self.client.retrbinary('retr', received.append, rest=rest) + self.check_data(b''.join(received), + RETR_DATA[rest:].encode(self.client.encoding)) def test_retrlines(self): received = [] @@ -614,7 +612,8 @@ def test_retrlines(self): def test_storbinary(self): f = io.BytesIO(RETR_DATA.encode(self.client.encoding)) self.client.storbinary('stor', f) - self.check_data(self.server.handler_instance.last_received_data, RETR_DATA) + self.check_data(self.server.handler_instance.last_received_data, + RETR_DATA.encode(self.server.encoding)) # test new callback arg flag = [] f.seek(0) @@ -633,7 +632,8 @@ def test_storlines(self): data = RETR_DATA.replace('\r\n', '\n').encode(self.client.encoding) f = io.BytesIO(data) self.client.storlines('stor', f) - self.check_data(self.server.handler_instance.last_received_data, RETR_DATA) + self.check_data(self.server.handler_instance.last_received_data, + RETR_DATA.encode(self.server.encoding)) # test new callback arg flag = [] f.seek(0) @@ -651,7 +651,7 @@ def test_nlst(self): def test_dir(self): l = [] - self.client.dir(lambda x: l.append(x)) + self.client.dir(l.append) self.assertEqual(''.join(l), LIST_DATA.replace('\r\n', '')) def test_mlsd(self): @@ -891,12 +891,10 @@ def test_makepasv(self): def test_transfer(self): def retr(): - def callback(data): - received.append(data.decode(self.client.encoding)) received = [] - self.client.retrbinary('retr', callback) - self.assertEqual(len(''.join(received)), len(RETR_DATA)) - self.assertEqual(''.join(received), RETR_DATA) + self.client.retrbinary('retr', received.append) + self.assertEqual(b''.join(received), + RETR_DATA.encode(self.client.encoding)) self.client.set_pasv(True) retr() self.client.set_pasv(False) diff --git a/mingw64/lib/python3.11/test/test_functools.py b/mingw64/lib/python3.11/test/test_functools.py index 382e7dbffdd..fb6e1860ac1 100644 --- a/mingw64/lib/python3.11/test/test_functools.py +++ b/mingw64/lib/python3.11/test/test_functools.py @@ -27,10 +27,16 @@ py_functools = import_helper.import_fresh_module('functools', blocked=['_functools']) -c_functools = import_helper.import_fresh_module('functools') +c_functools = import_helper.import_fresh_module('functools', + fresh=['_functools']) decimal = import_helper.import_fresh_module('decimal', fresh=['_decimal']) +_partial_types = [py_functools.partial] +if c_functools: + _partial_types.append(c_functools.partial) + + @contextlib.contextmanager def replaced_module(name, replacement): original_module = sys.modules[name] @@ -202,7 +208,7 @@ def test_repr(self): kwargs = {'a': object(), 'b': object()} kwargs_reprs = ['a={a!r}, b={b!r}'.format_map(kwargs), 'b={b!r}, a={a!r}'.format_map(kwargs)] - if self.partial in (c_functools.partial, py_functools.partial): + if self.partial in _partial_types: name = 'functools.partial' else: name = self.partial.__name__ @@ -224,7 +230,7 @@ def test_repr(self): for kwargs_repr in kwargs_reprs]) def test_recursive_repr(self): - if self.partial in (c_functools.partial, py_functools.partial): + if self.partial in _partial_types: name = 'functools.partial' else: name = self.partial.__name__ @@ -251,7 +257,7 @@ def test_recursive_repr(self): f.__setstate__((capture, (), {}, {})) def test_pickle(self): - with self.AllowPickle(): + with replaced_module('functools', self.module): f = self.partial(signature, ['asdf'], bar=[True]) f.attr = [] for proto in range(pickle.HIGHEST_PROTOCOL + 1): @@ -334,7 +340,7 @@ def test_setstate_subclasses(self): self.assertIs(type(r[0]), tuple) def test_recursive_pickle(self): - with self.AllowPickle(): + with replaced_module('functools', self.module): f = self.partial(capture) f.__setstate__((f, (), {}, {})) try: @@ -388,14 +394,9 @@ def __getitem__(self, key): @unittest.skipUnless(c_functools, 'requires the C _functools module') class TestPartialC(TestPartial, unittest.TestCase): if c_functools: + module = c_functools partial = c_functools.partial - class AllowPickle: - def __enter__(self): - return self - def __exit__(self, type, value, tb): - return False - def test_attributes_unwritable(self): # attributes should not be writable p = self.partial(capture, 1, 2, a=10, b=20) @@ -438,15 +439,9 @@ def __str__(self): class TestPartialPy(TestPartial, unittest.TestCase): + module = py_functools partial = py_functools.partial - class AllowPickle: - def __init__(self): - self._cm = replaced_module("functools", py_functools) - def __enter__(self): - return self._cm.__enter__() - def __exit__(self, type, value, tb): - return self._cm.__exit__(type, value, tb) if c_functools: class CPartialSubclass(c_functools.partial): @@ -1860,9 +1855,10 @@ def test_staticmethod(x): def py_cached_func(x, y): return 3 * x + y -@c_functools.lru_cache() -def c_cached_func(x, y): - return 3 * x + y +if c_functools: + @c_functools.lru_cache() + def c_cached_func(x, y): + return 3 * x + y class TestLRUPy(TestLRU, unittest.TestCase): @@ -1879,18 +1875,20 @@ def cached_staticmeth(x, y): return 3 * x + y +@unittest.skipUnless(c_functools, 'requires the C _functools module') class TestLRUC(TestLRU, unittest.TestCase): - module = c_functools - cached_func = c_cached_func, + if c_functools: + module = c_functools + cached_func = c_cached_func, - @module.lru_cache() - def cached_meth(self, x, y): - return 3 * x + y + @module.lru_cache() + def cached_meth(self, x, y): + return 3 * x + y - @staticmethod - @module.lru_cache() - def cached_staticmeth(x, y): - return 3 * x + y + @staticmethod + @module.lru_cache() + def cached_staticmeth(x, y): + return 3 * x + y class TestSingleDispatch(unittest.TestCase): diff --git a/mingw64/lib/python3.11/test/test_future_stmt/__init__.py b/mingw64/lib/python3.11/test/test_future_stmt/__init__.py new file mode 100644 index 00000000000..f2a39a3fe29 --- /dev/null +++ b/mingw64/lib/python3.11/test/test_future_stmt/__init__.py @@ -0,0 +1,6 @@ +import os +from test import support + + +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/mingw64/lib/python3.11/test/badsyntax_future10.py b/mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future10.py similarity index 100% rename from mingw64/lib/python3.11/test/badsyntax_future10.py rename to mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future10.py diff --git a/mingw64/lib/python3.11/test/badsyntax_future3.py b/mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future3.py similarity index 100% rename from mingw64/lib/python3.11/test/badsyntax_future3.py rename to mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future3.py diff --git a/mingw64/lib/python3.11/test/badsyntax_future4.py b/mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future4.py similarity index 100% rename from mingw64/lib/python3.11/test/badsyntax_future4.py rename to mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future4.py diff --git a/mingw64/lib/python3.11/test/badsyntax_future5.py b/mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future5.py similarity index 100% rename from mingw64/lib/python3.11/test/badsyntax_future5.py rename to mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future5.py diff --git a/mingw64/lib/python3.11/test/badsyntax_future6.py b/mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future6.py similarity index 100% rename from mingw64/lib/python3.11/test/badsyntax_future6.py rename to mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future6.py diff --git a/mingw64/lib/python3.11/test/badsyntax_future7.py b/mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future7.py similarity index 100% rename from mingw64/lib/python3.11/test/badsyntax_future7.py rename to mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future7.py diff --git a/mingw64/lib/python3.11/test/badsyntax_future8.py b/mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future8.py similarity index 100% rename from mingw64/lib/python3.11/test/badsyntax_future8.py rename to mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future8.py diff --git a/mingw64/lib/python3.11/test/badsyntax_future9.py b/mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future9.py similarity index 100% rename from mingw64/lib/python3.11/test/badsyntax_future9.py rename to mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future9.py diff --git a/mingw64/lib/python3.11/test/future_test1.py b/mingw64/lib/python3.11/test/test_future_stmt/future_test1.py similarity index 100% rename from mingw64/lib/python3.11/test/future_test1.py rename to mingw64/lib/python3.11/test/test_future_stmt/future_test1.py diff --git a/mingw64/lib/python3.11/test/future_test2.py b/mingw64/lib/python3.11/test/test_future_stmt/future_test2.py similarity index 100% rename from mingw64/lib/python3.11/test/future_test2.py rename to mingw64/lib/python3.11/test/test_future_stmt/future_test2.py diff --git a/mingw32/lib/python3.11/test/test_future.py b/mingw64/lib/python3.11/test/test_future_stmt/test_future.py similarity index 91% rename from mingw32/lib/python3.11/test/test_future.py rename to mingw64/lib/python3.11/test/test_future_stmt/test_future.py index c3e8420d667..13cee3ff6e4 100644 --- a/mingw32/lib/python3.11/test/test_future.py +++ b/mingw64/lib/python3.11/test/test_future_stmt/test_future.py @@ -25,57 +25,71 @@ def check_syntax_error(self, err, basename, lineno, offset=1): self.assertEqual(err.offset, offset) def test_future1(self): - with import_helper.CleanImport('future_test1'): - from test import future_test1 + with import_helper.CleanImport('test.test_future_stmt.future_test1'): + from test.test_future_stmt import future_test1 self.assertEqual(future_test1.result, 6) def test_future2(self): - with import_helper.CleanImport('future_test2'): - from test import future_test2 + with import_helper.CleanImport('test.test_future_stmt.future_test2'): + from test.test_future_stmt import future_test2 self.assertEqual(future_test2.result, 6) - def test_future3(self): - with import_helper.CleanImport('test_future3'): - from test import test_future3 + def test_future_single_import(self): + with import_helper.CleanImport( + 'test.test_future_stmt.test_future_single_import', + ): + from test.test_future_stmt import test_future_single_import + + def test_future_multiple_imports(self): + with import_helper.CleanImport( + 'test.test_future_stmt.test_future_multiple_imports', + ): + from test.test_future_stmt import test_future_multiple_imports + + def test_future_multiple_features(self): + with import_helper.CleanImport( + "test.test_future_stmt.test_future_multiple_features", + ): + from test.test_future_stmt import test_future_multiple_features def test_badfuture3(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future3 + from test.test_future_stmt import badsyntax_future3 self.check_syntax_error(cm.exception, "badsyntax_future3", 3) def test_badfuture4(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future4 + from test.test_future_stmt import badsyntax_future4 self.check_syntax_error(cm.exception, "badsyntax_future4", 3) def test_badfuture5(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future5 + from test.test_future_stmt import badsyntax_future5 self.check_syntax_error(cm.exception, "badsyntax_future5", 4) def test_badfuture6(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future6 + from test.test_future_stmt import badsyntax_future6 self.check_syntax_error(cm.exception, "badsyntax_future6", 3) def test_badfuture7(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future7 + from test.test_future_stmt import badsyntax_future7 self.check_syntax_error(cm.exception, "badsyntax_future7", 3, 53) def test_badfuture8(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future8 + from test.test_future_stmt import badsyntax_future8 self.check_syntax_error(cm.exception, "badsyntax_future8", 3) def test_badfuture9(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future9 + from test.test_future_stmt import badsyntax_future9 self.check_syntax_error(cm.exception, "badsyntax_future9", 3) def test_badfuture10(self): with self.assertRaises(SyntaxError) as cm: - from test import badsyntax_future10 + from test.test_future_stmt import badsyntax_future10 self.check_syntax_error(cm.exception, "badsyntax_future10", 3) def test_ensure_flags_dont_clash(self): @@ -113,10 +127,6 @@ def test_parserhack(self): else: self.fail("syntax error didn't occur") - def test_multiple_features(self): - with import_helper.CleanImport("test.test_future5"): - from test import test_future5 - def test_unicode_literals_exec(self): scope = {} exec("from __future__ import unicode_literals; x = ''", {}, scope) diff --git a/mingw64/lib/python3.11/test/test___future__.py b/mingw64/lib/python3.11/test/test_future_stmt/test_future_flags.py similarity index 100% rename from mingw64/lib/python3.11/test/test___future__.py rename to mingw64/lib/python3.11/test/test_future_stmt/test_future_flags.py diff --git a/mingw64/lib/python3.11/test/test_future5.py b/mingw64/lib/python3.11/test/test_future_stmt/test_future_multiple_features.py similarity index 100% rename from mingw64/lib/python3.11/test/test_future5.py rename to mingw64/lib/python3.11/test/test_future_stmt/test_future_multiple_features.py diff --git a/mingw64/lib/python3.11/test/test_future4.py b/mingw64/lib/python3.11/test/test_future_stmt/test_future_multiple_imports.py similarity index 100% rename from mingw64/lib/python3.11/test/test_future4.py rename to mingw64/lib/python3.11/test/test_future_stmt/test_future_multiple_imports.py diff --git a/mingw64/lib/python3.11/test/test_future3.py b/mingw64/lib/python3.11/test/test_future_stmt/test_future_single_import.py similarity index 100% rename from mingw64/lib/python3.11/test/test_future3.py rename to mingw64/lib/python3.11/test/test_future_stmt/test_future_single_import.py diff --git a/mingw64/lib/python3.11/test/test_gdb.py b/mingw64/lib/python3.11/test/test_gdb.py index 0f39b8f4571..5d042a45587 100644 --- a/mingw64/lib/python3.11/test/test_gdb.py +++ b/mingw64/lib/python3.11/test/test_gdb.py @@ -55,10 +55,6 @@ def get_gdb_version(): if not sysconfig.is_python_build(): raise unittest.SkipTest("test_gdb only works on source builds at the moment.") -if 'Clang' in platform.python_compiler() and sys.platform == 'darwin': - raise unittest.SkipTest("test_gdb doesn't work correctly when python is" - " built with LLVM clang") - if ((sysconfig.get_config_var('PGO_PROF_USE_FLAG') or 'xxx') in (sysconfig.get_config_var('PY_CORE_CFLAGS') or '')): raise unittest.SkipTest("test_gdb is not reliable on PGO builds") @@ -247,6 +243,17 @@ def get_stack_trace(self, source=None, script=None, for pattern in ( '(frame information optimized out)', 'Unable to read information on python frame', + # gh-91960: On Python built with "clang -Og", gdb gets + # "frame=" for _PyEval_EvalFrameDefault() parameter + '(unable to read python frame information)', + # gh-104736: On Python built with "clang -Og" on ppc64le, + # "py-bt" displays a truncated or not traceback, but "where" + # logs this error message: + 'Backtrace stopped: frame did not save the PC', + # gh-104736: When "bt" command displays something like: + # "#1 0x0000000000000000 in ?? ()", the traceback is likely + # truncated or wrong. + ' ?? ()', ): if pattern in out: raise unittest.SkipTest(f"{pattern!r} found in gdb output") @@ -317,6 +324,7 @@ def assertGdbRepr(self, val, exp_repr=None): ('%r did not equal expected %r; full output was:\n%s' % (gdb_repr, exp_repr, gdb_output))) + @support.requires_resource('cpu') def test_int(self): 'Verify the pretty-printing of various int values' self.assertGdbRepr(42) @@ -343,6 +351,7 @@ def test_lists(self): self.assertGdbRepr([]) self.assertGdbRepr(list(range(5))) + @support.requires_resource('cpu') def test_bytes(self): 'Verify the pretty-printing of bytes' self.assertGdbRepr(b'') @@ -357,6 +366,7 @@ def test_bytes(self): self.assertGdbRepr(bytes([b for b in range(255)])) + @support.requires_resource('cpu') def test_strings(self): 'Verify the pretty-printing of unicode strings' # We cannot simply call locale.getpreferredencoding() here, @@ -407,6 +417,7 @@ def test_tuples(self): self.assertGdbRepr((1,), '(1,)') self.assertGdbRepr(('foo', 'bar', 'baz')) + @support.requires_resource('cpu') def test_sets(self): 'Verify the pretty-printing of sets' if (gdb_major_version, gdb_minor_version) < (7, 3): @@ -425,6 +436,7 @@ def test_sets(self): id(s)''') self.assertEqual(gdb_repr, "{'b'}") + @support.requires_resource('cpu') def test_frozensets(self): 'Verify the pretty-printing of frozensets' if (gdb_major_version, gdb_minor_version) < (7, 3): @@ -828,6 +840,7 @@ def test_bt_full(self): @unittest.skipIf(python_is_optimized(), "Python was compiled with optimizations") + @support.requires_resource('cpu') def test_threads(self): 'Verify that "py-bt" indicates threads that are waiting for the GIL' cmd = ''' @@ -889,6 +902,7 @@ def test_gc(self): @unittest.skipIf(python_is_optimized(), "Python was compiled with optimizations") + @support.requires_resource('cpu') # Some older versions of gdb will fail with # "Cannot find new threads: generic error" # unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround diff --git a/mingw64/lib/python3.11/test/test_getopt.py b/mingw64/lib/python3.11/test/test_getopt.py index 64b9ce01e05..e1a66898136 100644 --- a/mingw64/lib/python3.11/test/test_getopt.py +++ b/mingw64/lib/python3.11/test/test_getopt.py @@ -1,8 +1,8 @@ # test_getopt.py # David Goodger 2000-08-19 -from test.support import verbose, run_doctest from test.support.os_helper import EnvironmentVarGuard +import doctest import unittest import getopt @@ -134,48 +134,49 @@ def test_gnu_getopt(self): self.assertEqual(opts, [('-a', '')]) self.assertEqual(args, ['arg1', '-b', '1', '--alpha', '--beta=2']) - def test_libref_examples(self): - s = """ - Examples from the Library Reference: Doc/lib/libgetopt.tex + def test_issue4629(self): + longopts, shortopts = getopt.getopt(['--help='], '', ['help=']) + self.assertEqual(longopts, [('--help', '')]) + longopts, shortopts = getopt.getopt(['--help=x'], '', ['help=']) + self.assertEqual(longopts, [('--help', 'x')]) + self.assertRaises(getopt.GetoptError, getopt.getopt, ['--help='], '', ['help']) - An example using only Unix style options: +def test_libref_examples(): + """ + Examples from the Library Reference: Doc/lib/libgetopt.tex + An example using only Unix style options: - >>> import getopt - >>> args = '-a -b -cfoo -d bar a1 a2'.split() - >>> args - ['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2'] - >>> optlist, args = getopt.getopt(args, 'abc:d:') - >>> optlist - [('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')] - >>> args - ['a1', 'a2'] - Using long option names is equally easy: + >>> import getopt + >>> args = '-a -b -cfoo -d bar a1 a2'.split() + >>> args + ['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2'] + >>> optlist, args = getopt.getopt(args, 'abc:d:') + >>> optlist + [('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')] + >>> args + ['a1', 'a2'] + Using long option names is equally easy: - >>> s = '--condition=foo --testing --output-file abc.def -x a1 a2' - >>> args = s.split() - >>> args - ['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2'] - >>> optlist, args = getopt.getopt(args, 'x', [ - ... 'condition=', 'output-file=', 'testing']) - >>> optlist - [('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')] - >>> args - ['a1', 'a2'] - """ - import types - m = types.ModuleType("libreftest", s) - run_doctest(m, verbose) + >>> s = '--condition=foo --testing --output-file abc.def -x a1 a2' + >>> args = s.split() + >>> args + ['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2'] + >>> optlist, args = getopt.getopt(args, 'x', [ + ... 'condition=', 'output-file=', 'testing']) + >>> optlist + [('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')] + >>> args + ['a1', 'a2'] + """ + +def load_tests(loader, tests, pattern): + tests.addTest(doctest.DocTestSuite()) + return tests - def test_issue4629(self): - longopts, shortopts = getopt.getopt(['--help='], '', ['help=']) - self.assertEqual(longopts, [('--help', '')]) - longopts, shortopts = getopt.getopt(['--help=x'], '', ['help=']) - self.assertEqual(longopts, [('--help', 'x')]) - self.assertRaises(getopt.GetoptError, getopt.getopt, ['--help='], '', ['help']) if __name__ == "__main__": unittest.main() diff --git a/mingw64/lib/python3.11/test/test_grammar.py b/mingw64/lib/python3.11/test/test_grammar.py index bcd8d584b0f..a00280b184e 100644 --- a/mingw64/lib/python3.11/test/test_grammar.py +++ b/mingw64/lib/python3.11/test/test_grammar.py @@ -13,10 +13,9 @@ # different import patterns to check that __annotations__ does not interfere # with import machinery -import test.ann_module as ann_module +import test.typinganndata.ann_module as ann_module import typing -from collections import ChainMap -from test import ann_module2 +from test.typinganndata import ann_module2 import test # These are shared with test_tokenize and other test modules. @@ -238,6 +237,10 @@ def check(test, error=False): check(f"[{num}for x in ()]") check(f"{num}spam", error=True) + # gh-88943: Invalid non-ASCII character following a numerical literal. + with self.assertRaisesRegex(SyntaxError, r"invalid character 'â„' \(U\+2044\)"): + compile(f"{num}â„7", "", "eval") + with warnings.catch_warnings(): warnings.filterwarnings('ignore', '"is" with a literal', SyntaxWarning) @@ -355,6 +358,11 @@ def test_var_annot_syntax_errors(self): check_syntax_error(self, "x: int: str") check_syntax_error(self, "def f():\n" " nonlocal x: int\n") + check_syntax_error(self, "def f():\n" + " global x: int\n") + check_syntax_error(self, "x: int = y = 1") + check_syntax_error(self, "z = w: int = 1") + check_syntax_error(self, "x: int = y: int = 1") # AST pass check_syntax_error(self, "[x, 0]: int\n") check_syntax_error(self, "f(): int\n") @@ -368,6 +376,12 @@ def test_var_annot_syntax_errors(self): check_syntax_error(self, "def f():\n" " global x\n" " x: int\n") + check_syntax_error(self, "def f():\n" + " x: int\n" + " nonlocal x\n") + check_syntax_error(self, "def f():\n" + " nonlocal x\n" + " x: int\n") def test_var_annot_basic_semantics(self): # execution order @@ -457,7 +471,7 @@ def test_var_annot_module_semantics(self): def test_var_annot_in_module(self): # check that functions fail the same way when executed # outside of module where they were defined - ann_module3 = import_helper.import_fresh_module("test.ann_module3") + ann_module3 = import_helper.import_fresh_module("test.typinganndata.ann_module3") with self.assertRaises(NameError): ann_module3.f_bad_ann() with self.assertRaises(NameError): diff --git a/mingw64/lib/python3.11/test/test_httplib.py b/mingw64/lib/python3.11/test/test_httplib.py index acae0127a13..47dbf08f370 100644 --- a/mingw64/lib/python3.11/test/test_httplib.py +++ b/mingw64/lib/python3.11/test/test_httplib.py @@ -1911,6 +1911,7 @@ def test_networked_good_cert(self): h.close() self.assertIn('nginx', server_string) + @support.requires_resource('walltime') def test_networked_bad_cert(self): # We feed a "CA" cert that is unrelated to the server's cert import ssl diff --git a/mingw64/lib/python3.11/test/test_imaplib.py b/mingw64/lib/python3.11/test/test_imaplib.py index ed26fa16d6e..f097ba68154 100644 --- a/mingw64/lib/python3.11/test/test_imaplib.py +++ b/mingw64/lib/python3.11/test/test_imaplib.py @@ -11,7 +11,7 @@ import socket from test.support import (verbose, - run_with_tz, run_with_locale, cpython_only, + run_with_tz, run_with_locale, cpython_only, requires_resource, requires_working_socket) from test.support import hashlib_helper from test.support import threading_helper @@ -77,6 +77,7 @@ def test_that_Time2Internaldate_returns_a_result(self): for t in self.timevalues(): imaplib.Time2Internaldate(t) + @socket_helper.skip_if_tcp_blackhole def test_imap4_host_default_value(self): # Check whether the IMAP4_PORT is truly unavailable. with socket.socket() as s: @@ -459,6 +460,7 @@ def test_simple_with_statement(self): with self.imap_class(*server.server_address): pass + @requires_resource('walltime') def test_imaplib_timeout_test(self): _, server = self._setup(SimpleIMAPHandler) addr = server.server_address[1] @@ -552,6 +554,7 @@ class NewIMAPSSLTests(NewIMAPTestsMixin, unittest.TestCase): imap_class = IMAP4_SSL server_class = SecureTCPServer + @requires_resource('walltime') def test_ssl_raises(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) self.assertEqual(ssl_context.verify_mode, ssl.CERT_REQUIRED) @@ -566,6 +569,7 @@ def test_ssl_raises(self): ssl_context=ssl_context) client.shutdown() + @requires_resource('walltime') def test_ssl_verified(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ssl_context.load_verify_locations(CAFILE) diff --git a/mingw64/lib/python3.11/test/test_imp.py b/mingw64/lib/python3.11/test/test_imp.py index 4bb03908fc2..4062afd7254 100644 --- a/mingw64/lib/python3.11/test/test_imp.py +++ b/mingw64/lib/python3.11/test/test_imp.py @@ -78,7 +78,7 @@ def test_find_module_encoding(self): with imp.find_module('module_' + mod, self.test_path)[0] as fd: self.assertEqual(fd.encoding, encoding) - path = [os.path.dirname(__file__)] + path = [os.path.join(os.path.dirname(__file__), 'tokenizedata')] with self.assertRaises(SyntaxError): imp.find_module('badsyntax_pep3120', path) @@ -203,9 +203,11 @@ def test_issue5604(self): os_helper.rmtree('__pycache__') def test_issue9319(self): - path = os.path.dirname(__file__) + path = os.path.join(os.path.dirname(__file__), "tokenizedata") self.assertRaises(SyntaxError, - imp.find_module, "badsyntax_pep3120", [path]) + imp.find_module, + "badsyntax_pep3120", + [path]) def test_load_from_source(self): # Verify that the imp module can correctly load and find .py files diff --git a/mingw64/lib/python3.11/test/test_import/__init__.py b/mingw64/lib/python3.11/test/test_import/__init__.py index 6e2606cdb05..131aebbd4e1 100644 --- a/mingw64/lib/python3.11/test/test_import/__init__.py +++ b/mingw64/lib/python3.11/test/test_import/__init__.py @@ -24,9 +24,10 @@ STDLIB_DIR, is_jython, swap_attr, swap_item, cpython_only, is_emscripten, is_wasi) from test.support.import_helper import ( - forget, make_legacy_pyc, unlink, unload, DirsOnSysPath, CleanImport) + forget, make_legacy_pyc, unlink, unload, ready_to_import, + DirsOnSysPath, CleanImport) from test.support.os_helper import ( - TESTFN, rmtree, temp_umask, TESTFN_UNENCODABLE, temp_dir) + TESTFN, rmtree, temp_umask, TESTFN_UNENCODABLE) from test.support import script_helper from test.support import threading_helper from test.test_importlib.util import uncache @@ -46,27 +47,6 @@ def remove_files(name): rmtree('__pycache__') -@contextlib.contextmanager -def _ready_to_import(name=None, source=""): - # sets up a temporary directory and removes it - # creates the module file - # temporarily clears the module from sys.modules (if any) - # reverts or removes the module when cleaning up - name = name or "spam" - with temp_dir() as tempdir: - path = script_helper.make_script(tempdir, name, source) - old_module = sys.modules.pop(name, None) - try: - sys.path.insert(0, tempdir) - yield name, path - sys.path.remove(tempdir) - finally: - if old_module is not None: - sys.modules[name] = old_module - elif name in sys.modules: - del sys.modules[name] - - class ImportTests(unittest.TestCase): def setUp(self): @@ -130,7 +110,7 @@ def test_from_import_missing_attr_path_is_canonical(self): def test_from_import_star_invalid_type(self): import re - with _ready_to_import() as (name, path): + with ready_to_import() as (name, path): with open(path, 'w', encoding='utf-8') as f: f.write("__all__ = [b'invalid_type']") globals = {} @@ -139,7 +119,7 @@ def test_from_import_star_invalid_type(self): ): exec(f"from {name} import *", globals) self.assertNotIn(b"invalid_type", globals) - with _ready_to_import() as (name, path): + with ready_to_import() as (name, path): with open(path, 'w', encoding='utf-8') as f: f.write("globals()[b'invalid_type'] = object()") globals = {} @@ -550,7 +530,7 @@ class FilePermissionTests(unittest.TestCase): ) def test_creation_mode(self): mask = 0o022 - with temp_umask(mask), _ready_to_import() as (name, path): + with temp_umask(mask), ready_to_import() as (name, path): cached_path = importlib.util.cache_from_source(path) module = __import__(name) if not os.path.exists(cached_path): @@ -569,7 +549,7 @@ def test_creation_mode(self): def test_cached_mode_issue_2051(self): # permissions of .pyc should match those of .py, regardless of mask mode = 0o600 - with temp_umask(0o022), _ready_to_import() as (name, path): + with temp_umask(0o022), ready_to_import() as (name, path): cached_path = importlib.util.cache_from_source(path) os.chmod(path, mode) __import__(name) @@ -585,7 +565,7 @@ def test_cached_mode_issue_2051(self): @os_helper.skip_unless_working_chmod def test_cached_readonly(self): mode = 0o400 - with temp_umask(0o022), _ready_to_import() as (name, path): + with temp_umask(0o022), ready_to_import() as (name, path): cached_path = importlib.util.cache_from_source(path) os.chmod(path, mode) __import__(name) @@ -600,7 +580,7 @@ def test_cached_readonly(self): def test_pyc_always_writable(self): # Initially read-only .pyc files on Windows used to cause problems # with later updates, see issue #6074 for details - with _ready_to_import() as (name, path): + with ready_to_import() as (name, path): # Write a Python file, make it read-only and import it with open(path, 'w', encoding='utf-8') as f: f.write("x = 'original'\n") diff --git a/mingw64/lib/python3.11/test/test_importlib/test_locks.py b/mingw64/lib/python3.11/test/test_importlib/test_locks.py index 56d73c496e6..5549d5448ba 100644 --- a/mingw64/lib/python3.11/test/test_importlib/test_locks.py +++ b/mingw64/lib/python3.11/test/test_importlib/test_locks.py @@ -29,6 +29,8 @@ class ModuleLockAsRLockTests: test_timeout = None # _release_save() unsupported test_release_save_unacquired = None + # _recursion_count() unsupported + test_recursion_count = None # lock status in repr unsupported test_repr = None test_locked_repr = None diff --git a/mingw64/lib/python3.11/test/test_inspect.py b/mingw64/lib/python3.11/test/test_inspect.py index fb4cba05721..650d56e39c4 100644 --- a/mingw64/lib/python3.11/test/test_inspect.py +++ b/mingw64/lib/python3.11/test/test_inspect.py @@ -27,7 +27,7 @@ from test.support import cpython_only from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ -from test.support.import_helper import DirsOnSysPath +from test.support.import_helper import DirsOnSysPath, ready_to_import from test.support.os_helper import TESTFN from test.support.script_helper import assert_python_ok, assert_python_failure from test import inspect_fodder as mod @@ -37,8 +37,6 @@ from test import inspect_stringized_annotations from test import inspect_stringized_annotations_2 -from test.test_import import _ready_to_import - # Functions tested in this suite: # ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode, @@ -4353,7 +4351,7 @@ def func(*args, **kwargs): def test_base_class_have_text_signature(self): # see issue 43118 - from test.ann_module7 import BufferedReader + from test.typinganndata.ann_module7 import BufferedReader class MyBufferedReader(BufferedReader): """buffer reader class.""" @@ -4505,7 +4503,7 @@ def assertInspectEqual(self, path, source): def test_getsource_reload(self): # see issue 1218234 - with _ready_to_import('reload_bug', self.src_before) as (name, path): + with ready_to_import('reload_bug', self.src_before) as (name, path): module = importlib.import_module(name) self.assertInspectEqual(path, module) with open(path, 'w', encoding='utf-8') as src: diff --git a/mingw64/lib/python3.11/test/test_io.py b/mingw64/lib/python3.11/test/test_io.py index 79aa2da5862..e54a13c2d84 100644 --- a/mingw64/lib/python3.11/test/test_io.py +++ b/mingw64/lib/python3.11/test/test_io.py @@ -1459,8 +1459,8 @@ def test_read_all(self): self.assertEqual(b"abcdefg", bufio.read()) - @support.requires_resource('cpu') @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threads(self): try: # Write out many bytes with exactly the same number of 0's, @@ -1834,8 +1834,8 @@ def test_truncate_after_write(self): f.truncate() self.assertEqual(f.tell(), buffer_size + 2) - @support.requires_resource('cpu') @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threads(self): try: # Write out many bytes from many threads and test they were @@ -4380,10 +4380,12 @@ def run(): self.assertFalse(err.strip('.!')) @threading_helper.requires_working_threading() + @support.requires_resource('walltime') def test_daemon_threads_shutdown_stdout_deadlock(self): self.check_daemon_threads_shutdown_deadlock('stdout') @threading_helper.requires_working_threading() + @support.requires_resource('walltime') def test_daemon_threads_shutdown_stderr_deadlock(self): self.check_daemon_threads_shutdown_deadlock('stderr') @@ -4557,11 +4559,13 @@ def alarm_handler(sig, frame): os.close(r) @requires_alarm + @support.requires_resource('walltime') def test_interrupted_read_retry_buffered(self): self.check_interrupted_read_retry(lambda x: x.decode('latin1'), mode="rb") @requires_alarm + @support.requires_resource('walltime') def test_interrupted_read_retry_text(self): self.check_interrupted_read_retry(lambda x: x, mode="r", encoding="latin1") @@ -4635,10 +4639,12 @@ def alarm2(sig, frame): raise @requires_alarm + @support.requires_resource('walltime') def test_interrupted_write_retry_buffered(self): self.check_interrupted_write_retry(b"x", mode="wb") @requires_alarm + @support.requires_resource('walltime') def test_interrupted_write_retry_text(self): self.check_interrupted_write_retry("x", mode="w", encoding="latin1") diff --git a/mingw64/lib/python3.11/test/test_itertools.py b/mingw64/lib/python3.11/test/test_itertools.py index 311c2a3288d..0d0030e4160 100644 --- a/mingw64/lib/python3.11/test/test_itertools.py +++ b/mingw64/lib/python3.11/test/test_itertools.py @@ -2229,6 +2229,7 @@ def gen2(x): self.assertEqual(hist, [0,1]) @support.skip_if_pgo_task + @support.requires_resource('cpu') def test_long_chain_of_empty_iterables(self): # Make sure itertools.chain doesn't run into recursion limits when # dealing with long chains of empty iterables. Even with a high diff --git a/mingw64/lib/python3.11/test/test_largefile.py b/mingw64/lib/python3.11/test/test_largefile.py index 3c11c59baef..3b0930fe69e 100644 --- a/mingw64/lib/python3.11/test/test_largefile.py +++ b/mingw64/lib/python3.11/test/test_largefile.py @@ -8,7 +8,7 @@ import socket import shutil import threading -from test.support import requires, bigmemtest +from test.support import requires, bigmemtest, requires_resource from test.support import SHORT_TIMEOUT from test.support import socket_helper from test.support.os_helper import TESTFN, unlink @@ -173,6 +173,7 @@ class TestCopyfile(LargeFileTest, unittest.TestCase): # Exact required disk space would be (size * 2), but let's give it a # bit more tolerance. @skip_no_disk_space(TESTFN, size * 2.5) + @requires_resource('cpu') def test_it(self): # Internally shutil.copyfile() can use "fast copy" methods like # os.sendfile(). @@ -222,6 +223,7 @@ def run(sock): # Exact required disk space would be (size * 2), but let's give it a # bit more tolerance. @skip_no_disk_space(TESTFN, size * 2.5) + @requires_resource('cpu') def test_it(self): port = socket_helper.find_unused_port() with socket.create_server(("", port)) as sock: diff --git a/mingw64/lib/python3.11/test/test_logging.py b/mingw64/lib/python3.11/test/test_logging.py index f1f2b75fef8..55c5cd56581 100644 --- a/mingw64/lib/python3.11/test/test_logging.py +++ b/mingw64/lib/python3.11/test/test_logging.py @@ -631,6 +631,7 @@ def test_path_objects(self): support.is_emscripten, "Emscripten cannot fstat unlinked files." ) @threading_helper.requires_working_threading() + @support.requires_resource('walltime') def test_race(self): # Issue #14632 refers. def remove_loop(fname, tries): diff --git a/mingw64/lib/python3.11/test/test_lzma.py b/mingw64/lib/python3.11/test/test_lzma.py index 145c8cfced4..49042d7390b 100644 --- a/mingw64/lib/python3.11/test/test_lzma.py +++ b/mingw64/lib/python3.11/test/test_lzma.py @@ -352,10 +352,10 @@ def test_compressor_bigmem(self, size): @bigmemtest(size=_4G + 100, memuse=3) def test_decompressor_bigmem(self, size): lzd = LZMADecompressor() - blocksize = 10 * 1024 * 1024 + blocksize = min(10 * 1024 * 1024, size) block = random.randbytes(blocksize) try: - input = block * (size // blocksize + 1) + input = block * ((size-1) // blocksize + 1) cdata = lzma.compress(input) ddata = lzd.decompress(cdata) self.assertEqual(ddata, input) diff --git a/mingw64/lib/python3.11/test/test_mailcap.py b/mingw64/lib/python3.11/test/test_mailcap.py index 8185f4a7806..e80e34063b2 100644 --- a/mingw64/lib/python3.11/test/test_mailcap.py +++ b/mingw64/lib/python3.11/test/test_mailcap.py @@ -128,7 +128,6 @@ def test_subst(self): (["", "audio/*", "foo.txt"], ""), (["echo foo", "audio/*", "foo.txt"], "echo foo"), (["echo %s", "audio/*", "foo.txt"], "echo foo.txt"), - (["echo %t", "audio/*", "foo.txt"], None), (["echo %t", "audio/wav", "foo.txt"], "echo audio/wav"), (["echo \\%t", "audio/*", "foo.txt"], "echo %t"), (["echo foo", "audio/*", "foo.txt", plist], "echo foo"), @@ -211,9 +210,6 @@ def test_findmatch(self): ([c, "audio/basic"], {"key": "description", "filename": fname}, ('"An audio fragment"', audio_basic_entry)), - ([c, "audio/*"], - {"filename": fname}, - (None, None)), ([c, "audio/wav"], {"filename": fname}, ("/usr/local/bin/showaudio audio/wav", audio_entry)), @@ -246,6 +242,30 @@ def test_test(self): ] self._run_cases(cases) + def test_unsafe_mailcap_input(self): + with self.assertWarnsRegex(mailcap.UnsafeMailcapInput, + 'Refusing to substitute parameter.*' + 'into a shell command'): + unsafe_param = mailcap.subst("echo %{total}", + "audio/wav", + "foo.txt", + ["total=*"]) + self.assertEqual(unsafe_param, None) + + with self.assertWarnsRegex(mailcap.UnsafeMailcapInput, + 'Refusing to substitute MIME type' + '.*into a shell'): + unsafe_mimetype = mailcap.subst("echo %t", "audio/*", "foo.txt") + self.assertEqual(unsafe_mimetype, None) + + with self.assertWarnsRegex(mailcap.UnsafeMailcapInput, + 'Refusing to use mailcap with filename.*' + 'Use a safe temporary filename.'): + unsafe_filename = mailcap.findmatch(MAILCAPDICT, + "audio/wav", + filename="foo*.txt") + self.assertEqual(unsafe_filename, (None, None)) + def _run_cases(self, cases): for c in cases: self.assertEqual(mailcap.findmatch(*c[0], **c[1]), c[2]) diff --git a/mingw64/lib/python3.11/test/test_mmap.py b/mingw64/lib/python3.11/test/test_mmap.py index bab86860089..dfcf3039422 100644 --- a/mingw64/lib/python3.11/test/test_mmap.py +++ b/mingw64/lib/python3.11/test/test_mmap.py @@ -255,10 +255,15 @@ def test_access_parameter(self): # Try writing with PROT_EXEC and without PROT_WRITE prot = mmap.PROT_READ | getattr(mmap, 'PROT_EXEC', 0) with open(TESTFN, "r+b") as f: - m = mmap.mmap(f.fileno(), mapsize, prot=prot) - self.assertRaises(TypeError, m.write, b"abcdef") - self.assertRaises(TypeError, m.write_byte, 0) - m.close() + try: + m = mmap.mmap(f.fileno(), mapsize, prot=prot) + except PermissionError: + # on macOS 14, PROT_READ | PROT_EXEC is not allowed + pass + else: + self.assertRaises(TypeError, m.write, b"abcdef") + self.assertRaises(TypeError, m.write_byte, 0) + m.close() def test_bad_file_desc(self): # Try opening a bad file descriptor... diff --git a/mingw64/lib/python3.11/test/test_module/__init__.py b/mingw64/lib/python3.11/test/test_module/__init__.py index 87d1a8e3d6c..c2bca45bb60 100644 --- a/mingw64/lib/python3.11/test/test_module/__init__.py +++ b/mingw64/lib/python3.11/test/test_module/__init__.py @@ -326,7 +326,9 @@ def test_annotations_getset_raises(self): del foo.__annotations__ def test_annotations_are_created_correctly(self): - ann_module4 = import_helper.import_fresh_module('test.ann_module4') + ann_module4 = import_helper.import_fresh_module( + 'test.typinganndata.ann_module4', + ) self.assertTrue("__annotations__" in ann_module4.__dict__) del ann_module4.__annotations__ self.assertFalse("__annotations__" in ann_module4.__dict__) diff --git a/mingw64/lib/python3.11/test/test_multibytecodec.py b/mingw64/lib/python3.11/test/test_multibytecodec.py index cf8bb5e3a05..6451df14696 100644 --- a/mingw64/lib/python3.11/test/test_multibytecodec.py +++ b/mingw64/lib/python3.11/test/test_multibytecodec.py @@ -363,6 +363,7 @@ def test_iso2022_jp_g0(self): e = '\u3406'.encode(encoding) self.assertFalse(any(x > 0x80 for x in e)) + @support.requires_resource('cpu') def test_bug1572832(self): for x in range(0x10000, 0x110000): # Any ISO 2022 codec will cause the segfault diff --git a/mingw64/lib/python3.11/test/test_multiprocessing_fork.py b/mingw64/lib/python3.11/test/test_multiprocessing_fork.py deleted file mode 100644 index 5000edb7c5c..00000000000 --- a/mingw64/lib/python3.11/test/test_multiprocessing_fork.py +++ /dev/null @@ -1,19 +0,0 @@ -import unittest -import test._test_multiprocessing - -import sys -from test import support - -if support.PGO: - raise unittest.SkipTest("test is not helpful for PGO") - -if sys.platform == "win32": - raise unittest.SkipTest("fork is not available on Windows") - -if sys.platform == 'darwin': - raise unittest.SkipTest("test may crash on macOS (bpo-33725)") - -test._test_multiprocessing.install_tests_in_module_dict(globals(), 'fork') - -if __name__ == '__main__': - unittest.main() diff --git a/mingw64/lib/python3.11/test/test_multiprocessing_forkserver.py b/mingw64/lib/python3.11/test/test_multiprocessing_forkserver.py deleted file mode 100644 index 6ad5faf9e8a..00000000000 --- a/mingw64/lib/python3.11/test/test_multiprocessing_forkserver.py +++ /dev/null @@ -1,16 +0,0 @@ -import unittest -import test._test_multiprocessing - -import sys -from test import support - -if support.PGO: - raise unittest.SkipTest("test is not helpful for PGO") - -if sys.platform == "win32": - raise unittest.SkipTest("forkserver is not available on Windows") - -test._test_multiprocessing.install_tests_in_module_dict(globals(), 'forkserver') - -if __name__ == '__main__': - unittest.main() diff --git a/mingw64/lib/python3.11/test/test_multiprocessing_spawn.py b/mingw64/lib/python3.11/test/test_multiprocessing_spawn.py deleted file mode 100644 index 6558952308f..00000000000 --- a/mingw64/lib/python3.11/test/test_multiprocessing_spawn.py +++ /dev/null @@ -1,12 +0,0 @@ -import unittest -import test._test_multiprocessing - -from test import support - -if support.PGO: - raise unittest.SkipTest("test is not helpful for PGO") - -test._test_multiprocessing.install_tests_in_module_dict(globals(), 'spawn') - -if __name__ == '__main__': - unittest.main() diff --git a/mingw64/lib/python3.11/test/test_netrc.py b/mingw64/lib/python3.11/test/test_netrc.py index 573d636de95..81e11a293cc 100644 --- a/mingw64/lib/python3.11/test/test_netrc.py +++ b/mingw64/lib/python3.11/test/test_netrc.py @@ -1,5 +1,5 @@ import netrc, os, unittest, sys, textwrap -from test.support import os_helper, run_unittest +from test.support import os_helper try: import pwd @@ -308,8 +308,6 @@ def test_security(self): self.assertEqual(nrc.hosts['foo.domain.com'], ('anonymous', '', 'pass')) -def test_main(): - run_unittest(NetrcTestCase) if __name__ == "__main__": - test_main() + unittest.main() diff --git a/mingw64/lib/python3.11/test/test_opcodes.py b/mingw64/lib/python3.11/test/test_opcodes.py index e880c3f1ac8..72488b2bb6b 100644 --- a/mingw64/lib/python3.11/test/test_opcodes.py +++ b/mingw64/lib/python3.11/test/test_opcodes.py @@ -1,7 +1,8 @@ # Python test set -- part 2, opcodes import unittest -from test import ann_module, support +from test import support +from test.typinganndata import ann_module class OpcodeTest(unittest.TestCase): diff --git a/mingw64/lib/python3.11/test/test_os.py b/mingw64/lib/python3.11/test/test_os.py index aa414ca1488..1e1980e3ac4 100644 --- a/mingw64/lib/python3.11/test/test_os.py +++ b/mingw64/lib/python3.11/test/test_os.py @@ -726,7 +726,7 @@ def test_access_denied(self): # denied. See issue 28075. # os.environ['TEMP'] should be located on a volume that # supports file ACLs. - fname = os.path.join(os.environ['TEMP'], self.fname) + fname = os.path.join(os.environ['TEMP'], self.fname + "_access") self.addCleanup(os_helper.unlink, fname) create_file(fname, b'ABC') # Deny the right to [S]YNCHRONIZE on the file to diff --git a/mingw64/lib/python3.11/test/test_pdb.py b/mingw64/lib/python3.11/test/test_pdb.py index 4f4a5692280..22fc2b35819 100644 --- a/mingw64/lib/python3.11/test/test_pdb.py +++ b/mingw64/lib/python3.11/test/test_pdb.py @@ -640,8 +640,10 @@ def test_pdb_alias_command(): ... o.method() >>> with PdbTestInput([ # doctest: +ELLIPSIS + ... 'alias pi', ... 'alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}")', ... 'alias ps pi self', + ... 'alias ps', ... 'pi o', ... 's', ... 'ps', @@ -650,8 +652,12 @@ def test_pdb_alias_command(): ... test_function() > (4)test_function() -> o.method() + (Pdb) alias pi + *** Unknown alias 'pi' (Pdb) alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}") (Pdb) alias ps pi self + (Pdb) alias ps + ps = pi self (Pdb) pi o o.attr1 = 10 o.attr2 = str diff --git a/mingw64/lib/python3.11/test/test_peepholer.py b/mingw64/lib/python3.11/test/test_peepholer.py index 241644ad7d2..d06a70bd296 100644 --- a/mingw64/lib/python3.11/test/test_peepholer.py +++ b/mingw64/lib/python3.11/test/test_peepholer.py @@ -3,6 +3,7 @@ import textwrap import unittest +from test import support from test.support.bytecode_helper import BytecodeTestCase @@ -523,6 +524,7 @@ def genexpr(): return (y for x in a for y in [f(x)]) self.assertEqual(count_instr_recursively(genexpr, 'FOR_ITER'), 1) + @support.requires_resource('cpu') def test_format_combinations(self): flags = '-+ #0' testcases = [ diff --git a/mingw64/lib/python3.11/test/test_pep646_syntax.py b/mingw64/lib/python3.11/test/test_pep646_syntax.py index 3ffa82dc55f..aac089b190b 100644 --- a/mingw64/lib/python3.11/test/test_pep646_syntax.py +++ b/mingw64/lib/python3.11/test/test_pep646_syntax.py @@ -1,3 +1,6 @@ +import doctest +import unittest + doctests = """ Setup @@ -317,10 +320,10 @@ __test__ = {'doctests' : doctests} -def test_main(verbose=False): - from test import support - from test import test_pep646_syntax - support.run_doctest(test_pep646_syntax, verbose) +def load_tests(loader, tests, pattern): + tests.addTest(doctest.DocTestSuite()) + return tests + if __name__ == "__main__": - test_main(verbose=True) + unittest.main() diff --git a/mingw64/lib/python3.11/test/test_poll.py b/mingw64/lib/python3.11/test/test_poll.py index 02165a0244d..1847ae95db9 100644 --- a/mingw64/lib/python3.11/test/test_poll.py +++ b/mingw64/lib/python3.11/test/test_poll.py @@ -8,7 +8,7 @@ import time import unittest from test.support import ( - cpython_only, requires_subprocess, requires_working_socket + cpython_only, requires_subprocess, requires_working_socket, requires_resource ) from test.support import threading_helper from test.support.os_helper import TESTFN @@ -124,6 +124,7 @@ def fileno(self): # select(), modified to use poll() instead. @requires_subprocess() + @requires_resource('walltime') def test_poll2(self): cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done' proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, diff --git a/mingw64/lib/python3.11/test/test_pty.py b/mingw64/lib/python3.11/test/test_pty.py index c9c2b42861c..a971f6b0250 100644 --- a/mingw64/lib/python3.11/test/test_pty.py +++ b/mingw64/lib/python3.11/test/test_pty.py @@ -80,17 +80,9 @@ def expectedFailureIfStdinIsTTY(fun): # because pty code is not too portable. class PtyTest(unittest.TestCase): def setUp(self): - old_alarm = signal.signal(signal.SIGALRM, self.handle_sig) - self.addCleanup(signal.signal, signal.SIGALRM, old_alarm) - old_sighup = signal.signal(signal.SIGHUP, self.handle_sighup) self.addCleanup(signal.signal, signal.SIGHUP, old_sighup) - # isatty() and close() can hang on some platforms. Set an alarm - # before running the test to make sure we don't hang forever. - self.addCleanup(signal.alarm, 0) - signal.alarm(10) - # Save original stdin window size. self.stdin_dim = None if _HAVE_WINSZ: @@ -101,9 +93,6 @@ def setUp(self): except tty.error: pass - def handle_sig(self, sig, frame): - self.fail("isatty hung") - @staticmethod def handle_sighup(signum, frame): pass diff --git a/mingw64/lib/python3.11/test/test_py_compile.py b/mingw64/lib/python3.11/test/test_py_compile.py index a4a52b180db..6a54d48eb16 100644 --- a/mingw64/lib/python3.11/test/test_py_compile.py +++ b/mingw64/lib/python3.11/test/test_py_compile.py @@ -132,7 +132,9 @@ def test_exceptions_propagate(self): os.chmod(self.directory, mode.st_mode) def test_bad_coding(self): - bad_coding = os.path.join(os.path.dirname(__file__), 'bad_coding2.py') + bad_coding = os.path.join(os.path.dirname(__file__), + 'tokenizedata', + 'bad_coding2.py') with support.captured_stderr(): self.assertIsNone(py_compile.compile(bad_coding, doraise=False)) self.assertFalse(os.path.exists( @@ -195,7 +197,9 @@ def test_invalidation_mode(self): self.assertEqual(flags, 0b1) def test_quiet(self): - bad_coding = os.path.join(os.path.dirname(__file__), 'bad_coding2.py') + bad_coding = os.path.join(os.path.dirname(__file__), + 'tokenizedata', + 'bad_coding2.py') with support.captured_stderr() as stderr: self.assertIsNone(py_compile.compile(bad_coding, doraise=False, quiet=2)) self.assertIsNone(py_compile.compile(bad_coding, doraise=True, quiet=2)) @@ -259,14 +263,18 @@ def test_with_files(self): self.assertTrue(os.path.exists(self.cache_path)) def test_bad_syntax(self): - bad_syntax = os.path.join(os.path.dirname(__file__), 'badsyntax_3131.py') + bad_syntax = os.path.join(os.path.dirname(__file__), + 'tokenizedata', + 'badsyntax_3131.py') rc, stdout, stderr = self.pycompilecmd_failure(bad_syntax) self.assertEqual(rc, 1) self.assertEqual(stdout, b'') self.assertIn(b'SyntaxError', stderr) def test_bad_syntax_with_quiet(self): - bad_syntax = os.path.join(os.path.dirname(__file__), 'badsyntax_3131.py') + bad_syntax = os.path.join(os.path.dirname(__file__), + 'tokenizedata', + 'badsyntax_3131.py') rc, stdout, stderr = self.pycompilecmd_failure('-q', bad_syntax) self.assertEqual(rc, 1) self.assertEqual(stdout, b'') diff --git a/mingw64/lib/python3.11/test/test_pyexpat.py b/mingw64/lib/python3.11/test/test_pyexpat.py index 6f0441b66d9..fa19c0ad9ee 100644 --- a/mingw64/lib/python3.11/test/test_pyexpat.py +++ b/mingw64/lib/python3.11/test/test_pyexpat.py @@ -1,13 +1,15 @@ # XXX TypeErrors on calling handlers, or on bad return values from a # handler, are obscure and unhelpful. -from io import BytesIO import os import platform import sys import sysconfig import unittest import traceback +from io import BytesIO +from test import support +from test.support import os_helper from xml.parsers import expat from xml.parsers.expat import errors @@ -441,37 +443,59 @@ def test7(self): # Test handling of exception from callback: class HandlerExceptionTest(unittest.TestCase): def StartElementHandler(self, name, attrs): - raise RuntimeError(name) + raise RuntimeError(f'StartElementHandler: <{name}>') def check_traceback_entry(self, entry, filename, funcname): - self.assertEqual(os.path.basename(entry[0]), filename) - self.assertEqual(entry[2], funcname) + self.assertEqual(os.path.basename(entry.filename), filename) + self.assertEqual(entry.name, funcname) + @support.cpython_only def test_exception(self): + # gh-66652: test _PyTraceback_Add() used by pyexpat.c to inject frames + + # Change the current directory to the Python source code directory + # if it is available. + src_dir = sysconfig.get_config_var('abs_builddir') + if src_dir: + have_source = os.path.isdir(src_dir) + else: + have_source = False + if have_source: + with os_helper.change_cwd(src_dir): + self._test_exception(have_source) + else: + self._test_exception(have_source) + + def _test_exception(self, have_source): + # Use path relative to the current directory which should be the Python + # source code directory (if it is available). + PYEXPAT_C = os.path.join('Modules', 'pyexpat.c') + parser = expat.ParserCreate() parser.StartElementHandler = self.StartElementHandler try: parser.Parse(b"
", True) - self.fail() - except RuntimeError as e: - self.assertEqual(e.args[0], 'a', - "Expected RuntimeError for element 'a', but" + \ - " found %r" % e.args[0]) - # Check that the traceback contains the relevant line in pyexpat.c - entries = traceback.extract_tb(e.__traceback__) - self.assertEqual(len(entries), 3) - self.check_traceback_entry(entries[0], - "test_pyexpat.py", "test_exception") - self.check_traceback_entry(entries[1], - "pyexpat.c", "StartElement") - self.check_traceback_entry(entries[2], - "test_pyexpat.py", "StartElementHandler") - if (sysconfig.is_python_build() - and not (sys.platform == 'win32' and platform.machine() == 'ARM') - and not is_emscripten - and not is_wasi - ): - self.assertIn('call_with_frame("StartElement"', entries[1][3]) + + self.fail("the parser did not raise RuntimeError") + except RuntimeError as exc: + self.assertEqual(exc.args[0], 'StartElementHandler: ', exc) + entries = traceback.extract_tb(exc.__traceback__) + + self.assertEqual(len(entries), 3, entries) + self.check_traceback_entry(entries[0], + "test_pyexpat.py", "_test_exception") + self.check_traceback_entry(entries[1], + os.path.basename(PYEXPAT_C), + "StartElement") + self.check_traceback_entry(entries[2], + "test_pyexpat.py", "StartElementHandler") + + # Check that the traceback contains the relevant line in + # Modules/pyexpat.c. Skip the test if Modules/pyexpat.c is not + # available. + if have_source and os.path.exists(PYEXPAT_C): + self.assertIn('call_with_frame("StartElement"', + entries[1].line) # Test Current* members: diff --git a/mingw64/lib/python3.11/test/test_regrtest.py b/mingw64/lib/python3.11/test/test_regrtest.py index 78552590a72..88c59b79dd5 100644 --- a/mingw64/lib/python3.11/test/test_regrtest.py +++ b/mingw64/lib/python3.11/test/test_regrtest.py @@ -20,7 +20,7 @@ import unittest from test import libregrtest from test import support -from test.support import os_helper +from test.support import os_helper, TestStats from test.libregrtest import utils, setup if not support.has_subprocess_support: @@ -411,7 +411,9 @@ def regex_search(self, regex, output): self.fail("%r not found in %r" % (regex, output)) return match - def check_line(self, output, regex): + def check_line(self, output, regex, full=False): + if full: + regex += '\n' regex = re.compile(r'^' + regex, re.MULTILINE) self.assertRegex(output, regex) @@ -423,21 +425,27 @@ def parse_executed_tests(self, output): def check_executed_tests(self, output, tests, skipped=(), failed=(), env_changed=(), omitted=(), - rerun={}, no_test_ran=(), + rerun={}, run_no_tests=(), + resource_denied=(), randomize=False, interrupted=False, - fail_env_changed=False): + fail_env_changed=False, + *, stats): if isinstance(tests, str): tests = [tests] if isinstance(skipped, str): skipped = [skipped] + if isinstance(resource_denied, str): + resource_denied = [resource_denied] if isinstance(failed, str): failed = [failed] if isinstance(env_changed, str): env_changed = [env_changed] if isinstance(omitted, str): omitted = [omitted] - if isinstance(no_test_ran, str): - no_test_ran = [no_test_ran] + if isinstance(run_no_tests, str): + run_no_tests = [run_no_tests] + if isinstance(stats, int): + stats = TestStats(stats) executed = self.parse_executed_tests(output) if randomize: @@ -481,12 +489,12 @@ def list_regex(line_format, tests): regex = LOG_PREFIX + f"Re-running {name} in verbose mode \\(matching: {match}\\)" self.check_line(output, regex) - if no_test_ran: - regex = list_regex('%s test%s run no tests', no_test_ran) + if run_no_tests: + regex = list_regex('%s test%s run no tests', run_no_tests) self.check_line(output, regex) good = (len(tests) - len(skipped) - len(failed) - - len(omitted) - len(env_changed) - len(no_test_ran)) + - len(omitted) - len(env_changed) - len(run_no_tests)) if good: regex = r'%s test%s OK\.$' % (good, plural(good)) if not skipped and not failed and good > 1: @@ -496,6 +504,33 @@ def list_regex(line_format, tests): if interrupted: self.check_line(output, 'Test suite interrupted by signal SIGINT.') + # Total tests + parts = [f'run={stats.tests_run:,}'] + if stats.failures: + parts.append(f'failures={stats.failures:,}') + if stats.skipped: + parts.append(f'skipped={stats.skipped:,}') + line = fr'Total tests: {" ".join(parts)}' + self.check_line(output, line, full=True) + + # Total test files + report = [f'success={good}'] + if failed: + report.append(f'failed={len(failed)}') + if env_changed: + report.append(f'env_changed={len(env_changed)}') + if skipped: + report.append(f'skipped={len(skipped)}') + if resource_denied: + report.append(f'resource_denied={len(resource_denied)}') + if rerun: + report.append(f'rerun={len(rerun)}') + if run_no_tests: + report.append(f'run_no_tests={len(run_no_tests)}') + line = fr'Total test files: {" ".join(report)}' + self.check_line(output, line, full=True) + + # Result result = [] if failed: result.append('FAILURE') @@ -505,15 +540,13 @@ def list_regex(line_format, tests): result.append('INTERRUPTED') if not any((good, result, failed, interrupted, skipped, env_changed, fail_env_changed)): - result.append("NO TEST RUN") + result.append("NO TESTS RAN") elif not result: result.append('SUCCESS') result = ', '.join(result) if rerun: - self.check_line(output, 'Tests result: FAILURE') result = 'FAILURE then %s' % result - - self.check_line(output, 'Tests result: %s' % result) + self.check_line(output, f'Result: {result}', full=True) def parse_random_seed(self, output): match = self.regex_search(r'Using random seed ([0-9]+)', output) @@ -602,7 +635,8 @@ def setUp(self): def check_output(self, output): self.parse_random_seed(output) - self.check_executed_tests(output, self.tests, randomize=True) + self.check_executed_tests(output, self.tests, + randomize=True, stats=len(self.tests)) def run_tests(self, args): output = self.run_python(args) @@ -715,8 +749,9 @@ def test_failing(self): test_failing = self.create_test('failing', code=code) tests = [test_ok, test_failing] - output = self.run_tests(*tests, exitcode=2) - self.check_executed_tests(output, tests, failed=test_failing) + output = self.run_tests(*tests, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, tests, failed=test_failing, + stats=TestStats(2, 1)) def test_resources(self): # test -u command line option @@ -735,17 +770,21 @@ def test_pass(self): # -u all: 2 resources enabled output = self.run_tests('-u', 'all', *test_names) - self.check_executed_tests(output, test_names) + self.check_executed_tests(output, test_names, stats=2) # -u audio: 1 resource enabled output = self.run_tests('-uaudio', *test_names) self.check_executed_tests(output, test_names, - skipped=tests['network']) + skipped=tests['network'], + resource_denied=tests['network'], + stats=1) # no option: 0 resources enabled output = self.run_tests(*test_names) self.check_executed_tests(output, test_names, - skipped=test_names) + skipped=test_names, + resource_denied=test_names, + stats=0) def test_random(self): # test -r and --randseed command line option @@ -756,13 +795,14 @@ def test_random(self): test = self.create_test('random', code) # first run to get the output with the random seed - output = self.run_tests('-r', test) + output = self.run_tests('-r', test, exitcode=EXITCODE_NO_TESTS_RAN) randseed = self.parse_random_seed(output) match = self.regex_search(r'TESTRANDOM: ([0-9]+)', output) test_random = int(match.group(1)) # try to reproduce with the random seed - output = self.run_tests('-r', '--randseed=%s' % randseed, test) + output = self.run_tests('-r', '--randseed=%s' % randseed, test, + exitcode=EXITCODE_NO_TESTS_RAN) randseed2 = self.parse_random_seed(output) self.assertEqual(randseed2, randseed) @@ -792,7 +832,8 @@ def test_fromfile(self): previous = name output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + stats = len(tests) + self.check_executed_tests(output, tests, stats=stats) # test format '[2/7] test_opcodes' with open(filename, "w") as fp: @@ -800,7 +841,7 @@ def test_fromfile(self): print("[%s/%s] %s" % (index, len(tests), name), file=fp) output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=stats) # test format 'test_opcodes' with open(filename, "w") as fp: @@ -808,7 +849,7 @@ def test_fromfile(self): print(name, file=fp) output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=stats) # test format 'Lib/test/test_opcodes.py' with open(filename, "w") as fp: @@ -816,20 +857,20 @@ def test_fromfile(self): print('Lib/test/%s.py' % name, file=fp) output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=stats) def test_interrupted(self): code = TEST_INTERRUPTED test = self.create_test('sigint', code=code) - output = self.run_tests(test, exitcode=130) + output = self.run_tests(test, exitcode=EXITCODE_INTERRUPTED) self.check_executed_tests(output, test, omitted=test, - interrupted=True) + interrupted=True, stats=0) def test_slowest(self): # test --slowest tests = [self.create_test() for index in range(3)] output = self.run_tests("--slowest", *tests) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=len(tests)) regex = ('10 slowest tests:\n' '(?:- %s: .*\n){%s}' % (self.TESTNAME_REGEX, len(tests))) @@ -846,9 +887,10 @@ def test_slowest_interrupted(self): args = ("--slowest", "-j2", test) else: args = ("--slowest", test) - output = self.run_tests(*args, exitcode=130) + output = self.run_tests(*args, exitcode=EXITCODE_INTERRUPTED) self.check_executed_tests(output, test, - omitted=test, interrupted=True) + omitted=test, interrupted=True, + stats=0) regex = ('10 slowest tests:\n') self.check_line(output, regex) @@ -857,7 +899,7 @@ def test_coverage(self): # test --coverage test = self.create_test('coverage') output = self.run_tests("--coverage", test) - self.check_executed_tests(output, [test]) + self.check_executed_tests(output, [test], stats=1) regex = (r'lines +cov% +module +\(path\)\n' r'(?: *[0-9]+ *[0-9]{1,2}% *[^ ]+ +\([^)]+\)+)+') self.check_line(output, regex) @@ -886,8 +928,9 @@ def test_run(self): builtins.__dict__['RUN'] = 1 """) test = self.create_test('forever', code=code) - output = self.run_tests('--forever', test, exitcode=2) - self.check_executed_tests(output, [test]*3, failed=test) + output = self.run_tests('--forever', test, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, [test]*3, failed=test, + stats=TestStats(1, 1)) def check_leak(self, code, what): test = self.create_test('huntrleaks', code=code) @@ -895,9 +938,9 @@ def check_leak(self, code, what): filename = 'reflog.txt' self.addCleanup(os_helper.unlink, filename) output = self.run_tests('--huntrleaks', '3:3:', test, - exitcode=2, + exitcode=EXITCODE_BAD_TEST, stderr=subprocess.STDOUT) - self.check_executed_tests(output, [test], failed=test) + self.check_executed_tests(output, [test], failed=test, stats=1) line = 'beginning 6 repetitions\n123456\n......\n' self.check_line(output, re.escape(line)) @@ -977,9 +1020,9 @@ def test_crashed(self): crash_test = self.create_test(name="crash", code=code) tests = [crash_test] - output = self.run_tests("-j2", *tests, exitcode=2) + output = self.run_tests("-j2", *tests, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, tests, failed=crash_test, - randomize=True) + randomize=True, stats=0) def parse_methods(self, output): regex = re.compile("^(test[^ ]+).*ok$", flags=re.MULTILINE) @@ -1074,12 +1117,14 @@ def test_env_changed(self): # don't fail by default output = self.run_tests(testname) - self.check_executed_tests(output, [testname], env_changed=testname) + self.check_executed_tests(output, [testname], + env_changed=testname, stats=1) # fail with --fail-env-changed - output = self.run_tests("--fail-env-changed", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=testname, - fail_env_changed=True) + fail_env_changed=True, stats=1) def test_rerun_fail(self): # FAILURE then FAILURE @@ -1096,9 +1141,11 @@ def test_fail_always(self): """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=2) + output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [testname], - failed=testname, rerun={testname: "test_fail_always"}) + failed=testname, + rerun={testname: "test_fail_always"}, + stats=TestStats(1, 1)) def test_rerun_success(self): # FAILURE then SUCCESS @@ -1119,7 +1166,8 @@ def test_fail_once(self): output = self.run_tests("-w", testname, exitcode=0) self.check_executed_tests(output, [testname], - rerun={testname: "test_fail_once"}) + rerun={testname: "test_fail_once"}, + stats=1) def test_rerun_setup_class_hook_failure(self): # FAILURE then FAILURE @@ -1139,7 +1187,8 @@ def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "ExampleTests"}) + rerun={testname: "ExampleTests"}, + stats=0) def test_rerun_teardown_class_hook_failure(self): # FAILURE then FAILURE @@ -1159,7 +1208,8 @@ def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "ExampleTests"}) + rerun={testname: "ExampleTests"}, + stats=1) def test_rerun_setup_module_hook_failure(self): # FAILURE then FAILURE @@ -1178,7 +1228,8 @@ def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: testname}) + rerun={testname: testname}, + stats=0) def test_rerun_teardown_module_hook_failure(self): # FAILURE then FAILURE @@ -1197,7 +1248,8 @@ def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: testname}) + rerun={testname: testname}, + stats=1) def test_rerun_setup_hook_failure(self): # FAILURE then FAILURE @@ -1216,7 +1268,8 @@ def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "test_success"}) + rerun={testname: "test_success"}, + stats=1) def test_rerun_teardown_hook_failure(self): # FAILURE then FAILURE @@ -1235,7 +1288,8 @@ def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "test_success"}) + rerun={testname: "test_success"}, + stats=1) def test_rerun_async_setup_hook_failure(self): # FAILURE then FAILURE @@ -1254,7 +1308,8 @@ async def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "test_success"}) + rerun={testname: "test_success"}, + stats=1) def test_rerun_async_teardown_hook_failure(self): # FAILURE then FAILURE @@ -1273,7 +1328,8 @@ async def test_success(self): output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, testname, failed=[testname], - rerun={testname: "test_success"}) + rerun={testname: "test_success"}, + stats=1) def test_no_tests_ran(self): code = textwrap.dedent(""" @@ -1285,8 +1341,11 @@ def test_bug(self): """) testname = self.create_test(code=code) - output = self.run_tests(testname, "-m", "nosuchtest", exitcode=0) - self.check_executed_tests(output, [testname], no_test_ran=testname) + output = self.run_tests(testname, "-m", "nosuchtest", + exitcode=EXITCODE_NO_TESTS_RAN) + self.check_executed_tests(output, [testname], + run_no_tests=testname, + stats=0) def test_no_tests_ran_skip(self): code = textwrap.dedent(""" @@ -1298,8 +1357,9 @@ def test_skipped(self): """) testname = self.create_test(code=code) - output = self.run_tests(testname, exitcode=0) - self.check_executed_tests(output, [testname]) + output = self.run_tests(testname) + self.check_executed_tests(output, [testname], + stats=TestStats(1, skipped=1)) def test_no_tests_ran_multiple_tests_nonexistent(self): code = textwrap.dedent(""" @@ -1312,9 +1372,11 @@ def test_bug(self): testname = self.create_test(code=code) testname2 = self.create_test(code=code) - output = self.run_tests(testname, testname2, "-m", "nosuchtest", exitcode=0) + output = self.run_tests(testname, testname2, "-m", "nosuchtest", + exitcode=EXITCODE_NO_TESTS_RAN) self.check_executed_tests(output, [testname, testname2], - no_test_ran=[testname, testname2]) + run_no_tests=[testname, testname2], + stats=0) def test_no_test_ran_some_test_exist_some_not(self): code = textwrap.dedent(""" @@ -1337,7 +1399,8 @@ def test_other_bug(self): output = self.run_tests(testname, testname2, "-m", "nosuchtest", "-m", "test_other_bug", exitcode=0) self.check_executed_tests(output, [testname, testname2], - no_test_ran=[testname]) + run_no_tests=[testname], + stats=1) @support.cpython_only def test_uncollectable(self): @@ -1360,10 +1423,12 @@ def test_garbage(self): """) testname = self.create_test(code=code) - output = self.run_tests("--fail-env-changed", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) def test_multiprocessing_timeout(self): code = textwrap.dedent(r""" @@ -1386,9 +1451,10 @@ def test_sleep(self): """) testname = self.create_test(code=code) - output = self.run_tests("-j2", "--timeout=1.0", testname, exitcode=2) + output = self.run_tests("-j2", "--timeout=1.0", testname, + exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [testname], - failed=testname) + failed=testname, stats=0) self.assertRegex(output, re.compile('%s timed out' % testname, re.MULTILINE)) @@ -1418,10 +1484,12 @@ def test_unraisable_exc(self): """) testname = self.create_test(code=code) - output = self.run_tests("--fail-env-changed", "-v", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", "-v", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) self.assertIn("Warning -- Unraisable exception", output) self.assertIn("Exception: weakref callback bug", output) @@ -1449,10 +1517,12 @@ def test_threading_excepthook(self): """) testname = self.create_test(code=code) - output = self.run_tests("--fail-env-changed", "-v", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", "-v", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) self.assertIn("Warning -- Uncaught thread exception", output) self.assertIn("Exception: bug in thread", output) @@ -1490,10 +1560,11 @@ def test_print_warning(self): for option in ("-v", "-W"): with self.subTest(option=option): cmd = ["--fail-env-changed", option, testname] - output = self.run_tests(*cmd, exitcode=3) + output = self.run_tests(*cmd, exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) self.assertRegex(output, regex) def test_unicode_guard_env(self): @@ -1519,6 +1590,34 @@ def test_cleanup(self): for name in names: self.assertFalse(os.path.exists(name), name) + @unittest.skipIf(support.is_wasi, + 'checking temp files is not implemented on WASI') + def test_leak_tmp_file(self): + code = textwrap.dedent(r""" + import os.path + import tempfile + import unittest + + class FileTests(unittest.TestCase): + def test_leak_tmp_file(self): + filename = os.path.join(tempfile.gettempdir(), 'mytmpfile') + with open(filename, "wb") as fp: + fp.write(b'content') + """) + testnames = [self.create_test(code=code) for _ in range(3)] + + output = self.run_tests("--fail-env-changed", "-v", "-j2", *testnames, + exitcode=EXITCODE_ENV_CHANGED) + self.check_executed_tests(output, testnames, + env_changed=testnames, + fail_env_changed=True, + randomize=True, + stats=len(testnames)) + for testname in testnames: + self.assertIn(f"Warning -- {testname} leaked temporary " + f"files (1): mytmpfile", + output) + def test_mp_decode_error(self): # gh-101634: If a worker stdout cannot be decoded, report a failed test # and a non-zero exit code. @@ -1552,7 +1651,47 @@ def test_mp_decode_error(self): exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [testname], failed=[testname], - randomize=True) + randomize=True, + stats=0) + + def test_doctest(self): + code = textwrap.dedent(fr''' + import doctest + import sys + from test import support + + def my_function(): + """ + Pass: + + >>> 1 + 1 + 2 + + Failure: + + >>> 2 + 3 + 23 + >>> 1 + 1 + 11 + + Skipped test (ignored): + + >>> id(1.0) # doctest: +SKIP + 7948648 + """ + + def load_tests(loader, tests, pattern): + tests.addTest(doctest.DocTestSuite()) + return tests + ''') + testname = self.create_test(code=code) + + output = self.run_tests("--fail-env-changed", "-v", "-j1", testname, + exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, [testname], + failed=[testname], + randomize=True, + stats=TestStats(1, 1, 0)) class TestUtils(unittest.TestCase): diff --git a/mingw64/lib/python3.11/test/test_runpy.py b/mingw64/lib/python3.11/test/test_runpy.py index 6aaa288c14e..628c8cae38a 100644 --- a/mingw64/lib/python3.11/test/test_runpy.py +++ b/mingw64/lib/python3.11/test/test_runpy.py @@ -12,7 +12,7 @@ import textwrap import unittest import warnings -from test.support import no_tracing, verbose, requires_subprocess +from test.support import no_tracing, verbose, requires_subprocess, requires_resource from test.support.import_helper import forget, make_legacy_pyc, unload from test.support.os_helper import create_empty_file, temp_dir from test.support.script_helper import make_script, make_zip_script @@ -733,6 +733,7 @@ def test_zipfile_error(self): self._check_import_error(zip_name, msg) @no_tracing + @requires_resource('cpu') def test_main_recursion_error(self): with temp_dir() as script_dir, temp_dir() as dummy_dir: mod_name = '__main__' diff --git a/mingw64/lib/python3.11/test/test_selectors.py b/mingw64/lib/python3.11/test/test_selectors.py index c2db88c2039..31757205ca3 100644 --- a/mingw64/lib/python3.11/test/test_selectors.py +++ b/mingw64/lib/python3.11/test/test_selectors.py @@ -279,6 +279,35 @@ def test_select(self): self.assertEqual([(wr_key, selectors.EVENT_WRITE)], result) + def test_select_read_write(self): + # gh-110038: when a file descriptor is registered for both read and + # write, the two events must be seen on a single call to select(). + s = self.SELECTOR() + self.addCleanup(s.close) + + sock1, sock2 = self.make_socketpair() + sock2.send(b"foo") + my_key = s.register(sock1, selectors.EVENT_READ | selectors.EVENT_WRITE) + + seen_read, seen_write = False, False + result = s.select() + # We get the read and write either in the same result entry or in two + # distinct entries with the same key. + self.assertLessEqual(len(result), 2) + for key, events in result: + self.assertTrue(isinstance(key, selectors.SelectorKey)) + self.assertEqual(key, my_key) + self.assertFalse(events & ~(selectors.EVENT_READ | + selectors.EVENT_WRITE)) + if events & selectors.EVENT_READ: + self.assertFalse(seen_read) + seen_read = True + if events & selectors.EVENT_WRITE: + self.assertFalse(seen_write) + seen_write = True + self.assertTrue(seen_read) + self.assertTrue(seen_write) + def test_context_manager(self): s = self.SELECTOR() self.addCleanup(s.close) @@ -449,6 +478,7 @@ class ScalableSelectorMixIn: # see issue #18963 for why it's skipped on older OS X versions @support.requires_mac_ver(10, 5) @unittest.skipUnless(resource, "Test needs resource module") + @support.requires_resource('cpu') def test_above_fd_setsize(self): # A scalable implementation should have no problem with more than # FD_SETSIZE file descriptors. Since we don't know the value, we just diff --git a/mingw64/lib/python3.11/test/test_signal.py b/mingw64/lib/python3.11/test/test_signal.py index ddd635197a7..f6632896100 100644 --- a/mingw64/lib/python3.11/test/test_signal.py +++ b/mingw64/lib/python3.11/test/test_signal.py @@ -745,6 +745,7 @@ def test_siginterrupt_on(self): interrupted = self.readpipe_interrupted(True) self.assertTrue(interrupted) + @support.requires_resource('walltime') def test_siginterrupt_off(self): # If a signal handler is installed and siginterrupt is called with # a false value for the second argument, when that signal arrives, it diff --git a/mingw64/lib/python3.11/test/test_site.py b/mingw64/lib/python3.11/test/test_site.py index b5dc381a2f3..613e946ba71 100644 --- a/mingw64/lib/python3.11/test/test_site.py +++ b/mingw64/lib/python3.11/test/test_site.py @@ -466,10 +466,10 @@ def test_sitecustomize_executed(self): else: self.fail("sitecustomize not imported automatically") - @test.support.requires_resource('network') - @test.support.system_must_validate_cert @unittest.skipUnless(hasattr(urllib.request, "HTTPSHandler"), 'need SSL support to download license') + @test.support.requires_resource('network') + @test.support.system_must_validate_cert def test_license_exists_at_url(self): # This test is a bit fragile since it depends on the format of the # string displayed by license in the absence of a LICENSE file. @@ -577,7 +577,7 @@ def _create_underpth_exe(self, lines, exe_pth=True): _pth_file = os.path.splitext(exe_file)[0] + '._pth' else: _pth_file = os.path.splitext(dll_file)[0] + '._pth' - with open(_pth_file, 'w') as f: + with open(_pth_file, 'w', encoding='utf8') as f: for line in lines: print(line, file=f) return exe_file @@ -614,7 +614,7 @@ def test_underpth_basic(self): os.path.dirname(exe_file), pth_lines) - output = subprocess.check_output([exe_file, '-c', + output = subprocess.check_output([exe_file, '-X', 'utf8', '-c', 'import sys; print("\\n".join(sys.path) if sys.flags.no_site else "")' ], encoding='utf-8', errors='surrogateescape') actual_sys_path = output.rstrip().split('\n') diff --git a/mingw64/lib/python3.11/test/test_smtpnet.py b/mingw64/lib/python3.11/test/test_smtpnet.py index 72f51cd8d81..2e0dc1aa276 100644 --- a/mingw64/lib/python3.11/test/test_smtpnet.py +++ b/mingw64/lib/python3.11/test/test_smtpnet.py @@ -61,6 +61,7 @@ def test_connect_default_port(self): server.ehlo() server.quit() + @support.requires_resource('walltime') def test_connect_using_sslcontext(self): context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) context.check_hostname = False diff --git a/mingw64/lib/python3.11/test/test_socket.py b/mingw64/lib/python3.11/test/test_socket.py index 13cb2a7945d..af0d2a4e6f6 100644 --- a/mingw64/lib/python3.11/test/test_socket.py +++ b/mingw64/lib/python3.11/test/test_socket.py @@ -5171,6 +5171,7 @@ def mocked_socket_module(self): finally: socket.socket = old_socket + @socket_helper.skip_if_tcp_blackhole def test_connect(self): port = socket_helper.find_unused_port() cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -5179,6 +5180,7 @@ def test_connect(self): cli.connect((HOST, port)) self.assertEqual(cm.exception.errno, errno.ECONNREFUSED) + @socket_helper.skip_if_tcp_blackhole def test_create_connection(self): # Issue #9792: errors raised by create_connection() should have # a proper errno attribute. @@ -6355,12 +6357,16 @@ def test_sha256(self): self.assertEqual(op.recv(512), expected) def test_hmac_sha1(self): - expected = bytes.fromhex("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79") + # gh-109396: In FIPS mode, Linux 6.5 requires a key + # of at least 112 bits. Use a key of 152 bits. + key = b"Python loves AF_ALG" + data = b"what do ya want for nothing?" + expected = bytes.fromhex("193dbb43c6297b47ea6277ec0ce67119a3f3aa66") with self.create_alg('hash', 'hmac(sha1)') as algo: - algo.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, b"Jefe") + algo.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, key) op, _ = algo.accept() with op: - op.sendall(b"what do ya want for nothing?") + op.sendall(data) self.assertEqual(op.recv(512), expected) # Although it should work with 3.19 and newer the test blocks on diff --git a/mingw64/lib/python3.11/test/test_source_encoding.py b/mingw64/lib/python3.11/test/test_source_encoding.py index 5fe0f312444..0c7f8ee861c 100644 --- a/mingw64/lib/python3.11/test/test_source_encoding.py +++ b/mingw64/lib/python3.11/test/test_source_encoding.py @@ -1,7 +1,7 @@ # -*- coding: koi8-r -*- import unittest -from test.support import script_helper, captured_stdout, requires_subprocess +from test.support import script_helper, captured_stdout, requires_subprocess, requires_resource from test.support.os_helper import TESTFN, unlink, rmtree from test.support.import_helper import unload import importlib @@ -69,6 +69,7 @@ def test_issue7820(self): def test_20731(self): sub = subprocess.Popen([sys.executable, os.path.join(os.path.dirname(__file__), + 'tokenizedata', 'coding20731.py')], stderr=subprocess.PIPE) err = sub.communicate()[1] @@ -101,10 +102,10 @@ def test_bad_coding2(self): self.verify_bad_module(module_name) def verify_bad_module(self, module_name): - self.assertRaises(SyntaxError, __import__, 'test.' + module_name) + self.assertRaises(SyntaxError, __import__, 'test.tokenizedata.' + module_name) path = os.path.dirname(__file__) - filename = os.path.join(path, module_name + '.py') + filename = os.path.join(path, 'tokenizedata', module_name + '.py') with open(filename, "rb") as fp: bytes = fp.read() self.assertRaises(SyntaxError, compile, bytes, filename, 'exec') @@ -251,6 +252,7 @@ def test_crcrcrlf2(self): class UTF8ValidatorTest(unittest.TestCase): @unittest.skipIf(not sys.platform.startswith("linux"), "Too slow to run on non-Linux platforms") + @requires_resource('cpu') def test_invalid_utf8(self): # This is a port of test_utf8_decode_invalid_sequences in # test_unicode.py to exercise the separate utf8 validator in diff --git a/mingw64/lib/python3.11/test/test_sqlite3/test_dbapi.py b/mingw64/lib/python3.11/test/test_sqlite3/test_dbapi.py index 899f5cfbd31..ff86291bc57 100644 --- a/mingw64/lib/python3.11/test/test_sqlite3/test_dbapi.py +++ b/mingw64/lib/python3.11/test/test_sqlite3/test_dbapi.py @@ -1837,7 +1837,7 @@ def test_on_conflict_replace(self): @requires_subprocess() class MultiprocessTests(unittest.TestCase): - CONNECTION_TIMEOUT = SHORT_TIMEOUT / 1000. # Defaults to 30 ms + CONNECTION_TIMEOUT = 0 # Disable the busy timeout. def tearDown(self): unlink(TESTFN) diff --git a/mingw64/lib/python3.11/test/test_sqlite3/test_dump.py b/mingw64/lib/python3.11/test/test_sqlite3/test_dump.py index d0c24b9c60e..c3ed3aefef0 100644 --- a/mingw64/lib/python3.11/test/test_sqlite3/test_dump.py +++ b/mingw64/lib/python3.11/test/test_sqlite3/test_dump.py @@ -117,6 +117,26 @@ def __getitem__(self, index): got = list(self.cx.iterdump()) self.assertEqual(expected, got) + def test_dump_virtual_tables(self): + # gh-64662 + expected = [ + "BEGIN TRANSACTION;", + "PRAGMA writable_schema=ON;", + ("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" + "VALUES('table','test','test',0,'CREATE VIRTUAL TABLE test USING fts4(example)');"), + "CREATE TABLE 'test_content'(docid INTEGER PRIMARY KEY, 'c0example');", + "CREATE TABLE 'test_docsize'(docid INTEGER PRIMARY KEY, size BLOB);", + ("CREATE TABLE 'test_segdir'(level INTEGER,idx INTEGER,start_block INTEGER," + "leaves_end_block INTEGER,end_block INTEGER,root BLOB,PRIMARY KEY(level, idx));"), + "CREATE TABLE 'test_segments'(blockid INTEGER PRIMARY KEY, block BLOB);", + "CREATE TABLE 'test_stat'(id INTEGER PRIMARY KEY, value BLOB);", + "PRAGMA writable_schema=OFF;", + "COMMIT;" + ] + self.cu.execute("CREATE VIRTUAL TABLE test USING fts4(example)") + actual = list(self.cx.iterdump()) + self.assertEqual(expected, actual) + if __name__ == "__main__": unittest.main() diff --git a/mingw64/lib/python3.11/test/test_sqlite3/test_factory.py b/mingw64/lib/python3.11/test/test_sqlite3/test_factory.py index 2b70093bd9b..67e81f77add 100644 --- a/mingw64/lib/python3.11/test/test_sqlite3/test_factory.py +++ b/mingw64/lib/python3.11/test/test_sqlite3/test_factory.py @@ -111,6 +111,7 @@ def tearDown(self): class RowFactoryTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") + self.con.row_factory = sqlite.Row def test_custom_factory(self): self.con.row_factory = lambda cur, row: list(row) @@ -118,7 +119,6 @@ def test_custom_factory(self): self.assertIsInstance(row, list) def test_sqlite_row_index(self): - self.con.row_factory = sqlite.Row row = self.con.execute("select 1 as a_1, 2 as b").fetchone() self.assertIsInstance(row, sqlite.Row) @@ -149,7 +149,6 @@ def test_sqlite_row_index(self): row[complex()] # index must be int or string def test_sqlite_row_index_unicode(self): - self.con.row_factory = sqlite.Row row = self.con.execute("select 1 as \xff").fetchone() self.assertEqual(row["\xff"], 1) with self.assertRaises(IndexError): @@ -159,7 +158,6 @@ def test_sqlite_row_index_unicode(self): def test_sqlite_row_slice(self): # A sqlite.Row can be sliced like a list. - self.con.row_factory = sqlite.Row row = self.con.execute("select 1, 2, 3, 4").fetchone() self.assertEqual(row[0:0], ()) self.assertEqual(row[0:1], (1,)) @@ -176,8 +174,7 @@ def test_sqlite_row_slice(self): self.assertEqual(row[3:0:-2], (4, 2)) def test_sqlite_row_iter(self): - """Checks if the row object is iterable""" - self.con.row_factory = sqlite.Row + # Checks if the row object is iterable. row = self.con.execute("select 1 as a, 2 as b").fetchone() # Is iterable in correct order and produces valid results: @@ -189,23 +186,20 @@ def test_sqlite_row_iter(self): self.assertEqual(items, [1, 2]) def test_sqlite_row_as_tuple(self): - """Checks if the row object can be converted to a tuple""" - self.con.row_factory = sqlite.Row + # Checks if the row object can be converted to a tuple. row = self.con.execute("select 1 as a, 2 as b").fetchone() t = tuple(row) self.assertEqual(t, (row['a'], row['b'])) def test_sqlite_row_as_dict(self): - """Checks if the row object can be correctly converted to a dictionary""" - self.con.row_factory = sqlite.Row + # Checks if the row object can be correctly converted to a dictionary. row = self.con.execute("select 1 as a, 2 as b").fetchone() d = dict(row) self.assertEqual(d["a"], row["a"]) self.assertEqual(d["b"], row["b"]) def test_sqlite_row_hash_cmp(self): - """Checks if the row object compares and hashes correctly""" - self.con.row_factory = sqlite.Row + # Checks if the row object compares and hashes correctly. row_1 = self.con.execute("select 1 as a, 2 as b").fetchone() row_2 = self.con.execute("select 1 as a, 2 as b").fetchone() row_3 = self.con.execute("select 1 as a, 3 as b").fetchone() @@ -238,21 +232,24 @@ def test_sqlite_row_hash_cmp(self): self.assertEqual(hash(row_1), hash(row_2)) def test_sqlite_row_as_sequence(self): - """ Checks if the row object can act like a sequence """ - self.con.row_factory = sqlite.Row + # Checks if the row object can act like a sequence. row = self.con.execute("select 1 as a, 2 as b").fetchone() as_tuple = tuple(row) self.assertEqual(list(reversed(row)), list(reversed(as_tuple))) self.assertIsInstance(row, Sequence) + def test_sqlite_row_keys(self): + # Checks if the row object can return a list of columns as strings. + row = self.con.execute("select 1 as a, 2 as b").fetchone() + self.assertEqual(row.keys(), ['a', 'b']) + def test_fake_cursor_class(self): # Issue #24257: Incorrect use of PyObject_IsInstance() caused # segmentation fault. # Issue #27861: Also applies for cursor factory. class FakeCursor(str): __class__ = sqlite.Cursor - self.con.row_factory = sqlite.Row self.assertRaises(TypeError, self.con.cursor, FakeCursor) self.assertRaises(TypeError, sqlite.Row, FakeCursor(), ()) diff --git a/mingw64/lib/python3.11/test/test_sqlite3/test_transactions.py b/mingw64/lib/python3.11/test/test_sqlite3/test_transactions.py index a67d72709d3..b8d786bbd71 100644 --- a/mingw64/lib/python3.11/test/test_sqlite3/test_transactions.py +++ b/mingw64/lib/python3.11/test/test_sqlite3/test_transactions.py @@ -23,21 +23,19 @@ import os, unittest import sqlite3 as sqlite -from test.support import LOOPBACK_TIMEOUT from test.support.os_helper import TESTFN, unlink from test.test_sqlite3.test_dbapi import memory_database -TIMEOUT = LOOPBACK_TIMEOUT / 10 - - class TransactionTests(unittest.TestCase): def setUp(self): - self.con1 = sqlite.connect(TESTFN, timeout=TIMEOUT) + # We can disable the busy handlers, since we control + # the order of SQLite C API operations. + self.con1 = sqlite.connect(TESTFN, timeout=0) self.cur1 = self.con1.cursor() - self.con2 = sqlite.connect(TESTFN, timeout=TIMEOUT) + self.con2 = sqlite.connect(TESTFN, timeout=0) self.cur2 = self.con2.cursor() def tearDown(self): @@ -117,10 +115,8 @@ def test_raise_timeout(self): self.cur2.execute("insert into test(i) values (5)") def test_locking(self): - """ - This tests the improved concurrency with pysqlite 2.3.4. You needed - to roll back con2 before you could commit con1. - """ + # This tests the improved concurrency with pysqlite 2.3.4. You needed + # to roll back con2 before you could commit con1. self.cur1.execute("create table test(i)") self.cur1.execute("insert into test(i) values (5)") with self.assertRaises(sqlite.OperationalError): diff --git a/mingw64/lib/python3.11/test/test_ssl.py b/mingw64/lib/python3.11/test/test_ssl.py index d6acbf36e6e..965c2728914 100644 --- a/mingw64/lib/python3.11/test/test_ssl.py +++ b/mingw64/lib/python3.11/test/test_ssl.py @@ -2398,6 +2398,7 @@ def test_timeout_connect_ex(self): self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK)) @unittest.skipUnless(socket_helper.IPV6_ENABLED, 'Needs IPv6') + @support.requires_resource('walltime') def test_get_server_certificate_ipv6(self): with socket_helper.transient_internet('ipv6.google.com'): _test_get_server_certificate(self, 'ipv6.google.com', 443) @@ -2956,6 +2957,7 @@ def try_protocol_combo(server_protocol, client_protocol, expect_success, class ThreadedTests(unittest.TestCase): + @support.requires_resource('walltime') def test_echo(self): """Basic test of an SSL client connecting to a server""" if support.verbose: diff --git a/mingw64/lib/python3.11/test/test_statistics.py b/mingw64/lib/python3.11/test/test_statistics.py index 3e172e974e1..9e69d918e37 100644 --- a/mingw64/lib/python3.11/test/test_statistics.py +++ b/mingw64/lib/python3.11/test/test_statistics.py @@ -2139,6 +2139,7 @@ def test_integer_sqrt_of_frac_rto(self): self.assertTrue(m * (r - 1)**2 < n < m * (r + 1)**2) @requires_IEEE_754 + @support.requires_resource('cpu') def test_float_sqrt_of_frac(self): def is_root_correctly_rounded(x: Fraction, root: float) -> bool: @@ -2744,6 +2745,7 @@ def test_cdf(self): self.assertTrue(math.isnan(X.cdf(float('NaN')))) @support.skip_if_pgo_task + @support.requires_resource('cpu') def test_inv_cdf(self): NormalDist = self.module.NormalDist diff --git a/mingw64/lib/python3.11/test/test_subprocess.py b/mingw64/lib/python3.11/test/test_subprocess.py index 8e9ad06c6eb..3142026ac53 100644 --- a/mingw64/lib/python3.11/test/test_subprocess.py +++ b/mingw64/lib/python3.11/test/test_subprocess.py @@ -268,6 +268,7 @@ def test_check_output_stdin_with_input_arg(self): self.assertIn('stdin', c.exception.args[0]) self.assertIn('input', c.exception.args[0]) + @support.requires_resource('walltime') def test_check_output_timeout(self): # check_output() function with timeout arg with self.assertRaises(subprocess.TimeoutExpired) as c: @@ -1290,6 +1291,7 @@ def test_bufsize_equal_one_binary_mode(self): with self.assertWarnsRegex(RuntimeWarning, 'line buffering'): self._test_bufsize_equal_one(line, b'', universal_newlines=False) + @support.requires_resource('cpu') def test_leaking_fds_on_error(self): # see bug #5179: Popen leaks file descriptors to PIPEs if # the child fails to execute; this will eventually exhaust @@ -1640,6 +1642,7 @@ def test_check_output_stdin_with_input_arg(self): self.assertIn('stdin', c.exception.args[0]) self.assertIn('input', c.exception.args[0]) + @support.requires_resource('walltime') def test_check_output_timeout(self): with self.assertRaises(subprocess.TimeoutExpired) as c: cp = self.run_python(( diff --git a/mingw64/lib/python3.11/test/test_support.py b/mingw64/lib/python3.11/test/test_support.py index 23bcceedd71..01ba88ce42c 100644 --- a/mingw64/lib/python3.11/test/test_support.py +++ b/mingw64/lib/python3.11/test/test_support.py @@ -7,6 +7,7 @@ import stat import subprocess import sys +import sysconfig import tempfile import textwrap import time @@ -510,6 +511,7 @@ def check_options(self, args, func, expected=None): self.assertEqual(proc.stdout.rstrip(), repr(expected)) self.assertEqual(proc.returncode, 0) + @support.requires_resource('cpu') def test_args_from_interpreter_flags(self): # Test test.support.args_from_interpreter_flags() for opts in ( @@ -697,6 +699,130 @@ def test_has_strftime_extensions(self): else: self.assertTrue(support.has_strftime_extensions) + def test_get_recursion_depth(self): + # test support.get_recursion_depth() + code = textwrap.dedent(""" + from test import support + import sys + try: + from _testcapi import USE_STACKCHECK + except ImportError: + USE_STACKCHECK = False + + def check(cond): + if not cond: + raise AssertionError("test failed") + + # depth 1 + check(support.get_recursion_depth() == 1) + + # depth 2 + def test_func(): + check(support.get_recursion_depth() == 2) + test_func() + + def test_recursive(depth, limit): + if depth >= limit: + # cannot call get_recursion_depth() at this depth, + # it can raise RecursionError + return + get_depth = support.get_recursion_depth() + print(f"test_recursive: {depth}/{limit}: " + f"get_recursion_depth() says {get_depth}") + check(get_depth == depth) + test_recursive(depth + 1, limit) + + if USE_STACKCHECK: + # f-string consumes 2 frames and -1 for USE_STACKCHECK + IGNORE = 3 + else: + # f-string consumes 2 frames + IGNORE = 2 + + # depth up to 25 + with support.infinite_recursion(max_depth=25): + limit = sys.getrecursionlimit() + print(f"test with sys.getrecursionlimit()={limit}") + test_recursive(2, limit - IGNORE) + + # depth up to 500 + with support.infinite_recursion(max_depth=500): + limit = sys.getrecursionlimit() + print(f"test with sys.getrecursionlimit()={limit}") + test_recursive(2, limit - IGNORE) + """) + script_helper.assert_python_ok("-c", code) + + def test_recursion(self): + # Test infinite_recursion() and get_recursion_available() functions. + def recursive_function(depth): + if depth: + recursive_function(depth - 1) + + for max_depth in (5, 25, 250): + with support.infinite_recursion(max_depth): + available = support.get_recursion_available() + + # Recursion up to 'available' additional frames should be OK. + recursive_function(available) + + # Recursion up to 'available+1' additional frames must raise + # RecursionError. Avoid self.assertRaises(RecursionError) which + # can consume more than 3 frames and so raises RecursionError. + try: + recursive_function(available + 1) + except RecursionError: + pass + else: + self.fail("RecursionError was not raised") + + # Test the bare minimumum: max_depth=4 + with support.infinite_recursion(4): + try: + recursive_function(4) + except RecursionError: + pass + else: + self.fail("RecursionError was not raised") + + #self.assertEqual(available, 2) + + def test_copy_python_src_ignore(self): + # Get source directory + src_dir = sysconfig.get_config_var('abs_srcdir') + if not src_dir: + src_dir = sysconfig.get_config_var('srcdir') + src_dir = os.path.abspath(src_dir) + + # Check that the source code is available + if not os.path.exists(src_dir): + self.skipTest(f"cannot access Python source code directory:" + f" {src_dir!r}") + # Check that the landmark copy_python_src_ignore() expects is available + # (Previously we looked for 'Lib\os.py', which is always present on Windows.) + landmark = os.path.join(src_dir, 'Modules') + if not os.path.exists(landmark): + self.skipTest(f"cannot access Python source code directory:" + f" {landmark!r} landmark is missing") + + # Test support.copy_python_src_ignore() + + # Source code directory + ignored = {'.git', '__pycache__'} + names = os.listdir(src_dir) + self.assertEqual(support.copy_python_src_ignore(src_dir, names), + ignored | {'build'}) + + # Doc/ directory + path = os.path.join(src_dir, 'Doc') + self.assertEqual(support.copy_python_src_ignore(path, os.listdir(path)), + ignored | {'build', 'venv'}) + + # Another directory + path = os.path.join(src_dir, 'Objects') + self.assertEqual(support.copy_python_src_ignore(path, os.listdir(path)), + ignored) + # XXX -follows a list of untested API # make_legacy_pyc # is_resource_enabled diff --git a/mingw64/lib/python3.11/test/test_symtable.py b/mingw64/lib/python3.11/test/test_symtable.py index 819354e4eee..f38d791c83d 100644 --- a/mingw64/lib/python3.11/test/test_symtable.py +++ b/mingw64/lib/python3.11/test/test_symtable.py @@ -252,6 +252,10 @@ def test_symtable_repr(self): self.assertEqual(str(self.top), "") self.assertEqual(str(self.spam), "") + def test_symtable_entry_repr(self): + expected = f"" + self.assertEqual(repr(self.top._table), expected) + if __name__ == '__main__': unittest.main() diff --git a/mingw64/lib/python3.11/test/test_sys.py b/mingw64/lib/python3.11/test/test_sys.py index 6f56c9ef97e..86cf1a794f9 100644 --- a/mingw64/lib/python3.11/test/test_sys.py +++ b/mingw64/lib/python3.11/test/test_sys.py @@ -269,20 +269,29 @@ def test_switchinterval(self): finally: sys.setswitchinterval(orig) - def test_recursionlimit(self): + def test_getrecursionlimit(self): + limit = sys.getrecursionlimit() + self.assertIsInstance(limit, int) + self.assertGreater(limit, 1) + self.assertRaises(TypeError, sys.getrecursionlimit, 42) - oldlimit = sys.getrecursionlimit() - self.assertRaises(TypeError, sys.setrecursionlimit) - self.assertRaises(ValueError, sys.setrecursionlimit, -42) - sys.setrecursionlimit(10000) - self.assertEqual(sys.getrecursionlimit(), 10000) - sys.setrecursionlimit(oldlimit) + + def test_setrecursionlimit(self): + old_limit = sys.getrecursionlimit() + try: + sys.setrecursionlimit(10_005) + self.assertEqual(sys.getrecursionlimit(), 10_005) + + self.assertRaises(TypeError, sys.setrecursionlimit) + self.assertRaises(ValueError, sys.setrecursionlimit, -42) + finally: + sys.setrecursionlimit(old_limit) def test_recursionlimit_recovery(self): if hasattr(sys, 'gettrace') and sys.gettrace(): self.skipTest('fatal error if run with a trace function') - oldlimit = sys.getrecursionlimit() + old_limit = sys.getrecursionlimit() def f(): f() try: @@ -301,35 +310,31 @@ def f(): with self.assertRaises(RecursionError): f() finally: - sys.setrecursionlimit(oldlimit) + sys.setrecursionlimit(old_limit) @test.support.cpython_only - def test_setrecursionlimit_recursion_depth(self): + def test_setrecursionlimit_to_depth(self): # Issue #25274: Setting a low recursion limit must be blocked if the # current recursion depth is already higher than limit. - from _testinternalcapi import get_recursion_depth - - def set_recursion_limit_at_depth(depth, limit): - recursion_depth = get_recursion_depth() - if recursion_depth >= depth: + old_limit = sys.getrecursionlimit() + try: + depth = support.get_recursion_depth() + with self.subTest(limit=sys.getrecursionlimit(), depth=depth): + # depth + 2 is OK + sys.setrecursionlimit(depth + 2) + + # reset the limit to be able to call self.assertRaises() + # context manager + sys.setrecursionlimit(old_limit) with self.assertRaises(RecursionError) as cm: - sys.setrecursionlimit(limit) + sys.setrecursionlimit(depth + 1) self.assertRegex(str(cm.exception), "cannot set the recursion limit to [0-9]+ " "at the recursion depth [0-9]+: " "the limit is too low") - else: - set_recursion_limit_at_depth(depth, limit) - - oldlimit = sys.getrecursionlimit() - try: - sys.setrecursionlimit(1000) - - for limit in (10, 25, 50, 75, 100, 150, 200): - set_recursion_limit_at_depth(limit, limit) finally: - sys.setrecursionlimit(oldlimit) + sys.setrecursionlimit(old_limit) def test_getwindowsversion(self): # Raise SkipTest if sys doesn't have getwindowsversion attribute diff --git a/mingw64/lib/python3.11/test/test_sys_settrace.py b/mingw64/lib/python3.11/test/test_sys_settrace.py index 96242bb260a..3540192b5bb 100644 --- a/mingw64/lib/python3.11/test/test_sys_settrace.py +++ b/mingw64/lib/python3.11/test/test_sys_settrace.py @@ -41,6 +41,20 @@ async def asynciter(iterable): for x in iterable: yield x +def clean_asynciter(test): + @wraps(test) + async def wrapper(*args, **kwargs): + cleanups = [] + def wrapped_asynciter(iterable): + it = asynciter(iterable) + cleanups.append(it.aclose) + return it + try: + return await test(*args, **kwargs, asynciter=wrapped_asynciter) + finally: + while cleanups: + await cleanups.pop()() + return wrapper # A very basic example. If this fails, we're in deep trouble. def basic(): @@ -1588,7 +1602,6 @@ def error_once(frame, event, arg): except Exception as ex: count = 0 tb = ex.__traceback__ - print(tb) while tb: if tb.tb_frame.f_code.co_name == "test_settrace_error": count += 1 @@ -1869,7 +1882,11 @@ def compare_jump_output(self, expected, received): def run_test(self, func, jumpFrom, jumpTo, expected, error=None, event='line', decorated=False): - tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated) + wrapped = func + while hasattr(wrapped, '__wrapped__'): + wrapped = wrapped.__wrapped__ + + tracer = JumpTracer(wrapped, jumpFrom, jumpTo, event, decorated) sys.settrace(tracer.trace) output = [] if error is None: @@ -1882,7 +1899,11 @@ def run_test(self, func, jumpFrom, jumpTo, expected, error=None, def run_async_test(self, func, jumpFrom, jumpTo, expected, error=None, event='line', decorated=False): - tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated) + wrapped = func + while hasattr(wrapped, '__wrapped__'): + wrapped = wrapped.__wrapped__ + + tracer = JumpTracer(wrapped, jumpFrom, jumpTo, event, decorated) sys.settrace(tracer.trace) output = [] if error is None: @@ -1950,7 +1971,8 @@ def test_jump_out_of_block_backwards(output): output.append(7) @async_jump_test(4, 5, [3, 5]) - async def test_jump_out_of_async_for_block_forwards(output): + @clean_asynciter + async def test_jump_out_of_async_for_block_forwards(output, asynciter): for i in [1]: async for i in asynciter([1, 2]): output.append(3) @@ -1958,7 +1980,8 @@ async def test_jump_out_of_async_for_block_forwards(output): output.append(5) @async_jump_test(5, 2, [2, 4, 2, 4, 5, 6]) - async def test_jump_out_of_async_for_block_backwards(output): + @clean_asynciter + async def test_jump_out_of_async_for_block_backwards(output, asynciter): for i in [1]: output.append(2) async for i in asynciter([1]): @@ -2769,6 +2792,7 @@ def test_jump_extended_args_unpack_ex_tricky(output): ) = output.append(4) or "Spam" output.append(5) + @support.requires_resource('cpu') def test_jump_extended_args_for_iter(self): # In addition to failing when extended arg handling is broken, this can # also hang for a *very* long time: diff --git a/mingw64/lib/python3.11/test/test_tarfile.py b/mingw64/lib/python3.11/test/test_tarfile.py index 13a75f39f9b..cad13a9e071 100644 --- a/mingw64/lib/python3.11/test/test_tarfile.py +++ b/mingw64/lib/python3.11/test/test_tarfile.py @@ -1,3 +1,4 @@ +import errno import sys import os import io @@ -2493,16 +2494,17 @@ def tarfilecmd_failure(self, *args): return script_helper.assert_python_failure('-m', 'tarfile', *args) def make_simple_tarfile(self, tar_name): - files = [support.findfile('tokenize_tests.txt'), + files = [support.findfile('tokenize_tests.txt', + subdir='tokenizedata'), support.findfile('tokenize_tests-no-coding-cookie-' - 'and-utf8-bom-sig-only.txt')] + 'and-utf8-bom-sig-only.txt', + subdir='tokenizedata')] self.addCleanup(os_helper.unlink, tar_name) with tarfile.open(tar_name, 'w') as tf: for tardata in files: tf.add(tardata, arcname=os.path.basename(tardata)) def make_evil_tarfile(self, tar_name): - files = [support.findfile('tokenize_tests.txt')] self.addCleanup(os_helper.unlink, tar_name) with tarfile.open(tar_name, 'w') as tf: benign = tarfile.TarInfo('benign') @@ -2583,9 +2585,11 @@ def test_list_command_invalid_file(self): self.assertEqual(rc, 1) def test_create_command(self): - files = [support.findfile('tokenize_tests.txt'), + files = [support.findfile('tokenize_tests.txt', + subdir='tokenizedata'), support.findfile('tokenize_tests-no-coding-cookie-' - 'and-utf8-bom-sig-only.txt')] + 'and-utf8-bom-sig-only.txt', + subdir='tokenizedata')] for opt in '-c', '--create': try: out = self.tarfilecmd(opt, tmpname, *files) @@ -2596,9 +2600,11 @@ def test_create_command(self): os_helper.unlink(tmpname) def test_create_command_verbose(self): - files = [support.findfile('tokenize_tests.txt'), + files = [support.findfile('tokenize_tests.txt', + subdir='tokenizedata'), support.findfile('tokenize_tests-no-coding-cookie-' - 'and-utf8-bom-sig-only.txt')] + 'and-utf8-bom-sig-only.txt', + subdir='tokenizedata')] for opt in '-v', '--verbose': try: out = self.tarfilecmd(opt, '-c', tmpname, *files, @@ -2610,7 +2616,7 @@ def test_create_command_verbose(self): os_helper.unlink(tmpname) def test_create_command_dotless_filename(self): - files = [support.findfile('tokenize_tests.txt')] + files = [support.findfile('tokenize_tests.txt', subdir='tokenizedata')] try: out = self.tarfilecmd('-c', dotlessname, *files) self.assertEqual(out, b'') @@ -2621,7 +2627,7 @@ def test_create_command_dotless_filename(self): def test_create_command_dot_started_filename(self): tar_name = os.path.join(TEMPDIR, ".testtar") - files = [support.findfile('tokenize_tests.txt')] + files = [support.findfile('tokenize_tests.txt', subdir='tokenizedata')] try: out = self.tarfilecmd('-c', tar_name, *files) self.assertEqual(out, b'') @@ -2631,9 +2637,11 @@ def test_create_command_dot_started_filename(self): os_helper.unlink(tar_name) def test_create_command_compressed(self): - files = [support.findfile('tokenize_tests.txt'), + files = [support.findfile('tokenize_tests.txt', + subdir='tokenizedata'), support.findfile('tokenize_tests-no-coding-cookie-' - 'and-utf8-bom-sig-only.txt')] + 'and-utf8-bom-sig-only.txt', + subdir='tokenizedata')] for filetype in (GzipTest, Bz2Test, LzmaTest): if not filetype.open: continue @@ -3716,9 +3724,21 @@ def test_modes(self): tmp_filename = os.path.join(TEMPDIR, "tmp.file") with open(tmp_filename, 'w'): pass - os.chmod(tmp_filename, os.stat(tmp_filename).st_mode | stat.S_ISVTX) - have_sticky_files = (os.stat(tmp_filename).st_mode & stat.S_ISVTX) - os.unlink(tmp_filename) + try: + try: + os.chmod(tmp_filename, + os.stat(tmp_filename).st_mode | stat.S_ISVTX) + except OSError as exc: + if exc.errno == getattr(errno, "EFTYPE", 0): + # gh-108948: On FreeBSD, regular users cannot set + # the sticky bit. + self.skipTest("chmod() failed with EFTYPE: " + "regular users cannot set sticky bit") + else: + raise + have_sticky_files = (os.stat(tmp_filename).st_mode & stat.S_ISVTX) + finally: + os.unlink(tmp_filename) os.mkdir(tmp_filename) os.chmod(tmp_filename, os.stat(tmp_filename).st_mode | stat.S_ISVTX) diff --git a/mingw64/lib/python3.11/test/test_tempfile.py b/mingw64/lib/python3.11/test/test_tempfile.py index ccf7ea072de..2632e77fc82 100644 --- a/mingw64/lib/python3.11/test/test_tempfile.py +++ b/mingw64/lib/python3.11/test/test_tempfile.py @@ -1726,9 +1726,25 @@ def test_modes(self): d.cleanup() self.assertFalse(os.path.exists(d.name)) - @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.lchflags') + @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.chflags') def test_flags(self): flags = stat.UF_IMMUTABLE | stat.UF_NOUNLINK + + # skip the test if these flags are not supported (ex: FreeBSD 13) + filename = os_helper.TESTFN + try: + open(filename, "w").close() + try: + os.chflags(filename, flags) + except OSError as exc: + # "OSError: [Errno 45] Operation not supported" + self.skipTest(f"chflags() doesn't support " + f"UF_IMMUTABLE|UF_NOUNLINK: {exc}") + else: + os.chflags(filename, 0) + finally: + os_helper.unlink(filename) + d = self.do_create(recurse=3, dirs=2, files=2) with d: # Change files and directories flags recursively. diff --git a/mingw64/lib/python3.11/test/test_threading.py b/mingw64/lib/python3.11/test/test_threading.py index 9c6561c099f..a4192acd6db 100644 --- a/mingw64/lib/python3.11/test/test_threading.py +++ b/mingw64/lib/python3.11/test/test_threading.py @@ -37,6 +37,23 @@ Py_DEBUG = hasattr(sys, 'gettotalrefcount') +# gh-89363: Skip fork() test if Python is built with Address Sanitizer (ASAN) +# to work around a libasan race condition, dead lock in pthread_create(). +skip_if_asan_fork = support.skip_if_sanitizer( + "libasan has a pthread_create() dead lock", + address=True) + + +def skip_unless_reliable_fork(test): + if not support.has_fork_support: + return unittest.skip("requires working os.fork()")(test) + if sys.platform in platforms_to_skip: + return unittest.skip("due to known OS bug related to thread+fork")(test) + if support.check_sanitizer(address=True): + return unittest.skip("libasan has a pthread_create() dead lock related to thread+fork")(test) + return test + + def restore_default_excepthook(testcase): testcase.addCleanup(setattr, threading, 'excepthook', threading.excepthook) threading.excepthook = threading.__excepthook__ @@ -533,7 +550,7 @@ def test_daemon_param(self): t = threading.Thread(daemon=True) self.assertTrue(t.daemon) - @support.requires_fork() + @skip_unless_reliable_fork def test_fork_at_exit(self): # bpo-42350: Calling os.fork() after threading._shutdown() must # not log an error. @@ -561,7 +578,7 @@ def exit_handler(): self.assertEqual(out, b'') self.assertEqual(err.rstrip(), b'child process ok') - @support.requires_fork() + @skip_unless_reliable_fork def test_dummy_thread_after_fork(self): # Issue #14308: a dummy thread in the active list doesn't mess up # the after-fork mechanism. @@ -588,7 +605,7 @@ def background_thread(evt): self.assertEqual(out, b'') self.assertEqual(err, b'') - @support.requires_fork() + @skip_unless_reliable_fork def test_is_alive_after_fork(self): # Try hard to trigger #18418: is_alive() could sometimes be True on # threads that vanished after a fork. @@ -622,7 +639,7 @@ def f(): th.start() th.join() - @support.requires_fork() + @skip_unless_reliable_fork @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()") def test_main_thread_after_fork(self): code = """if 1: @@ -643,8 +660,7 @@ def test_main_thread_after_fork(self): self.assertEqual(err, b"") self.assertEqual(data, "MainThread\nTrue\nTrue\n") - @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") - @support.requires_fork() + @skip_unless_reliable_fork @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()") def test_main_thread_after_fork_from_nonmain_thread(self): code = """if 1: @@ -1021,8 +1037,7 @@ def test_1_join_on_shutdown(self): """ self._run_and_join(script) - @support.requires_fork() - @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") + @skip_unless_reliable_fork def test_2_join_in_forked_process(self): # Like the test above, but from a forked interpreter script = """if 1: @@ -1042,8 +1057,7 @@ def test_2_join_in_forked_process(self): """ self._run_and_join(script) - @support.requires_fork() - @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") + @skip_unless_reliable_fork def test_3_join_in_forked_from_thread(self): # Like the test above, but fork() was called from a worker thread # In the forked process, the main Thread object must be marked as stopped. @@ -1113,8 +1127,7 @@ def main(): rc, out, err = assert_python_ok('-c', script) self.assertFalse(err) - @support.requires_fork() - @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") + @skip_unless_reliable_fork def test_reinit_tls_after_fork(self): # Issue #13817: fork() would deadlock in a multithreaded program with # the ad-hoc TLS implementation. @@ -1137,7 +1150,7 @@ def do_fork_and_wait(): for t in threads: t.join() - @support.requires_fork() + @skip_unless_reliable_fork def test_clear_threads_states_after_fork(self): # Issue #17094: check that threads states are cleared after fork() @@ -1603,6 +1616,9 @@ class ConditionAsRLockTests(lock_tests.RLockTests): # Condition uses an RLock by default and exports its API. locktype = staticmethod(threading.Condition) + def test_recursion_count(self): + self.skipTest("Condition does not expose _recursion_count()") + class ConditionTests(lock_tests.ConditionTests): condtype = staticmethod(threading.Condition) diff --git a/mingw64/lib/python3.11/test/test_timeout.py b/mingw64/lib/python3.11/test/test_timeout.py index fa85c7e6cd8..b4b0dd09a41 100644 --- a/mingw64/lib/python3.11/test/test_timeout.py +++ b/mingw64/lib/python3.11/test/test_timeout.py @@ -148,13 +148,12 @@ def setUp(self): def tearDown(self): self.sock.close() - @unittest.skipIf(True, 'need to replace these hosts; see bpo-35518') def testConnectTimeout(self): # Testing connect timeout is tricky: we need to have IP connectivity # to a host that silently drops our packets. We can't simulate this # from Python because it's a function of the underlying TCP/IP stack. - # So, the following Snakebite host has been defined: - blackhole = resolve_address('blackhole.snakebite.net', 56666) + # So, the following port on the pythontest.net host has been defined: + blackhole = resolve_address('pythontest.net', 56666) # Blackhole has been configured to silently drop any incoming packets. # No RSTs (for TCP) or ICMP UNREACH (for UDP/ICMP) will be sent back @@ -166,7 +165,7 @@ def testConnectTimeout(self): # to firewalling or general network configuration. In order to improve # our confidence in testing the blackhole, a corresponding 'whitehole' # has also been set up using one port higher: - whitehole = resolve_address('whitehole.snakebite.net', 56667) + whitehole = resolve_address('pythontest.net', 56667) # This address has been configured to immediately drop any incoming # packets as well, but it does it respectfully with regards to the @@ -180,20 +179,15 @@ def testConnectTimeout(self): # timeframe). # For the records, the whitehole/blackhole configuration has been set - # up using the 'pf' firewall (available on BSDs), using the following: + # up using the 'iptables' firewall, using the following rules: # - # ext_if="bge0" - # - # blackhole_ip="35.8.247.6" - # whitehole_ip="35.8.247.6" - # blackhole_port="56666" - # whitehole_port="56667" - # - # block return in log quick on $ext_if proto { tcp udp } \ - # from any to $whitehole_ip port $whitehole_port - # block drop in log quick on $ext_if proto { tcp udp } \ - # from any to $blackhole_ip port $blackhole_port + # -A INPUT -p tcp --destination-port 56666 -j DROP + # -A INPUT -p udp --destination-port 56666 -j DROP + # -A INPUT -p tcp --destination-port 56667 -j REJECT + # -A INPUT -p udp --destination-port 56667 -j REJECT # + # See https://github.com/python/psf-salt/blob/main/pillar/base/firewall/snakebite.sls + # for the current configuration. skip = True sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) diff --git a/mingw64/lib/python3.11/test/test_tokenize.py b/mingw64/lib/python3.11/test/test_tokenize.py index 63c2501cfe2..62f152fe431 100644 --- a/mingw64/lib/python3.11/test/test_tokenize.py +++ b/mingw64/lib/python3.11/test/test_tokenize.py @@ -999,7 +999,7 @@ class TestTokenizerAdheresToPep0263(TestCase): """ def _testFile(self, filename): - path = os.path.join(os.path.dirname(__file__), filename) + path = os.path.join(os.path.dirname(__file__), 'tokenizedata', filename) TestRoundtrip.check_roundtrip(self, open(path, 'rb')) def test_utf8_coding_cookie_and_no_utf8_bom(self): @@ -1560,7 +1560,7 @@ def test_roundtrip(self): self.check_roundtrip("if x == 1 : \n" " print(x)\n") - fn = support.findfile("tokenize_tests.txt") + fn = support.findfile("tokenize_tests.txt", subdir="tokenizedata") with open(fn, 'rb') as f: self.check_roundtrip(f) self.check_roundtrip("if x == 1:\n" @@ -1615,8 +1615,7 @@ def test_random_files(self): # pass the '-ucpu' option to process the full directory. import glob, random - fn = support.findfile("tokenize_tests.txt") - tempdir = os.path.dirname(fn) or os.curdir + tempdir = os.path.dirname(__file__) or os.curdir testfiles = glob.glob(os.path.join(glob.escape(tempdir), "test*.py")) # Tokenize is broken on test_pep3131.py because regular expressions are diff --git a/mingw64/lib/python3.11/test/test_tomllib/test_misc.py b/mingw64/lib/python3.11/test/test_tomllib/test_misc.py index a477a219fd9..9e677a337a2 100644 --- a/mingw64/lib/python3.11/test/test_tomllib/test_misc.py +++ b/mingw64/lib/python3.11/test/test_tomllib/test_misc.py @@ -9,6 +9,7 @@ import sys import tempfile import unittest +from test import support from . import tomllib @@ -92,13 +93,23 @@ def test_deepcopy(self): self.assertEqual(obj_copy, expected_obj) def test_inline_array_recursion_limit(self): - # 465 with default recursion limit - nest_count = int(sys.getrecursionlimit() * 0.465) - recursive_array_toml = "arr = " + nest_count * "[" + nest_count * "]" - tomllib.loads(recursive_array_toml) + with support.infinite_recursion(max_depth=100): + available = support.get_recursion_available() + nest_count = (available // 2) - 2 + # Add details if the test fails + with self.subTest(limit=sys.getrecursionlimit(), + available=available, + nest_count=nest_count): + recursive_array_toml = "arr = " + nest_count * "[" + nest_count * "]" + tomllib.loads(recursive_array_toml) def test_inline_table_recursion_limit(self): - # 310 with default recursion limit - nest_count = int(sys.getrecursionlimit() * 0.31) - recursive_table_toml = nest_count * "key = {" + nest_count * "}" - tomllib.loads(recursive_table_toml) + with support.infinite_recursion(max_depth=100): + available = support.get_recursion_available() + nest_count = (available // 3) - 1 + # Add details if the test fails + with self.subTest(limit=sys.getrecursionlimit(), + available=available, + nest_count=nest_count): + recursive_table_toml = nest_count * "key = {" + nest_count * "}" + tomllib.loads(recursive_table_toml) diff --git a/mingw64/lib/python3.11/test/test_tools/test_freeze.py b/mingw64/lib/python3.11/test/test_tools/test_freeze.py index 2ba36ca208f..671ec2961e7 100644 --- a/mingw64/lib/python3.11/test/test_tools/test_freeze.py +++ b/mingw64/lib/python3.11/test/test_tools/test_freeze.py @@ -15,8 +15,13 @@ @support.requires_zlib() @unittest.skipIf(sys.platform.startswith('win'), 'not supported on Windows') @support.skip_if_buildbot('not all buildbots have enough space') +# gh-103053: Skip test if Python is built with Profile Guided Optimization +# (PGO), since the test is just too slow in this case. +@unittest.skipIf(support.check_cflags_pgo(), + 'test is too slow with PGO') class TestFreeze(unittest.TestCase): + @support.requires_resource('cpu') # Building Python is slow def test_freeze_simple_script(self): script = textwrap.dedent(""" import sys diff --git a/mingw64/lib/python3.11/test/test_tools/test_reindent.py b/mingw64/lib/python3.11/test/test_tools/test_reindent.py index 34df0c5d511..3aa09130a5c 100644 --- a/mingw64/lib/python3.11/test/test_tools/test_reindent.py +++ b/mingw64/lib/python3.11/test/test_tools/test_reindent.py @@ -25,7 +25,7 @@ def test_help(self): self.assertGreater(err, b'') def test_reindent_file_with_bad_encoding(self): - bad_coding_path = findfile('bad_coding.py') + bad_coding_path = findfile('bad_coding.py', subdir='tokenizedata') rc, out, err = assert_python_ok(self.script, '-r', bad_coding_path) self.assertEqual(out, b'') self.assertNotEqual(err, b'') diff --git a/mingw64/lib/python3.11/test/test_trace.py b/mingw64/lib/python3.11/test/test_trace.py index fad2b3b8379..8be89eb0245 100644 --- a/mingw64/lib/python3.11/test/test_trace.py +++ b/mingw64/lib/python3.11/test/test_trace.py @@ -1,7 +1,7 @@ import os from pickle import dump import sys -from test.support import captured_stdout +from test.support import captured_stdout, requires_resource from test.support.os_helper import (TESTFN, rmtree, unlink) from test.support.script_helper import assert_python_ok, assert_python_failure import textwrap @@ -362,13 +362,19 @@ def tearDown(self): rmtree(TESTFN) unlink(TESTFN) - def _coverage(self, tracer, - cmd='import test.support, test.test_pprint;' - 'test.support.run_unittest(test.test_pprint.QueryTestCase)'): + DEFAULT_SCRIPT = '''if True: + import unittest + from test.test_pprint import QueryTestCase + loader = unittest.TestLoader() + tests = loader.loadTestsFromTestCase(QueryTestCase) + tests(unittest.TestResult()) + ''' + def _coverage(self, tracer, cmd=DEFAULT_SCRIPT): tracer.run(cmd) r = tracer.results() r.write_results(show_missing=True, summary=True, coverdir=TESTFN) + @requires_resource('cpu') def test_coverage(self): tracer = trace.Trace(trace=0, count=1) with captured_stdout() as stdout: diff --git a/mingw64/lib/python3.11/test/test_traceback.py b/mingw64/lib/python3.11/test/test_traceback.py index eadc9c440e3..ccc59870c2a 100644 --- a/mingw64/lib/python3.11/test/test_traceback.py +++ b/mingw64/lib/python3.11/test/test_traceback.py @@ -566,6 +566,24 @@ def f_with_binary_operator(): result_lines = self.get_exception(f_with_binary_operator) self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_binary_operators_with_spaces_and_parenthesis(self): + def f_with_binary_operator(): + a = 1 + b = "" + return ( a ) + b + + lineno_f = f_with_binary_operator.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n' + ' return ( a ) + b\n' + ' ~~~~~~~~~~^~~\n' + ) + result_lines = self.get_exception(f_with_binary_operator) + self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_subscript(self): def f_with_subscript(): some_dict = {'x': {'y': None}} @@ -600,6 +618,24 @@ def f_with_subscript(): result_lines = self.get_exception(f_with_subscript) self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_subscript_with_spaces_and_parenthesis(self): + def f_with_binary_operator(): + a = [] + b = c = 1 + return b [ a ] + c + + lineno_f = f_with_binary_operator.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n' + ' return b [ a ] + c\n' + ' ~~~~~~^^^^^^^^^\n' + ) + result_lines = self.get_exception(f_with_binary_operator) + self.assertEqual(result_lines, expected_error.splitlines()) + def test_traceback_specialization_with_syntax_error(self): bytecode = compile("1 / 0 / 1 / 2\n", TESTFN, "exec") @@ -1510,27 +1546,28 @@ def __repr__(self): err_msg = '' self.assertEqual(self.get_report(e), vanilla + err_msg + '\nFinal Note\n') - def test_exception_with_note_with_multiple_notes(self): - e = ValueError(42) - vanilla = self.get_report(e) + def test_exception_with_multiple_notes(self): + for e in [ValueError(42), SyntaxError('bad syntax')]: + with self.subTest(e=e): + vanilla = self.get_report(e) - e.add_note('Note 1') - e.add_note('Note 2') - e.add_note('Note 3') + e.add_note('Note 1') + e.add_note('Note 2') + e.add_note('Note 3') - self.assertEqual( - self.get_report(e), - vanilla + 'Note 1\n' + 'Note 2\n' + 'Note 3\n') + self.assertEqual( + self.get_report(e), + vanilla + 'Note 1\n' + 'Note 2\n' + 'Note 3\n') - del e.__notes__ - e.add_note('Note 4') - del e.__notes__ - e.add_note('Note 5') - e.add_note('Note 6') + del e.__notes__ + e.add_note('Note 4') + del e.__notes__ + e.add_note('Note 5') + e.add_note('Note 6') - self.assertEqual( - self.get_report(e), - vanilla + 'Note 5\n' + 'Note 6\n') + self.assertEqual( + self.get_report(e), + vanilla + 'Note 5\n' + 'Note 6\n') def test_exception_qualname(self): class A: diff --git a/mingw64/lib/python3.11/test/test_type_cache.py b/mingw64/lib/python3.11/test/test_type_cache.py index 8502f6b0584..9dc91dc9344 100644 --- a/mingw64/lib/python3.11/test/test_type_cache.py +++ b/mingw64/lib/python3.11/test/test_type_cache.py @@ -44,4 +44,4 @@ def test_tp_version_tag_unique(self): if __name__ == "__main__": - support.run_unittest(TypeCacheTests) + unittest.main() diff --git a/mingw64/lib/python3.11/test/test_typing.py b/mingw64/lib/python3.11/test/test_typing.py index 03988758541..149c29283d4 100644 --- a/mingw64/lib/python3.11/test/test_typing.py +++ b/mingw64/lib/python3.11/test/test_typing.py @@ -4641,7 +4641,7 @@ def test_errors(self): # We need this to make sure that `@no_type_check` respects `__module__` attr: -from test import ann_module8 +from test.typinganndata import ann_module8 @no_type_check class NoTypeCheck_Outer: @@ -5228,7 +5228,9 @@ def test_overload_registry_repeated(self): # Definitions needed for features introduced in Python 3.6 -from test import ann_module, ann_module2, ann_module3, ann_module5, ann_module6 +from test.typinganndata import ( + ann_module, ann_module2, ann_module3, ann_module5, ann_module6, +) T_a = TypeVar('T_a') diff --git a/mingw64/lib/python3.11/test/test_unicode_identifiers.py b/mingw64/lib/python3.11/test/test_unicode_identifiers.py index 5b9ced5d1cb..63c6c055824 100644 --- a/mingw64/lib/python3.11/test/test_unicode_identifiers.py +++ b/mingw64/lib/python3.11/test/test_unicode_identifiers.py @@ -19,7 +19,7 @@ def test_non_bmp_normalized(self): def test_invalid(self): try: - from test import badsyntax_3131 + from test.tokenizedata import badsyntax_3131 except SyntaxError as err: self.assertEqual(str(err), "invalid character '€' (U+20AC) (badsyntax_3131.py, line 2)") diff --git a/mingw64/lib/python3.11/test/test_unicodedata.py b/mingw64/lib/python3.11/test/test_unicodedata.py index 9e0097c892e..c02d15d54b5 100644 --- a/mingw64/lib/python3.11/test/test_unicodedata.py +++ b/mingw64/lib/python3.11/test/test_unicodedata.py @@ -295,6 +295,7 @@ def test_ucd_510(self): self.assertTrue("\u1d79".upper()=='\ua77d') self.assertTrue(".".upper()=='.') + @requires_resource('cpu') def test_bug_5828(self): self.assertEqual("\u1d79".lower(), "\u1d79") # Only U+0000 should have U+0000 as its upper/lower/titlecase variant @@ -335,6 +336,7 @@ def unistr(data): return "".join([chr(x) for x in data]) @requires_resource('network') + @requires_resource('cpu') def test_normalization(self): TESTDATAFILE = "NormalizationTest.txt" TESTDATAURL = f"http://www.pythontest.net/unicode/{unicodedata.unidata_version}/{TESTDATAFILE}" diff --git a/mingw64/lib/python3.11/test/test_unpack.py b/mingw64/lib/python3.11/test/test_unpack.py index f5ca1d455b5..515ec128a08 100644 --- a/mingw64/lib/python3.11/test/test_unpack.py +++ b/mingw64/lib/python3.11/test/test_unpack.py @@ -162,7 +162,7 @@ def test_extended_oparg_not_ignored(self): ns = {} exec(code, ns) unpack_400 = ns["unpack_400"] - # Warm up the the function for quickening (PEP 659) + # Warm up the function for quickening (PEP 659) for _ in range(30): y = unpack_400(range(400)) self.assertEqual(y, 399) diff --git a/mingw64/lib/python3.11/test/test_unparse.py b/mingw64/lib/python3.11/test/test_unparse.py index f1f1dd5dc26..d8f0060b3a4 100644 --- a/mingw64/lib/python3.11/test/test_unparse.py +++ b/mingw64/lib/python3.11/test/test_unparse.py @@ -662,6 +662,11 @@ def test_star_expr_assign_target_multiple(self): self.check_src_roundtrip("[a, b] = [c, d] = [e, f] = g") self.check_src_roundtrip("a, b = [c, d] = e, f = g") + def test_multiquote_joined_string(self): + self.check_ast_roundtrip("f\"'''{1}\\\"\\\"\\\"\" ") + self.check_ast_roundtrip("""f"'''{1}""\\"" """) + self.check_ast_roundtrip("""f'""\"{1}''' """) + self.check_ast_roundtrip("""f'""\"{1}""\\"' """) class DirectoryTestCase(ASTTestCase): diff --git a/mingw64/lib/python3.11/test/test_urllib2net.py b/mingw64/lib/python3.11/test/test_urllib2net.py index d8d882b2d33..f0874d8d3ce 100644 --- a/mingw64/lib/python3.11/test/test_urllib2net.py +++ b/mingw64/lib/python3.11/test/test_urllib2net.py @@ -133,6 +133,7 @@ def setUp(self): # XXX The rest of these tests aren't very good -- they don't check much. # They do sometimes catch some major disasters, though. + @support.requires_resource('walltime') def test_ftp(self): # Testing the same URL twice exercises the caching in CacheFTPHandler urls = [ @@ -196,6 +197,7 @@ def test_urlwithfrag(self): self.assertEqual(res.geturl(), "http://www.pythontest.net/index.html#frag") + @support.requires_resource('walltime') def test_redirect_url_withfrag(self): redirect_url_with_frag = "http://www.pythontest.net/redir/with_frag/" with socket_helper.transient_internet(redirect_url_with_frag): @@ -334,6 +336,7 @@ def test_http_timeout(self): FTP_HOST = 'ftp://www.pythontest.net/' + @support.requires_resource('walltime') def test_ftp_basic(self): self.assertIsNone(socket.getdefaulttimeout()) with socket_helper.transient_internet(self.FTP_HOST, timeout=None): @@ -352,6 +355,7 @@ def test_ftp_default_timeout(self): socket.setdefaulttimeout(None) self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) + @support.requires_resource('walltime') def test_ftp_no_timeout(self): self.assertIsNone(socket.getdefaulttimeout()) with socket_helper.transient_internet(self.FTP_HOST): @@ -363,6 +367,7 @@ def test_ftp_no_timeout(self): socket.setdefaulttimeout(None) self.assertIsNone(u.fp.fp.raw._sock.gettimeout()) + @support.requires_resource('walltime') def test_ftp_timeout(self): with socket_helper.transient_internet(self.FTP_HOST): u = _urlopen_with_retry(self.FTP_HOST, timeout=60) diff --git a/mingw64/lib/python3.11/test/test_urllibnet.py b/mingw64/lib/python3.11/test/test_urllibnet.py index 773101ce41f..49a3b5afdeb 100644 --- a/mingw64/lib/python3.11/test/test_urllibnet.py +++ b/mingw64/lib/python3.11/test/test_urllibnet.py @@ -109,6 +109,7 @@ def test_getcode(self): open_url.close() self.assertEqual(code, 404) + @support.requires_resource('walltime') def test_bad_address(self): # Make sure proper exception is raised when connecting to a bogus # address. @@ -191,6 +192,7 @@ def test_header(self): logo = "http://www.pythontest.net/" + @support.requires_resource('walltime') def test_data_header(self): with self.urlretrieve(self.logo) as (file_location, fileheaders): datevalue = fileheaders.get('Date') diff --git a/mingw64/lib/python3.11/test/test_utf8source.py b/mingw64/lib/python3.11/test/test_utf8source.py index 97dced8a622..c42b6aaaab5 100644 --- a/mingw64/lib/python3.11/test/test_utf8source.py +++ b/mingw64/lib/python3.11/test/test_utf8source.py @@ -1,5 +1,3 @@ -# This file is marked as binary in the CVS, to prevent MacCVS from recoding it. - import unittest class PEP3120Test(unittest.TestCase): @@ -16,7 +14,7 @@ def test_pep3120(self): def test_badsyntax(self): try: - import test.badsyntax_pep3120 + import test.tokenizedata.badsyntax_pep3120 except SyntaxError as msg: msg = str(msg).lower() self.assertTrue('utf-8' in msg) diff --git a/mingw64/lib/python3.11/test/test_venv.py b/mingw64/lib/python3.11/test/test_venv.py index 86ce60fef13..eb9227a3b70 100644 --- a/mingw64/lib/python3.11/test/test_venv.py +++ b/mingw64/lib/python3.11/test/test_venv.py @@ -20,7 +20,8 @@ from test.support import (captured_stdout, captured_stderr, requires_zlib, skip_if_broken_multiprocessing_synchronize, verbose, requires_subprocess, is_emscripten, is_wasi, - requires_venv_with_pip, TEST_HOME_DIR) + requires_venv_with_pip, TEST_HOME_DIR, + requires_resource, copy_python_src_ignore) from test.support.os_helper import (can_symlink, EnvironmentVarGuard, rmtree) import unittest import venv @@ -561,6 +562,7 @@ def test_zippath_from_non_installed_posix(self): platlibdir, stdlib_zip) additional_pythonpath_for_non_installed = [] + # Copy stdlib files to the non-installed python so venv can # correctly calculate the prefix. for eachpath in sys.path: @@ -570,14 +572,19 @@ def test_zippath_from_non_installed_posix(self): eachpath, os.path.join(non_installed_dir, platlibdir)) elif os.path.isfile(os.path.join(eachpath, "os.py")): - for name in os.listdir(eachpath): + names = os.listdir(eachpath) + ignored_names = copy_python_src_ignore(eachpath, names) + for name in names: + if name in ignored_names: + continue if name == "site-packages": continue fn = os.path.join(eachpath, name) if os.path.isfile(fn): shutil.copy(fn, libdir) elif os.path.isdir(fn): - shutil.copytree(fn, os.path.join(libdir, name)) + shutil.copytree(fn, os.path.join(libdir, name), + ignore=copy_python_src_ignore) else: additional_pythonpath_for_non_installed.append( eachpath) @@ -756,6 +763,7 @@ def nicer_error(self): ) @requires_venv_with_pip() + @requires_resource('cpu') def test_with_pip(self): self.do_test_with_pip(False) self.do_test_with_pip(True) diff --git a/mingw64/lib/python3.11/test/test_weakref.py b/mingw64/lib/python3.11/test/test_weakref.py index 1bc1d05f7da..4cdd66d3769 100644 --- a/mingw64/lib/python3.11/test/test_weakref.py +++ b/mingw64/lib/python3.11/test/test_weakref.py @@ -1933,6 +1933,7 @@ def test_threaded_weak_key_dict_copy(self): self.check_threaded_weak_dict_copy(weakref.WeakKeyDictionary, False) @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threaded_weak_key_dict_deepcopy(self): # Issue #35615: Weakref keys or values getting GC'ed during dict # copying should not result in a crash. @@ -1945,6 +1946,7 @@ def test_threaded_weak_value_dict_copy(self): self.check_threaded_weak_dict_copy(weakref.WeakValueDictionary, False) @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threaded_weak_value_dict_deepcopy(self): # Issue #35615: Weakref keys or values getting GC'ed during dict # copying should not result in a crash. diff --git a/mingw64/lib/python3.11/test/test_xml_etree.py b/mingw64/lib/python3.11/test/test_xml_etree.py index abf3c62156a..c095dd0b593 100644 --- a/mingw64/lib/python3.11/test/test_xml_etree.py +++ b/mingw64/lib/python3.11/test/test_xml_etree.py @@ -365,6 +365,7 @@ def test_path_cache(self): from xml.etree import ElementPath elem = ET.XML(SAMPLE_XML) + ElementPath._cache.clear() for i in range(10): ET.ElementTree(elem).find('./'+str(i)) cache_len_10 = len(ElementPath._cache) for i in range(10): ET.ElementTree(elem).find('./'+str(i)) @@ -3955,8 +3956,9 @@ def test_issue14818(self): # -------------------------------------------------------------------- class NoAcceleratorTest(unittest.TestCase): - def setUp(self): - if not pyET: + @classmethod + def setUpClass(cls): + if ET is not pyET: raise unittest.SkipTest('only for the Python version') # Test that the C accelerator was not imported for pyET @@ -4202,8 +4204,7 @@ def get_option(config, option_name, default=None): # -------------------------------------------------------------------- - -def test_main(module=None): +def setUpModule(module=None): # When invoked without a module, runs the Python ET tests by loading pyET. # Otherwise, uses the given module as the ET. global pyET @@ -4215,62 +4216,30 @@ def test_main(module=None): global ET ET = module - test_classes = [ - ModuleTest, - ElementSlicingTest, - BasicElementTest, - BadElementTest, - BadElementPathTest, - ElementTreeTest, - IOTest, - ParseErrorTest, - XIncludeTest, - ElementTreeTypeTest, - ElementFindTest, - ElementIterTest, - TreeBuilderTest, - XMLParserTest, - XMLPullParserTest, - BugsTest, - KeywordArgsTest, - C14NTest, - ] - - # These tests will only run for the pure-Python version that doesn't import - # _elementtree. We can't use skipUnless here, because pyET is filled in only - # after the module is loaded. - if pyET is not ET: - test_classes.extend([ - NoAcceleratorTest, - ]) + # don't interfere with subsequent tests + def cleanup(): + global ET, pyET + ET = pyET = None + unittest.addModuleCleanup(cleanup) # Provide default namespace mapping and path cache. from xml.etree import ElementPath nsmap = ET.register_namespace._namespace_map # Copy the default namespace mapping nsmap_copy = nsmap.copy() + unittest.addModuleCleanup(nsmap.update, nsmap_copy) + unittest.addModuleCleanup(nsmap.clear) + # Copy the path cache (should be empty) path_cache = ElementPath._cache + unittest.addModuleCleanup(setattr, ElementPath, "_cache", path_cache) ElementPath._cache = path_cache.copy() + # Align the Comment/PI factories. if hasattr(ET, '_set_factories'): old_factories = ET._set_factories(ET.Comment, ET.PI) - else: - old_factories = None - - try: - support.run_unittest(*test_classes) - finally: - from xml.etree import ElementPath - # Restore mapping and path cache - nsmap.clear() - nsmap.update(nsmap_copy) - ElementPath._cache = path_cache - if old_factories is not None: - ET._set_factories(*old_factories) - # don't interfere with subsequent tests - ET = pyET = None + unittest.addModuleCleanup(ET._set_factories, *old_factories) if __name__ == '__main__': - test_main() + unittest.main() diff --git a/mingw64/lib/python3.11/test/test_xml_etree_c.py b/mingw64/lib/python3.11/test/test_xml_etree_c.py index bec82085719..e7dee3efe3c 100644 --- a/mingw64/lib/python3.11/test/test_xml_etree_c.py +++ b/mingw64/lib/python3.11/test/test_xml_etree_c.py @@ -234,20 +234,25 @@ def test_element_with_children(self): self.check_sizeof(e, self.elementsize + self.extra + struct.calcsize('8P')) -def test_main(): - from test import test_xml_etree - - # Run the tests specific to the C implementation - support.run_unittest( - MiscTests, - TestAliasWorking, - TestAcceleratorImported, - SizeofTest, - ) - # Run the same test suite as the Python module - test_xml_etree.test_main(module=cET) +def install_tests(): + # Test classes should have __module__ referring to this module. + from test import test_xml_etree + for name, base in vars(test_xml_etree).items(): + if isinstance(base, type) and issubclass(base, unittest.TestCase): + class Temp(base): + pass + Temp.__name__ = Temp.__qualname__ = name + Temp.__module__ = __name__ + assert name not in globals() + globals()[name] = Temp + +install_tests() + +def setUpModule(): + from test import test_xml_etree + test_xml_etree.setUpModule(module=cET) if __name__ == '__main__': - test_main() + unittest.main() diff --git a/mingw64/lib/python3.11/test/test_xmlrpc.py b/mingw64/lib/python3.11/test/test_xmlrpc.py index 9ff5545f786..7f517dc7c13 100644 --- a/mingw64/lib/python3.11/test/test_xmlrpc.py +++ b/mingw64/lib/python3.11/test/test_xmlrpc.py @@ -1031,38 +1031,47 @@ def test_path2(self): self.assertEqual(p.add(6,8), 6+8) self.assertRaises(xmlrpclib.Fault, p.pow, 6, 8) + @support.requires_resource('walltime') def test_path3(self): p = xmlrpclib.ServerProxy(URL+"/is/broken") self.assertRaises(xmlrpclib.Fault, p.add, 6, 8) + @support.requires_resource('walltime') def test_invalid_path(self): p = xmlrpclib.ServerProxy(URL+"/invalid") self.assertRaises(xmlrpclib.Fault, p.add, 6, 8) + @support.requires_resource('walltime') def test_path_query_fragment(self): p = xmlrpclib.ServerProxy(URL+"/foo?k=v#frag") self.assertEqual(p.test(), "/foo?k=v#frag") + @support.requires_resource('walltime') def test_path_fragment(self): p = xmlrpclib.ServerProxy(URL+"/foo#frag") self.assertEqual(p.test(), "/foo#frag") + @support.requires_resource('walltime') def test_path_query(self): p = xmlrpclib.ServerProxy(URL+"/foo?k=v") self.assertEqual(p.test(), "/foo?k=v") + @support.requires_resource('walltime') def test_empty_path(self): p = xmlrpclib.ServerProxy(URL) self.assertEqual(p.test(), "/RPC2") + @support.requires_resource('walltime') def test_root_path(self): p = xmlrpclib.ServerProxy(URL + "/") self.assertEqual(p.test(), "/") + @support.requires_resource('walltime') def test_empty_path_query(self): p = xmlrpclib.ServerProxy(URL + "?k=v") self.assertEqual(p.test(), "?k=v") + @support.requires_resource('walltime') def test_empty_path_fragment(self): p = xmlrpclib.ServerProxy(URL + "#frag") self.assertEqual(p.test(), "#frag") diff --git a/mingw64/lib/python3.11/test/tokenizedata/__init__.py b/mingw64/lib/python3.11/test/tokenizedata/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/mingw64/lib/python3.11/test/bad_coding.py b/mingw64/lib/python3.11/test/tokenizedata/bad_coding.py similarity index 100% rename from mingw64/lib/python3.11/test/bad_coding.py rename to mingw64/lib/python3.11/test/tokenizedata/bad_coding.py diff --git a/mingw64/lib/python3.11/test/bad_coding2.py b/mingw64/lib/python3.11/test/tokenizedata/bad_coding2.py similarity index 100% rename from mingw64/lib/python3.11/test/bad_coding2.py rename to mingw64/lib/python3.11/test/tokenizedata/bad_coding2.py diff --git a/mingw64/lib/python3.11/test/badsyntax_3131.py b/mingw64/lib/python3.11/test/tokenizedata/badsyntax_3131.py similarity index 100% rename from mingw64/lib/python3.11/test/badsyntax_3131.py rename to mingw64/lib/python3.11/test/tokenizedata/badsyntax_3131.py diff --git a/mingw64/lib/python3.11/test/badsyntax_pep3120.py b/mingw64/lib/python3.11/test/tokenizedata/badsyntax_pep3120.py similarity index 100% rename from mingw64/lib/python3.11/test/badsyntax_pep3120.py rename to mingw64/lib/python3.11/test/tokenizedata/badsyntax_pep3120.py diff --git a/mingw64/lib/python3.11/test/coding20731.py b/mingw64/lib/python3.11/test/tokenizedata/coding20731.py similarity index 100% rename from mingw64/lib/python3.11/test/coding20731.py rename to mingw64/lib/python3.11/test/tokenizedata/coding20731.py diff --git a/mingw64/lib/python3.11/test/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt b/mingw64/lib/python3.11/test/tokenizedata/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt similarity index 100% rename from mingw64/lib/python3.11/test/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt rename to mingw64/lib/python3.11/test/tokenizedata/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt diff --git a/mingw64/lib/python3.11/test/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt b/mingw64/lib/python3.11/test/tokenizedata/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt similarity index 100% rename from mingw64/lib/python3.11/test/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt rename to mingw64/lib/python3.11/test/tokenizedata/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt diff --git a/mingw64/lib/python3.11/test/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt b/mingw64/lib/python3.11/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt similarity index 100% rename from mingw64/lib/python3.11/test/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt rename to mingw64/lib/python3.11/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt diff --git a/mingw64/lib/python3.11/test/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt b/mingw64/lib/python3.11/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt similarity index 100% rename from mingw64/lib/python3.11/test/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt rename to mingw64/lib/python3.11/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt diff --git a/mingw64/lib/python3.11/test/tokenize_tests.txt b/mingw64/lib/python3.11/test/tokenizedata/tokenize_tests.txt similarity index 100% rename from mingw64/lib/python3.11/test/tokenize_tests.txt rename to mingw64/lib/python3.11/test/tokenizedata/tokenize_tests.txt diff --git a/mingw64/lib/python3.11/test/ann_module.py b/mingw64/lib/python3.11/test/typinganndata/ann_module.py similarity index 100% rename from mingw64/lib/python3.11/test/ann_module.py rename to mingw64/lib/python3.11/test/typinganndata/ann_module.py diff --git a/mingw64/lib/python3.11/test/ann_module2.py b/mingw64/lib/python3.11/test/typinganndata/ann_module2.py similarity index 100% rename from mingw64/lib/python3.11/test/ann_module2.py rename to mingw64/lib/python3.11/test/typinganndata/ann_module2.py diff --git a/mingw64/lib/python3.11/test/ann_module3.py b/mingw64/lib/python3.11/test/typinganndata/ann_module3.py similarity index 100% rename from mingw64/lib/python3.11/test/ann_module3.py rename to mingw64/lib/python3.11/test/typinganndata/ann_module3.py diff --git a/mingw64/lib/python3.11/test/ann_module4.py b/mingw64/lib/python3.11/test/typinganndata/ann_module4.py similarity index 100% rename from mingw64/lib/python3.11/test/ann_module4.py rename to mingw64/lib/python3.11/test/typinganndata/ann_module4.py diff --git a/mingw64/lib/python3.11/test/ann_module5.py b/mingw64/lib/python3.11/test/typinganndata/ann_module5.py similarity index 100% rename from mingw64/lib/python3.11/test/ann_module5.py rename to mingw64/lib/python3.11/test/typinganndata/ann_module5.py diff --git a/mingw64/lib/python3.11/test/ann_module6.py b/mingw64/lib/python3.11/test/typinganndata/ann_module6.py similarity index 100% rename from mingw64/lib/python3.11/test/ann_module6.py rename to mingw64/lib/python3.11/test/typinganndata/ann_module6.py diff --git a/mingw64/lib/python3.11/test/ann_module7.py b/mingw64/lib/python3.11/test/typinganndata/ann_module7.py similarity index 100% rename from mingw64/lib/python3.11/test/ann_module7.py rename to mingw64/lib/python3.11/test/typinganndata/ann_module7.py diff --git a/mingw64/lib/python3.11/test/ann_module8.py b/mingw64/lib/python3.11/test/typinganndata/ann_module8.py similarity index 100% rename from mingw64/lib/python3.11/test/ann_module8.py rename to mingw64/lib/python3.11/test/typinganndata/ann_module8.py diff --git a/mingw64/lib/python3.11/threading.py b/mingw64/lib/python3.11/threading.py index 4f72938551d..70601fc0d5f 100644 --- a/mingw64/lib/python3.11/threading.py +++ b/mingw64/lib/python3.11/threading.py @@ -218,6 +218,13 @@ def _release_save(self): def _is_owned(self): return self._owner == get_ident() + # Internal method used for reentrancy checks + + def _recursion_count(self): + if self._owner != get_ident(): + return 0 + return self._count + _PyRLock = _RLock diff --git a/mingw64/lib/python3.11/timeit.py b/mingw64/lib/python3.11/timeit.py index 9dfd454936e..3250563f422 100644 --- a/mingw64/lib/python3.11/timeit.py +++ b/mingw64/lib/python3.11/timeit.py @@ -50,9 +50,9 @@ """ import gc +import itertools import sys import time -import itertools __all__ = ["Timer", "timeit", "repeat", "default_timer"] @@ -77,9 +77,11 @@ def inner(_it, _timer{init}): return _t1 - _t0 """ + def reindent(src, indent): """Helper to reindent a multi-line statement.""" - return src.replace("\n", "\n" + " "*indent) + return src.replace("\n", "\n" + " " * indent) + class Timer: """Class for timing execution speed of small code snippets. @@ -166,7 +168,7 @@ def timeit(self, number=default_number): To be precise, this executes the setup statement once, and then returns the time it takes to execute the main statement - a number of times, as a float measured in seconds. The + a number of times, as float seconds if using the default timer. The argument is the number of times through the loop, defaulting to one million. The main statement, the setup statement and the timer function to be used are passed to the constructor. @@ -228,16 +230,19 @@ def autorange(self, callback=None): return (number, time_taken) i *= 10 + def timeit(stmt="pass", setup="pass", timer=default_timer, number=default_number, globals=None): """Convenience function to create Timer object and call timeit method.""" return Timer(stmt, setup, timer, globals).timeit(number) + def repeat(stmt="pass", setup="pass", timer=default_timer, repeat=default_repeat, number=default_number, globals=None): """Convenience function to create Timer object and call repeat method.""" return Timer(stmt, setup, timer, globals).repeat(repeat, number) + def main(args=None, *, _wrap_timer=None): """Main program, used when run as a script. @@ -270,7 +275,7 @@ def main(args=None, *, _wrap_timer=None): timer = default_timer stmt = "\n".join(args) or "pass" - number = 0 # auto-determine + number = 0 # auto-determine setup = [] repeat = default_repeat verbose = 0 @@ -287,7 +292,7 @@ def main(args=None, *, _wrap_timer=None): time_unit = a else: print("Unrecognized unit. Please select nsec, usec, msec, or sec.", - file=sys.stderr) + file=sys.stderr) return 2 if o in ("-r", "--repeat"): repeat = int(a) @@ -321,7 +326,7 @@ def callback(number, time_taken): msg = "{num} loop{s} -> {secs:.{prec}g} secs" plural = (number != 1) print(msg.format(num=number, s='s' if plural else '', - secs=time_taken, prec=precision)) + secs=time_taken, prec=precision)) try: number, _ = t.autorange(callback) except: @@ -372,5 +377,6 @@ def format_time(dt): UserWarning, '', 0) return None + if __name__ == "__main__": sys.exit(main()) diff --git a/mingw64/lib/python3.11/traceback.py b/mingw64/lib/python3.11/traceback.py index 09950a8b55e..d3edd3a63ef 100644 --- a/mingw64/lib/python3.11/traceback.py +++ b/mingw64/lib/python3.11/traceback.py @@ -603,11 +603,21 @@ def _extract_caret_anchors_from_line_segment(segment): and not operator_str[operator_offset + 1].isspace() ): right_anchor += 1 + + while left_anchor < len(segment) and ((ch := segment[left_anchor]).isspace() or ch in ")#"): + left_anchor += 1 + right_anchor += 1 return _Anchors(normalize(left_anchor), normalize(right_anchor)) case ast.Subscript(): - subscript_start = normalize(expr.value.end_col_offset) - subscript_end = normalize(expr.slice.end_col_offset + 1) - return _Anchors(subscript_start, subscript_end) + left_anchor = normalize(expr.value.end_col_offset) + right_anchor = normalize(expr.slice.end_col_offset + 1) + while left_anchor < len(segment) and ((ch := segment[left_anchor]).isspace() or ch != "["): + left_anchor += 1 + while right_anchor < len(segment) and ((ch := segment[right_anchor]).isspace() or ch != "]"): + right_anchor += 1 + if right_anchor < len(segment): + right_anchor += 1 + return _Anchors(left_anchor, right_anchor) return None diff --git a/mingw64/lib/python3.11/unittest/loader.py b/mingw64/lib/python3.11/unittest/loader.py index 7e6ce2f224b..f4e3d6e8f27 100644 --- a/mingw64/lib/python3.11/unittest/loader.py +++ b/mingw64/lib/python3.11/unittest/loader.py @@ -87,9 +87,13 @@ def loadTestsFromTestCase(self, testCaseClass): raise TypeError("Test cases should not be derived from " "TestSuite. Maybe you meant to derive from " "TestCase?") - testCaseNames = self.getTestCaseNames(testCaseClass) - if not testCaseNames and hasattr(testCaseClass, 'runTest'): - testCaseNames = ['runTest'] + if testCaseClass in (case.TestCase, case.FunctionTestCase): + # We don't load any tests from base types that should not be loaded. + testCaseNames = [] + else: + testCaseNames = self.getTestCaseNames(testCaseClass) + if not testCaseNames and hasattr(testCaseClass, 'runTest'): + testCaseNames = ['runTest'] loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames)) return loaded_suite @@ -120,7 +124,11 @@ def loadTestsFromModule(self, module, *args, pattern=None, **kws): tests = [] for name in dir(module): obj = getattr(module, name) - if isinstance(obj, type) and issubclass(obj, case.TestCase): + if ( + isinstance(obj, type) + and issubclass(obj, case.TestCase) + and obj not in (case.TestCase, case.FunctionTestCase) + ): tests.append(self.loadTestsFromTestCase(obj)) load_tests = getattr(module, 'load_tests', None) @@ -189,7 +197,11 @@ def loadTestsFromName(self, name, module=None): if isinstance(obj, types.ModuleType): return self.loadTestsFromModule(obj) - elif isinstance(obj, type) and issubclass(obj, case.TestCase): + elif ( + isinstance(obj, type) + and issubclass(obj, case.TestCase) + and obj not in (case.TestCase, case.FunctionTestCase) + ): return self.loadTestsFromTestCase(obj) elif (isinstance(obj, types.FunctionType) and isinstance(parent, type) and diff --git a/mingw64/lib/python3.11/unittest/test/test_loader.py b/mingw64/lib/python3.11/unittest/test/test_loader.py index de2268cda90..24001822b2f 100644 --- a/mingw64/lib/python3.11/unittest/test/test_loader.py +++ b/mingw64/lib/python3.11/unittest/test/test_loader.py @@ -102,6 +102,22 @@ def runTest(self): self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), [Foo('runTest')]) + # "Do not load any tests from `TestCase` class itself." + def test_loadTestsFromTestCase__from_TestCase(self): + loader = unittest.TestLoader() + + suite = loader.loadTestsFromTestCase(unittest.TestCase) + self.assertIsInstance(suite, loader.suiteClass) + self.assertEqual(list(suite), []) + + # "Do not load any tests from `FunctionTestCase` class." + def test_loadTestsFromTestCase__from_FunctionTestCase(self): + loader = unittest.TestLoader() + + suite = loader.loadTestsFromTestCase(unittest.FunctionTestCase) + self.assertIsInstance(suite, loader.suiteClass) + self.assertEqual(list(suite), []) + ################################################################ ### /Tests for TestLoader.loadTestsFromTestCase @@ -123,6 +139,19 @@ def test(self): expected = [loader.suiteClass([MyTestCase('test')])] self.assertEqual(list(suite), expected) + # "This test ensures that internal `TestCase` subclasses are not loaded" + def test_loadTestsFromModule__TestCase_subclass_internals(self): + # See https://github.com/python/cpython/issues/84867 + m = types.ModuleType('m') + # Simulate imported names: + m.TestCase = unittest.TestCase + m.FunctionTestCase = unittest.FunctionTestCase + + loader = unittest.TestLoader() + suite = loader.loadTestsFromModule(m) + self.assertIsInstance(suite, loader.suiteClass) + self.assertEqual(list(suite), []) + # "This method searches `module` for classes derived from TestCase" # # What happens if no tests are found (no TestCase instances)? diff --git a/mingw64/lib/python3.11/venv/scripts/nt/python.exe b/mingw64/lib/python3.11/venv/scripts/nt/python.exe index ba6876592a3..d5e609b0ff7 100644 Binary files a/mingw64/lib/python3.11/venv/scripts/nt/python.exe and b/mingw64/lib/python3.11/venv/scripts/nt/python.exe differ diff --git a/mingw64/lib/python3.11/venv/scripts/nt/pythonw.exe b/mingw64/lib/python3.11/venv/scripts/nt/pythonw.exe index 7a9af8499d8..b96e0ded392 100644 Binary files a/mingw64/lib/python3.11/venv/scripts/nt/pythonw.exe and b/mingw64/lib/python3.11/venv/scripts/nt/pythonw.exe differ diff --git a/usr/bin/ex.exe b/usr/bin/ex.exe index a3f166758e5..798c5700030 100755 Binary files a/usr/bin/ex.exe and b/usr/bin/ex.exe differ diff --git a/usr/bin/gdb.exe b/usr/bin/gdb.exe index e2bda6dcf64..e16f8a0702f 100644 Binary files a/usr/bin/gdb.exe and b/usr/bin/gdb.exe differ diff --git a/usr/bin/gdbserver.exe b/usr/bin/gdbserver.exe index 4067eb6e7de..fd717a8c326 100644 Binary files a/usr/bin/gdbserver.exe and b/usr/bin/gdbserver.exe differ diff --git a/usr/bin/rview.exe b/usr/bin/rview.exe index 8d1403a5861..75af4aca090 100755 Binary files a/usr/bin/rview.exe and b/usr/bin/rview.exe differ diff --git a/usr/bin/rvim.exe b/usr/bin/rvim.exe index 8d1403a5861..75af4aca090 100755 Binary files a/usr/bin/rvim.exe and b/usr/bin/rvim.exe differ diff --git a/usr/bin/scp.exe b/usr/bin/scp.exe index 94bae86dc09..51b66148a2a 100755 Binary files a/usr/bin/scp.exe and b/usr/bin/scp.exe differ diff --git a/usr/bin/sftp.exe b/usr/bin/sftp.exe index 1c753f71d5a..e11966ddba4 100755 Binary files a/usr/bin/sftp.exe and b/usr/bin/sftp.exe differ diff --git a/usr/bin/ssh-add.exe b/usr/bin/ssh-add.exe index e4d60a46251..f367f88d457 100755 Binary files a/usr/bin/ssh-add.exe and b/usr/bin/ssh-add.exe differ diff --git a/usr/bin/ssh-agent.exe b/usr/bin/ssh-agent.exe index 49bf17a22c1..83ac09a4ffe 100755 Binary files a/usr/bin/ssh-agent.exe and b/usr/bin/ssh-agent.exe differ diff --git a/usr/bin/ssh-keygen.exe b/usr/bin/ssh-keygen.exe index edaade58e1b..29655df8a84 100755 Binary files a/usr/bin/ssh-keygen.exe and b/usr/bin/ssh-keygen.exe differ diff --git a/usr/bin/ssh-keyscan.exe b/usr/bin/ssh-keyscan.exe index 6b49492a60b..14fc86aa4b3 100755 Binary files a/usr/bin/ssh-keyscan.exe and b/usr/bin/ssh-keyscan.exe differ diff --git a/usr/bin/ssh.exe b/usr/bin/ssh.exe index befcadf860a..c5b39f6d151 100755 Binary files a/usr/bin/ssh.exe and b/usr/bin/ssh.exe differ diff --git a/usr/bin/sshd.exe b/usr/bin/sshd.exe index c02bbc1459d..ee0bcaa2825 100755 Binary files a/usr/bin/sshd.exe and b/usr/bin/sshd.exe differ diff --git a/usr/bin/view.exe b/usr/bin/view.exe index 8d1403a5861..75af4aca090 100755 Binary files a/usr/bin/view.exe and b/usr/bin/view.exe differ diff --git a/usr/bin/vim.exe b/usr/bin/vim.exe index 24473072502..7cd863d2cbc 100755 Binary files a/usr/bin/vim.exe and b/usr/bin/vim.exe differ diff --git a/usr/bin/vimdiff.exe b/usr/bin/vimdiff.exe index 24473072502..7cd863d2cbc 100755 Binary files a/usr/bin/vimdiff.exe and b/usr/bin/vimdiff.exe differ diff --git a/usr/bin/xxd.exe b/usr/bin/xxd.exe index 48e698b1dc5..cd514c73dee 100755 Binary files a/usr/bin/xxd.exe and b/usr/bin/xxd.exe differ diff --git a/usr/lib/ssh/sftp-server.exe b/usr/lib/ssh/sftp-server.exe index 0561ddfb697..bcc464830e5 100755 Binary files a/usr/lib/ssh/sftp-server.exe and b/usr/lib/ssh/sftp-server.exe differ diff --git a/usr/lib/ssh/ssh-keysign.exe b/usr/lib/ssh/ssh-keysign.exe index e61c34da683..7cbecae9dfe 100755 Binary files a/usr/lib/ssh/ssh-keysign.exe and b/usr/lib/ssh/ssh-keysign.exe differ diff --git a/usr/lib/ssh/ssh-pkcs11-helper.exe b/usr/lib/ssh/ssh-pkcs11-helper.exe index 6eda76c1a5d..493fb551726 100755 Binary files a/usr/lib/ssh/ssh-pkcs11-helper.exe and b/usr/lib/ssh/ssh-pkcs11-helper.exe differ diff --git a/usr/lib/ssh/ssh-sk-helper.exe b/usr/lib/ssh/ssh-sk-helper.exe index 654646a568e..e8b5060e66c 100644 Binary files a/usr/lib/ssh/ssh-sk-helper.exe and b/usr/lib/ssh/ssh-sk-helper.exe differ diff --git a/usr/share/applications/gvim.desktop b/usr/share/applications/gvim.desktop index 0793f702554..302687b7725 100644 --- a/usr/share/applications/gvim.desktop +++ b/usr/share/applications/gvim.desktop @@ -27,7 +27,7 @@ GenericName[ga]=Eagarthóir Téacs GenericName[it]=Editor di testi GenericName[ja]=テキストエディタ GenericName[ru]=ТекÑтовый редактор -GenericName[sr]=Едитор текÑÑ‚ +GenericName[sr]=Едитор текÑта GenericName[tr]=Metin Düzenleyici GenericName[uk]=Редактор ТекÑту GenericName[zh_CN]=文本编辑器 diff --git a/usr/share/applications/vim.desktop b/usr/share/applications/vim.desktop index 07201bb7e10..2b1ba47caca 100644 --- a/usr/share/applications/vim.desktop +++ b/usr/share/applications/vim.desktop @@ -27,7 +27,7 @@ GenericName[ga]=Eagarthóir Téacs GenericName[it]=Editor di testi GenericName[ja]=テキストエディタ GenericName[ru]=ТекÑтовый редактор -GenericName[sr]=Едитор текÑÑ‚ +GenericName[sr]=Едитор текÑта GenericName[tr]=Metin Düzenleyici GenericName[uk]=Редактор ТекÑту GenericName[zh_CN]=文本编辑器 diff --git a/usr/share/info/gdb.info-1.gz b/usr/share/info/gdb.info-1.gz index b3ad3f934ae..16a913727f6 100644 Binary files a/usr/share/info/gdb.info-1.gz and b/usr/share/info/gdb.info-1.gz differ diff --git a/usr/share/info/gdb.info-2.gz b/usr/share/info/gdb.info-2.gz index 32aacf3e528..e73c191770a 100644 Binary files a/usr/share/info/gdb.info-2.gz and b/usr/share/info/gdb.info-2.gz differ diff --git a/usr/share/info/gdb.info-3.gz b/usr/share/info/gdb.info-3.gz index 3d035e1dd6c..c71c469ece6 100644 Binary files a/usr/share/info/gdb.info-3.gz and b/usr/share/info/gdb.info-3.gz differ diff --git a/usr/share/info/gdb.info-4.gz b/usr/share/info/gdb.info-4.gz index 0cf43b47ce1..c745bdb545b 100644 Binary files a/usr/share/info/gdb.info-4.gz and b/usr/share/info/gdb.info-4.gz differ diff --git a/usr/share/info/gdb.info-5.gz b/usr/share/info/gdb.info-5.gz index b9cbe273a61..eb37a1d0491 100644 Binary files a/usr/share/info/gdb.info-5.gz and b/usr/share/info/gdb.info-5.gz differ diff --git a/usr/share/info/gdb.info-6.gz b/usr/share/info/gdb.info-6.gz index 8c4c265130c..977c81b0b6b 100644 Binary files a/usr/share/info/gdb.info-6.gz and b/usr/share/info/gdb.info-6.gz differ diff --git a/usr/share/info/gdb.info-7.gz b/usr/share/info/gdb.info-7.gz index 93ef4970018..275b9539c0a 100644 Binary files a/usr/share/info/gdb.info-7.gz and b/usr/share/info/gdb.info-7.gz differ diff --git a/usr/share/info/gdb.info-8.gz b/usr/share/info/gdb.info-8.gz index b064630fbc0..cbbb8c6d239 100644 Binary files a/usr/share/info/gdb.info-8.gz and b/usr/share/info/gdb.info-8.gz differ diff --git a/usr/share/info/gdb.info.gz b/usr/share/info/gdb.info.gz index a58e514089f..a9555d7a632 100644 Binary files a/usr/share/info/gdb.info.gz and b/usr/share/info/gdb.info.gz differ diff --git a/usr/share/man/man1/gdb-add-index.1.gz b/usr/share/man/man1/gdb-add-index.1.gz index 04c82409edb..b945f7c8cbc 100644 Binary files a/usr/share/man/man1/gdb-add-index.1.gz and b/usr/share/man/man1/gdb-add-index.1.gz differ diff --git a/usr/share/man/man1/gdb.1.gz b/usr/share/man/man1/gdb.1.gz index 18d32dea1e7..41eb9d37c95 100644 Binary files a/usr/share/man/man1/gdb.1.gz and b/usr/share/man/man1/gdb.1.gz differ diff --git a/usr/share/man/man1/gdbserver.1.gz b/usr/share/man/man1/gdbserver.1.gz index b76f1779e67..eb9637fbace 100644 Binary files a/usr/share/man/man1/gdbserver.1.gz and b/usr/share/man/man1/gdbserver.1.gz differ diff --git a/usr/share/man/man1/ssh-agent.1.gz b/usr/share/man/man1/ssh-agent.1.gz index 80a930558d3..63d45f18ceb 100644 Binary files a/usr/share/man/man1/ssh-agent.1.gz and b/usr/share/man/man1/ssh-agent.1.gz differ diff --git a/usr/share/man/man1/ssh-keygen.1.gz b/usr/share/man/man1/ssh-keygen.1.gz index ad892507794..6c375ef7fcd 100644 Binary files a/usr/share/man/man1/ssh-keygen.1.gz and b/usr/share/man/man1/ssh-keygen.1.gz differ diff --git a/usr/share/man/man5/gdbinit.5.gz b/usr/share/man/man5/gdbinit.5.gz index 1ae51cfa4cf..33a43d5c4ce 100644 Binary files a/usr/share/man/man5/gdbinit.5.gz and b/usr/share/man/man5/gdbinit.5.gz differ diff --git a/usr/share/man/man5/ssh_config.5.gz b/usr/share/man/man5/ssh_config.5.gz index f731b6fb25d..af944f6224e 100644 Binary files a/usr/share/man/man5/ssh_config.5.gz and b/usr/share/man/man5/ssh_config.5.gz differ diff --git a/usr/share/man/man8/sshd.8.gz b/usr/share/man/man8/sshd.8.gz index 71a22050edf..7b03044c0f7 100644 Binary files a/usr/share/man/man8/sshd.8.gz and b/usr/share/man/man8/sshd.8.gz differ diff --git a/usr/share/vim/vim90/autoload/netrw.vim b/usr/share/vim/vim90/autoload/netrw.vim index 14b1ab20d4a..9548b493752 100644 --- a/usr/share/vim/vim90/autoload/netrw.vim +++ b/usr/share/vim/vim90/autoload/netrw.vim @@ -2998,7 +2998,7 @@ fun! s:NetrwGetFile(readcmd, tfile, method) " to process this detection correctly. " call Decho("detect filetype of local version of remote file<".rfile.">",'~'.expand("")) " call Decho("..did_filetype()=".did_filetype()) - setl ft= +" setl ft= " call Decho("..initial filetype<".&ft."> for buf#".bufnr()."<".bufname().">") let iskkeep= &isk setl isk-=/ diff --git a/usr/share/vim/vim90/doc/builtin.txt b/usr/share/vim/vim90/doc/builtin.txt index a52a3df0b44..b4ea216f31e 100644 --- a/usr/share/vim/vim90/doc/builtin.txt +++ b/usr/share/vim/vim90/doc/builtin.txt @@ -1,4 +1,4 @@ -*builtin.txt* For Vim version 9.0. Last change: 2023 Aug 09 +*builtin.txt* For Vim version 9.0. Last change: 2023 Sep 27 VIM REFERENCE MANUAL by Bram Moolenaar @@ -6830,55 +6830,55 @@ printf({fmt}, {expr1} ...) *printf()* echo printf("%1$*2$.*3$f", 1.4142135, 6, 2) < 1.41 - *E1400* + *E1500* You cannot mix positional and non-positional arguments: > echo printf("%s%1$s", "One", "Two") -< E1400: Cannot mix positional and non-positional +< E1500: Cannot mix positional and non-positional arguments: %s%1$s - *E1401* + *E1501* You cannot skip a positional argument in a format string: > echo printf("%3$s%1$s", "One", "Two", "Three") -< E1401: format argument 2 unused in $-style +< E1501: format argument 2 unused in $-style format: %3$s%1$s - *E1402* + *E1502* You can re-use a [field-width] (or [precision]) argument: > echo printf("%1$d at width %2$d is: %01$*2$d", 1, 2) < 1 at width 2 is: 01 However, you can't use it as a different type: > echo printf("%1$d at width %2$ld is: %01$*2$d", 1, 2) -< E1402: Positional argument 2 used as field +< E1502: Positional argument 2 used as field width reused as different type: long int/int - *E1403* + *E1503* When a positional argument is used, but not the correct number or arguments is given, an error is raised: > echo printf("%1$d at width %2$d is: %01$*2$.*3$d", 1, 2) -< E1403: Positional argument 3 out of bounds: +< E1503: Positional argument 3 out of bounds: %1$d at width %2$d is: %01$*2$.*3$d Only the first error is reported: > echo printf("%01$*2$.*3$d %4$d", 1, 2) -< E1403: Positional argument 3 out of bounds: +< E1503: Positional argument 3 out of bounds: %01$*2$.*3$d %4$d - *E1404* + *E1504* A positional argument can be used more than once: > echo printf("%1$s %2$s %1$s", "One", "Two") < One Two One However, you can't use a different type the second time: > echo printf("%1$s %2$s %1$d", "One", "Two") -< E1404: Positional argument 1 type used +< E1504: Positional argument 1 type used inconsistently: int/string - *E1405* + *E1505* Various other errors that lead to a format string being wrongly formatted lead to: > echo printf("%1$d at width %2$d is: %01$*2$.3$d", 1, 2) -< E1405: Invalid format specifier: +< E1505: Invalid format specifier: %1$d at width %2$d is: %01$*2$.3$d prompt_getprompt({buf}) *prompt_getprompt()* @@ -9443,7 +9443,7 @@ strutf16len({string} [, {countcc}]) *strutf16len()* echo strutf16len('😊') returns 2 echo strutf16len('ąÌ') returns 1 echo strutf16len('ąÌ', v:true) returns 3 - +< Can also be used as a |method|: > GetText()->strutf16len() < @@ -11082,6 +11082,8 @@ winaltkeys Compiled with 'winaltkeys' option. windows Compiled with support for more than one window. (always true) writebackup Compiled with 'writebackup' default on. +xattr Compiled with extended attributes support |xattr| + (currently only supported on Linux). xfontset Compiled with X fontset support |xfontset|. xim Compiled with X input method support |xim|. xpm Compiled with pixmap support. diff --git a/usr/share/vim/vim90/doc/change.txt b/usr/share/vim/vim90/doc/change.txt index a00049bef3b..65da9a7c6b9 100644 --- a/usr/share/vim/vim90/doc/change.txt +++ b/usr/share/vim/vim90/doc/change.txt @@ -1,4 +1,4 @@ -*change.txt* For Vim version 9.0. Last change: 2023 Mar 07 +*change.txt* For Vim version 9.0. Last change: 2023 Sep 19 VIM REFERENCE MANUAL by Bram Moolenaar @@ -210,6 +210,7 @@ gR Enter Virtual Replace mode: Each character you type *v_r* {Visual}r{char} Replace all selected characters by {char}. + CTRL-C will be inserted literally. *v_C* {Visual}["x]C Delete the highlighted lines [into register x] and diff --git a/usr/share/vim/vim90/doc/cmdline.txt b/usr/share/vim/vim90/doc/cmdline.txt index d2e476f0063..3d63b1964b4 100644 --- a/usr/share/vim/vim90/doc/cmdline.txt +++ b/usr/share/vim/vim90/doc/cmdline.txt @@ -517,16 +517,26 @@ example, to match only files that end in ".c": > :e *.c$ This will not match a file ending in ".cpp". Without the "$" it does match. -The old value of an option can be obtained by hitting 'wildchar' just after -the '='. For example, typing 'wildchar' after ":set dir=" will insert the -current value of 'dir'. This overrules file name completion for the options -that take a file name. - If you would like using for CTRL-P in an xterm, put this command in your .cshrc: > xmodmap -e "keysym Tab = Tab Find" And this in your .vimrc: > :cmap [1~ +< *complete-set-option* +When setting an option using |:set=|, the old value of an option can be +obtained by hitting 'wildchar' just after the '='. For example, typing +'wildchar' after ":set dir=" will insert the current value of 'dir'. This +overrules file name completion for the options that take a file name. + +When using |:set=|, |:set+=|, or |:set^=|, string options that have +pre-defined names or syntax (e.g. 'diffopt', 'listchars') or are a list of +single-character flags (e.g. 'shortmess') will also present a list of possible +values for completion when using 'wildchar'. + +When using |:set-=|, comma-separated options like 'diffopt' or 'backupdir' +will show each item separately. Flag list options like 'shortmess' will show +both the entire old value and the individual flags. Otherwise completion will +just fill in with the entire old value. ============================================================================== 3. Ex command-lines *cmdline-lines* diff --git a/usr/share/vim/vim90/doc/editing.txt b/usr/share/vim/vim90/doc/editing.txt index da9aeb7feaa..a015c8462aa 100644 --- a/usr/share/vim/vim90/doc/editing.txt +++ b/usr/share/vim/vim90/doc/editing.txt @@ -1,4 +1,4 @@ -*editing.txt* For Vim version 9.0. Last change: 2023 Apr 23 +*editing.txt* For Vim version 9.0. Last change: 2023 Sep 27 VIM REFERENCE MANUAL by Bram Moolenaar @@ -385,7 +385,9 @@ as a wildcard when "[" is in the 'isfname' option. A simple way to avoid this is to use "path\[[]abc]", this matches the file "path\[abc]". *starstar-wildcard* -Expanding "**" is possible on Unix, Win32, macOS and a few other systems. +Expanding "**" is possible on Unix, Win32, macOS and a few other systems (but +it may depend on your 'shell' setting. It's known to work correctly for zsh; for +bash this requires at least bash version >= 4.X). This allows searching a directory tree. This goes up to 100 directories deep. Note there are some commands where this works slightly differently, see |file-searching|. @@ -1095,6 +1097,13 @@ will get the ACL info of the original file. The ACL info is also used to check if a file is read-only (when opening the file). + *xattr* *E1506* *E1507* *E1508* *E1509* +xattr stands for Extended Attributes It is an advanced way to save metadata +alongside the file in the filesystem. It depends on the actual filesystem +being used and Vim supports it only on a Linux system. + Vim attempts to preserve the extended attribute info when writing a file. +The backup file will get the extended attribute of the original file. + *read-only-share* When MS-Windows shares a drive on the network it can be marked as read-only. This means that even if the file read-only attribute is absent, and the ACL diff --git a/usr/share/vim/vim90/doc/ft_rust.txt b/usr/share/vim/vim90/doc/ft_rust.txt index 9d5eb8cce7b..fb8141c14d8 100644 --- a/usr/share/vim/vim90/doc/ft_rust.txt +++ b/usr/share/vim/vim90/doc/ft_rust.txt @@ -474,8 +474,8 @@ rust.vim Debugging register. :RustInfoToFile [filename] *:RustInfoToFile* - Saves debugging info of the Vim Rust plugin to the the given - file, overwritting it. + Saves debugging info of the Vim Rust plugin to the given file, + overwriting it. ============================================================================== MAPPINGS *rust-mappings* diff --git a/usr/share/vim/vim90/doc/motion.txt b/usr/share/vim/vim90/doc/motion.txt index 2ddd1b9cec5..403ef4f307a 100644 --- a/usr/share/vim/vim90/doc/motion.txt +++ b/usr/share/vim/vim90/doc/motion.txt @@ -1,4 +1,4 @@ -*motion.txt* For Vim version 9.0. Last change: 2022 Sep 26 +*motion.txt* For Vim version 9.0. Last change: 2023 Sep 28 VIM REFERENCE MANUAL by Bram Moolenaar @@ -592,14 +592,16 @@ a] *v_a]* *v_a[* *a]* *a[* a[ "a [] block", select [count] '[' ']' blocks. This goes backwards to the [count] unclosed '[', and finds the matching ']'. The enclosed text is selected, - including the '[' and ']'. + including the '[' and ']'. The |cpo-M| option flag + is used to handle escaped brackets. When used in Visual mode it is made characterwise. i] *v_i]* *v_i[* *i]* *i[* i[ "inner [] block", select [count] '[' ']' blocks. This goes backwards to the [count] unclosed '[', and finds the matching ']'. The enclosed text is selected, - excluding the '[' and ']'. + excluding the '[' and ']'. The |cpo-M| option flag + is used to handle escaped brackets. When used in Visual mode it is made characterwise. a) *v_a)* *a)* *a(* @@ -607,7 +609,8 @@ a( *vab* *v_ab* *v_a(* *ab* ab "a block", select [count] blocks, from "[count] [(" to the matching ')', including the '(' and ')' (see |[(|). Does not include white space outside of the - parenthesis. + parenthesis. The |cpo-M| option flag is used to + handle escaped parenthesis. When used in Visual mode it is made characterwise. i) *v_i)* *i)* *i(* @@ -615,19 +618,22 @@ i( *vib* *v_ib* *v_i(* *ib* ib "inner block", select [count] blocks, from "[count] [(" to the matching ')', excluding the '(' and ')' (see |[(|). If the cursor is not inside a () block, then - find the next "(". + find the next "(". The |cpo-M| option flag + is used to handle escaped parenthesis. When used in Visual mode it is made characterwise. a> *v_a>* *v_a<* *a>* *a<* a< "a <> block", select [count] <> blocks, from the [count]'th unmatched '<' backwards to the matching - '>', including the '<' and '>'. + '>', including the '<' and '>'. The |cpo-M| option flag + is used to handle escaped '<' and '>'. When used in Visual mode it is made characterwise. i> *v_i>* *v_i<* *i>* *i<* i< "inner <> block", select [count] <> blocks, from the [count]'th unmatched '<' backwards to the matching - '>', excluding the '<' and '>'. + '>', excluding the '<' and '>'. The |cpo-M| option flag + is used to handle escaped '<' and '>'. When used in Visual mode it is made characterwise. *v_at* *at* @@ -649,14 +655,16 @@ a} *v_a}* *a}* *a{* a{ *v_aB* *v_a{* *aB* aB "a Block", select [count] Blocks, from "[count] [{" to the matching '}', including the '{' and '}' (see - |[{|). + |[{|). The |cpo-M| option flag is used to handle + escaped braces. When used in Visual mode it is made characterwise. i} *v_i}* *i}* *i{* i{ *v_iB* *v_i{* *iB* iB "inner Block", select [count] Blocks, from "[count] [{" to the matching '}', excluding the '{' and '}' (see - |[{|). + |[{|). The |cpo-M| option flag is used to handle + escaped braces. When used in Visual mode it is made characterwise. a" *v_aquote* *aquote* @@ -683,6 +691,7 @@ i` *v_i`* *i`* Special case: With a count of 2 the quotes are included, but no extra white space as with a"/a'/a`. + *o_object-select* When used after an operator: For non-block objects: For the "a" commands: The operator applies to the object and the white @@ -698,6 +707,7 @@ For a block object: the surrounding braces are excluded. For the "a" commands, the braces are included. + *v_object-select* When used in Visual mode: When start and end of the Visual area are the same (just after typing "v"): One object is selected, the same as for using an operator. @@ -1069,14 +1079,14 @@ can go to cursor positions before older jumps, and back again. Thus you can move up and down the list. There is a separate jump list for each window. The maximum number of entries is fixed at 100. -For example, after three jump commands you have this jump list: - - jump line col file/text ~ - 3 1 0 some text ~ - 2 70 0 another line ~ - 1 1154 23 end. ~ - > ~ +For example, after three jump commands you have this jump list: > + jump line col file/text + 3 1 0 some text + 2 70 0 another line + 1 1154 23 end. + > +< The "file/text" column shows the file name, or the text at the jump if it is in the current file (an indent is removed and a long line is truncated to fit in the window). @@ -1085,14 +1095,14 @@ The marker ">" indicates the current position in the jumplist. It may not be shown when filtering the |:jumps| command using |:filter| You are currently in line 1167. If you then use the CTRL-O command, the -cursor is put in line 1154. This results in: - - jump line col file/text ~ - 2 1 0 some text ~ - 1 70 0 another line ~ - > 0 1154 23 end. ~ - 1 1167 0 foo bar ~ +cursor is put in line 1154. This results in: > + jump line col file/text + 2 1 0 some text + 1 70 0 another line + > 0 1154 23 end. + 1 1167 0 foo bar +< The pointer will be set at the last used jump position. The next CTRL-O command will use the entry above it, the next CTRL-I command will use the entry below it. If the pointer is below the last entry, this indicates that @@ -1116,15 +1126,15 @@ command. You can explicitly add a jump by setting the ' mark with "m'". Note that calling setpos() does not do this. After the CTRL-O command that got you into line 1154 you could give another -jump command (e.g., "G"). The jump list would then become: - - jump line col file/text ~ - 4 1 0 some text ~ - 3 70 0 another line ~ - 2 1167 0 foo bar ~ - 1 1154 23 end. ~ - > ~ - +jump command (e.g., "G"). The jump list would then become: > + + jump line col file/text + 4 1 0 some text + 3 70 0 another line + 2 1167 0 foo bar + 1 1154 23 end. + > +< The line numbers will be adjusted for deleted and inserted lines. This fails if you stop editing a file without writing, like with ":n!". @@ -1133,7 +1143,45 @@ When you split a window, the jumplist will be copied to the new window. If you have included the ' item in the 'viminfo' option the jumplist will be stored in the viminfo file and restored when starting Vim. - + *jumplist-stack* +When 'jumpoptions' option includes "stack", the jumplist behaves like the tag +stack. When jumping to a new location from the middle of the jumplist, the +locations after the current position will be discarded. With this option set +you can move through a tree of jump locations. When going back up a branch and +then down another branch, CTRL-O still takes you further up the tree. + +Given a jumplist like the following in which CTRL-O has been used to move back +three times to location X: > + + jump line col file/text + 2 1260 8 mark.c <-- location X-2 + 1 685 0 eval.c <-- location X-1 + > 0 462 36 eval.c <-- location X + 1 479 39 eval.c + 2 213 2 mark.c + 3 181 0 mark.c +< +jumping to (new) location Y results in the locations after the current +locations being removed: > + + jump line col file/text + 3 1260 8 mark.c <-- location X-2 + 2 685 0 eval.c <-- location X-1 + 1 462 36 eval.c <-- location X + > +< +Then, when yet another location Z is jumped to, the new location Y appears +directly after location X in the jumplist and location X remains in the same +position relative to the locations (X-1, X-2, etc., ...) that had been before +it prior to the original jump from X to Y: > + + jump line col file/text + 4 1260 8 mark.c <-- location X-2 + 3 685 0 eval.c <-- location X-1 + 2 462 36 eval.c <-- location X + 1 100 0 buffer.c <-- location Y + > +< CHANGE LIST JUMPS *changelist* *change-list-jumps* *E664* When making a change the cursor position is remembered. One position is diff --git a/usr/share/vim/vim90/doc/options.txt b/usr/share/vim/vim90/doc/options.txt index 6c82fa4959e..a24dd0490de 100644 --- a/usr/share/vim/vim90/doc/options.txt +++ b/usr/share/vim/vim90/doc/options.txt @@ -71,7 +71,7 @@ achieve special effects. These options come in three forms: 'ttytype' Warning: This may have a lot of side effects. - *:set-args* *E487* *E521* + *:set-args* *:set=* *E487* *E521* :se[t] {option}={value} or :se[t] {option}:{value} Set string or number option to {value}. @@ -79,7 +79,9 @@ achieve special effects. These options come in three forms: hex (preceded with 0x) or octal (preceded with '0'). The old value can be inserted by typing 'wildchar' (by default this is a or CTRL-E if 'compatible' is - set). See |cmdline-completion|. + set). Many string options with fixed syntax and names + also support completing known values. See + |cmdline-completion| and |complete-set-option|. White space between {option} and '=' is allowed and will be ignored. White space between '=' and {value} is not allowed. @@ -113,6 +115,9 @@ achieve special effects. These options come in three forms: When the option is a list of flags, {value} must be exactly as they appear in the option. Remove flags one by one to avoid problems. + The individual values from a comma separated list or + list of flags can be inserted by typing 'wildchar'. + See |complete-set-option|. Also see |:set-args| above. The {option} arguments to ":set" may be repeated. For example: > @@ -4899,6 +4904,16 @@ A jump table for the options with a short description can be found at |Q_op|. Otherwise only one space is inserted. NOTE: This option is set when 'compatible' is set. + *'jumpoptions'* *'jop'* +'jumpoptions' 'jop' string (default "") + global + List of words that change the behavior of the |jumplist|. + stack Make the jumplist behave like the tagstack. + Relative location of entries in the jumplist is + preserved at the cost of discarding subsequent entries + when navigating backwards in the jumplist and then + jumping to a location. |jumplist-stack| + *'key'* 'key' string (default "") local to buffer @@ -4913,6 +4928,8 @@ A jump table for the options with a short description can be found at |Q_op|. "echo &key". This is to avoid showing it to someone who shouldn't know. It also means you cannot see it yourself once you have set it, be careful not to make a typing error! + You also cannot use |:set-=|, |:set+=|, |:set^=| on this option to + prevent an attacker from guessing substrings in your key. You can use "&key" in an expression to detect whether encryption is enabled. When 'key' is set it returns "*****" (five stars). @@ -6747,9 +6764,9 @@ A jump table for the options with a short description can be found at |Q_op|. *'scrollbind'* *'scb'* *'noscrollbind'* *'noscb'* 'scrollbind' 'scb' boolean (default off) local to window - See also |scroll-binding|. When this option is set, the current - window scrolls as other scrollbind windows (windows that also have - this option set) scroll. This option is useful for viewing the + See also |scroll-binding|. When this option is set, scrolling the + current window also scrolls other scrollbind windows (windows that + also have this option set). This option is useful for viewing the differences between two versions of a file, see 'diff'. See |'scrollopt'| for options that determine how this option should be interpreted. diff --git a/usr/share/vim/vim90/doc/quickref.txt b/usr/share/vim/vim90/doc/quickref.txt index ffdfd108acf..65a560a30f8 100644 --- a/usr/share/vim/vim90/doc/quickref.txt +++ b/usr/share/vim/vim90/doc/quickref.txt @@ -772,6 +772,7 @@ Short explanation of each option: *option-list* 'iskeyword' 'isk' characters included in keywords 'isprint' 'isp' printable characters 'joinspaces' 'js' two spaces after a period with a join command +'jumpoptions' 'jop' specifies how jumping is done 'key' encryption key 'keymap' 'kmp' name of a keyboard mapping 'keymodel' 'km' enable starting/stopping selection with keys diff --git a/usr/share/vim/vim90/doc/scroll.txt b/usr/share/vim/vim90/doc/scroll.txt index 8e57be441c3..91fa22824f9 100644 --- a/usr/share/vim/vim90/doc/scroll.txt +++ b/usr/share/vim/vim90/doc/scroll.txt @@ -191,16 +191,16 @@ windows can be given this behavior by setting the (window-specific) other 'scrollbind' windows are scrolled the same amount, if possible. The behavior of 'scrollbind' can be modified by the 'scrollopt' option. -When using the scrollbars, the binding only happens when scrolling the window -with focus (where the cursor is). You can use this to avoid scroll-binding -for a moment without resetting options. +When using the scrollbars or the mouse wheel, the binding only happens when +scrolling the window with focus (where the cursor is). You can use this to +avoid scroll-binding for a moment without resetting options. When a window also has the 'diff' option set, the scroll-binding uses the differences between the two buffers to synchronize the position precisely. Otherwise the following method is used. *scrollbind-relative* -Each 'scrollbind' window keeps track of its "relative offset," which can be +Each 'scrollbind' window keeps track of its "relative offset", which can be thought of as the difference between the current window's vertical scroll position and the other window's vertical scroll position. When one of the 'scrollbind' windows is asked to vertically scroll past the beginning or end @@ -224,9 +224,10 @@ option. *scrollbind-quickadj* The 'scrollbind' flag is meaningful when using keyboard commands to vertically -scroll a window, and also meaningful when using the vertical scrollbar of the -window which has the cursor focus. However, when using the vertical scrollbar -of a window which doesn't have the cursor focus, 'scrollbind' is ignored. +scroll a window, and is also meaningful when using the vertical scrollbar or +the mouse wheel in the window which has the cursor focus. However, when using +the vertical scrollbar or the mouse wheel in a window which doesn't have the +cursor focus, 'scrollbind' is ignored. This allows quick adjustment of the relative offset of 'scrollbind' windows. ============================================================================== diff --git a/usr/share/vim/vim90/doc/tags b/usr/share/vim/vim90/doc/tags index 907d290f3e8..249800fd292 100644 --- a/usr/share/vim/vim90/doc/tags +++ b/usr/share/vim/vim90/doc/tags @@ -433,7 +433,9 @@ $quote eval.txt /*$quote* 'isp' options.txt /*'isp'* 'isprint' options.txt /*'isprint'* 'joinspaces' options.txt /*'joinspaces'* +'jop' options.txt /*'jop'* 'js' options.txt /*'js'* +'jumpoptions' options.txt /*'jumpoptions'* 'key' options.txt /*'key'* 'keymap' options.txt /*'keymap'* 'keymodel' options.txt /*'keymodel'* @@ -1481,6 +1483,7 @@ $quote eval.txt /*$quote* +wildmenu various.txt /*+wildmenu* +windows various.txt /*+windows* +writebackup various.txt /*+writebackup* ++xattr various.txt /*+xattr* +xfontset various.txt /*+xfontset* +xim various.txt /*+xim* +xpm various.txt /*+xpm* @@ -3206,6 +3209,7 @@ $quote eval.txt /*$quote* :set-inv options.txt /*:set-inv* :set-termcap options.txt /*:set-termcap* :set-verbose options.txt /*:set-verbose* +:set= options.txt /*:set=* :set^= options.txt /*:set^=* :set_env options.txt /*:set_env* :setf options.txt /*:setf* @@ -4418,13 +4422,11 @@ E1325 vim9class.txt /*E1325* E1326 vim9class.txt /*E1326* E1327 vim9class.txt /*E1327* E1328 vim9class.txt /*E1328* -E1329 vim9class.txt /*E1329* E133 userfunc.txt /*E133* E1330 vim9class.txt /*E1330* E1331 vim9class.txt /*E1331* E1332 vim9class.txt /*E1332* E1333 vim9class.txt /*E1333* -E1334 vim9class.txt /*E1334* E1335 vim9class.txt /*E1335* E1336 options.txt /*E1336* E1337 vim9class.txt /*E1337* @@ -4458,17 +4460,36 @@ E1361 syntax.txt /*E1361* E1362 vim9class.txt /*E1362* E1363 vim9class.txt /*E1363* E1364 recover.txt /*E1364* +E1365 vim9class.txt /*E1365* +E1366 vim9class.txt /*E1366* +E1367 vim9class.txt /*E1367* +E1368 vim9class.txt /*E1368* +E1369 vim9class.txt /*E1369* E137 starting.txt /*E137* E1370 vim9class.txt /*E1370* +E1371 vim9class.txt /*E1371* +E1372 vim9class.txt /*E1372* +E1373 vim9class.txt /*E1373* +E1374 vim9class.txt /*E1374* +E1375 vim9class.txt /*E1375* +E1376 vim9class.txt /*E1376* +E1377 vim9class.txt /*E1377* +E1378 vim9class.txt /*E1378* +E1379 vim9class.txt /*E1379* E138 starting.txt /*E138* +E1380 vim9class.txt /*E1380* +E1381 vim9class.txt /*E1381* +E1382 vim9class.txt /*E1382* +E1383 vim9class.txt /*E1383* +E1384 vim9class.txt /*E1384* +E1385 vim9class.txt /*E1385* +E1386 vim9class.txt /*E1386* +E1387 vim9class.txt /*E1387* +E1388 vim9class.txt /*E1388* +E1389 vim9class.txt /*E1389* E139 message.txt /*E139* +E1390 vim9class.txt /*E1390* E140 message.txt /*E140* -E1400 builtin.txt /*E1400* -E1401 builtin.txt /*E1401* -E1402 builtin.txt /*E1402* -E1403 builtin.txt /*E1403* -E1404 builtin.txt /*E1404* -E1405 builtin.txt /*E1405* E141 message.txt /*E141* E142 message.txt /*E142* E143 autocmd.txt /*E143* @@ -4480,6 +4501,16 @@ E148 repeat.txt /*E148* E149 helphelp.txt /*E149* E15 eval.txt /*E15* E150 helphelp.txt /*E150* +E1500 builtin.txt /*E1500* +E1501 builtin.txt /*E1501* +E1502 builtin.txt /*E1502* +E1503 builtin.txt /*E1503* +E1504 builtin.txt /*E1504* +E1505 builtin.txt /*E1505* +E1506 editing.txt /*E1506* +E1507 editing.txt /*E1507* +E1508 editing.txt /*E1508* +E1509 editing.txt /*E1509* E151 helphelp.txt /*E151* E152 helphelp.txt /*E152* E153 helphelp.txt /*E153* @@ -5905,6 +5936,7 @@ added-7.3 version7.txt /*added-7.3* added-7.4 version7.txt /*added-7.4* added-8.1 version8.txt /*added-8.1* added-8.2 version8.txt /*added-8.2* +added-9.1 version9.txt /*added-9.1* added-BeOS version5.txt /*added-BeOS* added-Mac version5.txt /*added-Mac* added-VMS version5.txt /*added-VMS* @@ -6285,6 +6317,7 @@ changed-7.3 version7.txt /*changed-7.3* changed-7.4 version7.txt /*changed-7.4* changed-8.1 version8.txt /*changed-8.1* changed-8.2 version8.txt /*changed-8.2* +changed-9.1 version9.txt /*changed-9.1* changelist motion.txt /*changelist* changelog.vim syntax.txt /*changelog.vim* changenr() builtin.txt /*changenr()* @@ -6367,7 +6400,7 @@ cino-{ indent.txt /*cino-{* cino-} indent.txt /*cino-}* cinoptions-values indent.txt /*cinoptions-values* class vim9class.txt /*class* -class-function vim9class.txt /*class-function* +class-method vim9class.txt /*class-method* clear-undo undo.txt /*clear-undo* clearmatches() builtin.txt /*clearmatches()* client-server remote.txt /*client-server* @@ -6457,6 +6490,7 @@ complete-items insert.txt /*complete-items* complete-popup insert.txt /*complete-popup* complete-popuphidden insert.txt /*complete-popuphidden* complete-script-local-functions cmdline.txt /*complete-script-local-functions* +complete-set-option cmdline.txt /*complete-set-option* complete_CTRL-E insert.txt /*complete_CTRL-E* complete_CTRL-Y insert.txt /*complete_CTRL-Y* complete_add() builtin.txt /*complete_add()* @@ -6472,6 +6506,7 @@ conceal syntax.txt /*conceal* confirm() builtin.txt /*confirm()* connection-refused message.txt /*connection-refused* console-menus gui.txt /*console-menus* +constructor vim9class.txt /*constructor* context.vim ft_context.txt /*context.vim* control intro.txt /*control* conversion-server mbyte.txt /*conversion-server* @@ -6645,6 +6680,7 @@ debugger.txt debugger.txt /*debugger.txt* dec-mouse options.txt /*dec-mouse* decada_members ft_ada.txt /*decada_members* deepcopy() builtin.txt /*deepcopy()* +default-constructor vim9class.txt /*default-constructor* defaults.vim starting.txt /*defaults.vim* defaults.vim-explained usr_05.txt /*defaults.vim-explained* define-function userfunc.txt /*define-function* @@ -8284,6 +8320,7 @@ json_encode() builtin.txt /*json_encode()* jtags tagsrch.txt /*jtags* jump-motions motion.txt /*jump-motions* jumplist motion.txt /*jumplist* +jumplist-stack motion.txt /*jumplist-stack* jumpto-diffs diff.txt /*jumpto-diffs* k motion.txt /*k* kcc uganda.txt /*kcc* @@ -8895,6 +8932,7 @@ netrw.vim pi_netrw.txt /*netrw.vim* netrw_filehandler pi_netrw.txt /*netrw_filehandler* netterm-mouse options.txt /*netterm-mouse* network pi_netrw.txt /*network* +new() vim9class.txt /*new()* new-5 version5.txt /*new-5* new-6 version6.txt /*new-6* new-7 version7.txt /*new-7* @@ -8955,6 +8993,7 @@ new-operator-mod version6.txt /*new-operator-mod* new-options-5.2 version5.txt /*new-options-5.2* new-options-5.4 version5.txt /*new-options-5.4* new-other-8.2 version8.txt /*new-other-8.2* +new-other-9.1 version9.txt /*new-other-9.1* new-perl-python version5.txt /*new-perl-python* new-persistent-undo version7.txt /*new-persistent-undo* new-plugins version6.txt /*new-plugins* @@ -9027,6 +9066,7 @@ numbersize-variable eval.txt /*numbersize-variable* o insert.txt /*o* o_CTRL-V motion.txt /*o_CTRL-V* o_V motion.txt /*o_V* +o_object-select motion.txt /*o_object-select* o_v motion.txt /*o_v* object vim9class.txt /*object* object-motions motion.txt /*object-motions* @@ -9114,6 +9154,7 @@ patches-8 version8.txt /*patches-8* patches-8.1 version8.txt /*patches-8.1* patches-8.2 version8.txt /*patches-8.2* patches-9 version9.txt /*patches-9* +patches-9.1 version9.txt /*patches-9.1* patches-after-8.2 version9.txt /*patches-after-8.2* pathshorten() builtin.txt /*pathshorten()* pattern pattern.txt /*pattern* @@ -9283,6 +9324,8 @@ printf-s builtin.txt /*printf-s* printf-x builtin.txt /*printf-x* printing print.txt /*printing* printing-formfeed print.txt /*printing-formfeed* +private-method vim9class.txt /*private-method* +private-variable vim9class.txt /*private-variable* profile repeat.txt /*profile* profiling repeat.txt /*profiling* profiling-variable eval.txt /*profiling-variable* @@ -10844,6 +10887,7 @@ v_iw motion.txt /*v_iw* v_i{ motion.txt /*v_i{* v_i} motion.txt /*v_i}* v_o visual.txt /*v_o* +v_object-select motion.txt /*v_object-select* v_p change.txt /*v_p* v_r change.txt /*v_r* v_s change.txt /*v_s* @@ -10890,6 +10934,7 @@ version-8.0 version8.txt /*version-8.0* version-8.1 version8.txt /*version-8.1* version-8.2 version8.txt /*version-8.2* version-9.0 version9.txt /*version-9.0* +version-9.1 version9.txt /*version-9.1* version-variable eval.txt /*version-variable* version4.txt version4.txt /*version4.txt* version5.txt version5.txt /*version5.txt* @@ -10905,6 +10950,7 @@ version8.1 version8.txt /*version8.1* version8.2 version8.txt /*version8.2* version8.txt version8.txt /*version8.txt* version9.0 version9.txt /*version9.0* +version9.1 version9.txt /*version9.1* version9.txt version9.txt /*version9.txt* versionlong-variable eval.txt /*versionlong-variable* vi intro.txt /*vi* @@ -10923,6 +10969,7 @@ vim-8.1 version8.txt /*vim-8.1* vim-8.2 version8.txt /*vim-8.2* vim-9 version9.txt /*vim-9* vim-9.0 version9.txt /*vim-9.0* +vim-9.1 version9.txt /*vim-9.1* vim-additions vi_diff.txt /*vim-additions* vim-announce intro.txt /*vim-announce* vim-arguments starting.txt /*vim-arguments* @@ -11182,6 +11229,7 @@ x-resources version5.txt /*x-resources* x11-clientserver remote.txt /*x11-clientserver* x11-cut-buffer gui_x11.txt /*x11-cut-buffer* x11-selection gui_x11.txt /*x11-selection* +xattr editing.txt /*xattr* xf86conf.vim syntax.txt /*xf86conf.vim* xfontset mbyte.txt /*xfontset* xfree-xterm syntax.txt /*xfree-xterm* diff --git a/usr/share/vim/vim90/doc/terminal.txt b/usr/share/vim/vim90/doc/terminal.txt index c02a885c272..62bc6e657ec 100644 --- a/usr/share/vim/vim90/doc/terminal.txt +++ b/usr/share/vim/vim90/doc/terminal.txt @@ -1532,7 +1532,7 @@ The function will be called with the list of arguments so far, and a second argument that is the name of the pty. *gdb-version* Only debuggers fully compatible with gdb will work. Vim uses the GDB/MI -interface. The "new-ui" command requires gdb version 7.12 or later. if you +interface. The "new-ui" command requires gdb version 7.12 or later. If you get this error: Undefined command: "new-ui". Try "help".~ Then your gdb is too old. diff --git a/usr/share/vim/vim90/doc/todo.txt b/usr/share/vim/vim90/doc/todo.txt index db1d771fd15..4dc8db44b6e 100644 --- a/usr/share/vim/vim90/doc/todo.txt +++ b/usr/share/vim/vim90/doc/todo.txt @@ -120,16 +120,9 @@ Upcoming larger works: - example plugin: https://github.com/uga-rosa/dps-vsctm.vim -Further Vim9 improvements, possibly after launch: +Further Vim9 improvements: - Classes and Interfaces. See |vim9-classes| - - Change access: public by default, private by prefixing "_". - Check for error: can't have same name twice (ignoring "_" prefix). - - Private methods? - either: private def Func() - or: def _Func() - Perhaps use "private" keyword instead of "_" prefix? - "final" object members - can only be set in the constructor. - - Support export/import of classes and interfaces. - Cannot use class type of itself in the method (Issue #12369) - Cannot use an object method in a lambda #12417 Define all methods before compiling them? @@ -137,13 +130,6 @@ Further Vim9 improvements, possibly after launch: Also #12081 first case. - Using list of functions does not work #12081 (repro in later message). - First argument of call() cannot be "obj.Func". (#11865) - - null_object - constant type 17 not supported (Issue #12043) - - problem compiling object method call as function call argument (Issue - #12081) - - Make ":defcompile ClassName" compile all functions and methods in the - class. - - Forward declaration of a class? E.g. for Clone() function. - email lifepillar 2023 Mar 26 - Getting member of variable with "any" type should be handled at runtime. Remove temporary solution from #12096 / patch 9.0.1375. - "obj.Method()" does not always work in a compiled function, assumes "obj" @@ -151,18 +137,21 @@ Further Vim9 improvements, possibly after launch: Issue #11822: any.Func() can be a dict or an object call, need to handle this at runtime. Also see #12198 for an example. Possibly issue #11981 can be fixed at the same time (has two examples). - - accept line breaks in member initialization. #11957 + - Support export/import of classes and interfaces. + - Make ":defcompile ClassName" compile all functions and methods in the + class. + - Forward declaration of a class? E.g. for Clone() function. + Email lifepillar 2023 Mar 26 - object empty(), len() - can class define a method to be used for them? - add to help: when using a default new() method then reordering object members may cause trouble. Can define new() without arguments to avoid. - - TODO items: check types for "implements" - members and methods - When "Meta" is a class, is "const MetaAlias = Meta" allowed? It should - either work or given an error. possibly give an error now and implement it + either work or given an error. Possibly give an error now and implement it later (using a typedef). #12006 - how about lock/unlock? - - When checking "implements" also check types of members and function args. - For chaining, allow using the class name as type for function return value. + - Implement "specifies" interface - Implement generics - Add "assignable" (class or child)? - More efficient way for interface member index than iterating over list? diff --git a/usr/share/vim/vim90/doc/various.txt b/usr/share/vim/vim90/doc/various.txt index e478c8266ea..b2b79039358 100644 --- a/usr/share/vim/vim90/doc/various.txt +++ b/usr/share/vim/vim90/doc/various.txt @@ -1,4 +1,4 @@ -*various.txt* For Vim version 9.0. Last change: 2022 Dec 13 +*various.txt* For Vim version 9.0. Last change: 2023 Sep 27 VIM REFERENCE MANUAL by Bram Moolenaar @@ -503,6 +503,7 @@ T *+windows* more than one window; Always enabled since 8.0.1118. m *+writebackup* |'writebackup'| is default on m *+xim* X input method |xim| *+xfontset* X fontset support |xfontset| +N *+xattr* compiled with extended attribute support (Linux only) *+xpm* pixmap support m *+xpm_w32* Win32 GUI only: pixmap support |w32-xpm-support| *+xsmp* XSMP (X session management) support diff --git a/usr/share/vim/vim90/doc/version9.txt b/usr/share/vim/vim90/doc/version9.txt index 95b766d6c84..09d6b3b7e36 100644 --- a/usr/share/vim/vim90/doc/version9.txt +++ b/usr/share/vim/vim90/doc/version9.txt @@ -1198,7 +1198,7 @@ Solution: Use "curtab" if "tp" is NULL. (closes #5475) Files: src/evalwindow.c, src/testdir/test_getvar.vim Patch 8.2.0118 -Problem: Crash when cycling to buffers involving popup window . +Problem: Crash when cycling to buffers involving popup window. Solution: Do not decrement buffer reference count. Files: src/popupwin.c, src/testdir/test_popupwin.vim, src/testdir/dumps/Test_popupwin_infopopup_7.dump @@ -31679,4 +31679,85 @@ Solution: make menu generation script use Vim9 script, fix errors. Files: runtime/makemenu.vim +============================================================================== +VERSION 9.1 *version-9.1* *version9.1* *vim-9.1* + +This section is about improvements made between version 9.0 and 9.1. + +This release has hundreds of bug fixes, there are a few new features and there +are many minor improvements. + +Vim9 classes +------------ + +Virtual text +------------ + +Smooth Scroll +------------- + +Other improvements *new-other-9.1* +------------------ + +Changed *changed-9.1* +------- + +Added *added-9.1* +----- + +Various syntax, indent and other plugins were added. + +Functions: ~ + +|err_teapot()| produce error 418 or 503 +|getbufoneline()| get a one line from the specified buffer +|getcellwidths()| get character cell width overrides +|getmouseshape()| get name of the current mouse shape +|getscriptinfo()| get list of sourced vim scripts +|indexof()| index in a List or Blob of a true expression +|instanceof()| check if a variable is an instance of a given class +|keytrans()| translate internal key codes to be usable with |:map| +|popup_findecho()| get window ID for popup used for |:echowindow| +|setcmdline()| set the current command line +|strutf16len()| number of UTF-16 code units in a string +|swapfilelist()| list of existing swap files in 'directory' +|test_mswin_event()| generate an MS-Windows event for testing +|utf16idx()| UTF-16 index of a byte in a string + + +Autocommands: ~ + +|TextChangedT| after a change was made to the text in Terminal mode +|WinResized| after a window in the current tab page is resized + + +Commands: ~ + +|:abstract| define an Vim9 abstract class +|:class| start of a class specification +|:defer| call function when current function is done +|:echowindow| same as :echomsg, but use a popup window +|:endinterface| end of an interface specification +|:endclass| end of a class specification +|:horizontal| following window command work horizontally +|:interface| start of an interface specification +|:public| prefix for a class or object member +|:static| prefix for a class member or function +|:this| prefix for an object member + + +Options: ~ + +'jumpoptions' specifies how jumping is done +'keyprotocol' what keyboard protocol to use for what terminal +'lispoptions' changes how Lisp indenting is done +'showcmdloc' where to show (partial) command +'smoothscroll' scroll by screen lines when 'wrap' is set +'splitkeep' determines scroll behavior for split windows + + +Patches *patches-9.1* +------- + + vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/usr/share/vim/vim90/doc/vim9class.txt b/usr/share/vim/vim90/doc/vim9class.txt index 20ad4bbab59..06602546968 100644 --- a/usr/share/vim/vim90/doc/vim9class.txt +++ b/usr/share/vim/vim90/doc/vim9class.txt @@ -1,4 +1,4 @@ -*vim9class.txt* For Vim version 9.0. Last change: 2023 Mar 22 +*vim9class.txt* For Vim version 9.0. Last change: 2023 Sep 18 VIM REFERENCE MANUAL by Bram Moolenaar @@ -11,7 +11,7 @@ Vim9 classes, objects, interfaces, types and enums. 1. Overview |Vim9-class-overview| 2. A simple class |Vim9-simple-class| -3. Class members and functions |Vim9-class-member| +3. Class variables and methods |Vim9-class-member| 4. Using an abstract class |Vim9-abstract-class| 5. Using an interface |Vim9-using-interface| 6. More class details |Vim9-class| @@ -37,7 +37,7 @@ The basic item is an object: functions are invoked "on the object", which is what sets it apart from the traditional separation of data and code that manipulates the data. - An object has a well defined interface, with typed member variables and - member functions. + methods. - Objects are created from a class and all objects have the same interface. This does not change at runtime, it is not dynamic. @@ -103,7 +103,7 @@ You can create an object from this class with the new() method: > var pos = TextPosition.new(1, 1) -The object members "lnum" and "col" can be accessed directly: > +The object variables "lnum" and "col" can be accessed directly: > echo $'The text position is ({pos.lnum}, {pos.col})' < *E1317* *E1327* @@ -111,50 +111,54 @@ If you have been using other object-oriented languages you will notice that in Vim the object members are consistently referred to with the "this." prefix. This is different from languages like Java and TypeScript. The naming convention makes the object members easy to spot. Also, when a -variable does not have the "this." prefix you know it is not an object member. +variable does not have the "this." prefix you know it is not an object +variable. -Member write access ~ +Object variable write access ~ -Now try to change an object member directly: > +Now try to change an object variable directly: > pos.lnum = 9 < *E1335* -This will give you an error! That is because by default object members can be -read but not set. That's why the TextPosition class provides a method for it: > +This will give you an error! That is because by default object variables can +be read but not set. That's why the TextPosition class provides a method for +it: > pos.SetLnum(9) -Allowing to read but not set an object member is the most common and safest +Allowing to read but not set an object variable is the most common and safest way. Most often there is no problem using a value, while setting a value may have side effects that need to be taken care of. In this case, the SetLnum() method could check if the line number is valid and either give an error or use the closest valid value. *:public* *E1331* -If you don't care about side effects and want to allow the object member to be -changed at any time, you can make it public: > +If you don't care about side effects and want to allow the object variable to +be changed at any time, you can make it public: > public this.lnum: number public this.col: number Now you don't need the SetLnum(), SetCol() and SetPosition() methods, setting "pos.lnum" directly above will no longer give an error. - *E1334* -If you try to set an object member that doesn't exist you get an error: > + *E1326* +If you try to set an object variable that doesn't exist you get an error: > pos.other = 9 -< E1334: Object member not found: other ~ +< E1326: Member not found on object "TextPosition": other ~ + *E1376* +A object variable cannot be accessed using the class name. -Private members ~ - *E1332* *E1333* -On the other hand, if you do not want the object members to be read directly, +Private variables ~ + *private-variable* *E1332* *E1333* +On the other hand, if you do not want the object variables to be read directly, you can make them private. This is done by prefixing an underscore to the name: > this._lnum: number this._col number -Now you need to provide methods to get the value of the private members. +Now you need to provide methods to get the value of the private variables. These are commonly called getters. We recommend using a name that starts with "Get": > @@ -166,7 +170,7 @@ These are commonly called getters. We recommend using a name that starts with return this._col enddef -This example isn't very useful, the members might as well have been public. +This example isn't very useful, the variables might as well have been public. It does become useful if you check the value. For example, restrict the line number to the total number of lines: > @@ -176,9 +180,9 @@ number to the total number of lines: > endif return this._lnum enddef - - +< Private methods ~ + *private-method* *E1366* If you want object methods to be accessible only from other methods of the same class and not used from outside the class, then you can make them private. This is done by prefixing the method name with an underscore: > @@ -199,9 +203,9 @@ the above class): > a._Foo() < Simplifying the new() method ~ - -Many constructors take values for the object members. Thus you very often see -this pattern: > + *new()* *constructor* +Many constructors take values for the object variables. Thus you very often +see this pattern: > class SomeClass this.lnum: number @@ -212,20 +216,22 @@ this pattern: > this.col = col enddef endclass - -Not only is this text you need to write, it also has the type of each member -twice. Since this is so common a shorter way to write new() is provided: > +< + *E1390* +Not only is this text you need to write, it also has the type of each +variables twice. Since this is so common a shorter way to write new() is +provided: > def new(this.lnum, this.col) enddef -The semantics are easy to understand: Providing the object member name, +The semantics are easy to understand: Providing the object variable name, including "this.", as the argument to new() means the value provided in the -new() call is assigned to that object member. This mechanism comes from the +new() call is assigned to that object variable. This mechanism comes from the Dart language. -Putting together this way of using new() and making the members public results -in a much shorter class definition than what we started with: > +Putting together this way of using new() and making the variables public +results in a much shorter class definition than what we started with: > class TextPosition public this.lnum: number @@ -242,26 +248,32 @@ in a much shorter class definition than what we started with: > The sequence of constructing a new object is: 1. Memory is allocated and cleared. All values are zero/false/empty. -2. For each declared member that has an initializer, the expression is - evaluated and assigned to the member. This happens in the sequence the - members are declared in the class. +2. For each declared object variable that has an initializer, the expression + is evaluated and assigned to the variable. This happens in the sequence + the variables are declared in the class. 3. Arguments in the new() method in the "this.name" form are assigned. 4. The body of the new() method is executed. If the class extends a parent class, the same thing happens. In the second -step the members of the parent class are done first. There is no need to call -"super()" or "new()" on the parent. +step the object variables of the parent class are initialized first. There is +no need to call "super()" or "new()" on the parent. + *E1365* When defining the new() method the return type should not be specified. It always returns an object of the class. + *E1386* +When invoking an object method, the method name should be preceded by the +object variable name. A object method cannot be invoked using the class +name. + ============================================================================== -3. class members and functions *Vim9-class-member* +3. Class Variables and Methods *Vim9-class-member* - *:static* *E1337* *E1338* + *:static* *E1337* *E1338* *E1368* Class members are declared with "static". They are used by the name without a -prefix: > +prefix in the class where they are defined: > class OtherThing this.size: number @@ -272,9 +284,13 @@ prefix: > enddef endclass < *E1340* *E1341* -Since the name is used as-is, shadowing the name by a function argument name +Since the name is used as-is, shadowing the name by a method argument name or local variable name is not allowed. + *E1374* *E1375* *E1384* *E1385* +To access a class member outside of the class where it is defined, the class +name prefix must be used. A class member cannot be accessed using an object. + Just like object members the access can be made private by using an underscore as the first character in the name, and it can be made public by prefixing "public": > @@ -285,10 +301,11 @@ as the first character in the name, and it can be made public by prefixing public static result: number # anybody can read and write endclass < - *class-function* -Class functions are also declared with "static". They have no access to -object members, they cannot use the "this" keyword. > - + *class-method* +Class methods are also declared with "static". They can use the class +variables but they have no access to the object variables, they cannot use the +"this" keyword. +> class OtherThing this.size: number static totalSize: number @@ -301,8 +318,9 @@ object members, they cannot use the "this" keyword. > enddef endclass -Inside the class the function can be called by name directly, outside the -class the class name must be prefixed: `OtherThing.ClearTotalSize()`. +Inside the class the class method can be called by name directly, outside the +class the class name must be prefixed: `OtherThing.ClearTotalSize()`. To use +a super class method in a child class, the class name must be prefixed. Just like object methods the access can be made private by using an underscore as the first character in the method name: > @@ -312,7 +330,7 @@ as the first character in the method name: > echo "Foo" enddef def Bar() - OtherThing._Foo() + _Foo() enddef endclass < @@ -320,6 +338,31 @@ as the first character in the method name: > Note that constructors cannot be declared as "static", because they always are. +To access the class methods and class variables of a super class in an +extended class, the class name prefix should be used just as from anywhere +outside of the defining class: > + + vim9script + class Vehicle + static nextID: number = 1000 + static def GetID(): number + nextID += 1 + return nextID + enddef + endclass + class Car extends Vehicle + this.myID: number + def new() + this.myID = Vehicle.GetID() + enddef + endclass +< +Class variables and methods are not inherited by a child class. A child class +can declare a static variable or a method with the same name as the one in the +super class. Depending on the class where the member is used the +corresponding class member will be used. The type of the class member in a +child class can be different from that in the super class. + ============================================================================== 4. Using an abstract class *Vim9-abstract-class* @@ -358,16 +401,19 @@ class, for which objects can be created. Example: > An abstract class is defined the same way as a normal class, except that it does not have any new() method. *E1359* - *abstract-method* + *abstract-method* *E1371* *E1372* An abstract method can be defined in an abstract class by using the "abstract" -prefix when defining the function: > +prefix when defining the method: > abstract class Shape abstract def Draw() + abstract static def SetColor() endclass - +< + *E1373* A class extending the abstract class must implement all the abstract methods. -Class methods in an abstract class can also be abstract methods. +The signature (arguments, argument types and return type) must be exactly the +same. Class methods in an abstract class can also be abstract methods. ============================================================================== @@ -409,9 +455,10 @@ a number. This example extends the one above: > return this.base * this.height / 2 enddef endclass - +< + *E1348* *E1349* *E1367* *E1382* *E1383* If a class declares to implement an interface, all the items specified in the -interface must appear in the class, with the same types. *E1348* *E1349* +interface must appear in the class, with the same types. The interface name can be used as a type: > @@ -422,7 +469,14 @@ The interface name can be used as a type: > for shape in shapes echo $'the surface is {shape.Surface()}' endfor +< + *E1378* *E1379* *E1380* *E1387* +An interface can contain only object methods and read-only object variables. +An interface cannot contain read-write and private object variables, private +object methods, class variables and class methods. +An interface can extend another interface using "extends". The sub-interface +inherits all the instance variables and methods from the super interface. ============================================================================== @@ -464,16 +518,22 @@ once. They can appear in any order, although this order is recommended: > extends ClassName implements InterfaceName, OtherInterface specifies SomeInterface -< *E1355* -Each member and function name can be used only once. It is not possible to -define a function with the same name and different type of arguments. +< *E1355* *E1369* +Each variable and method name can be used only once. It is not possible to +define a method with the same name and different type of arguments. It is not +possible to use a public and private member variable with the same name. A +object variable name used in a super class cannot be reused in a child class. -Member Initialization ~ -If the type of a member is not explicitly specified in a class, then it is set -to "any" during class definition. When an object is instantiated from the -class, then the type of the member is set. +Object Variable Initialization ~ +If the type of a variable is not explicitly specified in a class, then it is +set to "any" during class definition. When an object is instantiated from the +class, then the type of the variable is set. +The following reserved keyword names cannot be used as an object or class +variable name: "super", "this", "true", "false", "null", "null_blob", +"null_dict", "null_function", "null_list", "null_partial", "null_string", +"null_channel" and "null_job". Extending a class ~ *extends* @@ -483,33 +543,39 @@ The basic idea is to build on top of an existing class, add properties to it. The extended class is called the "base class" or "super class". The new class is called the "child class". -Object members from the base class are all taken over by the child class. It +Object variables from the base class are all taken over by the child class. It is not possible to override them (unlike some other languages). *E1356* *E1357* *E1358* -Object methods of the base class can be overruled. The signature (arguments, -argument types and return type) must be exactly the same. The method of the -base class can be called by prefixing "super.". +Object methods of the base class can be overruled. The number of arguments +must be exactly the same. The method argument type can be a contra-variant +type of the base class method argument type. The method return value type can +be a covariant type of the base class method return value type. The method of +the base class can be called by prefixing "super.". + + *E1377* +The access level of a method (public or private) in a child class should be +the same as the super class. Other object methods of the base class are taken over by the child class. -Class functions, including functions starting with "new", can be overruled, -like with object methods. The function on the base class can be called by -prefixing the name of the class (for class functions) or "super.". +Class methods, including methods starting with "new", can be overruled, like +with object methods. The method on the base class can be called by prefixing +the name of the class (for class methods) or "super.". Unlike other languages, the constructor of the base class does not need to be invoked. In fact, it cannot be invoked. If some initialization from the base class also needs to be done in a child class, put it in an object method and call that method from every constructor(). -If the base class did not specify a new() function then one was automatically -created. This function will not be taken over by the child class. The child -class can define its own new() function, or, if there isn't one, a new() -function will be added automatically. +If the base class did not specify a new() method then one was automatically +created. This method will not be taken over by the child class. The child +class can define its own new() method, or, if there isn't one, a new() method +will be added automatically. A class implementing an interface ~ - *implements* *E1346* *E1347* + *implements* *E1346* *E1347* *E1389* A class can implement one or more interfaces. The "implements" keyword can only appear once *E1350* . Multiple interfaces can be specified, separated by commas. Each interface name can appear only once. *E1351* @@ -517,28 +583,37 @@ commas. Each interface name can appear only once. *E1351* A class defining an interface ~ *specifies* -A class can declare its interface, the object members and methods, with a +A class can declare its interface, the object variables and methods, with a named interface. This avoids the need for separately specifying the interface, which is often done in many languages, especially Java. Items in a class ~ - *E1318* *E1325* *E1326* + *E1318* *E1325* *E1388* Inside a class, in between `:class` and `:endclass`, these items can appear: -- An object member declaration: > - this._memberName: memberType - this.memberName: memberType - public this.memberName: memberType +- An object variable declaration: > + this._privateVariableName: memberType + this.readonlyVariableName: memberType + public this.readwriteVariableName: memberType +- A class variable declaration: > + static _privateClassVariableName: memberType + static readonlyClassVariableName: memberType + static public readwriteClassVariableName: memberType - A constructor method: > def new(arguments) def newName(arguments) +- A class method: > + static def SomeMethod(arguments) + static def _PrivateMethod(arguments) - An object method: > def SomeMethod(arguments) -< *E1329* -For the object member the type must be specified. The best way is to do this -explicitly with ": {type}". For simple types you can also use an initializer, -such as "= 123", and Vim will see that the type is a number. Avoid doing this -for more complex types and when the type will be incomplete. For example: > + def _PrivateMethod(arguments) + +For the object variable the type must be specified. The best way is to do +this explicitly with ": {type}". For simple types you can also use an +initializer, such as "= 123", and Vim will see that the type is a number. +Avoid doing this for more complex types and when the type will be incomplete. +For example: > this.nameList = [] This specifies a list, but the item type is unknown. Better use: > this.nameList: list @@ -558,8 +633,8 @@ prefixed with `:export`: > export interface InterfaceName endinterface < *E1344* -An interface can declare object members, just like in a class but without any -initializer. +An interface can declare object variables, just like in a class but without +any initializer. *E1345* An interface can declare methods with `:def`, including the arguments and return type, but without the body and without `:enddef`. Example: > @@ -573,6 +648,8 @@ An interface name must start with an uppercase letter. *E1343* The "Has" prefix can be used to make it easier to guess this is an interface name, with a hint about what it provides. An interface can only be defined in a |Vim9| script file. *E1342* +An interface cannot "implement" another interface but it can "extend" another +interface. *E1381* null object ~ @@ -580,15 +657,15 @@ null object ~ When a variable is declared to have the type of an object, but it is not initialized, the value is null. When trying to use this null object Vim often does not know what class was supposed to be used. Vim then cannot check if -a member name is correct and you will get an "Using a null object" error, -even when the member name is invalid. *E1360* *E1362* *E1363* +a variable name is correct and you will get an "Using a null object" error, +even when the variable name is invalid. *E1360* *E1362* *E1363* Default constructor ~ - + *default-constructor* In case you define a class without a new() method, one will be automatically defined. This default constructor will have arguments for all the object -members, in the order they were specified. Thus if your class looks like: > +variables, in the order they were specified. Thus if your class looks like: > class AutoNew this.name: string @@ -596,14 +673,14 @@ members, in the order they were specified. Thus if your class looks like: > this.gender: Gender endclass -Then The default constructor will be: > +Then the default constructor will be: > def new(this.name = v:none, this.age = v:none, this.gender = v:none) enddef The "= v:none" default values make the arguments optional. Thus you can also call `new()` without any arguments. No assignment will happen and the default -value for the object members will be used. This is a more useful example, +value for the object variables will be used. This is a more useful example, with default values: > class TextPosition @@ -619,13 +696,13 @@ the name, you can define the constructor like this: > enddef < *E1328* Note that you cannot use another default value than "v:none" here. If you -want to initialize the object members, do it where they are declared. This +want to initialize the object variables, do it where they are declared. This way you only need to look in one place for the default values. -All object members will be used in the default constructor, also private +All object variables will be used in the default constructor, also private access ones. -If the class extends another one, the object members of that class will come +If the class extends another one, the object variables of that class will come first. @@ -739,7 +816,7 @@ the method being called is obvious. No overloading of the constructor ~ In Vim script, both legacy and |Vim9| script, there is no overloading of -functions. That means it is not possible to use the same function name with +methods. That means it is not possible to use the same method name with different types of arguments. Therefore there also is only one new() constructor. @@ -782,39 +859,40 @@ class implements an interface just because the methods happen to match is brittle and leads to obscure problems, let's not do that. -Using "this.member" everywhere ~ +Using "this.variable" everywhere ~ -The object members in various programming languages can often be accessed in +The object variables in various programming languages can often be accessed in different ways, depending on the location. Sometimes "this." has to be prepended to avoid ambiguity. They are usually declared without "this.". That is quite inconsistent and sometimes confusing. A very common issue is that in the constructor the arguments use the same name -as the object member. Then for these members "this." needs to be prefixed in -the body, while for other members this is not needed and often omitted. This -leads to a mix of members with and without "this.", which is inconsistent. +as the object variable. Then for these variables "this." needs to be prefixed +in the body, while for other variables this is not needed and often omitted. +This leads to a mix of variables with and without "this.", which is +inconsistent. For |Vim9| classes the "this." prefix is always used. Also for declaring the -members. Simple and consistent. When looking at the code inside a class it's -also directly clear which variable references are object members and which -aren't. +variables. Simple and consistent. When looking at the code inside a class +it's also directly clear which variable references are object variables and +which aren't. -Using class members ~ +Using class variables ~ -Using "static member" to declare a class member is very common, nothing new -here. In |Vim9| script these can be accessed directly by their name. Very -much like how a script-local variable can be used in a function. Since object -members are always accessed with "this." prepended, it's also quickly clear -what kind of member it is. +Using "static variable" to declare a class variable is very common, nothing +new here. In |Vim9| script these can be accessed directly by their name. +Very much like how a script-local variable can be used in a method. Since +object variables are always accessed with "this." prepended, it's also quickly +clear what kind of variable it is. -TypeScript prepends the class name before the class member, also inside the -class. This has two problems: The class name can be rather long, taking up -quite a bit of space, and when the class is renamed all these places need to -be changed too. +TypeScript prepends the class name before the class variable name, also inside +the class. This has two problems: The class name can be rather long, taking +up quite a bit of space, and when the class is renamed all these places need +to be changed too. -Declaring object and class members ~ +Declaring object and class variables ~ The main choice is whether to use "var" as with variable declarations. TypeScript does not use it: > @@ -823,7 +901,7 @@ TypeScript does not use it: > y = 0; } -Following that Vim object members could be declared like this: > +Following that Vim object variables could be declared like this: > class Point this.x: number this.y = 0 @@ -836,7 +914,7 @@ declaration. Adding "var" changes that: > var this.y = 0 endclass -We also need to be able to declare class members using the "static" keyword. +We also need to be able to declare class variables using the "static" keyword. There we can also choose to leave out "var": > class Point var this.x: number @@ -876,50 +954,50 @@ while there is no ClassName() method, it's a method by another name in the class called ClassName. Quite confusing. -Default read access to object members ~ +Default read access to object variables ~ -Some users will remark that the access rules for object members are +Some users will remark that the access rules for object variables are asymmetric. Well, that is intentional. Changing a value is a very different action than reading a value. The read operation has no side effects, it can be done any number of times without affecting the object. Changing the value can have many side effects, and even have a ripple effect, affecting other objects. -When adding object members one usually doesn't think much about this, just get -the type right. And normally the values are set in the new() method. +When adding object variables one usually doesn't think much about this, just +get the type right. And normally the values are set in the new() method. Therefore defaulting to read access only "just works" in most cases. And when directly writing you get an error, which makes you wonder if you actually want to allow that. This helps writing code with fewer mistakes. -Making object members private with an underscore ~ +Making object variables private with an underscore ~ -When an object member is private, it can only be read and changed inside the +When an object variable is private, it can only be read and changed inside the class (and in sub-classes), then it cannot be used outside of the class. Prepending an underscore is a simple way to make that visible. Various programming languages have this as a recommendation. -In case you change your mind and want to make the object member accessible +In case you change your mind and want to make the object variable accessible outside of the class, you will have to remove the underscore everywhere. Since the name only appears in the class (and sub-classes) they will be easy to find and change. The other way around is much harder: you can easily prepend an underscore to -the object member inside the class to make it private, but any usage elsewhere -you will have to track down and change. You may have to make it a "set" -method call. This reflects the real world problem that taking away access -requires work to be done for all places where that access exists. +the object variable inside the class to make it private, but any usage +elsewhere you will have to track down and change. You may have to make it a +"set" method call. This reflects the real world problem that taking away +access requires work to be done for all places where that access exists. An alternative would have been using the "private" keyword, just like "public" changes the access in the other direction. Well, that's just to reduce the number of keywords. -No protected object members ~ +No protected object variables ~ -Some languages provide several ways to control access to object members. The -most known is "protected", and the meaning varies from language to language. -Others are "shared", "private" and even "friend". +Some languages provide several ways to control access to object variables. +The most known is "protected", and the meaning varies from language to +language. Others are "shared", "private" and even "friend". These rules make life more difficult. That can be justified in projects where many people work on the same, complex code where it is easy to make mistakes. diff --git a/usr/share/vim/vim90/doc/visual.txt b/usr/share/vim/vim90/doc/visual.txt index 540d5c574f6..a91969e41e9 100644 --- a/usr/share/vim/vim90/doc/visual.txt +++ b/usr/share/vim/vim90/doc/visual.txt @@ -1,4 +1,4 @@ -*visual.txt* For Vim version 9.0. Last change: 2022 Dec 04 +*visual.txt* For Vim version 9.0. Last change: 2023 Sep 19 VIM REFERENCE MANUAL by Bram Moolenaar @@ -183,6 +183,8 @@ If you want to highlight exactly the same area as the last time, you can use CTRL-C In Visual mode: Stop Visual mode. When insert mode is pending (the mode message shows "-- (insert) VISUAL --"), it is also stopped. + On MS-Windows, you may need to press CTRL-Break + |dos-CTRL-Break|. ============================================================================== 3. Changing the Visual area *visual-change* diff --git a/usr/share/vim/vim90/filetype.vim b/usr/share/vim/vim90/filetype.vim index 2cd60fb6ae4..d083ff07018 100644 --- a/usr/share/vim/vim90/filetype.vim +++ b/usr/share/vim/vim90/filetype.vim @@ -184,6 +184,9 @@ au BufNewFile,BufRead *.atl,*.as setf atlas " Atom is based on XML au BufNewFile,BufRead *.atom setf xml +" Authzed +au BufNewFile,BufRead *.zed setf authzed + " Autoit v3 au BufNewFile,BufRead *.au3 setf autoit diff --git a/usr/share/vim/vim90/ftplugin/kotlin.vim b/usr/share/vim/vim90/ftplugin/kotlin.vim new file mode 100644 index 00000000000..b21de603ea2 --- /dev/null +++ b/usr/share/vim/vim90/ftplugin/kotlin.vim @@ -0,0 +1,33 @@ +" Vim filetype plugin file +" Language: Kotlin +" Maintainer: Alexander Udalov +" URL: https://github.com/udalov/kotlin-vim +" Last Change: 7 November 2021 +" 2023 Sep 17 by Vim Project (browsefilter) + +if exists('b:did_ftplugin') | finish | endif +let b:did_ftplugin = 1 + +let s:save_cpo = &cpo +set cpo&vim + +setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:// +setlocal commentstring=//\ %s + +setlocal formatoptions-=t formatoptions+=croqnl +silent! setlocal formatoptions+=j + +setlocal includeexpr=substitute(v:fname,'\\.','/','g') +setlocal suffixesadd=.kt + +let b:undo_ftplugin = "setlocal comments< commentstring< ". + \ "formatoptions< includeexpr< suffixesadd<" + +if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter") + let b:browsefilter = "Kotlin Source Files (*.kt, *kts)\t*.kt;*.kts\n" . + \ "All Files (*.*)\t*.*\n" + let b:undo_ftplugin .= " | unlet! b:browsefilter" +endif + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/usr/share/vim/vim90/ftplugin/rmd.vim b/usr/share/vim/vim90/ftplugin/rmd.vim index be6ab7335b7..a407c236dd9 100644 --- a/usr/share/vim/vim90/ftplugin/rmd.vim +++ b/usr/share/vim/vim90/ftplugin/rmd.vim @@ -2,7 +2,7 @@ " Language: R Markdown file " Maintainer: Jakson Alves de Aquino " Homepage: https://github.com/jalvesaq/R-Vim-runtime -" Last Change: Mon Feb 27, 2023 07:15PM +" Last Change: Mon May 29, 2023 06:31AM " Original work by Alex Zvoleff (adjusted from R help for rmd by Michel Kuhlmann) " Only do this when not yet done for this buffer @@ -32,12 +32,18 @@ function FormatRmd() return 1 endfunction +let s:last_line = 0 function SetRmdCommentStr() - if (search("^[ \t]*```[ ]*{r", "bncW") > search("^[ \t]*```$", "bncW")) || ((search('^---$', 'Wn') || search('^\.\.\.$', 'Wn')) && search('^---$', 'bnW')) - set commentstring=#\ %s - else - set commentstring= - endif + if line('.') == s:last_line + return + endif + let s:last_line = line('.') + + if (search("^[ \t]*```[ ]*{r", "bncW") > search("^[ \t]*```$", "bncW")) || ((search('^---$', 'Wn') || search('^\.\.\.$', 'Wn')) && search('^---$', 'bnW')) + set commentstring=#\ %s + else + set commentstring= + endif endfunction " If you do not want both 'comments' and 'commentstring' dynamically defined, diff --git a/usr/share/vim/vim90/ftplugin/sh.vim b/usr/share/vim/vim90/ftplugin/sh.vim index 4409f3f90c4..c227838d18f 100644 --- a/usr/share/vim/vim90/ftplugin/sh.vim +++ b/usr/share/vim/vim90/ftplugin/sh.vim @@ -39,8 +39,7 @@ if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter") let b:undo_ftplugin ..= " | unlet! b:browsefilter" endif -if (exists("b:is_bash") && (b:is_bash == 1)) || - \ (exists("b:is_sh") && (b:is_sh == 1)) +if (exists("b:is_bash") && (b:is_bash == 1)) if !has("gui_running") && executable("less") command! -buffer -nargs=1 Help silent exe '!bash -c "{ help "" 2>/dev/null || man ""; } | LESS= less"' | redraw! elseif has('terminal') diff --git a/usr/share/vim/vim90/indent/kotlin.vim b/usr/share/vim/vim90/indent/kotlin.vim new file mode 100644 index 00000000000..590a5074d16 --- /dev/null +++ b/usr/share/vim/vim90/indent/kotlin.vim @@ -0,0 +1,60 @@ +" Vim indent file +" Language: Kotlin +" Maintainer: Alexander Udalov +" URL: https://github.com/udalov/kotlin-vim +" Last Change: 7 November 2021 +" 2023 Sep 17 by Vim Project (undo_indent) + +if exists('b:did_indent') + finish +endif +let b:did_indent = 1 + +setlocal cinoptions& cinoptions+=j1,L0 +setlocal indentexpr=GetKotlinIndent() +setlocal indentkeys=0},0),!^F,o,O,e, +setlocal autoindent " TODO ? + +let b:undo_indent = "setlocal autoindent< cinoptions< indentexpr< indentkeys<" + +" TODO teach it to count bracket balance, etc. +function! GetKotlinIndent() + if v:lnum == 0 + return 0 + endif + + let prev_num = prevnonblank(v:lnum - 1) + let prev = getline(prev_num) + let prev_indent = indent(prev_num) + let cur = getline(v:lnum) + + if cur =~ '^\s*\*' + return cindent(v:lnum) + endif + + if prev =~ '^\s*\*/' + let st = prev + while st > 1 + if getline(st) =~ '^\s*/\*' + break + endif + let st = st - 1 + endwhile + return indent(st) + endif + + let prev_open_paren = prev =~ '^.*(\s*$' + let cur_close_paren = cur =~ '^\s*).*$' + let prev_open_brace = prev =~ '^.*\({\|->\)\s*$' + let cur_close_brace = cur =~ '^\s*}.*$' + + if prev_open_paren && !cur_close_paren || prev_open_brace && !cur_close_brace + return prev_indent + shiftwidth() + endif + + if cur_close_paren && !prev_open_paren || cur_close_brace && !prev_open_brace + return prev_indent - shiftwidth() + endif + + return prev_indent +endfunction diff --git a/usr/share/vim/vim90/lang/sr/LC_MESSAGES/vim.mo b/usr/share/vim/vim90/lang/sr/LC_MESSAGES/vim.mo index 3157712ed93..f044b077e3e 100644 Binary files a/usr/share/vim/vim90/lang/sr/LC_MESSAGES/vim.mo and b/usr/share/vim/vim90/lang/sr/LC_MESSAGES/vim.mo differ diff --git a/usr/share/vim/vim90/syntax/i3config.vim b/usr/share/vim/vim90/syntax/i3config.vim index 8bc2a6e03c7..3b4765153a5 100644 --- a/usr/share/vim/vim90/syntax/i3config.vim +++ b/usr/share/vim/vim90/syntax/i3config.vim @@ -1,10 +1,9 @@ " Vim syntax file " Language: i3 config file -" Original Author: Mohamed Boughaba +" Original Author: Josef Litos (JosefLitos/i3config.vim) " Maintainer: Quentin Hibon (github user hiqua) -" Version: 0.4.22 -" Reference version (JosefLitos/i3config.vim): 4.22 -" Last Change: 2023-09-12 +" Version: 1.0.0 +" Last Change: 2023-09-14 " References: " http://i3wm.org/docs/userguide.html#configuring @@ -25,18 +24,18 @@ syn match i3ConfigError /.\+/ syn keyword i3ConfigTodo TODO FIXME XXX contained " Helper type definitions -syn match i3ConfigSeparator /[,;]/ contained +syn match i3ConfigSeparator /[,;\\]/ contained syn match i3ConfigParen /[{}]/ contained syn keyword i3ConfigBoolean yes no enabled disabled on off true false contained -syn region i3ConfigString start=/\W\@<="/ skip=/\\"/ end=/"/ contained contains=i3ConfigShCommand,i3ConfigShDelim,i3ConfigShOper,i3ConfigShParam,i3ConfigNumber,i3ConfigVariable,i3ConfigExecAction keepend extend -syn region i3ConfigString start=/\W\@<='/ end=/'/ contained contains=i3ConfigShCommand,i3ConfigShDelim,i3ConfigShOper,i3ConfigShParam,i3ConfigNumber,i3ConfigVariable,i3ConfigExecAction keepend extend -syn match i3ConfigColor /#\w\{3,8}/ contained -syn match i3ConfigNumber /[a-zA-Z_$-]\@&|+=~^*!.?]\+/ contained -syn match i3ConfigShParam /\<-[a-zA-Z0-9_-]\+\>/ contained containedin=i3ConfigVar +syn match i3ConfigShParam /\<-[0-9A-Za-z_-]\+\>/ contained containedin=i3ConfigVar syn region i3ConfigExec start=/^\s*exec\(_always\)\?\( --no-startup-id\)\? [^{]/ skip=/\\$/ end=/$/ contains=i3ConfigExecKeyword,i3ConfigExecAlwaysKeyword,i3ConfigShCommand,i3ConfigShDelim,i3ConfigShOper,i3ConfigShParam,i3ConfigNumber,i3ConfigString,i3ConfigVariable,i3ConfigExecAction keepend " 4.21 Workspaces per output syn keyword i3ConfigWorkspaceKeyword workspace contained syn keyword i3ConfigWorkspaceOutput output contained -syn keyword i3ConfigWorkspaceDir prev next back_and_forth contained +syn keyword i3ConfigWorkspaceDir prev next back_and_forth number contained syn region i3ConfigWorkspaceLine start=/^workspace / skip=/\\$/ end=/$/ contains=i3ConfigWorkspaceKeyword,i3ConfigNumber,i3ConfigString,i3ConfigGaps,i3ConfigWorkspaceOutput,i3ConfigVariable,i3ConfigBoolean,i3ConfigSeparator keepend " 4.22 Changing colors @@ -136,121 +134,126 @@ syn match i3ConfigKeyword /^client\..*$/ contains=i3ConfigDotOperator,i3ConfigCl " 4.23 Interprocess communication syn match i3ConfigIpcKeyword /ipc-socket/ contained -syn match i3ConfigIpc /^ipc-socket .*$/ contains=i3ConfigIpcKeyword +syn match i3ConfigParamLine /^ipc-socket .*$/ contains=i3ConfigIpcKeyword " 4.24 Focus follows mouse syn keyword i3ConfigFocusFollowsMouseOpts always contained -syn match i3ConfigFocusFollowsMouse /^focus_follows_mouse \(yes\|no\|always\)$/ contains=i3ConfigBoolean,i3ConfigFocusFollowsMouseOpts +syn match i3ConfigKeyword /^focus_follows_mouse \(yes\|no\|always\)$/ contains=i3ConfigBoolean,i3ConfigFocusFollowsMouseOpts " 4.25 Mouse warping syn keyword i3ConfigMouseWarpingOpts output container none contained -syn match i3ConfigMouseWarping /^mouse_warping \w*$/ contains=i3ConfigMouseWarpingOpts +syn match i3ConfigKeyword /^mouse_warping \w*$/ contains=i3ConfigMouseWarpingOpts " 4.26 Popups while fullscreen syn keyword i3ConfigPopupFullscreenOpts smart ignore leave_fullscreen contained -syn match i3ConfigPopupFullscreen /^popup_during_fullscreen \w*$/ contains=i3ConfigPopupFullscreenOpts +syn match i3ConfigKeyword /^popup_during_fullscreen \w*$/ contains=i3ConfigPopupFullscreenOpts " 4.27 Focus wrapping syn keyword i3ConfigFocusWrappingOpts force workspace contained -syn match i3ConfigFocusWrapping /^focus_wrapping \(yes\|no\|force\|workspace\)$/ contains=i3ConfigBoolean,i3ConfigFocusWrappingOpts +syn match i3ConfigKeyword /^focus_wrapping \(yes\|no\|force\|workspace\)$/ contains=i3ConfigBoolean,i3ConfigFocusWrappingOpts " 4.28 Forcing Xinerama -syn match i3ConfigForceXinerama /^force_xinerama \(yes\|no\)$/ contains=i3ConfigBoolean +syn match i3ConfigKeyword /^force_xinerama \(yes\|no\)$/ contains=i3ConfigBoolean " 4.29 Automatic workspace back-and-forth -syn match i3ConfigAutomaticSwitch /^workspace_auto_back_and_forth \(yes\|no\)$/ contains=i3ConfigBoolean +syn match i3ConfigKeyword /^workspace_auto_back_and_forth \(yes\|no\)$/ contains=i3ConfigBoolean " 4.30 Delay urgency hint syn keyword i3ConfigTimeUnit ms contained -syn match i3ConfigDelayUrgency /^force_display_urgency_hint \d\+ ms$/ contains=i3ConfigBoolean,i3ConfigNumber,i3ConfigTimeUnit +syn match i3ConfigKeyword /^force_display_urgency_hint \d\+\( ms\)\?$/ contains=i3ConfigNumber,i3ConfigTimeUnit " 4.31 Focus on window activation syn keyword i3ConfigFocusOnActivationOpts smart urgent focus none contained -syn match i3ConfigFocusOnActivation /^focus_on_window_activation .*$/ contains=i3ConfigFocusOnActivationKeyword +syn match i3ConfigKeyword /^focus_on_window_activation \w*$/ contains=i3ConfigFocusOnActivationOpts " 4.32 Show marks in title syn match i3ConfigShowMarks /^show_marks \(yes\|no\)$/ contains=i3ConfigBoolean " 4.34 Tiling drag syn keyword i3ConfigTilingDragOpts modifier titlebar contained -syn match i3ConfigTilingDrag /^tiling_drag\( off\|\( modifier\| titlebar\)\{1,2\}\)$/ contains=i3ConfigTilingOpts,i3ConfigBoolean +syn match i3ConfigKeyword /^tiling_drag\( off\|\( modifier\| titlebar\)\{1,2\}\)$/ contains=i3ConfigTilingDragOpts,i3ConfigBoolean " 4.35 Gaps syn keyword i3ConfigGapsOpts inner outer horizontal vertical left right top bottom current all set plus minus toggle contained -syn region i3ConfigGaps start=/gaps/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigGapsOpts,i3ConfigNumber,i3ConfigVariable,i3ConfigSeparator keepend -syn match i3ConfigGapStyleLine /^gaps .*$/ contains=i3ConfigGaps +syn region i3ConfigGaps start=/gaps/ skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigGapsOpts,i3ConfigNumber,i3ConfigVariable,i3ConfigSeparator keepend +syn match i3ConfigGapsLine /^gaps .*$/ contains=i3ConfigGaps syn keyword i3ConfigSmartGapOpts inverse_outer contained -syn match i3ConfigSmartGap /^smart_gaps \(on\|off\|inverse_outer\)$/ contains=i3ConfigSmartGapOpts,i3ConfigBoolean +syn match i3ConfigKeyword /^smart_gaps \(on\|off\|inverse_outer\)$/ contains=i3ConfigSmartGapOpts,i3ConfigBoolean " 5 Configuring bar -syn match i3ConfigBarModifier /^\s\+modifier [^ ]\+$/ contained contains=i3ConfigBindModifier,i3ConfigVariable,i3ConfigBindModkey -syn keyword i3ConfigBarOpts bar i3bar_command status_command mode hidden_state id position output tray_output tray_padding font separator_symbol workspace_buttons workspace_min_width strip_workspace_numbers strip_workspace_name binding_mode_indicator padding contained -syn region i3ConfigBarBlock start=/^bar {$/ end=/^}$/ contains=i3ConfigBarOpts,i3ConfigBarModifier,i3ConfigBind,i3ConfigString,i3ConfigComment,i3ConfigFont,i3ConfigBoolean,i3ConfigNumber,i3ConfigParen,i3ConfigColor,i3ConfigVariable,i3ConfigColorsBlock fold keepend extend +syn match i3ConfigBarModifier /^\s\+modifier \S\+$/ contained contains=i3ConfigBindModifier,i3ConfigVariable,i3ConfigBindModkey,i3ConfigBarOptVals +syn keyword i3ConfigBarOpts bar i3bar_command status_command mode hidden_state id position output tray_output tray_padding separator_symbol workspace_buttons workspace_min_width strip_workspace_numbers strip_workspace_name binding_mode_indicator padding contained +syn keyword i3ConfigBarOptVals dock hide invisible show none top bottom primary nonprimary contained +syn region i3ConfigBarBlock start=/^bar {$/ end=/^}$/ contains=i3ConfigBarOpts,i3ConfigBarOptVals,i3ConfigBarModifier,i3ConfigBind,i3ConfigString,i3ConfigComment,i3ConfigFont,i3ConfigBoolean,i3ConfigNumber,i3ConfigParen,i3ConfigColor,i3ConfigVariable,i3ConfigColorsBlock,i3ConfigShOper,i3ConfigShCommand fold keepend extend " 5.16 Color block +syn keyword i3ConfigColorsKeyword colors contained syn match i3ConfigColorsOpts /\(focused_\)\?\(background\|statusline\|separator\)\|\(focused\|active\|inactive\|urgent\)_workspace\|binding_mode/ contained -syn region i3ConfigColorsBlock start=/^\s\+colors {$/ end=/^\s\+}$/ contained contains=i3ConfigColorsOpts,i3ConfigColor,i3ConfigVariable,i3ConfigComment,i3ConfigParen fold keepend extend +syn region i3ConfigColorsBlock start=/^\s\+colors {$/ end=/^\s\+}$/ contained contains=i3ConfigColorsKeyword,i3ConfigColorsOpts,i3ConfigColor,i3ConfigVariable,i3ConfigComment,i3ConfigParen fold keepend extend -" 6.0 Criteria-based commands -syn match i3ConfigConditionProp /\w\+\(-\w\+\)*/ contained -syn match i3ConfigConditionText /[^[ ]\+=/ contained contains=i3ConfigConditionProp,i3ConfigShOper -syn keyword i3ConfigConditionFocused __focused__ contained -syn region i3ConfigCondition start=/\[/ end=/\]/ contained contains=i3ConfigConditionText,i3ConfigShDelim,i3ConfigNumber,i3ConfigString,i3ConfigConditionFocused keepend extend -syn region i3ConfigCriteria start=/\[/ skip=/\\$/ end=/\(;\|$\)/ contained contains=i3ConfigCondition,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigBoolean,i3ConfigNumber,i3ConfigVariable,i3ConfigSeparator keepend +" 6.0 Command criteria +syn keyword i3ConfigConditionProp class instance window_role window_type machine id title urgent workspace con_mark con_id floating_from tiling_from contained +syn keyword i3ConfigConditionSpecial __focused__ all floating tiling contained +syn region i3ConfigCondition start=/\[/ end=/\]/ contained contains=i3ConfigShDelim,i3ConfigConditionProp,i3ConfigShOper,i3ConfigConditionSpecial,i3ConfigNumber,i3ConfigString keepend extend +syn region i3ConfigCriteria start=/\[/ skip=/\\$/ end=/\(;\|$\)/ contained contains=i3ConfigCondition,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigBoolean,i3ConfigNumber,i3ConfigVariable,i3ConfigSeparator keepend transparent " 6.1 Actions through shell syn match i3ConfigExecActionKeyword /i3-msg/ contained -syn region i3ConfigExecAction start=/[a-z3-]\+msg '/ skip=/\\$\| '/ end=/'/ contained contains=i3ConfigExecActionKeyword,i3ConfigShCommand,i3ConfigNumber,i3ConfigShOper,i3ConfigCriteria,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigVariable keepend extend -syn region i3ConfigExecAction start=/[a-z3-]\+msg "/ skip=/\\$\| "/ end=/"/ contained contains=i3ConfigExecActionKeyword,i3ConfigShCommand,i3ConfigNumber,i3ConfigShOper,i3ConfigCriteria,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigVariable keepend extend -syn region i3ConfigExecAction start=/[a-z3-]\+msg\( ['"-]\)\@!/ skip=/\\$/ end=/\([&|;})'"]\|$\)/ contained contains=i3ConfigExecActionKeyword,i3ConfigShCommand,i3ConfigNumber,i3ConfigShOper,i3ConfigCriteria,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigVariable keepend +syn region i3ConfigExecAction start=/[a-z3-]\+msg "/ skip=/ "\|\\$/ end=/"\|$/ contained contains=i3ConfigExecActionKeyword,i3ConfigShCommand,i3ConfigNumber,i3ConfigShOper,i3ConfigCriteria,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigVariable keepend extend +syn region i3ConfigExecAction start=/[a-z3-]\+msg '/ skip=/ '\|\\$/ end=/'\|$/ contained contains=i3ConfigExecActionKeyword,i3ConfigShCommand,i3ConfigNumber,i3ConfigShOper,i3ConfigCriteria,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigVariable keepend extend +syn region i3ConfigExecAction start=/[a-z3-]\+msg ['"-]\@!/ skip=/\\$/ end=/[&|;})'"]\@=\|$/ contained contains=i3ConfigExecActionKeyword,i3ConfigShCommand,i3ConfigNumber,i3ConfigShOper,i3ConfigCriteria,i3ConfigAction,i3ConfigActionKeyword,i3ConfigOption,i3ConfigVariable keepend extend " 6.1 Executing applications (4.20) -syn region i3ConfigAction start=/exec/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigExecKeyword,i3ConfigShCommand,i3ConfigShDelim,i3ConfigShOper,i3ConfigShParam,i3ConfigNumber,i3ConfigString,i3ConfigVariable,i3ConfigSeparator keepend +syn region i3ConfigAction start=/exec/ skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigExecKeyword,i3ConfigExecAction,i3ConfigShCommand,i3ConfigShDelim,i3ConfigShOper,i3ConfigShParam,i3ConfigNumber,i3ConfigString,i3ConfigVariable,i3ConfigSeparator keepend " 6.3 Manipulating layout syn keyword i3ConfigLayoutKeyword layout contained syn keyword i3ConfigLayoutOpts default tabbed stacking splitv splith toggle split all contained -syn region i3ConfigAction start=/layout/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigLayoutKeyword,i3ConfigLayoutOpts,i3ConfigSeparator keepend +syn region i3ConfigAction start=/layout/ skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigLayoutKeyword,i3ConfigLayoutOpts,i3ConfigSeparator keepend transparent " 6.4 Focusing containers syn keyword i3ConfigFocusKeyword focus contained syn keyword i3ConfigFocusOpts left right up down parent child next prev sibling floating tiling mode_toggle contained syn keyword i3ConfigFocusOutputOpts left right down up current primary nonprimary next prev contained -syn region i3ConfigFocusOutput start=/ output / skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigMoveType,i3ConfigWorkspaceOutput,i3ConfigFocusOutputOpts,i3ConfigString,i3ConfigNumber,i3ConfigSeparator keepend +syn region i3ConfigFocusOutput start=/ output / skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigWorkspaceOutput,i3ConfigFocusOutputOpts,i3ConfigString,i3ConfigNumber,i3ConfigSeparator keepend syn match i3ConfigFocusOutputLine /^focus output .*$/ contains=i3ConfigFocusKeyword,i3ConfigFocusOutput -syn region i3ConfigAction start=/focus/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigFocusKeyword,i3ConfigFocusOpts,i3ConfigFocusOutput,i3ConfigString,i3ConfigSeparator keepend +syn region i3ConfigAction start=/focus/ skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigFocusKeyword,i3ConfigFocusOpts,i3ConfigFocusOutput,i3ConfigString,i3ConfigSeparator keepend transparent " 6.8 Focusing workspaces (4.21) -syn region i3ConfigAction start=/workspace / skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigWorkspaceKeyword,i3ConfigWorkspaceDir,i3ConfigNumber,i3ConfigString,i3ConfigGaps,i3ConfigWorkspaceOutput,i3ConfigVariable,i3ConfigBoolean,i3ConfigSeparator keepend +syn region i3ConfigAction start=/workspace / skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigWorkspaceKeyword,i3ConfigWorkspaceDir,i3ConfigNumber,i3ConfigString,i3ConfigGaps,i3ConfigWorkspaceOutput,i3ConfigVariable,i3ConfigBoolean,i3ConfigSeparator keepend transparent -" 6.9-6.11 Moving containers +" 6.8.2 Renaming workspaces +syn keyword i3ConfigRenameKeyword rename contained +syn region i3ConfigAction start=/rename workspace/ end=/[,;]\|$/ contained contains=i3ConfigRenameKeyword,i3ConfigMoveDir,i3ConfigMoveType,i3ConfigNumber,i3ConfigVariable,i3ConfigString keepend transparent + +" 6.5,6.9-6.11 Moving containers syn keyword i3ConfigMoveKeyword move contained -syn keyword i3ConfigMoveDir left right down up position absolute center to contained +syn keyword i3ConfigMoveDir left right down up position absolute center to current contained syn keyword i3ConfigMoveType window container workspace output mark mouse scratchpad contained syn match i3ConfigUnit / px\| ppt/ contained -syn region i3ConfigAction start=/move/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigMoveKeyword,i3ConfigMoveDir,i3ConfigMoveType,i3ConfigWorkspaceDir,i3ConfigUnit,i3ConfigNumber,i3ConfigVariable,i3ConfigSeparator keepend +syn region i3ConfigAction start=/move/ skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigMoveKeyword,i3ConfigMoveDir,i3ConfigMoveType,i3ConfigWorkspaceDir,i3ConfigUnit,i3ConfigNumber,i3ConfigVariable,i3ConfigString,i3ConfigSeparator,i3ConfigShParam keepend transparent " 6.12 Resizing containers/windows syn keyword i3ConfigResizeKeyword resize contained syn keyword i3ConfigResizeOpts grow shrink up down left right set width height or contained -syn region i3ConfigAction start=/resize/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=i3ConfigResizeKeyword,i3ConfigResizeOpts,i3ConfigNumber,i3ConfigUnit,i3ConfigSeparator keepend +syn region i3ConfigAction start=/resize/ skip=/\\$/ end=/[,;]\|$/ contained contains=i3ConfigResizeKeyword,i3ConfigResizeOpts,i3ConfigNumber,i3ConfigUnit,i3ConfigSeparator keepend transparent " 6.14 VIM-like marks -syn keyword i3ConfigMarkKeyword mark contained -syn match i3ConfigMark /mark\( --\(add\|replace\)\( --toggle\)\?\)\?/ contained contains=i3ConfigMarkKeyword -syn region i3ConfigAction start=/\\ze\@=.*<(class|object)>" +syn match ktModifier "\v\ze\@=.*" +syn match ktModifier "\v<(tailrec|operator|infix)>\ze\@=.*" +syn match ktModifier "\v\ze\@=.*" +syn match ktModifier "\v\ze\@=.*" +syn match ktModifier "\v<(internal|private|protected|public)>\ze\@=.*<(class|object|interface|typealias|fun|val|var|constructor|get|set)>" + +syn match ktOperator "\v\?:|::|\<\=? | \>\=?|[!=]\=\=?|\??|[-*+/%]\=?|[!&|]" + +syn keyword ktTodo TODO FIXME XXX contained +syn match ktShebang "\v^#!.*$" +syn match ktLineComment "\v//.*$" contains=ktTodo,@Spell +syn region ktComment matchgroup=ktCommentMatchGroup start="/\*" end="\*/" contains=ktComment,ktTodo,@Spell + +syn region ktDocComment start="/\*\*" end="\*/" contains=ktDocTag,ktTodo,@Spell +syn match ktDocTag "\v\@(author|constructor|receiver|return|since|suppress)>" contained +syn match ktDocTag "\v\@(exception|param|property|throws|see|sample)>\s*\S+" contains=ktDocTagParam contained +syn match ktDocTagParam "\v(\s|\[)\S+" contained +syn match ktComment "/\*\*/" + +syn match ktSpecialCharError "\v\\." contained +syn match ktSpecialChar "\v\\([tbnr'"$\\]|u\x{4})" contained +syn region ktString start='"' skip='\\"' end='"' contains=ktSimpleInterpolation,ktComplexInterpolation,ktSpecialChar,ktSpecialCharError,@Spell +syn region ktString start='"""' end='""""*' contains=ktSimpleInterpolation,ktComplexInterpolation,@Spell +syn match ktCharacter "\v'[^']*'" contains=ktSpecialChar,ktSpecialCharError +syn match ktCharacter "\v'\\''" contains=ktSpecialChar +syn match ktCharacter "\v'[^\\]'" + +syn match ktAnnotation "\v(\w)@" + +syn region ktFold start="{" end="}" transparent fold + +exec "syntax sync ccomment ktComment minlines=10" + +hi def link ktStatement Statement +hi def link ktConditional Conditional +hi def link ktRepeat Repeat +hi def link ktOperator Operator +hi def link ktKeyword Keyword +hi def link ktException Exception +hi def link ktReservedKeyword Error + +hi def link ktInclude Include + +hi def link ktType Type +hi def link ktModifier StorageClass +hi def link ktStructure Structure +hi def link ktTypedef Typedef + +hi def link ktBoolean Boolean +hi def link ktConstant Constant + +hi def link ktTodo Todo +hi def link ktShebang Comment +hi def link ktLineComment Comment +hi def link ktComment Comment +hi def link ktCommentMatchGroup Comment +hi def link ktDocComment Comment +hi def link ktDocTag Special +hi def link ktDocTagParam Identifier + +hi def link ktSpecialChar SpecialChar +hi def link ktSpecialCharError Error +hi def link ktString String +hi def link ktCharacter Character + +hi def link ktAnnotation Identifier +hi def link ktLabel Identifier + +hi def link ktSimpleInterpolation Identifier +hi def link ktComplexInterpolationBrace Identifier + +hi def link ktNumber Number +hi def link ktFloat Float + +hi def link ktExclExcl Special +hi def link ktArrow Structure + +let b:current_syntax = 'kotlin' + +" vim:foldmethod=marker diff --git a/usr/share/vim/vim90/syntax/rmd.vim b/usr/share/vim/vim90/syntax/rmd.vim index 0eab0e6fab5..93343dd7296 100644 --- a/usr/share/vim/vim90/syntax/rmd.vim +++ b/usr/share/vim/vim90/syntax/rmd.vim @@ -1,7 +1,7 @@ " Language: Markdown with chunks of R, Python and other languages " Maintainer: Jakson Aquino " Homepage: https://github.com/jalvesaq/R-Vim-runtime -" Last Change: Fri Feb 24, 2023 08:28AM +" Last Change: Wed May 17, 2023 06:34AM " " For highlighting pandoc extensions to markdown like citations and TeX and " many other advanced features like folding of markdown sections, it is @@ -26,6 +26,8 @@ let g:rmd_syn_hl_chunk = get(g:, 'rmd_syn_hl_chunk', 0) let s:save_pandoc_lngs = get(g:, 'pandoc#syntax#codeblocks#embeds#langs', []) let g:pandoc#syntax#codeblocks#embeds#langs = [] +let g:rmd_dynamic_fenced_languages = get(g:, 'rmd_dynamic_fenced_languages', v:true) + " Step_1: Source pandoc.vim if it is installed: runtime syntax/pandoc.vim if exists("b:current_syntax") @@ -95,6 +97,11 @@ else hi def link yamlColonError Error endif + " Conceal char for manual line break + if &encoding ==# 'utf-8' + syn match rmdNewLine ' $' conceal cchar=↵ + endif + " You don't need this if either your markdown/syntax.vim already highlights " citations or you are writing standard markdown if g:rmd_syn_hl_citations @@ -127,32 +134,78 @@ syn match knitrBodyValue ': \zs.*\ze$' keepend contained containedin=knitrBodyOp syn match knitrBodyVar '| \zs\S\{-}\ze:' contained containedin=knitrBodyOptions let g:rmd_fenced_languages = get(g:, 'rmd_fenced_languages', ['r']) -for s:type in g:rmd_fenced_languages - if s:type =~ '=' - let s:ft = substitute(s:type, '.*=', '', '') - let s:nm = substitute(s:type, '=.*', '', '') + +let s:no_syntax_vim = [] +function IncludeLanguage(lng) + if a:lng =~ '=' + let ftpy = substitute(a:lng, '.*=', '', '') + let lnm = substitute(a:lng, '=.*', '', '') else - let s:ft = s:type - let s:nm = s:type + let ftpy = a:lng + let lnm = a:lng + endif + if index(s:no_syntax_vim, ftpy) >= 0 + return endif - unlet! b:current_syntax - exe 'syn include @Rmd'.s:nm.' syntax/'.s:ft.'.vim' - if g:rmd_syn_hl_chunk - exe 'syn match knitrChunkDelim /```\s*{\s*'.s:nm.'/ contained containedin=knitrChunkBrace contains=knitrChunkLabel' - exe 'syn match knitrChunkLabelDelim /```\s*{\s*'.s:nm.',\=\s*[-[:alnum:]]\{-1,}[,}]/ contained containedin=knitrChunkBrace' - syn match knitrChunkDelim /}\s*$/ contained containedin=knitrChunkBrace - exe 'syn match knitrChunkBrace /```\s*{\s*'.s:nm.'.*$/ contained containedin=rmd'.s:nm.'Chunk contains=knitrChunkDelim,knitrChunkLabelDelim,@Rmd'.s:nm - exe 'syn region rmd'.s:nm.'Chunk start="^\s*```\s*{\s*=\?'.s:nm.'\>.*$" matchgroup=rmdCodeDelim end="^\s*```\ze\s*$" keepend contains=knitrChunkBrace,@Rmd'.s:nm - - hi link knitrChunkLabel Identifier - hi link knitrChunkDelim rmdCodeDelim - hi link knitrChunkLabelDelim rmdCodeDelim + if len(globpath(&rtp, "syntax/" . ftpy . ".vim")) + unlet! b:current_syntax + exe 'syn include @Rmd'.lnm.' syntax/'.ftpy.'.vim' + let b:current_syntax = "rmd" + if g:rmd_syn_hl_chunk + exe 'syn match knitrChunkDelim /```\s*{\s*'.lnm.'/ contained containedin=knitrChunkBrace contains=knitrChunkLabel' + exe 'syn match knitrChunkLabelDelim /```\s*{\s*'.lnm.',\=\s*[-[:alnum:]]\{-1,}[,}]/ contained containedin=knitrChunkBrace' + syn match knitrChunkDelim /}\s*$/ contained containedin=knitrChunkBrace + exe 'syn match knitrChunkBrace /```\s*{\s*'.lnm.'.*$/ contained containedin=rmd'.lnm.'Chunk contains=knitrChunkDelim,knitrChunkLabelDelim,@Rmd'.lnm + exe 'syn region rmd'.lnm.'Chunk start="^\s*```\s*{\s*=\?'.lnm.'\>.*$" matchgroup=rmdCodeDelim end="^\s*```\ze\s*$" keepend contains=knitrChunkBrace,@Rmd'.lnm + + hi link knitrChunkLabel Identifier + hi link knitrChunkDelim rmdCodeDelim + hi link knitrChunkLabelDelim rmdCodeDelim + else + exe 'syn region rmd'.lnm.'Chunk matchgroup=rmdCodeDelim start="^\s*```\s*{\s*=\?'.lnm.'\>.*$" matchgroup=rmdCodeDelim end="^\s*```\ze\s*$" keepend contains=@Rmd'.lnm + endif else - exe 'syn region rmd'.s:nm.'Chunk matchgroup=rmdCodeDelim start="^\s*```\s*{\s*=\?'.s:nm.'\>.*$" matchgroup=rmdCodeDelim end="^\s*```\ze\s*$" keepend contains=@Rmd'.s:nm + " Avoid the cost of running globpath() whenever the buffer is saved + let s:no_syntax_vim += [ftpy] endif +endfunction + +for s:type in g:rmd_fenced_languages + call IncludeLanguage(s:type) endfor unlet! s:type +function CheckRmdFencedLanguages() + let alines = getline(1, '$') + call filter(alines, "v:val =~ '^```{'") + call map(alines, "substitute(v:val, '^```{', '', '')") + call map(alines, "substitute(v:val, '\\W.*', '', '')") + for tpy in alines + if len(tpy) == 0 + continue + endif + let has_lng = 0 + for lng in g:rmd_fenced_languages + if tpy == lng + let has_lng = 1 + continue + endif + endfor + if has_lng == 0 + let g:rmd_fenced_languages += [tpy] + call IncludeLanguage(tpy) + endif + endfor +endfunction + +if g:rmd_dynamic_fenced_languages + call CheckRmdFencedLanguages() + augroup RmdSyntax + autocmd! + autocmd BufWritePost call CheckRmdFencedLanguages() + augroup END +endif + " Step_4: Highlight code recognized by pandoc but not defined in pandoc.vim yet: syn match pandocDivBegin '^:::\+ {.\{-}}' contains=pandocHeaderAttr syn match pandocDivEnd '^:::\+$' diff --git a/usr/share/vim/vim90/syntax/swayconfig.vim b/usr/share/vim/vim90/syntax/swayconfig.vim index 290e8cc1ac3..7b1c889d6d7 100644 --- a/usr/share/vim/vim90/syntax/swayconfig.vim +++ b/usr/share/vim/vim90/syntax/swayconfig.vim @@ -1,10 +1,9 @@ " Vim syntax file -" Language: sway window manager config -" Original Author: Josef Litos +" Language: sway config file +" Original Author: Josef Litos (JosefLitos/i3config.vim) " Maintainer: James Eapen -" Version: 0.2.2 -" Reference version (JosefLitos/i3config.vim): 1.8.1 -" Last Change: 2023-09-12 +" Version: 1.0.0 +" Last Change: 2023-09-14 " References: " http://i3wm.org/docs/userguide.html#configuring @@ -20,9 +19,12 @@ endif runtime! syntax/i3config.vim " i3 extensions -syn match i3ConfigSet /^\s*set \$\w\+ .*$/ contains=i3ConfigVariable,i3ConfigSetKeyword,i3ConfigColor,i3ConfigString,i3ConfigNoStartupId,i3ConfigNumber,swayConfigOutputCommand,i3ConfigShCommand,i3ConfigShDelim,i3ConfigShParam,i3ConfigShOper +syn keyword i3ConfigActionKeyword opacity urgent shortcuts_inhibitor splitv splith splitt contained +syn keyword i3ConfigOption set plus minus allow deny csd v h t contained -syn keyword i3ConfigActionKeyword opacity contained +syn keyword i3ConfigConditionProp app_id pid shell contained + +syn keyword i3ConfigWorkspaceDir prev_on_output next_on_output contained syn keyword swayConfigBindKeyword bindswitch bindgesture contained syn match i3ConfigBindArgument /--\(locked\|to-code\|no-repeat\|input-device=[:0-9a-zA-Z_/-]\+\|no-warn\)/ contained @@ -31,6 +33,8 @@ syn region i3ConfigBind start=/^\s*bind\(switch\|gesture\) / skip=/\\$/ end=/$/ syn match swayConfigBindBlockHeader /^\s*bind\(sym\|code\) .*{$/ contained contains=i3ConfigBindKeyword,i3ConfigBindArgument,i3ConfigParen syn match swayConfigBindBlockCombo /^\s\+\(--[a-z-]\+ \)*[$a-zA-Z0-9_+]\+ [a-z[]\@=/ contained contains=i3ConfigBindArgument,i3ConfigBindCombo syn region i3ConfigBind start=/^\s*bind\(sym\|code\) .*{$/ end=/^\s*}$/ contains=swayConfigBindBlockHeader,swayConfigBindBlockCombo,i3ConfigCriteria,i3ConfigAction,i3ConfigSeparator,i3ConfigActionKeyword,i3ConfigOption,i3ConfigString,i3ConfigNumber,i3ConfigVariable,i3ConfigBoolean,i3ConfigComment,i3ConfigParen fold keepend extend +" fix for extra long bindsym blocks that would be parsed incorrectly when scrolling up +syn region i3ConfigBlockOrphan start=/^\s\+\S/ skip=/^\s\|^$/ end=/^}\?/ contains=swayConfigBindBlockCombo,i3ConfigCriteria,i3ConfigAction,i3ConfigSeparator,i3ConfigActionKeyword,i3ConfigOption,i3ConfigString,i3ConfigNumber,i3ConfigVariable,i3ConfigBoolean,i3ConfigComment,i3ConfigParen keepend extend syn keyword i3ConfigClientOpts focused_tab_title contained @@ -39,16 +43,22 @@ syn region swayConfigExecBlock start=/exec\(_always\)\? {/ end=/^}$/ contains=i3 syn keyword swayConfigFloatingModifierOpts normal inverse contained syn match i3ConfigKeyword /^floating_modifier [$a-zA-Z0-9+]\+ \(normal\|inverse\)$/ contains=i3ConfigVariable,i3ConfigBindModkey,swayConfigFloatingModifierOpts -syn match i3ConfigEdge /^hide_edge_borders\( --i3\)\? \(none\|vertical\|horizontal\|both\|smart\|smart_no_gaps\)\s\?$/ contains=i3ConfigEdgeKeyword,i3ConfigShParam +syn match i3ConfigKeyword /^hide_edge_borders --i3 \w*$/ contains=i3ConfigEdgeKeyword,i3ConfigShParam -syn keyword i3ConfigBarBlockKeyword swaybar_command gaps height pango_markup status_edge_padding status_padding wrap_scroll tray_bindcode tray_bindsym icon_theme contained +syn keyword i3ConfigBarOpts swaybar_command gaps height pango_markup status_edge_padding status_padding wrap_scroll tray_bindcode tray_bindsym icon_theme contained +syn keyword i3ConfigBarOptVals overlay contained syn keyword i3ConfigExecActionKeyword swaymsg contained " Sway-only options " Xwayland syn keyword swayConfigXOpt enable disable force contained -syn match i3ConfigKeyword /^xwayland .*$/ contains=swayConfigXOpt +syn match i3ConfigKeyword /^xwayland \w*$/ contains=swayConfigXOpt + +" Inhibit idle +syn keyword swayConfigInhibitKeyword inhibit_idle contained +syn keyword swayConfigInhibitOpts focus fullscreen open none visible contained +syn match i3ConfigAction /inhibit_idle \w*/ contained contains=swayConfigInhibitKeyword,swayConfigInhibitOpts " Bindswitch syn match swayConfigBindswitchArgument /--\(locked\|no-warn\|reload\)/ contained @@ -64,65 +74,77 @@ syn keyword swayConfigBindgestureDir up down left right inward outward clockwise syn match swayConfigBindgesture /\(hold\(:[1-5]\)\?\|swipe\(:[3-5]\)\?\(:up\|:down\|:left\|:right\)\?\|pinch\(:[2-5]\)\?:\(+\?\(inward\|outward\|clockwise\|counterclockwise\|up\|down\|left\|right\)\)\+\) / contained contains=i3ConfigNumber,swayConfigBindgestureType,i3ConfigColonOperator,swayConfigBindgestureDir,i3ConfigBindModifier syn region i3ConfigBind start=/^\s*bindgesture\s\+.*{$/ end=/^\s*}$/ contains=swayConfigBindKeyword,swayConfigBindgesture,swayConfigBindgestureArgument,i3ConfigCriteria,i3ConfigAction,i3ConfigSeparator,i3ConfigActionKeyword,i3ConfigOption,i3ConfigString,i3ConfigNumber,i3ConfigVariable,i3ConfigBoolean,i3ConfigParen fold keepend extend +" Tiling drag threshold +syn match i3ConfigKeyword /^tiling_drag_threshold \d\+$/ contains=i3ConfigNumber + " Titlebar commands syn match i3ConfigKeyword /^titlebar_border_thickness \(\d\+\|\$\S\+\)$/ contains=i3ConfigNumber,i3ConfigVariable syn match i3ConfigKeyword /^titlebar_padding \(\d\+\|\$\S\+\)\( \d\+\)\?$/ contains=i3ConfigNumber,i3ConfigVariable syn match swayConfigDeviceOps /[*,:;]/ contained -" Output monitors -syn keyword swayConfigOutputKeyword output contained -syn keyword swayConfigOutputOpts mode resolution res modeline position pos scale scale_filter subpixel background bg transform disable enable power dpms max_render_time adaptive_sync render_bit_depth contained -syn keyword swayConfigOutputOptVals linear nearest smart rgb bgr vrgb vbgr none normal flipped fill stretch fit center tile solid_color clockwise anticlockwise toggle contained -syn match swayConfigOutputFPS /@[0-9.]\+Hz/ contained -syn match swayConfigOutputMode / [0-9]\+x[0-9]\+\(@[0-9.]\+Hz\)\?/ contained contains=swayConfigOutputFPS,i3ConfigNumber -syn region i3ConfigAction start=/output/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=swayConfigOutputKeyword,swayConfigOutputMode,swayConfigOutputOpts,swayConfigOutputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigColor,i3ConfigBoolean,swayConfigDeviceOps keepend -syn region swayConfigOutput start=/^output/ skip=/\\$/ end=/$/ contains=swayConfigOutputKeyword,swayConfigOutputMode,swayConfigOutputOpts,swayConfigOutputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigColor,i3ConfigBoolean,swayConfigDeviceOps keepend -syn region swayConfigOutput start=/^output .* {$/ end=/}$/ contains=swayConfigOutputKeyword,swayConfigOutputMode,swayConfigOutputOpts,swayConfigOutputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigColor,i3ConfigBoolean,swayConfigDeviceOps,i3ConfigParen keepend extend - " Input devices syn keyword swayConfigInputKeyword input contained +syn keyword swayConfigInputType touchpad pointer keyboard touch tablet_tool tablet_pad switch contained +syn match swayConfigInputTypePair /\/ contained contains=i3ConfigColonOperator,swayConfigInputType +syn region swayConfigInputStart start=/^input / end=/\s/ contained contains=swayConfigInputKeyword,swayConfigInputTypePair,i3ConfigString keepend extend syn keyword swayConfigInputOpts xkb_layout xkb_variant xkb_rules xkb_switch_layout xkb_numlock xkb_file xkb_capslock xkb_model repeat_delay repeat_rate map_to_output map_to_region map_from_region tool_mode accel_profile dwt dwtp drag_lock drag click_method middle_emulation tap events calibration_matrix natural_scroll left_handed pointer_accel scroll_button scroll_factor scroll_method tap_button_map contained -syn keyword swayConfigInputOptVals absolute relative adaptive flat none button_areas clickfinger toggle two_finger edge on_button_down lrm lmr contained -syn match swayConfigColonPairVal /:[0-9a-z_-]\+/ contained contains=i3ConfigColonOperator -syn match swayConfigColonPair /[a-z]\+:[0-9a-z_-]\+/ contained contains=swayConfigColonPairVal -syn match swayConfigInputXkbOpts /xkb_options \([a-z]\+:[0-9a-z_-]\+,\?\)\+/ contained contains=swayConfigColonPair,swayConfigDeviceOps -syn region i3ConfigAction start=/input/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=swayConfigInputKeyword,swayConfigColonPair,swayConfigInputXkbOpts,swayConfigInputOpts,swayConfigInputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigBoolean,swayConfigDeviceOps keepend -syn region i3ConfigInput start=/^input/ skip=/\\$/ end=/$/ contains=swayConfigInputKeyword,swayConfigColonPair,swayConfigInputXkbOpts,swayConfigInputOpts,swayConfigInputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigBoolean,swayConfigDeviceOps keepend -syn region i3ConfigInput start=/^input .* {/ end=/}$/ contains=swayConfigInputKeyword,swayConfigColonPair,swayConfigInputXkbOpts,swayConfigInputOpts,swayConfigInputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigBoolean,swayConfigDeviceOps,i3ConfigParen keepend extend +syn keyword swayConfigInputOptVals absolute relative adaptive flat none button_areas clickfinger toggle two_finger edge on_button_down lrm lmr next prev pen eraser brush pencil airbrush disabled_on_external_mouse disable contained +syn match swayConfigXkbOptsPairVal /:[0-9a-z_-]\+/ contained contains=i3ConfigColonOperator +syn match swayConfigXkbOptsPair /[a-z]\+:[0-9a-z_-]\+/ contained contains=swayConfigXkbOptsPairVal +syn match swayConfigInputXkbOpts /xkb_options \([a-z]\+:[0-9a-z_-]\+,\?\)\+/ contained contains=swayConfigXkbOptsPair,swayConfigDeviceOps +syn region i3ConfigAction start=/input/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=swayConfigInputStart,swayConfigInputXkbOpts,swayConfigInputOpts,swayConfigInputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigBoolean,swayConfigDeviceOps keepend transparent +syn region i3ConfigInput start=/^input/ skip=/\\$/ end=/$/ contains=swayConfigInputStart,swayConfigInputXkbOpts,swayConfigInputOpts,swayConfigInputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigBoolean,swayConfigDeviceOps keepend +syn region i3ConfigInput start=/^input .* {/ end=/}$/ contains=swayConfigInputStart,swayConfigInputXkbOpts,swayConfigInputOpts,swayConfigInputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigBoolean,swayConfigDeviceOps,i3ConfigParen keepend extend " Seat syn keyword swayConfigSeatKeyword seat contained syn keyword swayConfigSeatOpts attach cursor fallback hide_cursor idle_inhibit idle_wake keyboard_grouping shortcuts_inhibitor pointer_constraint xcursor_theme contained syn match swayConfigSeatOptVals /when-typing/ contained syn keyword swayConfigSeatOptVals move set press release none smart activate deactivate toggle escape enable disable contained -syn region i3ConfigAction start=/seat/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=swayConfigSeatKeyword,i3ConfigString,i3ConfigNumber,i3ConfigBoolean,swayConfigSeatOptVals,swayConfigSeatOpts,swayConfigDeviceOps keepend -syn region swayConfigSeat start=/seat/ skip=/\\$/ end=/$/ contains=swayConfigSeatKeyword,i3ConfigString,i3ConfigNumber,i3ConfigBoolean,swayConfigSeatOptVals,swayConfigSeatOpts,swayConfigDeviceOps keepend -syn region swayConfigSeat start=/seat .* {$/ end=/}$/ contains=swayConfigSeatKeyword,i3ConfigString,i3ConfigNumber,i3ConfigBoolean,swayConfigSeatOptVals,swayConfigSeatOpts,swayConfigDeviceOps,i3ConfigParen keepend extend +syn region i3ConfigAction start=/seat/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=swayConfigSeatKeyword,i3ConfigString,i3ConfigNumber,i3ConfigBoolean,swayConfigSeatOptVals,swayConfigSeatOpts,swayConfigDeviceOps,swayConfigInputType keepend transparent +syn region swayConfigSeat start=/seat/ skip=/\\$/ end=/$/ contains=swayConfigSeatKeyword,i3ConfigString,i3ConfigNumber,i3ConfigBoolean,swayConfigSeatOptVals,swayConfigSeatOpts,swayConfigDeviceOps,swayConfigInputType keepend +syn region swayConfigSeat start=/seat .* {$/ end=/}$/ contains=swayConfigSeatKeyword,i3ConfigString,i3ConfigNumber,i3ConfigBoolean,swayConfigSeatOptVals,swayConfigSeatOpts,swayConfigDeviceOps,i3ConfigParen,swayConfigInputType keepend extend + +" Output monitors +syn keyword swayConfigOutputKeyword output contained +syn keyword swayConfigOutputOpts mode resolution res modeline position pos scale scale_filter subpixel background bg transform disable enable power dpms max_render_time adaptive_sync render_bit_depth contained +syn keyword swayConfigOutputOptVals linear nearest smart rgb bgr vrgb vbgr none normal flipped fill stretch fit center tile solid_color clockwise anticlockwise toggle contained +syn match swayConfigOutputOptVals /--custom\|flipped-\(90\|180\|270\)/ contained +syn match swayConfigOutputFPS /@[0-9.]\+Hz/ contained +syn match swayConfigOutputMode / [0-9]\+x[0-9]\+\(@[0-9.]\+Hz\)\?/ contained contains=swayConfigOutputFPS +syn region i3ConfigAction start=/output/ skip=/\\$/ end=/\([,;]\|$\)/ contained contains=swayConfigOutputKeyword,swayConfigOutputMode,swayConfigOutputOpts,swayConfigOutputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigColor,i3ConfigBoolean,swayConfigDeviceOps keepend transparent +syn region swayConfigOutput start=/^output/ skip=/\\$/ end=/$/ contains=swayConfigOutputKeyword,swayConfigOutputMode,swayConfigOutputOpts,swayConfigOutputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigColor,i3ConfigBoolean,swayConfigDeviceOps keepend +syn region swayConfigOutput start=/^output .* {$/ end=/}$/ contains=swayConfigOutputKeyword,swayConfigOutputMode,swayConfigOutputOpts,swayConfigOutputOptVals,i3ConfigVariable,i3ConfigNumber,i3ConfigString,i3ConfigColor,i3ConfigBoolean,swayConfigDeviceOps,i3ConfigParen keepend extend " Define the highlighting. -hi def link swayConfigFloatingModifierOpts i3ConfigOption -hi def link swayConfigBindKeyword i3ConfigBindKeyword -hi def link swayConfigXOpt i3ConfigOption -hi def link swayConfigBindswitchArgument i3ConfigBindArgument -hi def link swayConfigBindswitchType i3ConfigMoveType -hi def link swayConfigBindswitchState i3ConfigMoveDir -hi def link swayConfigBindgestureArgument i3ConfigBindArgument -hi def link swayConfigBindgestureType i3ConfigMoveType -hi def link swayConfigBindgestureDir i3ConfigMoveDir -hi def link swayConfigDeviceOps i3ConfigOperator -hi def link swayConfigOutputKeyword i3ConfigCommand -hi def link swayConfigOutputOptVals i3ConfigOption -hi def link swayConfigOutputOpts i3ConfigOption -hi def link swayConfigOutputFPS Constant -hi def link swayConfigInputKeyword i3ConfigCommand -hi def link swayConfigInputOptVals i3ConfigShParam -hi def link swayConfigInputOpts i3ConfigOption -hi def link swayConfigInputXkbOpts i3ConfigOption -hi def link swayConfigColonPairVal i3ConfigString -hi def link swayConfigColonPair i3ConfigShParam -hi def link swayConfigSeatKeyword i3ConfigCommand -hi def link swayConfigSeatOptVals i3ConfigOption -hi def link swayConfigSeatOpts i3ConfigOption +hi def link swayConfigFloatingModifierOpts i3ConfigOption +hi def link swayConfigBindKeyword i3ConfigBindKeyword +hi def link swayConfigXOpt i3ConfigOption +hi def link swayConfigInhibitKeyword i3ConfigCommand +hi def link swayConfigInhibitOpts i3ConfigOption +hi def link swayConfigBindswitchArgument i3ConfigBindArgument +hi def link swayConfigBindswitchType i3ConfigMoveType +hi def link swayConfigBindswitchState i3ConfigMoveDir +hi def link swayConfigBindgestureArgument i3ConfigBindArgument +hi def link swayConfigBindgestureType i3ConfigMoveType +hi def link swayConfigBindgestureDir i3ConfigMoveDir +hi def link swayConfigDeviceOps i3ConfigOperator +hi def link swayConfigInputKeyword i3ConfigCommand +hi def link swayConfigInputType i3ConfigMoveType +hi def link swayConfigInputTypePair i3ConfigMoveDir +hi def link swayConfigInputOptVals i3ConfigShParam +hi def link swayConfigInputOpts i3ConfigOption +hi def link swayConfigXkbOptsPairVal i3ConfigString +hi def link swayConfigXkbOptsPair i3ConfigShParam +hi def link swayConfigInputXkbOpts i3ConfigOption +hi def link swayConfigSeatKeyword i3ConfigCommand +hi def link swayConfigSeatOptVals swayConfigInputOptVals +hi def link swayConfigSeatOpts swayConfigInputOpts +hi def link swayConfigOutputKeyword i3ConfigCommand +hi def link swayConfigOutputOptVals swayConfigInputOptVals +hi def link swayConfigOutputOpts swayConfigInputOpts +hi def link swayConfigOutputFPS Constant +hi def link swayConfigOutputMode i3ConfigNumber let b:current_syntax = "swayconfig" diff --git a/usr/share/vim/vim90/tutor/tutor.nl b/usr/share/vim/vim90/tutor/tutor.nl index eb5414d2dcc..d07cd9836e1 100644 --- a/usr/share/vim/vim90/tutor/tutor.nl +++ b/usr/share/vim/vim90/tutor/tutor.nl @@ -366,7 +366,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Les 3.1: HET COMMANDO PLAK - ** Tik p ('put') en plak daarmee zojuist gewiste tekst na te cursor. ** + ** Tik p ('put') en plak daarmee zojuist gewiste tekst na de cursor. ** 1. Ga met de cursor naar de eerste regel met ---> hierna. diff --git a/usr/share/vim/vim90/tutor/tutor.nl.utf-8 b/usr/share/vim/vim90/tutor/tutor.nl.utf-8 index 1f4be70fefd..d6a1c7f1e19 100644 --- a/usr/share/vim/vim90/tutor/tutor.nl.utf-8 +++ b/usr/share/vim/vim90/tutor/tutor.nl.utf-8 @@ -366,7 +366,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Les 3.1: HET COMMANDO PLAK - ** Tik p ('put') en plak daarmee zojuist gewiste tekst na te cursor. ** + ** Tik p ('put') en plak daarmee zojuist gewiste tekst na de cursor. ** 1. Ga met de cursor naar de eerste regel met ---> hierna. diff --git a/var/lib/pacman/local/gdb-13.1-2/mtree b/var/lib/pacman/local/gdb-13.1-2/mtree deleted file mode 100644 index 76c1dfeb22e..00000000000 Binary files a/var/lib/pacman/local/gdb-13.1-2/mtree and /dev/null differ diff --git a/var/lib/pacman/local/gdb-13.1-2/desc b/var/lib/pacman/local/gdb-13.2-1/desc similarity index 78% rename from var/lib/pacman/local/gdb-13.1-2/desc rename to var/lib/pacman/local/gdb-13.2-1/desc index 3afd960ef90..1db1094a6b0 100644 --- a/var/lib/pacman/local/gdb-13.1-2/desc +++ b/var/lib/pacman/local/gdb-13.2-1/desc @@ -2,7 +2,7 @@ gdb %VERSION% -13.1-2 +13.2-1 %BASE% gdb @@ -17,16 +17,16 @@ https://www.gnu.org/software/gdb/ x86_64 %BUILDDATE% -1694796792 +1696410438 %INSTALLDATE% -1695006023 +1696474806 %PACKAGER% -CI (msys2/msys2-autobuild/0852421d/6200370894) +CI (msys2/msys2-autobuild/a79a8c4c/6403823233) %SIZE% -13826490 +13827001 %LICENSE% spdx:GPL-3.0-or-later diff --git a/var/lib/pacman/local/gdb-13.1-2/files b/var/lib/pacman/local/gdb-13.2-1/files similarity index 100% rename from var/lib/pacman/local/gdb-13.1-2/files rename to var/lib/pacman/local/gdb-13.2-1/files diff --git a/var/lib/pacman/local/gdb-13.2-1/mtree b/var/lib/pacman/local/gdb-13.2-1/mtree new file mode 100644 index 00000000000..66907e1e062 Binary files /dev/null and b/var/lib/pacman/local/gdb-13.2-1/mtree differ diff --git a/var/lib/pacman/local/mingw-w64-i686-python-3.11.5-5/mtree b/var/lib/pacman/local/mingw-w64-i686-python-3.11.5-5/mtree deleted file mode 100644 index f0335f57805..00000000000 Binary files a/var/lib/pacman/local/mingw-w64-i686-python-3.11.5-5/mtree and /dev/null differ diff --git a/var/lib/pacman/local/mingw-w64-i686-python-3.11.5-5/desc b/var/lib/pacman/local/mingw-w64-i686-python-3.11.6-1/desc similarity index 89% rename from var/lib/pacman/local/mingw-w64-i686-python-3.11.5-5/desc rename to var/lib/pacman/local/mingw-w64-i686-python-3.11.6-1/desc index ef8db3b0302..209b2487fa6 100644 --- a/var/lib/pacman/local/mingw-w64-i686-python-3.11.5-5/desc +++ b/var/lib/pacman/local/mingw-w64-i686-python-3.11.6-1/desc @@ -2,7 +2,7 @@ mingw-w64-i686-python %VERSION% -3.11.5-5 +3.11.6-1 %BASE% mingw-w64-python @@ -17,16 +17,16 @@ https://www.python.org/ any %BUILDDATE% -1695930311 +1696324186 %INSTALLDATE% -1696129219 +1696474817 %PACKAGER% -CI (msys2/msys2-autobuild/a79a8c4c/6343502959) +CI (msys2/msys2-autobuild/a79a8c4c/6390866570) %SIZE% -201911261 +201761700 %REASON% 1 diff --git a/var/lib/pacman/local/mingw-w64-i686-python-3.11.5-5/files b/var/lib/pacman/local/mingw-w64-i686-python-3.11.6-1/files similarity index 98% rename from var/lib/pacman/local/mingw-w64-i686-python-3.11.5-5/files rename to var/lib/pacman/local/mingw-w64-i686-python-3.11.6-1/files index d31e868e8cb..36631a21e14 100644 --- a/var/lib/pacman/local/mingw-w64-i686-python-3.11.5-5/files +++ b/var/lib/pacman/local/mingw-w64-i686-python-3.11.6-1/files @@ -3315,11 +3315,11 @@ mingw32/lib/python3.11/lib2to3/fixes/fix_xrange.py mingw32/lib/python3.11/lib2to3/fixes/fix_xreadlines.py mingw32/lib/python3.11/lib2to3/fixes/fix_zip.py mingw32/lib/python3.11/lib2to3/Grammar.txt -mingw32/lib/python3.11/lib2to3/Grammar3.11.5.final.0.pickle +mingw32/lib/python3.11/lib2to3/Grammar3.11.6.final.0.pickle mingw32/lib/python3.11/lib2to3/main.py mingw32/lib/python3.11/lib2to3/patcomp.py mingw32/lib/python3.11/lib2to3/PatternGrammar.txt -mingw32/lib/python3.11/lib2to3/PatternGrammar3.11.5.final.0.pickle +mingw32/lib/python3.11/lib2to3/PatternGrammar3.11.6.final.0.pickle mingw32/lib/python3.11/lib2to3/pgen2/ mingw32/lib/python3.11/lib2to3/pgen2/__init__.py mingw32/lib/python3.11/lib2to3/pgen2/__pycache__/ @@ -3705,30 +3705,6 @@ mingw32/lib/python3.11/test/__pycache__/_test_venv_multiprocessing.cpython-311.p mingw32/lib/python3.11/test/__pycache__/_typed_dict_helper.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/_typed_dict_helper.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/_typed_dict_helper.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module2.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module2.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module2.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module3.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module3.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module3.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module4.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module4.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module4.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module5.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module5.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module5.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module6.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module6.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module6.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module7.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module7.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module7.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module8.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module8.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/ann_module8.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/audiotests.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/audiotests.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/audiotests.cpython-311.pyc @@ -3741,27 +3717,9 @@ mingw32/lib/python3.11/test/__pycache__/autotest.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/bisect_cmd.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/bisect_cmd.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/bisect_cmd.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/coding20731.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/coding20731.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/coding20731.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/curses_tests.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/curses_tests.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/curses_tests.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/dataclass_module_1.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/dataclass_module_1.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/dataclass_module_1.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/dataclass_module_1_str.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/dataclass_module_1_str.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/dataclass_module_1_str.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/dataclass_module_2.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/dataclass_module_2.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/dataclass_module_2.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/dataclass_module_2_str.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/dataclass_module_2_str.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/dataclass_module_2_str.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/dataclass_textanno.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/dataclass_textanno.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/dataclass_textanno.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/datetimetester.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/datetimetester.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/datetimetester.cpython-311.pyc @@ -3786,12 +3744,6 @@ mingw32/lib/python3.11/test/__pycache__/final_b.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/fork_wait.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/fork_wait.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/fork_wait.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/future_test1.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/future_test1.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/future_test1.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/future_test2.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/future_test2.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/future_test2.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/gdb_sample.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/gdb_sample.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/gdb_sample.cpython-311.pyc @@ -3903,9 +3855,6 @@ mingw32/lib/python3.11/test/__pycache__/string_tests.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/test___all__.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/test___all__.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/test___all__.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/test___future__.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/test___future__.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/test___future__.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/test__locale.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/test__locale.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/test__locale.cpython-311.pyc @@ -4107,9 +4056,6 @@ mingw32/lib/python3.11/test/__pycache__/test_compileall.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/test_complex.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/test_complex.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/test_complex.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/test_concurrent_futures.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/test_concurrent_futures.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/test_concurrent_futures.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/test_configparser.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/test_configparser.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/test_configparser.cpython-311.pyc @@ -4152,9 +4098,6 @@ mingw32/lib/python3.11/test/__pycache__/test_ctypes.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/test_curses.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/test_curses.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/test_curses.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/test_dataclasses.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/test_dataclasses.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/test_dataclasses.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/test_datetime.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/test_datetime.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/test_datetime.cpython-311.pyc @@ -4335,18 +4278,6 @@ mingw32/lib/python3.11/test/__pycache__/test_funcattrs.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/test_functools.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/test_functools.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/test_functools.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/test_future.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/test_future.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/test_future.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/test_future3.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/test_future3.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/test_future3.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/test_future4.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/test_future4.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/test_future4.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/test_future5.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/test_future5.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/test_future5.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/test_gc.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/test_gc.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/test_gc.cpython-311.pyc @@ -4563,18 +4494,9 @@ mingw32/lib/python3.11/test/__pycache__/test_msilib.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/test_multibytecodec.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/test_multibytecodec.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/test_multibytecodec.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/test_multiprocessing_fork.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/test_multiprocessing_fork.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/test_multiprocessing_fork.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/test_multiprocessing_forkserver.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/test_multiprocessing_forkserver.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/test_multiprocessing_forkserver.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/test_multiprocessing_main_handling.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/test_multiprocessing_main_handling.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/test_multiprocessing_main_handling.cpython-311.pyc -mingw32/lib/python3.11/test/__pycache__/test_multiprocessing_spawn.cpython-311.opt-1.pyc -mingw32/lib/python3.11/test/__pycache__/test_multiprocessing_spawn.cpython-311.opt-2.pyc -mingw32/lib/python3.11/test/__pycache__/test_multiprocessing_spawn.cpython-311.pyc mingw32/lib/python3.11/test/__pycache__/test_named_expressions.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/__pycache__/test_named_expressions.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/__pycache__/test_named_expressions.cpython-311.pyc @@ -5183,14 +5105,6 @@ mingw32/lib/python3.11/test/_test_multiprocessing.py mingw32/lib/python3.11/test/_test_venv_multiprocessing.py mingw32/lib/python3.11/test/_typed_dict_helper.py mingw32/lib/python3.11/test/allsans.pem -mingw32/lib/python3.11/test/ann_module.py -mingw32/lib/python3.11/test/ann_module2.py -mingw32/lib/python3.11/test/ann_module3.py -mingw32/lib/python3.11/test/ann_module4.py -mingw32/lib/python3.11/test/ann_module5.py -mingw32/lib/python3.11/test/ann_module6.py -mingw32/lib/python3.11/test/ann_module7.py -mingw32/lib/python3.11/test/ann_module8.py mingw32/lib/python3.11/test/audiodata/ mingw32/lib/python3.11/test/audiodata/pluck-alaw.aifc mingw32/lib/python3.11/test/audiodata/pluck-pcm16.aiff @@ -5211,20 +5125,8 @@ mingw32/lib/python3.11/test/audiotest.au mingw32/lib/python3.11/test/audiotests.py mingw32/lib/python3.11/test/audit-tests.py mingw32/lib/python3.11/test/autotest.py -mingw32/lib/python3.11/test/bad_coding.py -mingw32/lib/python3.11/test/bad_coding2.py mingw32/lib/python3.11/test/badcert.pem mingw32/lib/python3.11/test/badkey.pem -mingw32/lib/python3.11/test/badsyntax_3131.py -mingw32/lib/python3.11/test/badsyntax_future10.py -mingw32/lib/python3.11/test/badsyntax_future3.py -mingw32/lib/python3.11/test/badsyntax_future4.py -mingw32/lib/python3.11/test/badsyntax_future5.py -mingw32/lib/python3.11/test/badsyntax_future6.py -mingw32/lib/python3.11/test/badsyntax_future7.py -mingw32/lib/python3.11/test/badsyntax_future8.py -mingw32/lib/python3.11/test/badsyntax_future9.py -mingw32/lib/python3.11/test/badsyntax_pep3120.py mingw32/lib/python3.11/test/bisect_cmd.py mingw32/lib/python3.11/test/capath/ mingw32/lib/python3.11/test/capath/4e1295a3.0 @@ -5269,7 +5171,6 @@ mingw32/lib/python3.11/test/cjkencodings/shift_jisx0213-utf8.txt mingw32/lib/python3.11/test/cjkencodings/shift_jisx0213.txt mingw32/lib/python3.11/test/clinic.test.c mingw32/lib/python3.11/test/cmath_testcases.txt -mingw32/lib/python3.11/test/coding20731.py mingw32/lib/python3.11/test/crashers/ mingw32/lib/python3.11/test/crashers/__pycache__/ mingw32/lib/python3.11/test/crashers/__pycache__/bogus_code_obj.cpython-311.opt-1.pyc @@ -5304,11 +5205,6 @@ mingw32/lib/python3.11/test/crashers/underlying_dict.py mingw32/lib/python3.11/test/curses_tests.py mingw32/lib/python3.11/test/data/ mingw32/lib/python3.11/test/data/README -mingw32/lib/python3.11/test/dataclass_module_1.py -mingw32/lib/python3.11/test/dataclass_module_1_str.py -mingw32/lib/python3.11/test/dataclass_module_2.py -mingw32/lib/python3.11/test/dataclass_module_2_str.py -mingw32/lib/python3.11/test/dataclass_textanno.py mingw32/lib/python3.11/test/datetimetester.py mingw32/lib/python3.11/test/decimaltestdata/ mingw32/lib/python3.11/test/decimaltestdata/abs.decTest @@ -5510,8 +5406,6 @@ mingw32/lib/python3.11/test/final_b.py mingw32/lib/python3.11/test/floating_points.txt mingw32/lib/python3.11/test/fork_wait.py mingw32/lib/python3.11/test/formatfloat_testcases.txt -mingw32/lib/python3.11/test/future_test1.py -mingw32/lib/python3.11/test/future_test2.py mingw32/lib/python3.11/test/gdb_sample.py mingw32/lib/python3.11/test/idnsans.pem mingw32/lib/python3.11/test/ieee754.txt @@ -5644,7 +5538,6 @@ mingw32/lib/python3.11/test/sample_doctest_no_doctests.py mingw32/lib/python3.11/test/secp384r1.pem mingw32/lib/python3.11/test/selfsigned_pythontestdotnet.pem mingw32/lib/python3.11/test/seq_tests.py -mingw32/lib/python3.11/test/sgml_input.html mingw32/lib/python3.11/test/signalinterproctester.py mingw32/lib/python3.11/test/Sine-1000Hz-300ms.aif mingw32/lib/python3.11/test/sndhdrdata/ @@ -5738,7 +5631,6 @@ mingw32/lib/python3.11/test/support/threading_helper.py mingw32/lib/python3.11/test/support/warnings_helper.py mingw32/lib/python3.11/test/talos-2019-0758.pem mingw32/lib/python3.11/test/test___all__.py -mingw32/lib/python3.11/test/test___future__.py mingw32/lib/python3.11/test/test__locale.py mingw32/lib/python3.11/test/test__opcode.py mingw32/lib/python3.11/test/test__osx_support.py @@ -5986,7 +5878,6 @@ mingw32/lib/python3.11/test/test_compare.py mingw32/lib/python3.11/test/test_compile.py mingw32/lib/python3.11/test/test_compileall.py mingw32/lib/python3.11/test/test_complex.py -mingw32/lib/python3.11/test/test_concurrent_futures.py mingw32/lib/python3.11/test/test_configparser.py mingw32/lib/python3.11/test/test_contains.py mingw32/lib/python3.11/test/test_context.py @@ -6012,7 +5903,32 @@ mingw32/lib/python3.11/test/test_crypt.py mingw32/lib/python3.11/test/test_csv.py mingw32/lib/python3.11/test/test_ctypes.py mingw32/lib/python3.11/test/test_curses.py -mingw32/lib/python3.11/test/test_dataclasses.py +mingw32/lib/python3.11/test/test_dataclasses/ +mingw32/lib/python3.11/test/test_dataclasses/__init__.py +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/ +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/__init__.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/__init__.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/__init__.cpython-311.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_1.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_1.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_1.cpython-311.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_1_str.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_1_str.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_1_str.cpython-311.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_2.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_2.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_2.cpython-311.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_2_str.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_2_str.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_2_str.cpython-311.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_textanno.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_textanno.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_textanno.cpython-311.pyc +mingw32/lib/python3.11/test/test_dataclasses/dataclass_module_1.py +mingw32/lib/python3.11/test/test_dataclasses/dataclass_module_1_str.py +mingw32/lib/python3.11/test/test_dataclasses/dataclass_module_2.py +mingw32/lib/python3.11/test/test_dataclasses/dataclass_module_2_str.py +mingw32/lib/python3.11/test/test_dataclasses/dataclass_textanno.py mingw32/lib/python3.11/test/test_datetime.py mingw32/lib/python3.11/test/test_dbm.py mingw32/lib/python3.11/test/test_dbm_dumb.py @@ -6214,10 +6130,48 @@ mingw32/lib/python3.11/test/test_fstring.py mingw32/lib/python3.11/test/test_ftplib.py mingw32/lib/python3.11/test/test_funcattrs.py mingw32/lib/python3.11/test/test_functools.py -mingw32/lib/python3.11/test/test_future.py -mingw32/lib/python3.11/test/test_future3.py -mingw32/lib/python3.11/test/test_future4.py -mingw32/lib/python3.11/test/test_future5.py +mingw32/lib/python3.11/test/test_future_stmt/ +mingw32/lib/python3.11/test/test_future_stmt/__init__.py +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/ +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/__init__.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/__init__.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/__init__.cpython-311.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/future_test1.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/future_test1.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/future_test1.cpython-311.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/future_test2.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/future_test2.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/future_test2.cpython-311.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/test_future.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/test_future.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/test_future.cpython-311.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/test_future_flags.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/test_future_flags.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/test_future_flags.cpython-311.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/test_future_multiple_features.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/test_future_multiple_features.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/test_future_multiple_features.cpython-311.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/test_future_multiple_imports.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/test_future_multiple_imports.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/test_future_multiple_imports.cpython-311.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/test_future_single_import.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/test_future_single_import.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/test_future_stmt/__pycache__/test_future_single_import.cpython-311.pyc +mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future10.py +mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future3.py +mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future4.py +mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future5.py +mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future6.py +mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future7.py +mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future8.py +mingw32/lib/python3.11/test/test_future_stmt/badsyntax_future9.py +mingw32/lib/python3.11/test/test_future_stmt/future_test1.py +mingw32/lib/python3.11/test/test_future_stmt/future_test2.py +mingw32/lib/python3.11/test/test_future_stmt/test_future.py +mingw32/lib/python3.11/test/test_future_stmt/test_future_flags.py +mingw32/lib/python3.11/test/test_future_stmt/test_future_multiple_features.py +mingw32/lib/python3.11/test/test_future_stmt/test_future_multiple_imports.py +mingw32/lib/python3.11/test/test_future_stmt/test_future_single_import.py mingw32/lib/python3.11/test/test_gc.py mingw32/lib/python3.11/test/test_gdb.py mingw32/lib/python3.11/test/test_generator_stop.py @@ -6942,10 +6896,7 @@ mingw32/lib/python3.11/test/test_module/good_getattr.py mingw32/lib/python3.11/test/test_modulefinder.py mingw32/lib/python3.11/test/test_msilib.py mingw32/lib/python3.11/test/test_multibytecodec.py -mingw32/lib/python3.11/test/test_multiprocessing_fork.py -mingw32/lib/python3.11/test/test_multiprocessing_forkserver.py mingw32/lib/python3.11/test/test_multiprocessing_main_handling.py -mingw32/lib/python3.11/test/test_multiprocessing_spawn.py mingw32/lib/python3.11/test/test_named_expressions.py mingw32/lib/python3.11/test/test_netrc.py mingw32/lib/python3.11/test/test_nis.py @@ -7434,11 +7385,25 @@ mingw32/lib/python3.11/test/testtar.tar mingw32/lib/python3.11/test/testtar.tar.xz mingw32/lib/python3.11/test/tf_inherit_check.py mingw32/lib/python3.11/test/time_hashlib.py -mingw32/lib/python3.11/test/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt -mingw32/lib/python3.11/test/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt -mingw32/lib/python3.11/test/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt -mingw32/lib/python3.11/test/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt -mingw32/lib/python3.11/test/tokenize_tests.txt +mingw32/lib/python3.11/test/tokenizedata/ +mingw32/lib/python3.11/test/tokenizedata/__init__.py +mingw32/lib/python3.11/test/tokenizedata/__pycache__/ +mingw32/lib/python3.11/test/tokenizedata/__pycache__/__init__.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/tokenizedata/__pycache__/__init__.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/tokenizedata/__pycache__/__init__.cpython-311.pyc +mingw32/lib/python3.11/test/tokenizedata/__pycache__/coding20731.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/tokenizedata/__pycache__/coding20731.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/tokenizedata/__pycache__/coding20731.cpython-311.pyc +mingw32/lib/python3.11/test/tokenizedata/bad_coding.py +mingw32/lib/python3.11/test/tokenizedata/bad_coding2.py +mingw32/lib/python3.11/test/tokenizedata/badsyntax_3131.py +mingw32/lib/python3.11/test/tokenizedata/badsyntax_pep3120.py +mingw32/lib/python3.11/test/tokenizedata/coding20731.py +mingw32/lib/python3.11/test/tokenizedata/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt +mingw32/lib/python3.11/test/tokenizedata/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt +mingw32/lib/python3.11/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt +mingw32/lib/python3.11/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt +mingw32/lib/python3.11/test/tokenizedata/tokenize_tests.txt mingw32/lib/python3.11/test/tracedmodules/ mingw32/lib/python3.11/test/tracedmodules/__init__.py mingw32/lib/python3.11/test/tracedmodules/__pycache__/ @@ -7455,9 +7420,41 @@ mingw32/lib/python3.11/test/typinganndata/__pycache__/ mingw32/lib/python3.11/test/typinganndata/__pycache__/__init__.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/typinganndata/__pycache__/__init__.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/typinganndata/__pycache__/__init__.cpython-311.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module.cpython-311.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module2.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module2.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module2.cpython-311.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module3.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module3.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module3.cpython-311.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module4.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module4.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module4.cpython-311.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module5.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module5.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module5.cpython-311.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module6.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module6.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module6.cpython-311.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module7.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module7.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module7.cpython-311.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module8.cpython-311.opt-1.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module8.cpython-311.opt-2.pyc +mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module8.cpython-311.pyc mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module9.cpython-311.opt-1.pyc mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module9.cpython-311.opt-2.pyc mingw32/lib/python3.11/test/typinganndata/__pycache__/ann_module9.cpython-311.pyc +mingw32/lib/python3.11/test/typinganndata/ann_module.py +mingw32/lib/python3.11/test/typinganndata/ann_module2.py +mingw32/lib/python3.11/test/typinganndata/ann_module3.py +mingw32/lib/python3.11/test/typinganndata/ann_module4.py +mingw32/lib/python3.11/test/typinganndata/ann_module5.py +mingw32/lib/python3.11/test/typinganndata/ann_module6.py +mingw32/lib/python3.11/test/typinganndata/ann_module7.py +mingw32/lib/python3.11/test/typinganndata/ann_module8.py mingw32/lib/python3.11/test/typinganndata/ann_module9.py mingw32/lib/python3.11/test/win_console_handler.py mingw32/lib/python3.11/test/xmltestdata/ diff --git a/var/lib/pacman/local/mingw-w64-i686-python-3.11.6-1/mtree b/var/lib/pacman/local/mingw-w64-i686-python-3.11.6-1/mtree new file mode 100644 index 00000000000..12ac539fb51 Binary files /dev/null and b/var/lib/pacman/local/mingw-w64-i686-python-3.11.6-1/mtree differ diff --git a/var/lib/pacman/local/mingw-w64-x86_64-git-extra-1.1.636.2db97b993-1/desc b/var/lib/pacman/local/mingw-w64-x86_64-git-extra-1.1.636.2db97b993-1/desc index 072f147798e..38edcf811ed 100644 --- a/var/lib/pacman/local/mingw-w64-x86_64-git-extra-1.1.636.2db97b993-1/desc +++ b/var/lib/pacman/local/mingw-w64-x86_64-git-extra-1.1.636.2db97b993-1/desc @@ -20,7 +20,7 @@ any 1682971619 %INSTALLDATE% -1696129241 +1696474841 %PACKAGER% Johannes Schindelin diff --git a/var/lib/pacman/local/mingw-w64-x86_64-python-3.11.5-5/mtree b/var/lib/pacman/local/mingw-w64-x86_64-python-3.11.5-5/mtree deleted file mode 100644 index b07deb2ae3b..00000000000 Binary files a/var/lib/pacman/local/mingw-w64-x86_64-python-3.11.5-5/mtree and /dev/null differ diff --git a/var/lib/pacman/local/mingw-w64-x86_64-python-3.11.5-5/desc b/var/lib/pacman/local/mingw-w64-x86_64-python-3.11.6-1/desc similarity index 90% rename from var/lib/pacman/local/mingw-w64-x86_64-python-3.11.5-5/desc rename to var/lib/pacman/local/mingw-w64-x86_64-python-3.11.6-1/desc index f6e4047438f..6f2e4bedff3 100644 --- a/var/lib/pacman/local/mingw-w64-x86_64-python-3.11.5-5/desc +++ b/var/lib/pacman/local/mingw-w64-x86_64-python-3.11.6-1/desc @@ -2,7 +2,7 @@ mingw-w64-x86_64-python %VERSION% -3.11.5-5 +3.11.6-1 %BASE% mingw-w64-python @@ -17,16 +17,16 @@ https://www.python.org/ any %BUILDDATE% -1695930202 +1696324376 %INSTALLDATE% -1696129233 +1696474829 %PACKAGER% -CI (msys2/msys2-autobuild/a79a8c4c/6343502959) +CI (msys2/msys2-autobuild/a79a8c4c/6390866570) %SIZE% -202152170 +202004145 %REASON% 1 diff --git a/var/lib/pacman/local/mingw-w64-x86_64-python-3.11.5-5/files b/var/lib/pacman/local/mingw-w64-x86_64-python-3.11.6-1/files similarity index 98% rename from var/lib/pacman/local/mingw-w64-x86_64-python-3.11.5-5/files rename to var/lib/pacman/local/mingw-w64-x86_64-python-3.11.6-1/files index 0bca4d3f3cc..9bf92620a27 100644 --- a/var/lib/pacman/local/mingw-w64-x86_64-python-3.11.5-5/files +++ b/var/lib/pacman/local/mingw-w64-x86_64-python-3.11.6-1/files @@ -3315,11 +3315,11 @@ mingw64/lib/python3.11/lib2to3/fixes/fix_xrange.py mingw64/lib/python3.11/lib2to3/fixes/fix_xreadlines.py mingw64/lib/python3.11/lib2to3/fixes/fix_zip.py mingw64/lib/python3.11/lib2to3/Grammar.txt -mingw64/lib/python3.11/lib2to3/Grammar3.11.5.final.0.pickle +mingw64/lib/python3.11/lib2to3/Grammar3.11.6.final.0.pickle mingw64/lib/python3.11/lib2to3/main.py mingw64/lib/python3.11/lib2to3/patcomp.py mingw64/lib/python3.11/lib2to3/PatternGrammar.txt -mingw64/lib/python3.11/lib2to3/PatternGrammar3.11.5.final.0.pickle +mingw64/lib/python3.11/lib2to3/PatternGrammar3.11.6.final.0.pickle mingw64/lib/python3.11/lib2to3/pgen2/ mingw64/lib/python3.11/lib2to3/pgen2/__init__.py mingw64/lib/python3.11/lib2to3/pgen2/__pycache__/ @@ -3705,30 +3705,6 @@ mingw64/lib/python3.11/test/__pycache__/_test_venv_multiprocessing.cpython-311.p mingw64/lib/python3.11/test/__pycache__/_typed_dict_helper.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/_typed_dict_helper.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/_typed_dict_helper.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module2.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module2.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module2.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module3.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module3.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module3.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module4.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module4.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module4.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module5.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module5.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module5.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module6.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module6.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module6.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module7.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module7.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module7.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module8.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module8.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/ann_module8.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/audiotests.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/audiotests.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/audiotests.cpython-311.pyc @@ -3741,27 +3717,9 @@ mingw64/lib/python3.11/test/__pycache__/autotest.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/bisect_cmd.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/bisect_cmd.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/bisect_cmd.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/coding20731.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/coding20731.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/coding20731.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/curses_tests.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/curses_tests.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/curses_tests.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/dataclass_module_1.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/dataclass_module_1.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/dataclass_module_1.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/dataclass_module_1_str.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/dataclass_module_1_str.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/dataclass_module_1_str.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/dataclass_module_2.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/dataclass_module_2.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/dataclass_module_2.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/dataclass_module_2_str.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/dataclass_module_2_str.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/dataclass_module_2_str.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/dataclass_textanno.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/dataclass_textanno.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/dataclass_textanno.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/datetimetester.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/datetimetester.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/datetimetester.cpython-311.pyc @@ -3786,12 +3744,6 @@ mingw64/lib/python3.11/test/__pycache__/final_b.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/fork_wait.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/fork_wait.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/fork_wait.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/future_test1.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/future_test1.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/future_test1.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/future_test2.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/future_test2.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/future_test2.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/gdb_sample.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/gdb_sample.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/gdb_sample.cpython-311.pyc @@ -3903,9 +3855,6 @@ mingw64/lib/python3.11/test/__pycache__/string_tests.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/test___all__.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/test___all__.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/test___all__.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/test___future__.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/test___future__.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/test___future__.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/test__locale.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/test__locale.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/test__locale.cpython-311.pyc @@ -4107,9 +4056,6 @@ mingw64/lib/python3.11/test/__pycache__/test_compileall.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/test_complex.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/test_complex.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/test_complex.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/test_concurrent_futures.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/test_concurrent_futures.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/test_concurrent_futures.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/test_configparser.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/test_configparser.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/test_configparser.cpython-311.pyc @@ -4152,9 +4098,6 @@ mingw64/lib/python3.11/test/__pycache__/test_ctypes.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/test_curses.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/test_curses.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/test_curses.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/test_dataclasses.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/test_dataclasses.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/test_dataclasses.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/test_datetime.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/test_datetime.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/test_datetime.cpython-311.pyc @@ -4335,18 +4278,6 @@ mingw64/lib/python3.11/test/__pycache__/test_funcattrs.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/test_functools.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/test_functools.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/test_functools.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/test_future.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/test_future.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/test_future.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/test_future3.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/test_future3.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/test_future3.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/test_future4.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/test_future4.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/test_future4.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/test_future5.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/test_future5.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/test_future5.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/test_gc.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/test_gc.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/test_gc.cpython-311.pyc @@ -4563,18 +4494,9 @@ mingw64/lib/python3.11/test/__pycache__/test_msilib.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/test_multibytecodec.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/test_multibytecodec.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/test_multibytecodec.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/test_multiprocessing_fork.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/test_multiprocessing_fork.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/test_multiprocessing_fork.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/test_multiprocessing_forkserver.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/test_multiprocessing_forkserver.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/test_multiprocessing_forkserver.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/test_multiprocessing_main_handling.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/test_multiprocessing_main_handling.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/test_multiprocessing_main_handling.cpython-311.pyc -mingw64/lib/python3.11/test/__pycache__/test_multiprocessing_spawn.cpython-311.opt-1.pyc -mingw64/lib/python3.11/test/__pycache__/test_multiprocessing_spawn.cpython-311.opt-2.pyc -mingw64/lib/python3.11/test/__pycache__/test_multiprocessing_spawn.cpython-311.pyc mingw64/lib/python3.11/test/__pycache__/test_named_expressions.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/__pycache__/test_named_expressions.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/__pycache__/test_named_expressions.cpython-311.pyc @@ -5183,14 +5105,6 @@ mingw64/lib/python3.11/test/_test_multiprocessing.py mingw64/lib/python3.11/test/_test_venv_multiprocessing.py mingw64/lib/python3.11/test/_typed_dict_helper.py mingw64/lib/python3.11/test/allsans.pem -mingw64/lib/python3.11/test/ann_module.py -mingw64/lib/python3.11/test/ann_module2.py -mingw64/lib/python3.11/test/ann_module3.py -mingw64/lib/python3.11/test/ann_module4.py -mingw64/lib/python3.11/test/ann_module5.py -mingw64/lib/python3.11/test/ann_module6.py -mingw64/lib/python3.11/test/ann_module7.py -mingw64/lib/python3.11/test/ann_module8.py mingw64/lib/python3.11/test/audiodata/ mingw64/lib/python3.11/test/audiodata/pluck-alaw.aifc mingw64/lib/python3.11/test/audiodata/pluck-pcm16.aiff @@ -5211,20 +5125,8 @@ mingw64/lib/python3.11/test/audiotest.au mingw64/lib/python3.11/test/audiotests.py mingw64/lib/python3.11/test/audit-tests.py mingw64/lib/python3.11/test/autotest.py -mingw64/lib/python3.11/test/bad_coding.py -mingw64/lib/python3.11/test/bad_coding2.py mingw64/lib/python3.11/test/badcert.pem mingw64/lib/python3.11/test/badkey.pem -mingw64/lib/python3.11/test/badsyntax_3131.py -mingw64/lib/python3.11/test/badsyntax_future10.py -mingw64/lib/python3.11/test/badsyntax_future3.py -mingw64/lib/python3.11/test/badsyntax_future4.py -mingw64/lib/python3.11/test/badsyntax_future5.py -mingw64/lib/python3.11/test/badsyntax_future6.py -mingw64/lib/python3.11/test/badsyntax_future7.py -mingw64/lib/python3.11/test/badsyntax_future8.py -mingw64/lib/python3.11/test/badsyntax_future9.py -mingw64/lib/python3.11/test/badsyntax_pep3120.py mingw64/lib/python3.11/test/bisect_cmd.py mingw64/lib/python3.11/test/capath/ mingw64/lib/python3.11/test/capath/4e1295a3.0 @@ -5269,7 +5171,6 @@ mingw64/lib/python3.11/test/cjkencodings/shift_jisx0213-utf8.txt mingw64/lib/python3.11/test/cjkencodings/shift_jisx0213.txt mingw64/lib/python3.11/test/clinic.test.c mingw64/lib/python3.11/test/cmath_testcases.txt -mingw64/lib/python3.11/test/coding20731.py mingw64/lib/python3.11/test/crashers/ mingw64/lib/python3.11/test/crashers/__pycache__/ mingw64/lib/python3.11/test/crashers/__pycache__/bogus_code_obj.cpython-311.opt-1.pyc @@ -5304,11 +5205,6 @@ mingw64/lib/python3.11/test/crashers/underlying_dict.py mingw64/lib/python3.11/test/curses_tests.py mingw64/lib/python3.11/test/data/ mingw64/lib/python3.11/test/data/README -mingw64/lib/python3.11/test/dataclass_module_1.py -mingw64/lib/python3.11/test/dataclass_module_1_str.py -mingw64/lib/python3.11/test/dataclass_module_2.py -mingw64/lib/python3.11/test/dataclass_module_2_str.py -mingw64/lib/python3.11/test/dataclass_textanno.py mingw64/lib/python3.11/test/datetimetester.py mingw64/lib/python3.11/test/decimaltestdata/ mingw64/lib/python3.11/test/decimaltestdata/abs.decTest @@ -5510,8 +5406,6 @@ mingw64/lib/python3.11/test/final_b.py mingw64/lib/python3.11/test/floating_points.txt mingw64/lib/python3.11/test/fork_wait.py mingw64/lib/python3.11/test/formatfloat_testcases.txt -mingw64/lib/python3.11/test/future_test1.py -mingw64/lib/python3.11/test/future_test2.py mingw64/lib/python3.11/test/gdb_sample.py mingw64/lib/python3.11/test/idnsans.pem mingw64/lib/python3.11/test/ieee754.txt @@ -5644,7 +5538,6 @@ mingw64/lib/python3.11/test/sample_doctest_no_doctests.py mingw64/lib/python3.11/test/secp384r1.pem mingw64/lib/python3.11/test/selfsigned_pythontestdotnet.pem mingw64/lib/python3.11/test/seq_tests.py -mingw64/lib/python3.11/test/sgml_input.html mingw64/lib/python3.11/test/signalinterproctester.py mingw64/lib/python3.11/test/Sine-1000Hz-300ms.aif mingw64/lib/python3.11/test/sndhdrdata/ @@ -5738,7 +5631,6 @@ mingw64/lib/python3.11/test/support/threading_helper.py mingw64/lib/python3.11/test/support/warnings_helper.py mingw64/lib/python3.11/test/talos-2019-0758.pem mingw64/lib/python3.11/test/test___all__.py -mingw64/lib/python3.11/test/test___future__.py mingw64/lib/python3.11/test/test__locale.py mingw64/lib/python3.11/test/test__opcode.py mingw64/lib/python3.11/test/test__osx_support.py @@ -5986,7 +5878,6 @@ mingw64/lib/python3.11/test/test_compare.py mingw64/lib/python3.11/test/test_compile.py mingw64/lib/python3.11/test/test_compileall.py mingw64/lib/python3.11/test/test_complex.py -mingw64/lib/python3.11/test/test_concurrent_futures.py mingw64/lib/python3.11/test/test_configparser.py mingw64/lib/python3.11/test/test_contains.py mingw64/lib/python3.11/test/test_context.py @@ -6012,7 +5903,32 @@ mingw64/lib/python3.11/test/test_crypt.py mingw64/lib/python3.11/test/test_csv.py mingw64/lib/python3.11/test/test_ctypes.py mingw64/lib/python3.11/test/test_curses.py -mingw64/lib/python3.11/test/test_dataclasses.py +mingw64/lib/python3.11/test/test_dataclasses/ +mingw64/lib/python3.11/test/test_dataclasses/__init__.py +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/ +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/__init__.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/__init__.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/__init__.cpython-311.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_1.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_1.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_1.cpython-311.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_1_str.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_1_str.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_1_str.cpython-311.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_2.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_2.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_2.cpython-311.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_2_str.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_2_str.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_module_2_str.cpython-311.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_textanno.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_textanno.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/test_dataclasses/__pycache__/dataclass_textanno.cpython-311.pyc +mingw64/lib/python3.11/test/test_dataclasses/dataclass_module_1.py +mingw64/lib/python3.11/test/test_dataclasses/dataclass_module_1_str.py +mingw64/lib/python3.11/test/test_dataclasses/dataclass_module_2.py +mingw64/lib/python3.11/test/test_dataclasses/dataclass_module_2_str.py +mingw64/lib/python3.11/test/test_dataclasses/dataclass_textanno.py mingw64/lib/python3.11/test/test_datetime.py mingw64/lib/python3.11/test/test_dbm.py mingw64/lib/python3.11/test/test_dbm_dumb.py @@ -6214,10 +6130,48 @@ mingw64/lib/python3.11/test/test_fstring.py mingw64/lib/python3.11/test/test_ftplib.py mingw64/lib/python3.11/test/test_funcattrs.py mingw64/lib/python3.11/test/test_functools.py -mingw64/lib/python3.11/test/test_future.py -mingw64/lib/python3.11/test/test_future3.py -mingw64/lib/python3.11/test/test_future4.py -mingw64/lib/python3.11/test/test_future5.py +mingw64/lib/python3.11/test/test_future_stmt/ +mingw64/lib/python3.11/test/test_future_stmt/__init__.py +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/ +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/__init__.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/__init__.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/__init__.cpython-311.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/future_test1.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/future_test1.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/future_test1.cpython-311.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/future_test2.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/future_test2.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/future_test2.cpython-311.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/test_future.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/test_future.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/test_future.cpython-311.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/test_future_flags.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/test_future_flags.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/test_future_flags.cpython-311.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/test_future_multiple_features.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/test_future_multiple_features.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/test_future_multiple_features.cpython-311.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/test_future_multiple_imports.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/test_future_multiple_imports.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/test_future_multiple_imports.cpython-311.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/test_future_single_import.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/test_future_single_import.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/test_future_stmt/__pycache__/test_future_single_import.cpython-311.pyc +mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future10.py +mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future3.py +mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future4.py +mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future5.py +mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future6.py +mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future7.py +mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future8.py +mingw64/lib/python3.11/test/test_future_stmt/badsyntax_future9.py +mingw64/lib/python3.11/test/test_future_stmt/future_test1.py +mingw64/lib/python3.11/test/test_future_stmt/future_test2.py +mingw64/lib/python3.11/test/test_future_stmt/test_future.py +mingw64/lib/python3.11/test/test_future_stmt/test_future_flags.py +mingw64/lib/python3.11/test/test_future_stmt/test_future_multiple_features.py +mingw64/lib/python3.11/test/test_future_stmt/test_future_multiple_imports.py +mingw64/lib/python3.11/test/test_future_stmt/test_future_single_import.py mingw64/lib/python3.11/test/test_gc.py mingw64/lib/python3.11/test/test_gdb.py mingw64/lib/python3.11/test/test_generator_stop.py @@ -6942,10 +6896,7 @@ mingw64/lib/python3.11/test/test_module/good_getattr.py mingw64/lib/python3.11/test/test_modulefinder.py mingw64/lib/python3.11/test/test_msilib.py mingw64/lib/python3.11/test/test_multibytecodec.py -mingw64/lib/python3.11/test/test_multiprocessing_fork.py -mingw64/lib/python3.11/test/test_multiprocessing_forkserver.py mingw64/lib/python3.11/test/test_multiprocessing_main_handling.py -mingw64/lib/python3.11/test/test_multiprocessing_spawn.py mingw64/lib/python3.11/test/test_named_expressions.py mingw64/lib/python3.11/test/test_netrc.py mingw64/lib/python3.11/test/test_nis.py @@ -7434,11 +7385,25 @@ mingw64/lib/python3.11/test/testtar.tar mingw64/lib/python3.11/test/testtar.tar.xz mingw64/lib/python3.11/test/tf_inherit_check.py mingw64/lib/python3.11/test/time_hashlib.py -mingw64/lib/python3.11/test/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt -mingw64/lib/python3.11/test/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt -mingw64/lib/python3.11/test/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt -mingw64/lib/python3.11/test/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt -mingw64/lib/python3.11/test/tokenize_tests.txt +mingw64/lib/python3.11/test/tokenizedata/ +mingw64/lib/python3.11/test/tokenizedata/__init__.py +mingw64/lib/python3.11/test/tokenizedata/__pycache__/ +mingw64/lib/python3.11/test/tokenizedata/__pycache__/__init__.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/tokenizedata/__pycache__/__init__.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/tokenizedata/__pycache__/__init__.cpython-311.pyc +mingw64/lib/python3.11/test/tokenizedata/__pycache__/coding20731.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/tokenizedata/__pycache__/coding20731.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/tokenizedata/__pycache__/coding20731.cpython-311.pyc +mingw64/lib/python3.11/test/tokenizedata/bad_coding.py +mingw64/lib/python3.11/test/tokenizedata/bad_coding2.py +mingw64/lib/python3.11/test/tokenizedata/badsyntax_3131.py +mingw64/lib/python3.11/test/tokenizedata/badsyntax_pep3120.py +mingw64/lib/python3.11/test/tokenizedata/coding20731.py +mingw64/lib/python3.11/test/tokenizedata/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt +mingw64/lib/python3.11/test/tokenizedata/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt +mingw64/lib/python3.11/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt +mingw64/lib/python3.11/test/tokenizedata/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt +mingw64/lib/python3.11/test/tokenizedata/tokenize_tests.txt mingw64/lib/python3.11/test/tracedmodules/ mingw64/lib/python3.11/test/tracedmodules/__init__.py mingw64/lib/python3.11/test/tracedmodules/__pycache__/ @@ -7455,9 +7420,41 @@ mingw64/lib/python3.11/test/typinganndata/__pycache__/ mingw64/lib/python3.11/test/typinganndata/__pycache__/__init__.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/typinganndata/__pycache__/__init__.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/typinganndata/__pycache__/__init__.cpython-311.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module.cpython-311.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module2.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module2.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module2.cpython-311.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module3.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module3.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module3.cpython-311.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module4.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module4.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module4.cpython-311.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module5.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module5.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module5.cpython-311.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module6.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module6.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module6.cpython-311.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module7.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module7.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module7.cpython-311.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module8.cpython-311.opt-1.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module8.cpython-311.opt-2.pyc +mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module8.cpython-311.pyc mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module9.cpython-311.opt-1.pyc mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module9.cpython-311.opt-2.pyc mingw64/lib/python3.11/test/typinganndata/__pycache__/ann_module9.cpython-311.pyc +mingw64/lib/python3.11/test/typinganndata/ann_module.py +mingw64/lib/python3.11/test/typinganndata/ann_module2.py +mingw64/lib/python3.11/test/typinganndata/ann_module3.py +mingw64/lib/python3.11/test/typinganndata/ann_module4.py +mingw64/lib/python3.11/test/typinganndata/ann_module5.py +mingw64/lib/python3.11/test/typinganndata/ann_module6.py +mingw64/lib/python3.11/test/typinganndata/ann_module7.py +mingw64/lib/python3.11/test/typinganndata/ann_module8.py mingw64/lib/python3.11/test/typinganndata/ann_module9.py mingw64/lib/python3.11/test/win_console_handler.py mingw64/lib/python3.11/test/xmltestdata/ diff --git a/var/lib/pacman/local/mingw-w64-x86_64-python-3.11.6-1/mtree b/var/lib/pacman/local/mingw-w64-x86_64-python-3.11.6-1/mtree new file mode 100644 index 00000000000..44fb293edef Binary files /dev/null and b/var/lib/pacman/local/mingw-w64-x86_64-python-3.11.6-1/mtree differ diff --git a/var/lib/pacman/local/openssh-9.4p1-1/mtree b/var/lib/pacman/local/openssh-9.4p1-1/mtree deleted file mode 100644 index eeb35701b47..00000000000 Binary files a/var/lib/pacman/local/openssh-9.4p1-1/mtree and /dev/null differ diff --git a/var/lib/pacman/local/openssh-9.4p1-1/desc b/var/lib/pacman/local/openssh-9.5p1-1/desc similarity index 90% rename from var/lib/pacman/local/openssh-9.4p1-1/desc rename to var/lib/pacman/local/openssh-9.5p1-1/desc index 7e285964ae7..4483da1c05f 100644 --- a/var/lib/pacman/local/openssh-9.4p1-1/desc +++ b/var/lib/pacman/local/openssh-9.5p1-1/desc @@ -2,7 +2,7 @@ openssh %VERSION% -9.4p1-1 +9.5p1-1 %BASE% openssh @@ -17,16 +17,16 @@ http://www.openssh.org/portable.html x86_64 %BUILDDATE% -1691669322 +1696424903 %INSTALLDATE% -1691683978 +1696474829 %PACKAGER% Johannes Schindelin %SIZE% -6631512 +6719832 %GROUPS% net-utils diff --git a/var/lib/pacman/local/openssh-9.4p1-1/files b/var/lib/pacman/local/openssh-9.5p1-1/files similarity index 100% rename from var/lib/pacman/local/openssh-9.4p1-1/files rename to var/lib/pacman/local/openssh-9.5p1-1/files diff --git a/var/lib/pacman/local/openssh-9.5p1-1/mtree b/var/lib/pacman/local/openssh-9.5p1-1/mtree new file mode 100644 index 00000000000..bc371aa1b2e Binary files /dev/null and b/var/lib/pacman/local/openssh-9.5p1-1/mtree differ diff --git a/var/lib/pacman/local/vim-9.0.1907-1/mtree b/var/lib/pacman/local/vim-9.0.1907-1/mtree deleted file mode 100644 index 87af41d8ae4..00000000000 Binary files a/var/lib/pacman/local/vim-9.0.1907-1/mtree and /dev/null differ diff --git a/var/lib/pacman/local/vim-9.0.1907-1/desc b/var/lib/pacman/local/vim-9.0.1969-1/desc similarity index 78% rename from var/lib/pacman/local/vim-9.0.1907-1/desc rename to var/lib/pacman/local/vim-9.0.1969-1/desc index ec78f95e891..d39c9b582d0 100644 --- a/var/lib/pacman/local/vim-9.0.1907-1/desc +++ b/var/lib/pacman/local/vim-9.0.1969-1/desc @@ -2,7 +2,7 @@ vim %VERSION% -9.0.1907-1 +9.0.1969-1 %BASE% vim @@ -17,16 +17,16 @@ https://www.vim.org x86_64 %BUILDDATE% -1695032064 +1696323890 %INSTALLDATE% -1695092470 +1696474833 %PACKAGER% -CI (msys2/msys2-autobuild/3f5f60aa/6221121438) +CI (msys2/msys2-autobuild/a79a8c4c/6390866570) %SIZE% -58586775 +58732245 %GROUPS% editors diff --git a/var/lib/pacman/local/vim-9.0.1907-1/files b/var/lib/pacman/local/vim-9.0.1969-1/files similarity index 99% rename from var/lib/pacman/local/vim-9.0.1907-1/files rename to var/lib/pacman/local/vim-9.0.1969-1/files index f01c15eafe4..9e7eaed3c65 100644 --- a/var/lib/pacman/local/vim-9.0.1907-1/files +++ b/var/lib/pacman/local/vim-9.0.1969-1/files @@ -713,6 +713,7 @@ usr/share/vim/vim90/ftplugin/jsonnet.vim usr/share/vim/vim90/ftplugin/jsp.vim usr/share/vim/vim90/ftplugin/julia.vim usr/share/vim/vim90/ftplugin/kconfig.vim +usr/share/vim/vim90/ftplugin/kotlin.vim usr/share/vim/vim90/ftplugin/kwt.vim usr/share/vim/vim90/ftplugin/ld.vim usr/share/vim/vim90/ftplugin/less.vim @@ -965,6 +966,7 @@ usr/share/vim/vim90/indent/json.vim usr/share/vim/vim90/indent/jsonc.vim usr/share/vim/vim90/indent/jsp.vim usr/share/vim/vim90/indent/julia.vim +usr/share/vim/vim90/indent/kotlin.vim usr/share/vim/vim90/indent/krl.vim usr/share/vim/vim90/indent/ld.vim usr/share/vim/vim90/indent/less.vim @@ -1854,6 +1856,7 @@ usr/share/vim/vim90/syntax/julia.vim usr/share/vim/vim90/syntax/kconfig.vim usr/share/vim/vim90/syntax/kivy.vim usr/share/vim/vim90/syntax/kix.vim +usr/share/vim/vim90/syntax/kotlin.vim usr/share/vim/vim90/syntax/krl.vim usr/share/vim/vim90/syntax/kscript.vim usr/share/vim/vim90/syntax/kwt.vim diff --git a/var/lib/pacman/local/vim-9.0.1969-1/mtree b/var/lib/pacman/local/vim-9.0.1969-1/mtree new file mode 100644 index 00000000000..ba9845c800f Binary files /dev/null and b/var/lib/pacman/local/vim-9.0.1969-1/mtree differ diff --git a/var/lib/pacman/sync/clang32.db b/var/lib/pacman/sync/clang32.db index f25eb63a42f..1b13fafbd45 100644 Binary files a/var/lib/pacman/sync/clang32.db and b/var/lib/pacman/sync/clang32.db differ diff --git a/var/lib/pacman/sync/clang32.db.sig b/var/lib/pacman/sync/clang32.db.sig index 818fbb37c9e..b531817eb53 100644 Binary files a/var/lib/pacman/sync/clang32.db.sig and b/var/lib/pacman/sync/clang32.db.sig differ diff --git a/var/lib/pacman/sync/clang64.db b/var/lib/pacman/sync/clang64.db index 752fe9f3328..c25a68ea9f0 100644 Binary files a/var/lib/pacman/sync/clang64.db and b/var/lib/pacman/sync/clang64.db differ diff --git a/var/lib/pacman/sync/clang64.db.sig b/var/lib/pacman/sync/clang64.db.sig index 3d0cb914884..31c50041257 100644 Binary files a/var/lib/pacman/sync/clang64.db.sig and b/var/lib/pacman/sync/clang64.db.sig differ diff --git a/var/lib/pacman/sync/clangarm64.db b/var/lib/pacman/sync/clangarm64.db index f816418a4f7..0508474895a 100644 Binary files a/var/lib/pacman/sync/clangarm64.db and b/var/lib/pacman/sync/clangarm64.db differ diff --git a/var/lib/pacman/sync/clangarm64.db.sig b/var/lib/pacman/sync/clangarm64.db.sig index 5f30c7eb51e..9de96965428 100644 Binary files a/var/lib/pacman/sync/clangarm64.db.sig and b/var/lib/pacman/sync/clangarm64.db.sig differ diff --git a/var/lib/pacman/sync/git-for-windows.db b/var/lib/pacman/sync/git-for-windows.db index 09f84855feb..17721521e2a 100644 Binary files a/var/lib/pacman/sync/git-for-windows.db and b/var/lib/pacman/sync/git-for-windows.db differ diff --git a/var/lib/pacman/sync/git-for-windows.db.sig b/var/lib/pacman/sync/git-for-windows.db.sig index de98f727d6e..9a3f730475d 100644 Binary files a/var/lib/pacman/sync/git-for-windows.db.sig and b/var/lib/pacman/sync/git-for-windows.db.sig differ diff --git a/var/lib/pacman/sync/mingw32.db b/var/lib/pacman/sync/mingw32.db index fff9ca85c50..433dd4699fd 100644 Binary files a/var/lib/pacman/sync/mingw32.db and b/var/lib/pacman/sync/mingw32.db differ diff --git a/var/lib/pacman/sync/mingw32.db.sig b/var/lib/pacman/sync/mingw32.db.sig index a6966631bfe..38345a49aae 100644 Binary files a/var/lib/pacman/sync/mingw32.db.sig and b/var/lib/pacman/sync/mingw32.db.sig differ diff --git a/var/lib/pacman/sync/mingw64.db b/var/lib/pacman/sync/mingw64.db index e1f708aca9a..1b1a1d4a570 100644 Binary files a/var/lib/pacman/sync/mingw64.db and b/var/lib/pacman/sync/mingw64.db differ diff --git a/var/lib/pacman/sync/mingw64.db.sig b/var/lib/pacman/sync/mingw64.db.sig index b723e7b03bd..f85f488e0b6 100644 Binary files a/var/lib/pacman/sync/mingw64.db.sig and b/var/lib/pacman/sync/mingw64.db.sig differ diff --git a/var/lib/pacman/sync/msys.db b/var/lib/pacman/sync/msys.db index 843113eeb07..0070a1c7902 100644 Binary files a/var/lib/pacman/sync/msys.db and b/var/lib/pacman/sync/msys.db differ diff --git a/var/lib/pacman/sync/msys.db.sig b/var/lib/pacman/sync/msys.db.sig index bbc7203f3db..7f0b6768ac0 100644 Binary files a/var/lib/pacman/sync/msys.db.sig and b/var/lib/pacman/sync/msys.db.sig differ diff --git a/var/lib/pacman/sync/ucrt64.db b/var/lib/pacman/sync/ucrt64.db index 36aead5e845..3412e2369db 100644 Binary files a/var/lib/pacman/sync/ucrt64.db and b/var/lib/pacman/sync/ucrt64.db differ diff --git a/var/lib/pacman/sync/ucrt64.db.sig b/var/lib/pacman/sync/ucrt64.db.sig index ed477809625..21db7d8bb59 100644 Binary files a/var/lib/pacman/sync/ucrt64.db.sig and b/var/lib/pacman/sync/ucrt64.db.sig differ